]> jfr.im git - irc/quakenet/newserv.git/blob - chanserv/chancmds/bandel.c
CHANSERV: better batcher error handling for expired accounts/accounts with no email.
[irc/quakenet/newserv.git] / chanserv / chancmds / bandel.c
1 /* Automatically generated by refactor.pl.
2 *
3 *
4 * CMDNAME: bandel
5 * CMDALIASES: unban
6 * CMDLEVEL: QCMD_AUTHED
7 * CMDARGS: 2
8 * CMDDESC: Removes a single ban from a channel.
9 * CMDFUNC: csc_dobandel
10 * CMDPROTO: int csc_dobandel(void *source, int cargc, char **cargv);
11 * CMDHELP: Usage: @UCOMMAND@ <channel> <ban>
12 * CMDHELP: Removes the specified persistent or channel ban, where:
13 * CMDHELP: channel - the channel to use
14 * CMDHELP: ban - either a ban mask (nick!user@host), or #number (see BANLIST)
15 * CMDHELP: Removing channel bans requires operator (+o) access on the named channel.
16 * CMDHELP: Removing persistent bans requires master (+m) access on the named channel.
17 */
18
19 #include "../chanserv.h"
20 #include "../../nick/nick.h"
21 #include "../../lib/flags.h"
22 #include "../../lib/irc_string.h"
23 #include "../../channel/channel.h"
24 #include "../../parser/parser.h"
25 #include "../../irc/irc.h"
26 #include "../../localuser/localuserchannel.h"
27 #include <string.h>
28 #include <stdio.h>
29
30 int csc_dobandel(void *source, int cargc, char **cargv) {
31 nick *sender=source;
32 chanindex *cip;
33 regban **rbh, *rbp;
34 chanban *cbp;
35 regchan *rcp;
36 chanban *theban=NULL;
37 modechanges changes;
38 int i,banid=0;
39
40 if (cargc<2) {
41 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unban");
42 return CMD_ERROR;
43 }
44
45 if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL, "unban", 0, 0)))
46 return CMD_ERROR;
47
48 rcp=cip->exts[chanservext];
49
50 /* OK, let's see what they want to remove.. */
51 if (*cargv[1]=='#') {
52 /* Remove by ID number */
53 if (!(banid=strtoul(cargv[1]+1, NULL, 10))) {
54 chanservstdmessage(sender, QM_UNKNOWNBAN, cargv[1], cip->name->content);
55 return CMD_ERROR;
56 }
57 } else {
58 /* Remove by ban string */
59 theban=makeban(cargv[1]);
60 }
61
62 i=0;
63 for (rbh=&(rcp->bans);*rbh;rbh=&((*rbh)->next)) {
64 i++;
65 if ((banid && i==banid) ||
66 (theban && banequal(theban, (*rbh)->cbp))) {
67 /* got it - they will need master access to remove this */
68 rbp=*rbh;
69
70 if (!cs_checkaccess(sender, NULL, CA_MASTERPRIV, cip, "unban", 0, 0))
71 return CMD_ERROR;
72
73 chanservstdmessage(sender, QM_REMOVEDPERMBAN, bantostring(rbp->cbp), cip->name->content);
74 if (cip->channel) {
75 localsetmodeinit(&changes, cip->channel, chanservnick);
76 localdosetmode_ban(&changes, bantostring(rbp->cbp), MCB_DEL);
77 localsetmodeflush(&changes, 1);
78 }
79
80 /* Remove from database */
81 csdb_deleteban(rbp);
82 /* Remove from list */
83 (*rbh)=rbp->next;
84 /* Free ban/string and actual regban */
85 freesstring(rbp->reason);
86 freechanban(rbp->cbp);
87 freeregban(rbp);
88
89 if (theban)
90 freechanban(theban);
91
92 return CMD_OK;
93 }
94 }
95
96 /* If we've run out of registered bans, let's try channel bans */
97 if (cip->channel && cip->channel->bans) {
98 for (cbp=cip->channel->bans;cbp;cbp=cbp->next) {
99 for (rbp=rcp->bans;rbp;rbp=rbp->next) {
100 if (banequal(rbp->cbp,cbp))
101 break;
102 }
103
104 if (rbp)
105 continue;
106
107 i++;
108 if ((banid && (i==banid)) ||
109 (theban && banequal(theban, cbp))) {
110 char *banmask = bantostring(cbp);
111
112 /* got it - this is just a channel ban */
113 chanservstdmessage(sender, QM_REMOVEDCHANBAN, banmask, cip->name->content);
114 localsetmodeinit(&changes, cip->channel, chanservnick);
115 localdosetmode_ban(&changes, banmask, MCB_DEL);
116 localsetmodeflush(&changes, 1);
117
118 if (theban)
119 freechanban(theban);
120
121 return CMD_OK;
122 }
123 }
124 }
125
126 chanservstdmessage(sender, QM_UNKNOWNBAN, cargv[1], cip->name->content);
127
128 return CMD_OK;
129 }