]> jfr.im git - irc/quakenet/newserv.git/commitdiff
whowas: Keep track of nick changes.
authorGunnar Beutner <redacted>
Sun, 4 Aug 2013 22:49:22 +0000 (00:49 +0200)
committerGunnar Beutner <redacted>
Sun, 4 Aug 2013 22:49:22 +0000 (00:49 +0200)
--HG--
branch : shroudtrusts

whowas/whowas.c
whowas/whowas.h
whowas/whowas_commands.c

index 6ce62d80ec55712fe10fb0c56a42b3ef0c0fe037..8679503836ee5c207e4c2d2c174f44fd53abaf00 100644 (file)
@@ -12,45 +12,22 @@ MODULE_VERSION("");
 whowas *whowas_head = NULL, *whowas_tail = NULL;
 int whowas_count = 0;
 
-static void ww_handlequitorkill(int hooknum, void *arg) {
-  void **args = arg;
-  nick *np = args[0];
-  char *reason = args[1];
-  char *rreason;
-  char resbuf[512];
+whowas *whowas_fromnick(nick *np) {
   whowas *ww;
-  time_t now;
-
-  time(&now);
-
-  /* Clean up old records. */
-  while ((ww = whowas_tail) && (ww->seen < now - WW_MAXAGE || whowas_count >= WW_MAXENTRIES)) {
-    whowas_tail = ww->prev;
-
-    if (ww->prev)
-      ww->prev->next = NULL;
-    else
-      whowas_head = ww->prev;
-
-    whowas_count--;
-    free(ww);
-  }
 
   /* Create a new record. */
   ww = malloc(sizeof(whowas));
+  memset(ww, 0, sizeof(whowas));
   strncpy(ww->nick, np->nick, NICKLEN);
   strncpy(ww->ident, np->ident, USERLEN);
   strncpy(ww->host, np->host->name->content, HOSTLEN);
   strncpy(ww->realname, np->realname->name->content, REALLEN);
   ww->seen = getnettime();
 
-  if (hooknum == HOOK_NICK_KILL && (rreason = strchr(reason, ' '))) {
-    sprintf(resbuf, "Killed%s", rreason);
-    reason = resbuf;
-  }
-
-  ww->reason = getsstring(reason, WW_REASONLEN);
+  return ww;
+}
 
+void whowas_linkrecord(whowas *ww) {
   if (whowas_head)
     whowas_head->prev = ww;
 
@@ -65,19 +42,86 @@ static void ww_handlequitorkill(int hooknum, void *arg) {
   whowas_count++;
 }
 
-void _init(void) {
-  registerhook(HOOK_NICK_QUIT, ww_handlequitorkill);
-  registerhook(HOOK_NICK_KILL, ww_handlequitorkill);
+void whowas_unlinkrecord(whowas *ww) {
+  if (!ww->next)
+    whowas_tail = ww->prev;
+
+  if (ww->prev)
+    ww->prev->next = NULL;
+  else
+    whowas_head = ww->prev;
+
+  whowas_count--;
 }
 
-void _fini(void) {
-  whowas *ww;
+static void whowas_cleanup(void) {
+  time_t now;
 
-  deregisterhook(HOOK_NICK_QUIT, ww_handlequitorkill);
-  deregisterhook(HOOK_NICK_KILL, ww_handlequitorkill);
+  time(&now);
 
-  while ((ww = whowas_head)) {
-    whowas_head = ww->next;
-    free(ww);
+  /* Clean up old records. */
+  while (whowas_tail && (whowas_tail->seen < now - WW_MAXAGE || whowas_count >= WW_MAXENTRIES)) {
+    whowas_unlinkrecord(whowas_tail);
+    free(whowas_tail);
   }
 }
+
+static void whowas_handlequitorkill(int hooknum, void *arg) {
+  void **args = arg;
+  nick *np = args[0];
+  char *reason = args[1];
+  char *rreason;
+  char resbuf[512];
+  whowas *ww;
+
+  whowas_cleanup();
+
+  /* Create a new record. */
+  ww = whowas_fromnick(np);
+
+  if (hooknum == HOOK_NICK_KILL) {
+    if ((rreason = strchr(reason, ' '))) {
+      sprintf(resbuf, "Killed%s", rreason);
+      reason = resbuf;
+    }
+
+    ww->type = WHOWAS_KILL;
+  } else
+    ww->type = WHOWAS_QUIT;
+
+  ww->reason = getsstring(reason, WW_REASONLEN);
+
+  whowas_linkrecord(ww);
+}
+
+static void whowas_handlerename(int hooknum, void *arg) {
+  void **args = arg;
+  nick *np = args[0];
+  char *oldnick = args[1];
+  whowas *ww;
+
+  whowas_cleanup();
+
+  ww = whowas_fromnick(np);
+  ww->type = WHOWAS_RENAME;
+  ww->newnick = getsstring(ww->nick, NICKLEN);
+  strncpy(ww->nick, oldnick, NICKLEN);
+  ww->nick[NICKLEN] = '\0';
+
+  whowas_linkrecord(ww);
+}
+
+void _init(void) {
+  registerhook(HOOK_NICK_QUIT, whowas_handlequitorkill);
+  registerhook(HOOK_NICK_KILL, whowas_handlequitorkill);
+  registerhook(HOOK_NICK_RENAME, whowas_handlerename);
+}
+
+void _fini(void) {
+  deregisterhook(HOOK_NICK_QUIT, whowas_handlequitorkill);
+  deregisterhook(HOOK_NICK_KILL, whowas_handlequitorkill);
+  deregisterhook(HOOK_NICK_RENAME, whowas_handlerename);
+
+  while (whowas_head)
+    whowas_unlinkrecord(whowas_head);
+}
index 217a85f6f0decc92ef0956beb141bb49ba4eed04..64922dfde04723bec7dbb9c0a50fa04dbba563a5 100644 (file)
@@ -4,13 +4,19 @@
 #define WW_REASONLEN 512
 
 typedef struct whowas {
+  time_t seen;
   char nick[NICKLEN + 1];
   char ident[USERLEN + 1];
   char host[HOSTLEN + 1];
   char realname[REALLEN + 1];
+
+  int type;
+
+  /* WHOWAS_QUIT or WHOWAS_KILL */
   sstring *reason;
 
-  time_t seen;
+  /* WHOWAS_RENAME */
+  sstring *newnick;
 
   struct whowas *next;
   struct whowas *prev;
@@ -19,3 +25,6 @@ typedef struct whowas {
 extern whowas *whowas_head, *whowas_tail;
 extern int whowas_count;
 
+#define WHOWAS_QUIT 0
+#define WHOWAS_KILL 1
+#define WHOWAS_RENAME 2
index 90e37ff4967ddd78f3091f6fa721f21f5cc56649..fa88341139661dc5af7d281402224ba74e3ea12b 100644 (file)
@@ -9,7 +9,7 @@
 
 MODULE_VERSION("");
 
-static int ww_cmdwhowas(void *source, int cargc, char **cargv) {
+static int whowas_cmdwhowas(void *source, int cargc, char **cargv) {
   nick *np = source;
   char *pattern;
   whowas *ww;
@@ -34,7 +34,10 @@ static int ww_cmdwhowas(void *source, int cargc, char **cargv) {
       if (matches <= limit) {
         strftime(timebuf, 30, "%d/%m/%y %H:%M:%S", localtime(&(ww->seen)));
 
-        controlreply(np, "[%s] %s (%s): %s", timebuf, hostmask, ww->realname, ww->reason->content);
+        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);
       } else if (matches == limit + 1) {
         controlreply(np, "--- More than %d matches, skipping the rest", limit);
       }
@@ -47,9 +50,9 @@ static int ww_cmdwhowas(void *source, int cargc, char **cargv) {
 }
 
 void _init(void) {
-  registercontrolhelpcmd("whowas", NO_OPER, 2, &ww_cmdwhowas, "Usage: whowas <mask> ?limit?\nLooks up information about recently disconnected users.");
+  registercontrolhelpcmd("whowas", NO_OPER, 2, &whowas_cmdwhowas, "Usage: whowas <mask> ?limit?\nLooks up information about recently disconnected users.");
 }
 
 void _fini(void) {
-  deregistercontrolcmd("whowas", &ww_cmdwhowas);
+  deregistercontrolcmd("whowas", &whowas_cmdwhowas);
 }