]> jfr.im git - irc/quakenet/newserv.git/blobdiff - newsearch/ns-gline.c
SearchCtx should contain 'type' - this is to make life easier when defining new searc...
[irc/quakenet/newserv.git] / newsearch / ns-gline.c
index 7f6a27d4e456dc2d0a07998bcf8da4e03d6296df..8735dc6bfb8bd0f557499da63ae3e05994e33a8c 100644 (file)
@@ -6,48 +6,94 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
-#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"
 
 /* used for *_free functions that need to warn users of certain things
    i.e. hitting too many users in a (kill) or (gline) - declared in newsearch.c */
 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->type == SEARCHTYPE_CHANNEL)
     localdata->marker = nextchanmarker();
   else
     localdata->marker = nextnickmarker();
 
-  /* gline durations */
-  if (argc<1)
+  switch (argc) {
+  case 0:
     localdata->duration = NSGLINE_DURATION;
-  else {
+    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 { /* 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';
+      } else {
+        localdata->reason[len-1] = '\0';
+      }
+    }
+    break;
+
+  case 2:
     localdata->duration = durationtolong(argv[0]);
     /* error checking on gline duration */
     if (localdata->duration == 0)
       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';
+    }
+
+    break;
+  default:
+    free(localdata);
+    parseError = "gline: invalid number of arguments";
+    return NULL;
   }
 
   if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
@@ -65,14 +111,14 @@ 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->type == SEARCHTYPE_CHANNEL) {
     cip = (chanindex *)theinput;
     cip->marker = localdata->marker;
     localdata->count += cip->channel->users->totalusers;
@@ -86,23 +132,25 @@ void *gline_exe(struct searchNode *thenode, void *theinput) {
   return (void *)1;
 }
 
-void gline_free(struct searchNode *thenode) {
+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->type == SEARCHTYPE_CHANNEL) {
     for (i=0;i<CHANNELHASHSIZE;i++) {
       for (cip=chantable[i];cip;cip=ncip) {
         ncip = cip->next;
@@ -113,15 +161,14 @@ void gline_free(struct searchNode *thenode) {
     
             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 :You (%s!%s@%s) have been glined for violating our terms of service.", 
-                    mynumeric->content, IPtostr(np->p_ipaddr), localdata->duration, np->nick, np->ident, IPtostr(np->p_ipaddr));
-                else
-                  irc_send("%s GL * +%s@%s %u :You (%s!%s@%s) have been glined for violating our terms of service.", 
-                    mynumeric->content, np->ident, IPtostr(np->p_ipaddr), localdata->duration, np->nick, np->ident, IPtostr(np->p_ipaddr));
-                }
+                  irc_send("%s GL * +*@%s %u %d :%s", mynumeric->content, IPtostr(np->p_ipaddr), localdata->duration, ti, msgbuf);
                 else
-                  safe++;
+                  irc_send("%s GL * +%s@%s %u %d :%s", mynumeric->content, np->ident, IPtostr(np->p_ipaddr), localdata->duration, ti, msgbuf);
+              }
+              else
+                safe++;
             }
           }
         }
@@ -134,12 +181,11 @@ void gline_free(struct searchNode *thenode) {
         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 :You (%s!%s@%s) have been glined for violating our terms of service.", 
-                mynumeric->content, IPtostr(np->p_ipaddr), localdata->duration, np->nick, np->ident, IPtostr(np->p_ipaddr));
+              irc_send("%s GL * +*@%s %u %d :%s", mynumeric->content, IPtostr(np->p_ipaddr), localdata->duration, ti, msgbuf);
             else
-              irc_send("%s GL * +%s@%s %u :You (%s!%s@%s) have been glined for violating our terms of service.", 
-                mynumeric->content, np->ident, IPtostr(np->p_ipaddr), localdata->duration, np->nick, np->ident, IPtostr(np->p_ipaddr));
+              irc_send("%s GL * +%s@%s %u %d :%s", mynumeric->content, np->ident, IPtostr(np->p_ipaddr), localdata->duration, ti, msgbuf);
           }
           else
               safe++;
@@ -148,10 +194,10 @@ void gline_free(struct searchNode *thenode) {
     }
   }
   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->type == SEARCHTYPE_CHANNEL) ? "chansearch" : "nicksearch", longtoduration(localdata->duration, 1), safe);
   free(localdata);
   free(thenode);
 }