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