X-Git-Url: https://jfr.im/git/irc/quakenet/newserv.git/blobdiff_plain/2ba836f274fe46d15b1fe972d6a202b61f028ad9..8855bb48b449ed06cfd3ce528b3c0a77c37cb24b:/newsearch/ns-kill.c?ds=sidebyside diff --git a/newsearch/ns-kill.c b/newsearch/ns-kill.c index a8166787..f0cb2dea 100644 --- a/newsearch/ns-kill.c +++ b/newsearch/ns-kill.c @@ -7,7 +7,7 @@ #include #include -#include "../control/control.h" /* controlreply() */ +#include "../control/control.h" #include "../localuser/localuser.h" /* killuser() */ #include "../lib/irc_string.h" /* IPtostr() */ #include "../lib/strlfunc.h" @@ -16,47 +16,49 @@ i.e. hitting too many users in a (kill) or (gline) - declared in newsearch.c */ extern nick *senderNSExtern; -void *kill_exe(struct searchNode *thenode, void *theinput); -void kill_free(struct searchNode *thenode); -static const char *defaultreason = "You (%u) have been disconnected for violating our terms of service"; +void *kill_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput); +void kill_free(searchCtx *ctx, struct searchNode *thenode); +static const char *defaultreason = "You (%n) have been disconnected for violating our terms of service"; struct kill_localdata { unsigned int marker; int count; - int type; char reason[NSMAX_REASON_LEN]; }; -struct searchNode *kill_parse(int type, int argc, char **argv) { +struct searchNode *kill_parse(searchCtx *ctx, int argc, char **argv) { struct kill_localdata *localdata; struct searchNode *thenode; - int len; if (!(localdata = (struct kill_localdata *) malloc(sizeof(struct kill_localdata)))) { parseError = "malloc: could not allocate memory for this search."; return NULL; } localdata->count = 0; - localdata->type = type; - if (type == SEARCHTYPE_CHANNEL) + if (ctx->searchcmd == reg_chansearch) localdata->marker = nextchanmarker(); - else + else if (ctx->searchcmd == reg_nicksearch) localdata->marker = nextnickmarker(); + else { + free(localdata); + parseError = "kill: invalid search type"; + return NULL; + } if (argc==1) { - char *p = argv[0]; - if(*p == '\"') - *p++; - len = strlcpy(localdata->reason, p, sizeof(localdata->reason)); - if(len >= sizeof(localdata->reason)) { - localdata->reason[sizeof(localdata->reason)-1] = '\0'; - } else { - localdata->reason[len-1] = '\0'; + struct searchNode *reasonstr; + char *p; + if (!(reasonstr=argtoconststr("kill", ctx, argv[0], &p))) { + free(localdata); + return NULL; } - } - else + + strlcpy(localdata->reason, p, sizeof(localdata->reason)); + reasonstr->free(ctx, reasonstr); + } else { strlcpy(localdata->reason, defaultreason, sizeof(localdata->reason)); - + } + if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) { /* couldn't malloc() memory for thenode, so free localdata to avoid leakage */ parseError = "malloc: could not allocate memory for this search."; @@ -72,19 +74,18 @@ struct searchNode *kill_parse(int type, int argc, char **argv) { return thenode; } -void *kill_exe(struct searchNode *thenode, void *theinput) { +void *kill_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) { struct kill_localdata *localdata; nick *np; chanindex *cip; localdata = thenode->localdata; - if (localdata->type == SEARCHTYPE_CHANNEL) { + if (ctx->searchcmd == reg_chansearch) { cip = (chanindex *)theinput; cip->marker = localdata->marker; localdata->count += cip->channel->users->totalusers; - } - else { + } else { np = (nick *)theinput; np->marker = localdata->marker; localdata->count++; @@ -93,10 +94,10 @@ void *kill_exe(struct searchNode *thenode, void *theinput) { return (void *)1; } -void kill_free(struct searchNode *thenode) { +void kill_free(searchCtx *ctx, struct searchNode *thenode) { struct kill_localdata *localdata; nick *np, *nnp; - chanindex *cip, *ncip; + chanindex *cip; int i, j, safe=0; unsigned int nickmarker; char msgbuf[512]; @@ -105,63 +106,58 @@ void kill_free(struct searchNode *thenode) { if (localdata->count > NSMAX_KILL_LIMIT) { /* need to warn the user that they have just tried to twat half the network ... */ - controlreply(senderNSExtern, "Warning: your pattern matches too many users (%d) - nothing done.", localdata->count); + ctx->reply(senderNSExtern, "Warning: your pattern matches too many users (%d) - nothing done.", localdata->count); free(localdata); free(thenode); return; } - if (localdata->type == SEARCHTYPE_CHANNEL) { + /* For channel searches, mark up all the nicks in the relevant channels first */ + if (ctx->searchcmd == reg_chansearch) { nickmarker=nextnickmarker(); for (i=0;inext; - if (cip != NULL && cip->channel != NULL && cip->marker == localdata->marker) { - for (j=0;jchannel->users->hashsize;j++) { - if (cip->channel->users->content[j]==nouser) - continue; - - if ((np=getnickbynumeric(cip->channel->users->content[j]))) { - if (!IsOper(np) && !IsService(np) && !IsXOper(np)) { - np->marker=nickmarker; - } - else - safe++; - } - } - } - } - } - for (i=0;inext; - if (np->marker == nickmarker) { - nssnprintf(msgbuf, sizeof(msgbuf), localdata->reason, np); - killuser(NULL, np, "%s", msgbuf); + for (cip=chantable[i];cip;cip=cip->next) { + /* Skip empty and non-matching channels */ + if (!cip->channel || cip->marker != localdata->marker) + continue; + + for (j=0;jchannel->users->hashsize;j++) { + if (cip->channel->users->content[j]==nouser) + continue; + + if ((np=getnickbynumeric(cip->channel->users->content[j]))) + np->marker=nickmarker; } } } + } else { + /* For nick searches they're already marked, pick up the saved value */ + nickmarker=localdata->marker; } - else { - for (i=0;inext; - if (np->marker == localdata->marker) { - if (!IsOper(np) && !IsService(np) && !IsXOper(np)) { - nssnprintf(msgbuf, sizeof(msgbuf), localdata->reason, np); - killuser(NULL, np, "%s", msgbuf); - } - else - safe++; - } + + /* Now do the actual kills */ + for (i=0;inext; + + if (np->marker != nickmarker) + continue; + + if (IsOper(np) || IsService(np) || IsXOper(np)) { + safe++; + continue; } + + nssnprintf(msgbuf, sizeof(msgbuf), localdata->reason, np); + killuser(NULL, np, "%s", msgbuf); } } + if (safe) - controlreply(senderNSExtern, "Warning: your pattern matched privileged users (%d in total) - these have not been touched.", safe); + ctx->reply(senderNSExtern, "Warning: your pattern matched privileged users (%d in total) - these have not been touched.", safe); /* notify opers of the action */ - controlwall(NO_OPER, NL_KICKKILLS, "%s/%s killed %d %s via %s [%d untouched].", senderNSExtern->nick, senderNSExtern->authname, (localdata->count - safe), - (localdata->count - safe) != 1 ? "users" : "user", (localdata->type == SEARCHTYPE_CHANNEL) ? "chansearch" : "nicksearch", safe); + ctx->wall(NL_KICKKILLS, "%s/%s killed %d %s via %s [%d untouched].", senderNSExtern->nick, senderNSExtern->authname, (localdata->count - safe), + (localdata->count - safe) != 1 ? "users" : "user", (ctx->searchcmd == reg_chansearch) ? "chansearch" : "nicksearch", safe); free(localdata); free(thenode); }