]> jfr.im git - irc/quakenet/newserv.git/blob - whowas/whowas.c
FAKEUSERS: First attempt at simplifying fakeuser code
[irc/quakenet/newserv.git] / whowas / whowas.c
1 #include <stdio.h>
2 #include <string.h>
3 #include "../core/hooks.h"
4 #include "../control/control.h"
5 #include "../irc/irc.h"
6 #include "../lib/irc_string.h"
7 #include "whowas.h"
8
9 static whowas *wwhead, *wwtail;
10 static int wwcount;
11
12 int ww_cmdwhowas(void *source, int cargc, char **cargv) {
13 nick *np = source;
14 char *pattern;
15 whowas *ww;
16 char hostmask[WW_MASKLEN+1];
17 char timebuf[30];
18 int matches = 0, limit = 500;
19
20 if(cargc<1)
21 return CMD_USAGE;
22
23 pattern = cargv[0];
24
25 if(cargc>1)
26 limit = strtol(cargv[1], NULL, 10);
27
28 for(ww=wwhead;ww;ww=ww->next) {
29 snprintf(hostmask, sizeof(hostmask), "%s!%s@%s", ww->nick, ww->ident, ww->host);
30
31 if (match2strings(pattern, hostmask)) {
32 matches++;
33
34 if(matches<=limit) {
35 strftime(timebuf, 30, "%d/%m/%y %H:%M:%S", localtime(&(ww->seen)));
36
37 controlreply(np, "[%s] %s (%s): %s", timebuf, hostmask, ww->realname, ww->reason->content);
38 } else if(matches==limit+1) {
39 controlreply(np, "--- More than %d matches, skipping the rest", limit);
40 }
41 }
42 }
43
44 controlreply(np, "--- Found %d entries.", matches);
45
46 return CMD_OK;
47 }
48
49 void ww_handlequitorkill(int hooknum, void *arg) {
50 void **args=arg;
51 nick *np=args[0];
52 char *reason=args[1];
53 char *rreason;
54 char resbuf[512];
55 whowas *ww;
56 time_t now;
57
58 time(&now);
59
60 /* Clean up old records. */
61 while((ww = wwtail) && (ww->seen < now - WW_MAXAGE || wwcount >= WW_MAXENTRIES)) {
62 wwtail = ww->prev;
63
64 if (ww->prev)
65 ww->prev->next = NULL;
66 else
67 wwhead = ww->prev;
68
69 wwcount--;
70 free(ww);
71 }
72
73 /* Create a new record. */
74 ww = malloc(sizeof(whowas));
75 strncpy(ww->nick, np->nick, NICKLEN);
76 strncpy(ww->ident, np->ident, USERLEN);
77 strncpy(ww->host, np->host->name->content, HOSTLEN);
78 strncpy(ww->realname, np->realname->name->content, REALLEN);
79 ww->seen = getnettime();
80
81 if(hooknum==HOOK_NICK_KILL && (rreason=strchr(reason,' '))) {
82 sprintf(resbuf,"Killed%s",rreason);
83 reason=resbuf;
84 }
85
86 ww->reason = getsstring(reason, WW_REASONLEN);
87
88 if(wwhead)
89 wwhead->prev = ww;
90
91 ww->next = wwhead;
92 wwhead = ww;
93
94 ww->prev = NULL;
95
96 if(!wwtail)
97 wwtail = ww;
98
99 wwcount++;
100 }
101
102 void _init(void) {
103 registerhook(HOOK_NICK_QUIT, ww_handlequitorkill);
104 registerhook(HOOK_NICK_KILL, ww_handlequitorkill);
105
106 registercontrolhelpcmd("whowas", NO_OPER, 2, &ww_cmdwhowas, "Usage: whowas <mask> ?limit?\nLooks up information about recently disconnected users.");
107 }
108
109 void _fini(void) {
110 whowas *ww;
111
112 deregisterhook(HOOK_NICK_QUIT, ww_handlequitorkill);
113 deregisterhook(HOOK_NICK_KILL, ww_handlequitorkill);
114
115 deregistercontrolcmd("whowas", &ww_cmdwhowas);
116
117 while((ww = wwhead)) {
118 wwhead = ww->next;
119 free(ww);
120 }
121 }