]> jfr.im git - irc/quakenet/newserv.git/blame - authhash/authhash.c
fix play module for iptrie
[irc/quakenet/newserv.git] / authhash / authhash.c
CommitLineData
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 10MODULE_VERSION("");
6155f93e
CP
11
12#define AUTHHASHSIZE 40000
13#define authhash(x) ((crc32i(x))%AUTHHASHSIZE)
14
15nick *authtable[AUTHHASHSIZE];
16
17int nextbyauthext = -1;
18int nextbyhashext = -1;
19
20#define nextbyhash(x) x->exts[nextbyhashext]
21#define rnextbyauth(x) x->exts[nextbyauthext]
22
23void ah_onnick(int hooknum, void *arg);
24void ah_onauth(int hooknum, void *arg);
25void ah_onquit(int hooknum, void *arg);
26
27void _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
48void _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
60void 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
89void 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
136nick *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}