]> jfr.im git - irc/quakenet/newserv.git/commitdiff
Implement nick chasing for the block command.
authorGunnar Beutner <redacted>
Mon, 5 Aug 2013 05:51:15 +0000 (07:51 +0200)
committerGunnar Beutner <redacted>
Mon, 5 Aug 2013 05:51:15 +0000 (07:51 +0200)
--HG--
branch : shroudtrusts

glines/glines.h
glines/glines_buf.c
glines/glines_commands.c
whowas/whowas.c
whowas/whowas.h
whowas/whowas_commands.c

index f7d5de517b92ab71b714ff947ede21d373805c80..c7f7e744812a0223ad1d725e4c761f422de5cf83 100644 (file)
@@ -4,6 +4,7 @@
 #include "../lib/sstring.h"
 #include "../nick/nick.h"
 #include "../channel/channel.h"
+#include "../whowas/whowas.h"
 
 #define SNIRCD_VERSION 134
 
@@ -125,6 +126,7 @@ void glinebufinit(glinebuf *gbuf, int id);
 gline *glinebufadd(glinebuf *gbuf, const char *mask, const char *creator, const char *reason, time_t expire, time_t lastmod, time_t lifetime);
 void glinebufaddbyip(glinebuf *gbuf, const char *user, struct irc_in_addr *ip, unsigned char bits, int flags, const char *creator, const char *reason, time_t expire, time_t lastmod, time_t lifetime);
 void glinebufaddbynick(glinebuf *gbuf, nick *, int flags, const char *creator, const char *reason, time_t expire, time_t lastmod, time_t lifetime);
+void glinebufaddbywhowas(glinebuf *gbuf, whowas *, int flags, const char *creator, const char *reason, time_t expire, time_t lastmod, time_t lifetime);
 void glinebufcounthits(glinebuf *gbuf, int *users, int *channels);
 int glinebufchecksane(glinebuf *gbuf, nick *spewto, int overridesanity, int overridelimit);
 void glinebufspew(glinebuf *gbuf, nick *spewto);
index 63f048914889fb99437890c93e2a5e446ff72ce0..2a15e733458f60651becb805d28e566cb9cbf002 100644 (file)
@@ -94,6 +94,16 @@ void glinebufaddbynick(glinebuf *gbuf, nick *np, int flags, const char *creator,
   }
 }
 
+void glinebufaddbywhowas(glinebuf *gbuf, whowas *ww, int flags, const char *creator, const char *reason, time_t expire, time_t lastmod, time_t lifetime) {
+  if (flags & GLINE_ALWAYS_NICK) {
+    char mask[512];
+    snprintf(mask, sizeof(mask), "%s!*@*", ww->nick);
+    glinebufadd(gbuf, mask, creator, reason, expire, lastmod, lifetime);
+  } else {
+    glinebufaddbyip(gbuf, ww->ident, &ww->ip, 128, flags, creator, reason, expire, lastmod, lifetime);
+  }
+}
+
 void glinebufcounthits(glinebuf *gbuf, int *users, int *channels) {
   gline *gl;
   int i, hit, slot;
index 68f93ed687631d4f56297da8f44844fa8ba00ae1..ae2f4aa631518e4ad479b53cec38a5cacd5191b6 100644 (file)
@@ -18,7 +18,7 @@ MODULE_VERSION("");
 static void registercommands(int, void *);
 static void deregistercommands(int, void *);
 
-static int parse_gline_flags(nick *sender, const char *flagparam, int *overridesanity, int *overridelimit, int *simulate, int *coff) {
+static int parse_gline_flags(nick *sender, const char *flagparam, int *overridesanity, int *overridelimit, int *simulate, int *chase, int *coff) {
   const char *pos;
 
   *coff = 0;
@@ -26,6 +26,9 @@ static int parse_gline_flags(nick *sender, const char *flagparam, int *overrides
   *overridelimit = 0;
   *simulate = 0;
 
+  if (chase)
+    *chase = 0;
+
   if (flagparam[0] == '-') {
     *coff = 1;
 
@@ -40,41 +43,45 @@ static int parse_gline_flags(nick *sender, const char *flagparam, int *overrides
        case 'S':
          *simulate = 1;
          break;
+        case 'c':
+          if (!chase)
+            goto invalid;
+
+          *chase = 1;
+          break;
        default:
-         controlreply(sender, "Invalid flag specified: %c", *pos);
-         return 0;
+          goto invalid;
       }
     }
   }
 
   return 1;
+
+invalid:
+  controlreply(sender, "Invalid flag specified: %c", *pos);
+  return 0;
 }
 
 static int glines_cmdblock(void *source, int cargc, char **cargv) {
   nick *sender = source;
   nick *target;
+  whowas *ww;
   int hits, duration, id;
-  int coff, overridesanity, overridelimit, simulate;
+  int coff, overridesanity, overridelimit, simulate, chase;
   char *reason;
   char creator[128];
   glinebuf gbuf;
+  int ownww;
 
   if (cargc < 1)
     return CMD_USAGE;
 
-  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, &coff))
+  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, &chase, &coff))
     return CMD_ERROR;
 
   if (cargc < 3 + coff)
     return CMD_USAGE;
 
-  target = getnickbynick(cargv[coff]);
-
-  if (!target) {
-    controlreply(sender, "Sorry, couldn't find that user.");
-    return CMD_ERROR;
-  }
-
   duration = durationtolong(cargv[coff + 1]);
 
   if (duration <= 0) {
@@ -82,6 +89,24 @@ static int glines_cmdblock(void *source, int cargc, char **cargv) {
     return CMD_ERROR;
   }
 
+  target = getnickbynick(cargv[coff]);
+
+  if (!target) {
+    ww = whowas_chase(cargv[coff], 1800);
+   
+    if (!ww) {
+      controlreply(sender, "Sorry, couldn't find that user.");
+      return CMD_ERROR;
+    }
+   
+    ownww = 0;
+
+    controlreply(sender, "Found matching whowas record:");    whowas_spew(ww, sender);
+  } else {
+    ww = whowas_fromnick(target);
+    ownww = 1;
+  }
+
   rejoinline(cargv[coff + 2], cargc - coff - 2);
   reason = cargv[coff + 2];
 
@@ -92,18 +117,22 @@ static int glines_cmdblock(void *source, int cargc, char **cargv) {
 
   glinebufinit(&gbuf, 0);
   glinebufcommentv(&gbuf, "BLOCK", cargc + coff - 1, cargv);
-  glinebufaddbynick(&gbuf, target, 0, creator, reason, getnettime() + duration, getnettime(), getnettime() + duration);
+  glinebufaddbywhowas(&gbuf, ww, 0, creator, reason, getnettime() + duration, getnettime(), getnettime() + duration);
 
   glinebufspew(&gbuf, sender);
 
   if (!glinebufchecksane(&gbuf, sender, overridesanity, overridelimit)) {
     glinebufabort(&gbuf);
+    if (ownww)
+      whowas_free(ww);
     controlreply(sender, "G-Lines failed sanity checks. Not setting G-Lines.");
     return CMD_ERROR;
   }
 
   if (simulate) {
     glinebufabort(&gbuf);
+    if (ownww)
+      whowas_free(ww);
     controlreply(sender, "Simulation complete. Not setting G-Lines.");
     return CMD_ERROR;
   }
@@ -111,7 +140,10 @@ static int glines_cmdblock(void *source, int cargc, char **cargv) {
   glinebufcounthits(&gbuf, &hits, NULL);
   id = glinebufcommit(&gbuf, 1);
 
-  controlwall(NO_OPER, NL_GLINES, "%s BLOCK'ed user '%s!%s@%s' for %s with reason '%s' (%d hits)", controlid(sender), target->nick, target->ident, target->host->name->content, longtoduration(duration, 0), reason, hits);
+  controlwall(NO_OPER, NL_GLINES, "%s BLOCK'ed user '%s!%s@%s' for %s with reason '%s' (%d hits)", controlid(sender), ww->nick, ww->ident, ww->host, longtoduration(duration, 0), reason, hits);
+
+  if (ownww)
+    whowas_free(ww);
 
   controlreply(sender, "Done. G-Line transaction ID: %d", id);
 
@@ -132,7 +164,7 @@ static int glines_cmdgline(void *source, int cargc, char **cargv) {
   if (cargc < 1)
     return CMD_USAGE;
 
-  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, &coff))
+  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, NULL, &coff))
     return CMD_ERROR;
 
   if (cargc < 3 + coff)
@@ -218,7 +250,7 @@ static int glines_cmdsmartgline(void *source, int cargc, char **cargv) {
   if (cargc < 1)
     return CMD_USAGE;
 
-  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, &coff))
+  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, NULL, &coff))
     return CMD_ERROR;
 
   if (cargc < 3 + coff)
@@ -368,7 +400,7 @@ static int glines_cmdclearchan(void *source, int cargc, char **cargv) {
   if (cargc < 1)
     return CMD_USAGE;
 
-  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, &coff))
+  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, NULL, &coff))
     return CMD_ERROR;
 
   if (cargc < 2 + coff)
@@ -522,7 +554,7 @@ static int glines_cmdtrustgline(void *source, int cargc, char **cargv) {
   if (cargc < 1)
     return CMD_USAGE;
 
-  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, &coff))
+  if (!parse_gline_flags(sender, cargv[0], &overridesanity, &overridelimit, &simulate, NULL, &coff))
     return CMD_ERROR;
 
   if (cargc < 4 + coff)
@@ -968,7 +1000,7 @@ static void registercommands(int hooknum, void *arg) {
     return;
   commandsregistered = 1;
 
-  registercontrolhelpcmd("block", NO_OPER, 4, glines_cmdblock, "Usage: block ?flags? <nick> <duration> <reason>\nSets a gline using an appropriate mask given the user's nickname.\nFlags can be one or more of:\n-f - bypass sanity checks\n-l - bypass hit limits\n-S - simulate who the glines would hit");
+  registercontrolhelpcmd("block", NO_OPER, 4, glines_cmdblock, "Usage: block ?flags? <nick> <duration> <reason>\nSets a gline using an appropriate mask given the user's nickname.\nFlags can be one or more of:\n-f - bypass sanity checks\n-l - bypass hit limits\n-S - simulate who the glines would hit\n-c - chase nick across quits/kills/nick changes");
   registercontrolhelpcmd("gline", NO_OPER, 4, glines_cmdgline, "Usage: gline ?flags? <mask> <duration> <reason>\nSets a gline.\nFlags can be one or more of:\n-f - bypass sanity checks\n-l - bypass hit limits\n-S - simulate who the glines would hit");
   registercontrolhelpcmd("smartgline", NO_OPER, 4, glines_cmdsmartgline, "Usage: smartgline ?flags? <user@host> <duration> <reason>\nSets a gline. Automatically adjusts the mask depending on whether the specified mask is trusted.\nFlags can be one or more of:\n-f - bypass sanity checks\n-l - bypass hit limits\n-S - simulate who the glines would hit");
   registercontrolhelpcmd("ungline", NO_OPER, 1, glines_cmdungline, "Usage: ungline <mask>\nDeactivates a gline.");
index 439caea9b76c29e7354260954b2d7f620289bc1d..06949beafa4776bdafe72f43cd74b84c15813fe4 100644 (file)
@@ -55,15 +55,25 @@ void whowas_unlinkrecord(whowas *ww) {
   whowas_count--;
 }
 
+void whowas_free(whowas *ww) {
+  if (!ww)
+    return;
+
+  freesstring(ww->reason);
+  free(ww);
+}
+
 static void whowas_cleanup(void) {
   time_t now;
+  whowas *ww;
 
   time(&now);
 
   /* Clean up old records. */
   while (whowas_tail && (whowas_tail->seen < now - WW_MAXAGE || whowas_count >= WW_MAXENTRIES)) {
-    whowas_unlinkrecord(whowas_tail);
-    free(whowas_tail);
+    ww = whowas_tail;
+    whowas_unlinkrecord(ww);
+    whowas_free(ww);
   }
 }
 
@@ -129,6 +139,19 @@ whowas *whowas_chase(const char *nick, int maxage) {
   return NULL;
 }
 
+void whowas_spew(whowas *ww, nick *np) {
+  char timebuf[30];
+  char hostmask[WW_MASKLEN + 1];
+
+  snprintf(hostmask, sizeof(hostmask), "%s!%s@%s [%s]", ww->nick, ww->ident, ww->host, IPtostr(ww->ip));
+  strftime(timebuf, 30, "%d/%m/%y %H:%M:%S", localtime(&(ww->seen)));
+
+  if (ww->type == WHOWAS_RENAME)
+    controlreply(np, "[%s] NICK %s (%s) -> %s", timebuf, hostmask, ww->realname, ww->newnick->content);
+  else
+    controlreply(np, "[%s] %s %s (%s): %s", timebuf, (ww->type == WHOWAS_QUIT) ? "QUIT" : "KILL", hostmask, ww->realname, ww->reason->content);
+}
+
 void _init(void) {
   registerhook(HOOK_NICK_QUIT, whowas_handlequitorkill);
   registerhook(HOOK_NICK_KILL, whowas_handlequitorkill);
index ccd40298d7f44a4e579edaf2f45c98cb5c40d4ba..825b12c000ebe710fc1d5d65b8622d69f4a29195 100644 (file)
@@ -30,4 +30,7 @@ extern int whowas_count;
 #define WHOWAS_KILL 1
 #define WHOWAS_RENAME 2
 
+whowas *whowas_fromnick(nick *np);
 whowas *whowas_chase(const char *nick, int maxage);
+void whowas_spew(whowas *ww, nick *np);
+void whowas_free(whowas *ww);
index 7643cdb48b40fcc22d231ff628372e3936a0dc74..5b2cd3644c848e6605bb136d16de4892d615f5ea 100644 (file)
@@ -9,19 +9,6 @@
 
 MODULE_VERSION("");
 
-static void whowas_spewrecord(whowas *ww, nick *np) {
-  char timebuf[30];
-  char hostmask[WW_MASKLEN + 1];
-
-  snprintf(hostmask, sizeof(hostmask), "%s!%s@%s [%s]", ww->nick, ww->ident, ww->host, IPtostr(ww->ip));
-  strftime(timebuf, 30, "%d/%m/%y %H:%M:%S", localtime(&(ww->seen)));
-
-  if (ww->type == WHOWAS_RENAME)
-    controlreply(np, "[%s] NICK %s (%s) -> %s", timebuf, hostmask, ww->realname, ww->newnick->content);
-  else
-    controlreply(np, "[%s] %s %s (%s): %s", timebuf, (ww->type == WHOWAS_QUIT) ? "QUIT" : "KILL", hostmask, ww->realname, ww->reason->content);
-}
-
 static int whowas_cmdwhowas(void *source, int cargc, char **cargv) {
   nick *sender = source;
   char *pattern;
@@ -44,7 +31,7 @@ static int whowas_cmdwhowas(void *source, int cargc, char **cargv) {
       matches++;
 
       if (matches <= limit)
-        whowas_spewrecord(ww, sender);
+        whowas_spew(ww, sender);
       else if (matches == limit + 1)
         controlreply(sender, "--- More than %d matches, skipping the rest", limit);
     }
@@ -69,7 +56,7 @@ static int whowas_cmdwhowaschase(void *source, int cargc, char **cargv) {
     return CMD_OK;
   }
 
-  whowas_spewrecord(ww, sender);
+  whowas_spew(ww, sender);
   controlreply(sender, "Done.");
 
   return CMD_OK;