]> jfr.im git - irc/quakenet/newserv.git/blame - whowas/whowas.c
Add documentation files.
[irc/quakenet/newserv.git] / whowas / whowas.c
CommitLineData
fa6819a7 1#include <string.h>
0eb4cbd3 2#include <stdio.h>
fa6819a7
GB
3#include "../core/hooks.h"
4#include "../control/control.h"
5#include "../irc/irc.h"
6#include "../lib/irc_string.h"
363e3ed0 7#include "../lib/version.h"
fa6819a7
GB
8#include "whowas.h"
9
363e3ed0 10MODULE_VERSION("");
fa6819a7 11
0495c1d1
GB
12whowas whowasrecs[WW_MAXENTRIES];
13int whowasoffset = 0;
d6385de2 14
0495c1d1 15whowas *whowas_fromnick(nick *np, int standalone) {
fa6819a7 16 whowas *ww;
0eb4cbd3
GB
17 nick *wnp;
18 struct irc_in_addr ipaddress_canonical;
fa6819a7
GB
19
20 /* Create a new record. */
0495c1d1
GB
21 if (standalone)
22 ww = malloc(sizeof(whowas));
23 else {
24 ww = &whowasrecs[whowasoffset];
25 whowas_clean(ww);
26 whowasoffset = (whowasoffset + 1) % WW_MAXENTRIES;
27 }
28
4030a47e 29 memset(ww, 0, sizeof(whowas));
0eb4cbd3 30
0495c1d1 31 wnp = &ww->nick;
0eb4cbd3
GB
32 memset(wnp, 0, sizeof(nick));
33 strncpy(wnp->nick, np->nick, NICKLEN + 1);
34 wnp->numeric = np->numeric;
35 strncpy(wnp->ident, np->ident, USERLEN + 1);
36
37 wnp->host = newhost();
38 memset(wnp->host, 0, sizeof(host));
39 wnp->host->name = getsstring(np->host->name->content, HOSTLEN);
40
41 wnp->realname = newrealname();
42 memset(wnp->realname, 0, sizeof(realname));
43 wnp->realname->name = getsstring(np->realname->name->content, REALLEN);
81e02f8e
GB
44 wnp->shident = np->shident ? getsstring(np->shident->content, 512) : NULL;
45 wnp->sethost = np->sethost ? getsstring(np->sethost->content, 512) : NULL;
46 wnp->opername = np->opername ? getsstring(np->opername->content, 512) : NULL;
0eb4cbd3
GB
47 wnp->umodes = np->umodes;
48 if (np->auth) {
49 wnp->auth = newauthname();
50 memset(wnp->auth, 0, sizeof(authname));
51 wnp->auth->userid = np->auth->userid;
52 strncpy(wnp->auth->name, np->auth->name, ACCOUNTLEN + 1);
b965fa47 53 wnp->authname = wnp->auth->name;
0eb4cbd3 54 }
0eb4cbd3
GB
55 wnp->timestamp = np->timestamp;
56 wnp->accountts = np->accountts;
57 wnp->away = np->away ? getsstring(np->away->content, 512) : NULL;
58
59 memcpy(&wnp->ipaddress, &np->ipaddress, sizeof(struct irc_in_addr));
60
61 ip_canonicalize_tunnel(&ipaddress_canonical, &np->ipaddress);
62 wnp->ipnode = refnode(iptree, &ipaddress_canonical, PATRICIA_MAXBITS);
63
64 wnp->next = (nick *)ww; /* Yuck. */
65
0eb4cbd3 66 ww->timestamp = getnettime();
a45da344 67 ww->type = WHOWAS_USED;
fa6819a7 68
4030a47e
GB
69 return ww;
70}
d6385de2 71
0495c1d1 72void whowas_clean(whowas *ww) {
0eb4cbd3
GB
73 nick *np;
74
0495c1d1 75 if (!ww || ww->type == WHOWAS_UNUSED)
accce086
GB
76 return;
77
0495c1d1 78 np = &ww->nick;
0eb4cbd3
GB
79 freesstring(np->host->name);
80 freehost(np->host);
81 freesstring(np->realname->name);
82 freerealname(np->realname);
83 freesstring(np->shident);
84 freesstring(np->sethost);
85 freesstring(np->opername);
86 freeauthname(np->auth);
87 freesstring(np->away);
0495c1d1 88
accce086 89 freesstring(ww->reason);
0495c1d1 90 ww->type = WHOWAS_UNUSED;
accce086
GB
91}
92
0495c1d1
GB
93void whowas_free(whowas *ww) {
94 whowas_clean(ww);
95 free(ww);
fa6819a7 96}
4030a47e
GB
97
98static void whowas_handlequitorkill(int hooknum, void *arg) {
99 void **args = arg;
100 nick *np = args[0];
101 char *reason = args[1];
102 char *rreason;
103 char resbuf[512];
104 whowas *ww;
105
4030a47e 106 /* Create a new record. */
0495c1d1 107 ww = whowas_fromnick(np, 0);
4030a47e
GB
108
109 if (hooknum == HOOK_NICK_KILL) {
110 if ((rreason = strchr(reason, ' '))) {
111 sprintf(resbuf, "Killed%s", rreason);
112 reason = resbuf;
113 }
114
115 ww->type = WHOWAS_KILL;
98005421
GB
116 } else {
117 if (strncmp(reason, "G-lined", 7) == 0)
118 ww->type = WHOWAS_KILL;
119 else
120 ww->type = WHOWAS_QUIT;
121 }
4030a47e
GB
122
123 ww->reason = getsstring(reason, WW_REASONLEN);
4030a47e
GB
124}
125
126static void whowas_handlerename(int hooknum, void *arg) {
127 void **args = arg;
128 nick *np = args[0];
129 char *oldnick = args[1];
130 whowas *ww;
0eb4cbd3 131 nick *wnp;
4030a47e 132
0495c1d1 133 ww = whowas_fromnick(np, 0);
4030a47e 134 ww->type = WHOWAS_RENAME;
0495c1d1 135 wnp = &ww->nick;
0eb4cbd3
GB
136 ww->newnick = getsstring(wnp->nick, NICKLEN);
137 strncpy(wnp->nick, oldnick, NICKLEN + 1);
4030a47e
GB
138}
139
0495c1d1 140whowas *whowas_chase(const char *target, int maxage) {
56cab147 141 whowas *ww;
0495c1d1 142 nick *wnp;
56cab147 143 time_t now;
0495c1d1 144 int i;
56cab147
GB
145
146 now = getnettime();
147
0495c1d1
GB
148 for (i = whowasoffset + WW_MAXENTRIES - 1; i >= whowasoffset; i--) {
149 ww = &whowasrecs[i % WW_MAXENTRIES];
150
151 if (ww->type == WHOWAS_UNUSED)
152 continue;
153
154 wnp = &ww->nick;
155
0eb4cbd3 156 if (ww->timestamp < now - maxage)
56cab147
GB
157 break; /* records are in timestamp order, we're done */
158
0495c1d1 159 if (ircd_strcmp(wnp->nick, target) == 0)
56cab147
GB
160 return ww;
161 }
162
163 return NULL;
164}
165
0eb4cbd3 166const char *whowas_format(whowas *ww) {
0495c1d1 167 nick *np = &ww->nick;
0eb4cbd3 168 static char buf[512];
accce086 169 char timebuf[30];
0eb4cbd3 170 char hostmask[512];
accce086 171
432206be 172 snprintf(hostmask, sizeof(hostmask), "%s!%s@%s%s%s [%s] (%s)",
0eb4cbd3
GB
173 np->nick, np->ident, np->host->name->content,
174 np->auth ? "/" : "", np->auth ? np->authname : "",
fdcb5d66 175 IPtostr(np->ipaddress),
432206be 176 printflags(np->umodes, umodeflags));
0eb4cbd3 177 strftime(timebuf, sizeof(timebuf), "%d/%m/%y %H:%M:%S", localtime(&(ww->timestamp)));
accce086
GB
178
179 if (ww->type == WHOWAS_RENAME)
0eb4cbd3 180 snprintf(buf, sizeof(buf), "[%s] NICK %s r(%s) -> %s", timebuf, hostmask, np->realname->name->content, ww->newnick->content);
accce086 181 else
0eb4cbd3
GB
182 snprintf(buf, sizeof(buf), "[%s] %s %s r(%s): %s", timebuf, (ww->type == WHOWAS_QUIT) ? "QUIT" : "KILL", hostmask, np->realname->name->content, ww->reason->content);
183
184 return buf;
185}
186
187unsigned int nextwhowasmarker() {
188 whowas *ww;
0495c1d1 189 int i;
0eb4cbd3
GB
190 static unsigned int whowasmarker=0;
191
192 whowasmarker++;
193
194 if (!whowasmarker) {
195 /* If we wrapped to zero, zap the marker on all records */
0495c1d1
GB
196 for (i = 0; i < WW_MAXENTRIES; i++) {
197 ww = &whowasrecs[i % WW_MAXENTRIES];
198 ww->marker=0;
199 }
200
0eb4cbd3
GB
201 whowasmarker++;
202 }
203
204 return whowasmarker;
accce086
GB
205}
206
4030a47e
GB
207void _init(void) {
208 registerhook(HOOK_NICK_QUIT, whowas_handlequitorkill);
209 registerhook(HOOK_NICK_KILL, whowas_handlequitorkill);
210 registerhook(HOOK_NICK_RENAME, whowas_handlerename);
211}
212
213void _fini(void) {
0495c1d1
GB
214 int i;
215 whowas *ww;
216
4030a47e
GB
217 deregisterhook(HOOK_NICK_QUIT, whowas_handlequitorkill);
218 deregisterhook(HOOK_NICK_KILL, whowas_handlequitorkill);
219 deregisterhook(HOOK_NICK_RENAME, whowas_handlerename);
220
0495c1d1 221 for (i = 0; i < WW_MAXENTRIES; i++) {
96fa425f 222 ww = &whowasrecs[i];
0495c1d1
GB
223 whowas_clean(ww);
224 }
4030a47e 225}