]>
Commit | Line | Data |
---|---|---|
6155f93e CP |
1 | /* authhash.c */ |
2 | ||
3 | #include "../lib/irc_string.h" | |
4 | #include "../nick/nick.h" | |
5 | #include "../core/hooks.h" | |
6 | #include "../core/error.h" | |
9c022a42 | 7 | #include "../lib/version.h" |
6155f93e CP |
8 | #include "authhash.h" |
9 | ||
70b0a4e5 | 10 | MODULE_VERSION(""); |
6155f93e CP |
11 | |
12 | #define AUTHHASHSIZE 40000 | |
13 | #define authhash(x) ((crc32i(x))%AUTHHASHSIZE) | |
14 | ||
15 | nick *authtable[AUTHHASHSIZE]; | |
16 | ||
17 | int nextbyauthext = -1; | |
18 | int nextbyhashext = -1; | |
19 | ||
20 | #define nextbyhash(x) x->exts[nextbyhashext] | |
21 | #define rnextbyauth(x) x->exts[nextbyauthext] | |
22 | ||
23 | void ah_onnick(int hooknum, void *arg); | |
24 | void ah_onauth(int hooknum, void *arg); | |
25 | void ah_onquit(int hooknum, void *arg); | |
26 | ||
27 | void _init() { | |
28 | nick *np; | |
29 | int i; | |
30 | ||
31 | nextbyauthext = registernickext("authnext"); | |
32 | if(nextbyauthext == -1) | |
33 | return; | |
34 | ||
35 | nextbyhashext = registernickext("authhash"); | |
36 | if(nextbyhashext == -1) | |
37 | return; | |
38 | ||
39 | for(i=0;i<NICKHASHSIZE;i++) | |
40 | for(np=nicktable[i];np;np=np->next) | |
41 | ah_onauth(HOOK_NICK_NEWNICK, np); | |
42 | ||
43 | registerhook(HOOK_NICK_NEWNICK, &ah_onauth); | |
44 | registerhook(HOOK_NICK_ACCOUNT, &ah_onauth); | |
45 | registerhook(HOOK_NICK_LOSTNICK, &ah_onquit); | |
46 | } | |
47 | ||
48 | void _fini() { | |
49 | deregisterhook(HOOK_NICK_LOSTNICK, &ah_onquit); | |
50 | deregisterhook(HOOK_NICK_ACCOUNT, &ah_onauth); | |
51 | deregisterhook(HOOK_NICK_NEWNICK, &ah_onauth); | |
52 | ||
53 | if(nextbyhashext != -1) | |
54 | releasenickext(nextbyhashext); | |
55 | ||
56 | if(nextbyauthext != -1) | |
57 | releasenickext(nextbyauthext); | |
58 | } | |
59 | ||
60 | void ah_onauth(int hooknum, void *arg) { | |
61 | nick *np = (nick *)arg, *existing, *pred; | |
62 | long hash; | |
63 | ||
64 | if(!np || !IsAccount(np)) | |
65 | return; | |
66 | ||
67 | hash = authhash(np->authname); | |
68 | ||
69 | for(pred=NULL,existing=authtable[hash];existing;pred=existing,existing=nextbyhash(existing)) | |
70 | if(!ircd_strcmp(existing->authname, np->authname)) | |
71 | break; | |
72 | ||
73 | if(!existing) { | |
74 | nextbyhash(np) = authtable[hash]; /* np->nextbyhash = authtable[hash]; */ | |
75 | authtable[hash] = np; | |
76 | } else { | |
77 | rnextbyauth(np) = existing; /* np->nextbyauth = existing */ | |
78 | nextbyhash(np) = nextbyhash(existing); /* np->nextbyhash = existing->nextbyhash */ | |
79 | nextbyhash(existing) = NULL; /* existing->nextbyhash = NULL */ | |
80 | ||
81 | if(pred) { | |
82 | nextbyhash(pred) = np; /* pred->nextbyhash = np */ | |
83 | } else { | |
84 | authtable[hash] = np; | |
85 | } | |
86 | } | |
87 | } | |
88 | ||
89 | void ah_onquit(int hooknum, void *arg) { | |
90 | nick *np = (nick *)arg, *authpred, *hashpred, *nextauth, *nexthash; | |
91 | long hash; | |
92 | ||
93 | if(!np || !IsAccount(np)) | |
94 | return; | |
95 | ||
96 | hash = authhash(np->authname); | |
97 | nexthash = nextbyhash(np); | |
98 | ||
99 | authpred = getnickbyauth(np->authname); | |
100 | if(authpred == np) { | |
101 | authpred = NULL; | |
102 | ||
103 | if(authtable[hash] == np) { | |
104 | hashpred = NULL; | |
105 | } else { | |
106 | for(hashpred=authtable[hash];nextbyhash(hashpred);hashpred=nextbyhash(hashpred)) | |
107 | if(!ircd_strcmp(((nick *)nextbyhash(hashpred))->authname, np->authname)) | |
108 | break; | |
109 | } | |
110 | } else { | |
111 | nexthash = nextbyhash(authpred); | |
112 | ||
113 | for(authpred=getnickbyauth(np->authname);rnextbyauth(authpred);authpred=rnextbyauth(authpred)) | |
114 | if(np == rnextbyauth(authpred)) | |
115 | break; | |
116 | } | |
117 | ||
118 | nextauth = rnextbyauth(np); | |
119 | if(authpred) { | |
120 | rnextbyauth(authpred) = nextauth; | |
121 | } else { | |
122 | if(nextauth && hashpred) { | |
123 | nextbyhash(hashpred) = nextauth; | |
124 | nextbyhash(nextauth) = nexthash; | |
125 | } else if(!nextauth && hashpred) { | |
126 | nextbyhash(hashpred) = nexthash; | |
127 | } else if(nextauth && !hashpred) { | |
128 | authtable[hash] = nextauth; | |
129 | nextbyhash(nextauth) = nexthash; | |
130 | } else { | |
131 | authtable[hash] = nexthash; | |
132 | } | |
133 | } | |
134 | } | |
135 | ||
136 | nick *getnickbyauth(const char *auth) { | |
137 | nick *np; | |
138 | ||
139 | for(np=authtable[authhash(auth)];np;np=nextbyhash(np)) | |
140 | if(!ircd_strcmp(np->authname, auth)) | |
141 | break; | |
142 | ||
143 | return np; | |
144 | } |