X-Git-Url: https://jfr.im/git/irc/quakenet/newserv.git/blobdiff_plain/2ba836f274fe46d15b1fe972d6a202b61f028ad9..e183df684345d1a147f20be68bd9e6129c341354:/newsearch/ns-gline.c diff --git a/newsearch/ns-gline.c b/newsearch/ns-gline.c index 7803cdb4..55dbcab4 100644 --- a/newsearch/ns-gline.c +++ b/newsearch/ns-gline.c @@ -7,8 +7,9 @@ #include #include #include +#include -#include "../control/control.h" /* controlreply() */ +#include "../control/control.h" #include "../irc/irc.h" /* irc_send() */ #include "../lib/irc_string.h" /* IPtostr(), longtoduration(), durationtolong() */ #include "../lib/strlfunc.h" @@ -18,84 +19,94 @@ extern nick *senderNSExtern; static const char *defaultreason = "You (%u) have been g-lined for violating our terms of service"; -void *gline_exe(struct searchNode *thenode, void *theinput); -void gline_free(struct searchNode *thenode); +void *gline_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput); +void gline_free(searchCtx *ctx, struct searchNode *thenode); struct gline_localdata { unsigned int marker; unsigned int duration; int count; - int type; char reason[NSMAX_REASON_LEN]; }; -struct searchNode *gline_parse(int type, int argc, char **argv) { +struct searchNode *gline_parse(searchCtx *ctx, int argc, char **argv) { struct gline_localdata *localdata; struct searchNode *thenode; - int len; - char *p; if (!(localdata = (struct gline_localdata *) malloc(sizeof(struct gline_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 = "gline: invalid search type"; + return NULL; + } - switch (argc) { - case 0: + /* default duration, default reason */ + if(argc == 0) { localdata->duration = NSGLINE_DURATION; strlcpy(localdata->reason, defaultreason, sizeof(localdata->reason)); - break; - - case 1: - if (strchr(argv[0], ' ') == NULL) { /* duration specified */ - localdata->duration = durationtolong(argv[0]); - /* error checking on gline duration */ - if (localdata->duration == 0) - localdata->duration = NSGLINE_DURATION; - strlcpy(localdata->reason, defaultreason, sizeof(localdata->reason)); + } else if(argc > 2) { + free(localdata); + parseError = "gline: invalid number of arguments"; + return NULL; + } else { + char *argzerop, *reasonp, *durationp; + struct searchNode *durationsn, *reasonsn, *argzerosn; + + if (!(argzerosn=argtoconststr("gline", ctx, argv[0], &argzerop))) { + free(localdata); + return NULL; } - else { /* reason specified */ - localdata->duration = NSGLINE_DURATION; - 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'; + if(argc == 1) { + durationp = reasonp = NULL; + durationsn = reasonsn = NULL; + + /* if we have a space it's a reason */ + if(strchr(argzerop, ' ')) { + reasonsn = argzerosn; + reasonp = argzerop; } else { - localdata->reason[len-1] = '\0'; + durationsn = argzerosn; + durationp = argzerop; } + } else { + durationsn = argzerosn; + durationp = argzerop; + + if (!(reasonsn=argtoconststr("gline", ctx, argv[1], &reasonp))) { + durationsn->free(ctx, durationsn); + free(localdata); + return NULL; + } + } + + if(!reasonp) { + strlcpy(localdata->reason, defaultreason, sizeof(localdata->reason)); + } else { + strlcpy(localdata->reason, reasonp, sizeof(localdata->reason)); + reasonsn->free(ctx, reasonsn); } - break; - case 2: - localdata->duration = durationtolong(argv[0]); - /* error checking on gline duration */ - if (localdata->duration == 0) + if(!durationp) { localdata->duration = NSGLINE_DURATION; - - p = argv[1]; - 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'; + localdata->duration = durationtolong(durationp); + durationsn->free(ctx, durationsn); + + if (localdata->duration == 0) { + parseError = "gline duration invalid."; + free(localdata); + return NULL; + } } - - break; - default: - free(localdata); - parseError = "gline: invalid number of arguments"; - return NULL; } if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) { @@ -113,17 +124,18 @@ struct searchNode *gline_parse(int type, int argc, char **argv) { return thenode; } -void *gline_exe(struct searchNode *thenode, void *theinput) { +void *gline_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) { struct gline_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; + if (cip->channel != NULL) + localdata->count += cip->channel->users->totalusers; } else { np = (nick *)theinput; @@ -134,24 +146,38 @@ void *gline_exe(struct searchNode *thenode, void *theinput) { return (void *)1; } -void gline_free(struct searchNode *thenode) { +static int glineuser(nick *np, struct gline_localdata *localdata, time_t ti) { + char msgbuf[512]; + if (!IsOper(np) && !IsService(np) && !IsXOper(np)) { + nssnprintf(msgbuf, sizeof(msgbuf), localdata->reason, np); + if (np->host->clonecount <= NSMAX_GLINE_CLONES) + irc_send("%s GL * +*@%s %u %jd :%s", mynumeric->content, IPtostr(np->p_ipaddr), localdata->duration, (intmax_t)ti, msgbuf); + else + irc_send("%s GL * +%s@%s %u %jd :%s", mynumeric->content, np->ident, IPtostr(np->p_ipaddr), localdata->duration, (intmax_t)ti, msgbuf); + return 1; + } + + return 0; +} + +void gline_free(searchCtx *ctx, struct searchNode *thenode) { struct gline_localdata *localdata; nick *np, *nnp; chanindex *cip, *ncip; int i, j, safe=0; - char msgbuf[512]; + time_t ti = time(NULL); localdata = thenode->localdata; if (localdata->count > NSMAX_GLINE_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) { + if (ctx->searchcmd == reg_chansearch) { for (i=0;inext; @@ -161,14 +187,7 @@ void gline_free(struct searchNode *thenode) { continue; if ((np=getnickbynumeric(cip->channel->users->content[j]))) { - if (!IsOper(np) && !IsService(np) && !IsXOper(np)) { - nssnprintf(msgbuf, sizeof(msgbuf), localdata->reason, np); - if (np->host->clonecount <= NSMAX_GLINE_CLONES) - irc_send("%s GL * +*@%s %u :%s", mynumeric->content, IPtostr(np->p_ipaddr), localdata->duration, msgbuf); - else - irc_send("%s GL * +%s@%s %u :%s", mynumeric->content, np->ident, IPtostr(np->p_ipaddr), localdata->duration, msgbuf); - } - else + if(!glineuser(np, localdata, ti)) safe++; } } @@ -181,24 +200,17 @@ void gline_free(struct searchNode *thenode) { for (np=nicktable[i];np;np=nnp) { nnp = np->next; if (np->marker == localdata->marker) { - if (!IsOper(np) && !IsService(np) && !IsXOper(np)) { - nssnprintf(msgbuf, sizeof(msgbuf), localdata->reason, np); - if (np->host->clonecount <= NSMAX_GLINE_CLONES) - irc_send("%s GL * +*@%s %u :%s", mynumeric->content, IPtostr(np->p_ipaddr), localdata->duration, msgbuf); - else - irc_send("%s GL * +%s@%s %u :%s", mynumeric->content, np->ident, IPtostr(np->p_ipaddr), localdata->duration, msgbuf); - } - else - safe++; + if(!glineuser(np, localdata, ti)) + safe++; } } } } 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_GLINES, "%s/%s glined %d %s via %s for %s [%d untouched].", senderNSExtern->nick, senderNSExtern->authname, (localdata->count - safe), - (localdata->count - safe) != 1 ? "users" : "user", (localdata->type == SEARCHTYPE_CHANNEL) ? "chansearch" : "nicksearch", longtoduration(localdata->duration, 1), safe); + ctx->wall(NL_GLINES, "%s/%s glined %d %s via %s for %s [%d untouched].", senderNSExtern->nick, senderNSExtern->authname, (localdata->count - safe), + (localdata->count - safe) != 1 ? "users" : "user", (ctx->searchcmd == reg_chansearch) ? "chansearch" : "nicksearch", longtoduration(localdata->duration, 1), safe); free(localdata); free(thenode); }