]> jfr.im git - irc/quakenet/newserv.git/blob - chanserv/authtracker/authtracker_hooks.c
411a04c1d8ef11682b45d4cb13ce2a2de37c89fa
[irc/quakenet/newserv.git] / chanserv / authtracker / authtracker_hooks.c
1 /* authtracker module: Tracks when users come and go... */
2
3 #include "authtracker.h"
4 #include "../chanserv.h"
5 #include "../../core/hooks.h"
6 #include "../../nick/nick.h"
7 #include "../../lib/irc_string.h"
8
9 #include <time.h>
10 #include <string.h>
11
12 #define NTERFACER_AUTH "nterfacer"
13
14 /* OK, we need to deal separately with users who have definitely gone (QUIT
15 * or KILL) and those who has mysteriously vanished (lost in netsplit).
16 * There are hooks for all these things, but sadly QUIT and KILL also
17 * trigger the generic "lost nick" hook. Luckily, these things always
18 * happen one after the other without any intervening quits, so we will keep
19 * track of the last QUIT or KILL details and ignore the subsequent
20 * LOSTNICK. */
21
22 unsigned int at_lastnum;
23 time_t at_lastauthts;
24 unsigned long at_lastuserid;
25
26 unsigned long at_getuserid(nick *np) {
27 /* If they are not +r, forget it. */
28 if (!IsAccount(np))
29 return 0;
30
31 /* Ignore that pesky nterfacer */
32 #ifdef NTERFACER_AUTH
33 if (!ircd_strcmp(np->authname, NTERFACER_AUTH))
34 return 0;
35 #endif
36
37 /* Use the userid from authext only. */
38 if (np->auth)
39 return np->auth->userid;
40
41 Error("authtracker",ERR_WARNING,"Unable to get userID from IsAccount() user %s",np->nick);
42 return 0;
43 }
44
45 void at_handlequitorkill(int hooknum, void *arg) {
46 void **args=arg;
47 nick *np=args[0];
48 char *reason=args[1];
49 char *rreason;
50 unsigned long userid;
51
52 /* Ignore unauthed users, or those with no accountts */
53 if (!(userid=at_getuserid(np)) || !np->accountts)
54 return;
55
56 at_lastuserid=userid;
57 at_lastauthts=np->accountts;
58 at_lastnum=np->numeric;
59
60 if (hooknum==HOOK_NICK_KILL && (rreason=strchr(reason,'@')))
61 reason=rreason;
62
63 at_logquit(userid, np->accountts, time(NULL), reason);
64 }
65
66 void at_handlelostnick(int hooknum, void *arg) {
67 nick *np=arg;
68 unsigned long userid;
69
70 if (!(userid=at_getuserid(np)) || !np->accountts)
71 return;
72
73 /* Don't do this for a user that just left normally (see above) */
74 if ((userid==at_lastuserid) && (np->accountts == at_lastauthts) && (np->numeric==at_lastnum))
75 return;
76
77 at_lostnick(np->numeric, userid, np->accountts, time(NULL), AT_NETSPLIT);
78 }
79
80 void at_newnick(int hooknum, void *arg) {
81 nick *np=arg;
82 unsigned long userid;
83
84 /* Ignore unauthed users, or those with no TS */
85 if (!(userid=at_getuserid(np)) || !np->accountts)
86 return;
87
88 /* OK, we've seen an authed user appear. If it's a known ghost we can zap it */
89 if (!at_foundnick(np->numeric, userid, np->accountts)) {
90 /* If we didn't zap a ghost then it's a new session */
91 at_lognewsession(userid, np);
92 }
93 }
94
95 void at_serverlinked(int hooknum, void *arg) {
96 unsigned long servernum=(unsigned long)arg;
97
98 at_serverback(servernum);
99 }
100
101 void at_hookinit() {
102 registerhook(HOOK_NICK_QUIT, at_handlequitorkill);
103 registerhook(HOOK_NICK_KILL, at_handlequitorkill);
104 registerhook(HOOK_NICK_LOSTNICK, at_handlelostnick);
105 registerhook(HOOK_NICK_NEWNICK, at_newnick);
106 registerhook(HOOK_NICK_ACCOUNT, at_newnick);
107 registerhook(HOOK_SERVER_LINKED, at_serverlinked);
108 }
109
110 void at_hookfini() {
111 deregisterhook(HOOK_NICK_QUIT, at_handlequitorkill);
112 deregisterhook(HOOK_NICK_KILL, at_handlequitorkill);
113 deregisterhook(HOOK_NICK_LOSTNICK, at_handlelostnick);
114 deregisterhook(HOOK_NICK_NEWNICK, at_newnick);
115 deregisterhook(HOOK_NICK_ACCOUNT, at_newnick);
116 deregisterhook(HOOK_SERVER_LINKED, at_serverlinked);
117 }