localdosetmode_ban(&changes, bantostring(cip->channel->bans), MCB_DEL);
}
+ /* remove the registered bans that match on me */
+ cs_unbanfn(sender, cip, (UnbanFN)nickmatchban, sender, 1);
+
/* deopall */
for (i=0,lp=cip->channel->users->content;
i<cip->channel->users->hashsize;i++,lp++) {
int csc_dounbanmask(void *source, int cargc, char **cargv) {
nick *sender=source;
chanindex *cip;
- regban **rbh, *rbp;
- chanban **cbh, *cbp;
- regchan *rcp;
- chanban *theban;
- modechanges changes;
- char *banstr;
+ struct chanban *theban;
if (cargc<2) {
chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unbanmask");
if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL, "unbanmask", 0, 0)))
return CMD_ERROR;
- rcp=cip->exts[chanservext];
theban=makeban(cargv[1]);
+ /* nice cast here */
+ cs_unbanfn(sender, cip, (UnbanFN)banoverlap, theban, 1);
+ cs_log(sender,"UNBANMASK %s",bantostring(theban));
- if (cip->channel)
- localsetmodeinit(&changes, cip->channel, chanservnick);
-
- for (rbh=&(rcp->bans); *rbh; ) {
- rbp=*rbh;
- if (banoverlap(theban, rbp->cbp)) {
- banstr=bantostring(rbp->cbp);
- /* Check perms and remove */
- if (!cs_checkaccess(sender, NULL, CA_MASTERPRIV, cip, NULL, 0, 1)) {
- chanservstdmessage(sender, QM_NOTREMOVEDPERMBAN, banstr, cip->name->content);
- rbh=&(rbp->next);
- } else {
- chanservstdmessage(sender, QM_REMOVEDPERMBAN, banstr, cip->name->content);
- if (cip->channel)
- localdosetmode_ban(&changes, banstr, MCB_DEL);
- /* Remove from database */
- csdb_deleteban(rbp);
- /* Remove from list */
- (*rbh)=rbp->next;
- /* Free ban/string and update setby refcount, and free actual regban */
- freesstring(rbp->reason);
- freechanban(rbp->cbp);
- freeregban(rbp);
- }
- } else {
- rbh=&(rbp->next);
- }
- }
-
- if (cip->channel) {
- for (cbh=&(cip->channel->bans); *cbh; ) {
- cbp=*cbh;
- if (banoverlap(theban, cbp)) {
- /* Remove */
- banstr=bantostring(cbp);
- chanservstdmessage(sender, QM_REMOVEDCHANBAN, banstr, cip->name->content);
- localdosetmode_ban(&changes, banstr, MCB_DEL);
- } else {
- cbh=&(cbp->next);
- }
- }
- localsetmodeflush(&changes,1);
- }
-
-
chanservstdmessage(sender, QM_DONE);
return CMD_OK;
}
int csc_dounbanme(void *source, int cargc, char **cargv) {
nick *sender=source;
- regchan *rcp;
chanindex *cip;
- modechanges changes;
- chanban **cbh;
-
+
if (cargc<1) {
chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "unbanme");
return CMD_ERROR;
if (!(cip=cs_checkaccess(sender, cargv[0], CA_OPPRIV, NULL, "unbanme", 0, 0)))
return CMD_ERROR;
- rcp=cip->exts[chanservext];
-
- if (cip->channel) {
- localsetmodeinit(&changes, cip->channel, chanservnick);
-
- for (cbh=&(cip->channel->bans);*cbh;) {
- if (nickmatchban(sender, *cbh))
- localdosetmode_ban(&changes, bantostring(*cbh), MCB_DEL);
- else
- cbh=&((*cbh)->next);
- }
-
- localsetmodeflush(&changes, 1);
- }
+ cs_unbanfn(sender, cip, (UnbanFN)nickmatchban, sender, 1);
cs_log(sender,"UNBANME %s",cip->name->content);
chanservstdmessage(sender, QM_DONE);
#define QM_REPLACINGBANSDURATION 153
#define QM_TOOMANYCHANLEVS 154
#define QM_TOOMANYBANS 155
+#define QM_WARNNOTREMOVEDPERMBAN 156
/* List of privileged operations */
int checkhashpass(reguser *rup, const char *junk, const char *hash);
flag_t cs_sanitisechanlev(flag_t flags);
+typedef int (*UnbanFN)(void *arg, struct chanban *ban);
+void cs_unbanfn(nick *sender, chanindex *cip, UnbanFN fn, void *arg, int removepermbans);
+
/* chanservstdcmds.c */
int cs_doshowcommands(void *source, int cargc, char **cargv);
int cs_dohelp(void *source, int cargc, char **cargv);
return rup;
}
+
+/*
+ * Unbans a mask from a channel, including permbans if user has correct privs.
+ */
+void cs_unbanfn(nick *sender, chanindex *cip, UnbanFN fn, void *arg, int removepermbans) {
+ regban **rbh, *rbp;
+ chanban **cbh, *cbp;
+ regchan *rcp;
+ modechanges changes;
+ char *banstr;
+
+ rcp=cip->exts[chanservext];
+
+ if (cip->channel)
+ localsetmodeinit(&changes, cip->channel, chanservnick);
+
+ for (rbh=&(rcp->bans); *rbh; ) {
+ rbp=*rbh;
+ if (fn(arg, rbp->cbp)) {
+ banstr=bantostring(rbp->cbp);
+ /* Check perms and remove */
+ if(!removepermbans) {
+ chanservstdmessage(sender, QM_WARNNOTREMOVEDPERMBAN, banstr, cip->name->content);
+ rbh=&(rbp->next);
+ } else if (!cs_checkaccess(sender, NULL, CA_MASTERPRIV, cip, NULL, 0, 1)) {
+ chanservstdmessage(sender, QM_NOTREMOVEDPERMBAN, banstr, cip->name->content);
+ rbh=&(rbp->next);
+ } else {
+ chanservstdmessage(sender, QM_REMOVEDPERMBAN, banstr, cip->name->content);
+ if (cip->channel)
+ localdosetmode_ban(&changes, banstr, MCB_DEL);
+ /* Remove from database */
+ csdb_deleteban(rbp);
+ /* Remove from list */
+ (*rbh)=rbp->next;
+ /* Free ban/string and update setby refcount, and free actual regban */
+ freesstring(rbp->reason);
+ freechanban(rbp->cbp);
+ freeregban(rbp);
+ }
+ } else {
+ rbh=&(rbp->next);
+ }
+ }
+
+ if (cip->channel) {
+ for (cbh=&(cip->channel->bans); *cbh; ) {
+ cbp=*cbh;
+ if (fn(arg, cbp)) {
+ /* Remove */
+ banstr=bantostring(cbp);
+ chanservstdmessage(sender, QM_REMOVEDCHANBAN, banstr, cip->name->content);
+ localdosetmode_ban(&changes, banstr, MCB_DEL);
+ } else {
+ cbh=&(cbp->next);
+ }
+ }
+ localsetmodeflush(&changes,1);
+ }
+}
/* 153*/ "Replacing existing ban with the same mask as it has a shorter duration.",
/* 154*/ "Channel has too many user entries, aborting.",
/* 155*/ "Channel has too many bans set, aborting.",
+ /* 156*/ "Warning: not removing registered ban %s from %s.",
};
void initmessages() {