]> jfr.im git - irc/quakenet/newserv.git/blobdiff - glines/glines_commands.c
Fix incorrect error message.
[irc/quakenet/newserv.git] / glines / glines_commands.c
index 01135cfe1df7c8ede3b3d4ed2cb42ee8e18c8b3f..1f64a39dfdb7dfbd78b90b1952aa57148760ce5d 100644 (file)
@@ -38,7 +38,12 @@ static int glines_cmdblock(void *source, int cargc, char **cargv) {
 
   duration = durationtolong(cargv[1]);
 
-  if (duration <= 0 || duration > MAXUSERGLINEDURATION) {
+  if (duration <= 0) {
+    controlreply(sender, "Invalid duration specified.");
+    return CMD_ERROR;
+  }
+
+  if (duration > MAXUSERGLINEDURATION) {
     controlreply(sender, "Sorry, glines may not last longer than %s.", longtoduration(MAXUSERGLINEDURATION, 0));
     return CMD_ERROR;
   }
@@ -64,42 +69,74 @@ static int glines_cmdblock(void *source, int cargc, char **cargv) {
   return CMD_OK;
 }
 
-static int glines_cmdrawgline(void *source, int cargc, char **cargv) {
+static int glines_cmdgline(void *source, int cargc, char **cargv) {
   nick *sender = source;
   int duration, users, channels;
-  char *mask, *reason;
+  char *mask, *reason, *pos;
   char creator[32];
+  int coff, sanitychecks, operlimit;
   glinebuf gbuf;
-#ifdef SNIRCD_13
+#if SNIRCD_VERSION < 140
   gline *gl;
 #endif
 
-  if (cargc < 3)
+  if (cargc < 1)
     return CMD_USAGE;
 
-  mask = cargv[0];
+  coff = 0;
+  sanitychecks = 1;
+  operlimit = 1;
+    
+  if (cargv[0][0] == '-') {
+    coff = 1;
+    
+    for (pos = &(cargv[0][1]); *pos; pos++) {
+      switch (*pos) {
+       case 'S':
+         sanitychecks = 0;
+         break;
+       case 'l':
+         operlimit = 0;
+         break;
+       default:
+         controlreply(sender, "Invalid flag specified: %c", *pos);
+         return CMD_ERROR;
+      }
+    }
+  }
 
-  duration = durationtolong(cargv[1]);
+  if (cargc < 3 + coff)
+    return CMD_USAGE;
 
-  if (duration <= 0 || duration > MAXUSERGLINEDURATION) {
+  mask = cargv[coff];
+
+  duration = durationtolong(cargv[coff + 1]);
+
+  if (duration <= 0) {
+    controlreply(sender, "Invalid duration specified.");
+    return CMD_ERROR;
+  }
+
+  if (duration > MAXUSERGLINEDURATION) {
     controlreply(sender, "Sorry, glines may not last longer than %s.", longtoduration(MAXUSERGLINEDURATION, 0));
     return CMD_ERROR;
   }
 
-  reason = cargv[2];
+  rejoinline(cargv[coff + 2], cargc - coff - 2);
+  reason = cargv[coff + 2];
 
   if (strlen(reason) < MINUSERGLINEREASON) {
     controlreply(sender, "Please specify a proper gline reason.");
     return CMD_ERROR;
   }
 
-#ifdef SNIRCD_13
+#if SNIRCD_VERSION < 140
   gl = findgline(mask);
 
   if (gl) {
-     /* snircd 1.3:  warn opers that they can't modify this gline */
+     /* warn opers that they can't modify this gline */
     if (gl->flags & GLINE_ACTIVE) {
-      controlreply(sender, "Active G-Line already exists on %s - unable to modify", cargv[0]);
+      controlreply(sender, "Active G-Line already exists on %s - unable to modify", mask);
       return CMD_ERROR;
     }
 
@@ -110,33 +147,46 @@ static int glines_cmdrawgline(void *source, int cargc, char **cargv) {
   snprintf(creator, sizeof(creator), "#%s", sender->authname);
 
   glinebufinit(&gbuf, 1);
-  glinebufadd(&gbuf, mask, creator, reason, getnettime() + duration, getnettime(), getnettime() + duration);
-  glinebufcounthits(&gbuf, &users, &channels);
 
-  if (channels > MAXUSERGLINECHANNELHITS) {
-    glinebufabandon(&gbuf);
-    controlreply(sender, "G-Line on '%s' would hit %d channels. Limit is %d. Not setting G-Lines.", mask, channels, MAXUSERGLINECHANNELHITS);
+  if (!glinebufadd(&gbuf, mask, creator, reason, getnettime() + duration, getnettime(), getnettime() + duration)) {
+    controlreply(sender, "Invalid G-Line mask.");
     return CMD_ERROR;
-  } else if (users > MAXUSERGLINEUSERHITS) {
+  }
+
+  if (operlimit) {
+    glinebufcounthits(&gbuf, &users, &channels);
+  
+    if (channels > MAXUSERGLINECHANNELHITS) {
+      glinebufabandon(&gbuf);
+      controlreply(sender, "G-Line on '%s' would hit %d channels. Limit is %d. Not setting G-Line.", mask, channels, MAXUSERGLINECHANNELHITS);
+      return CMD_ERROR;
+    } else if (users > MAXUSERGLINEUSERHITS) {
+      glinebufabandon(&gbuf);
+      controlreply(sender, "G-Line on '%s' would hit %d users. Limit is %d. Not setting G-Line.", mask, users, MAXUSERGLINEUSERHITS);
+      return CMD_ERROR;
+    }
+  }
+
+  if (sanitychecks && glinebufsanitize(&gbuf) > 0) {
     glinebufabandon(&gbuf);
-    controlreply(sender, "G-Line on '%s' would hit %d users. Limit is %d. Not setting G-Lines.", mask, users, MAXUSERGLINEUSERHITS);
+    controlreply(sender, "G-Line failed sanity checks. Not setting G-Line.");
     return CMD_ERROR;
   }
-
+  
   glinebufflush(&gbuf, 1);
 
-  controlwall(NO_OPER, NL_GLINES, "%s RAWGLINE'd mask '%s' for %s with reason '%s' (hits %d users/%d channels)", controlid(sender), mask, longtoduration(duration, 0), reason, users, channels);
+  controlwall(NO_OPER, NL_GLINES, "%s GLINE'd mask '%s' for %s with reason '%s' (hits %d users/%d channels)",
+    controlid(sender), mask, longtoduration(duration, 0), reason, users, channels);
 
   controlreply(sender, "Done.");
 
   return CMD_OK;
 }
 
-static int glines_cmdrawglinesimulate(void *source, int cargc, char **cargv) {
+static int glines_cmdglinesimulate(void *source, int cargc, char **cargv) {
   nick *sender = source;
   char *mask;
   glinebuf gbuf;
-  gline *gl;
   int users, channels;
   char creator[32];
 
@@ -148,9 +198,9 @@ static int glines_cmdrawglinesimulate(void *source, int cargc, char **cargv) {
   snprintf(creator, sizeof(creator), "#%s", sender->authname);
 
   glinebufinit(&gbuf, 0);
-  gl = glinebufadd(&gbuf, mask, creator, "Simulate", getnettime(), getnettime(), getnettime());
 
-  if (!gl) {
+  if (!glinebufadd(&gbuf, mask, creator, "Simulate", getnettime(), getnettime(), getnettime())) {
+    glinebufabandon(&gbuf);
     controlreply(sender, "Invalid G-Line mask.");
     return CMD_ERROR;
   }
@@ -163,7 +213,7 @@ static int glines_cmdrawglinesimulate(void *source, int cargc, char **cargv) {
   return CMD_OK;
 }
 
-static int glines_cmdgline(void *source, int cargc, char **cargv) {
+static int glines_cmdsmartgline(void *source, int cargc, char **cargv) {
   nick *sender = source;
   char *origmask;
   char mask[512];
@@ -181,13 +231,18 @@ static int glines_cmdgline(void *source, int cargc, char **cargv) {
   origmask = cargv[0];
 
   if (origmask[0] == '#' || origmask[0] == '&') {
-    controlreply(sender, "Please use rawgline for badchans and regex glines.");
+    controlreply(sender, "Please use \"gline\" for badchans and regex glines.");
     return CMD_ERROR;
   }
 
   duration = durationtolong(cargv[1]);
 
-  if (duration <= 0 || duration > MAXUSERGLINEDURATION) {
+  if (duration <= 0) {
+    controlreply(sender, "Invalid duration specified.");
+    return CMD_ERROR;
+  }
+
+  if (duration > MAXUSERGLINEDURATION) {
     controlreply(sender, "Sorry, glines may not last longer than %s.", longtoduration(MAXUSERGLINEDURATION, 0));
     return CMD_ERROR;
   }
@@ -202,7 +257,7 @@ static int glines_cmdgline(void *source, int cargc, char **cargv) {
   strncpy(mask, origmask, sizeof(mask));
 
   if (strchr(mask, '!')) {
-    controlreply(sender, "Use rawgline to place nick glines.");
+    controlreply(sender, "Use \"gline\" to place nick glines.");
     return CMD_ERROR;
   }
 
@@ -312,7 +367,12 @@ static int glines_cmdclearchan(void *source, int cargc, char **cargv) {
 
     duration = durationtolong(cargv[2]);
 
-    if (duration <= 0 || duration > MAXUSERGLINEDURATION) {
+    if (duration <= 0) {
+      controlreply(sender, "Invalid duration specified.");
+      return CMD_ERROR;
+    }
+
+    if (duration > MAXUSERGLINEDURATION) {
       controlreply(sender, "Sorry, glines may not last longer than %s.", longtoduration(MAXUSERGLINEDURATION, 0));
       return CMD_ERROR;
     }
@@ -691,6 +751,33 @@ static int glines_cmdglist(void *source, int cargc, char **cargv) {
   return CMD_OK;
 }
 
+static int glines_cmdcleanupglines(void *source, int cargc, char **cargv) {
+  nick *sender = source;
+  gline **pnext, *gl;
+  int count;
+  
+  count = 0;
+  
+  for (pnext = &glinelist; *pnext; pnext = &((*pnext)->next)) {
+    gl = *pnext;
+    
+    if (!(gl->flags & GLINE_ACTIVE)) {
+      gline_destroy(gl, 0, 1);
+      count++;
+    }
+    
+    if (!*pnext)
+      break;
+  }
+  
+  controlwall(NO_OPER, NL_GLINES, "%s CLEANUPGLINES'd %d G-Lines.",
+    controlid(sender), count);
+  
+  controlreply(sender, "Done.");
+  
+  return CMD_OK;
+}
+
 static int glines_cmdsyncglines(void *source, int cargc, char **cargv) {
   nick *sender = source;
   gline *gl;
@@ -747,15 +834,16 @@ static void registercommands(int hooknum, void *arg) {
   commandsregistered = 1;
 
   registercontrolhelpcmd("block", NO_OPER, 3, glines_cmdblock, "Usage: block <nick> <duration> <reason>\nSets a gline using an appropriate mask given the user's nickname.");
-  registercontrolhelpcmd("rawgline", NO_OPER, 3, glines_cmdrawgline, "Usage: rawgline <mask> <duration> <reason>\nSets a gline.");
-  registercontrolhelpcmd("rawglinesimulate", NO_OPER, 1, glines_cmdrawglinesimulate, "Usage: rawglinesimulate <mask>\nSimulates what happens when a gline is set.");
-  registercontrolhelpcmd("gline", NO_OPER, 3, glines_cmdgline, "Usage: gline <user@host> <duration> <reason>\nSets a gline. Automatically adjusts the mask so as not to hit unrelated trusted users.");
+  registercontrolhelpcmd("gline", NO_OPER, 4, glines_cmdgline, "Usage: gline ?flags? <mask> <duration> <reason>\nSets a gline. Flags can be one or more of:\n-S - bypass sanity checks\n-l - bypass hit limits");
+  registercontrolhelpcmd("glinesimulate", NO_OPER, 1, glines_cmdglinesimulate, "Usage: glinesimulate <mask>\nSimulates what happens when a gline is set.");
+  registercontrolhelpcmd("smartgline", NO_OPER, 3, glines_cmdsmartgline, "Usage: gline <user@host> <duration> <reason>\nSets a gline. Automatically adjusts the mask so as not to hit unrelated trusted users.");
   registercontrolhelpcmd("ungline", NO_OPER, 1, glines_cmdungline, "Usage: ungline <mask>\nDeactivates a gline.");
   registercontrolhelpcmd("clearchan", NO_OPER, 4, glines_cmdclearchan, "Usage: clearchan <#channel> <how> <duration> ?reason?\nClears a channel.\nhow can be one of:\nkick - Kicks users.\nkill - Kills users.\ngline - Glines non-authed users (using an appropriate mask).\nglineall - Glines users.\nDuration is only valid when glining users. Reason defaults to \"Clearing channel.\".");
   registercontrolhelpcmd("trustgline", NO_OPER, 4, glines_cmdtrustgline, "Usage: trustgline <#id|name> <user> <duration> <reason>\nSets a gline on the specified username for each host in the specified trust group. The username may contain wildcards.");
   registercontrolhelpcmd("trustungline", NO_OPER, 2, glines_cmdtrustungline, "Usage: trustungline <#id|name> <user>\nRemoves a gline that was previously set with trustgline.");
   registercontrolhelpcmd("glstats", NO_OPER, 0, glines_cmdglstats, "Usage: glstat\nShows statistics about G-Lines.");
   registercontrolhelpcmd("glist", NO_OPER, 2, glines_cmdglist, "Usage: glist [-flags] <mask>\nLists matching G-Lines.\nValid flags are:\n-c: Count G-Lines.\n-f: Find G-Lines active on <mask>.\n-x: Find G-Lines matching <mask> exactly.\n-R: Find G-lines on realnames.\n-o: Search for glines by owner.\n-r: Search for glines by reason.\n-i: Include inactive glines.");
+  registercontrolhelpcmd("cleanupglines", NO_OPER, 0, glines_cmdcleanupglines, "Usage: cleanupglines\nDestroys all deactivated G-Lines.");
   registercontrolhelpcmd("syncglines", NO_DEVELOPER, 0, glines_cmdsyncglines, "Usage: syncglines\nSends all G-Lines to all other servers.");
   registercontrolhelpcmd("loadglines", NO_DEVELOPER, 0, glines_cmdloadglines, "Usage: loadglines\nForce load of glines.");
   registercontrolhelpcmd("saveglines", NO_DEVELOPER, 0, glines_cmdsaveglines, "Usage: saveglines\nForce save of glines.");
@@ -767,15 +855,16 @@ static void deregistercommands(int hooknum, void *arg) {
   commandsregistered = 0;
 
   deregistercontrolcmd("block", glines_cmdblock);
-  deregistercontrolcmd("rawgline", glines_cmdrawgline);
-  deregistercontrolcmd("rawglinesimulate", glines_cmdrawglinesimulate);
   deregistercontrolcmd("gline", glines_cmdgline);
+  deregistercontrolcmd("glinesimulate", glines_cmdglinesimulate);
+  deregistercontrolcmd("smartgline", glines_cmdsmartgline);
   deregistercontrolcmd("ungline", glines_cmdungline);
   deregistercontrolcmd("clearchan", glines_cmdclearchan);
   deregistercontrolcmd("trustgline", glines_cmdtrustgline);
   deregistercontrolcmd("trustungline", glines_cmdtrustungline);
   deregistercontrolcmd("glstats", glines_cmdglstats);
   deregistercontrolcmd("glist", glines_cmdglist);
+  deregistercontrolcmd("cleanupglines", glines_cmdcleanupglines);
   deregistercontrolcmd("syncglines", glines_cmdsyncglines);
   deregistercontrolcmd("loadglines", glines_cmdloadglines);
   deregistercontrolcmd("saveglines", glines_cmdsaveglines);