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;
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);
+}
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;
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);
}
}
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);
}