]> jfr.im git - irc/quakenet/newserv.git/blame - chanserv/database/chanservdb_hash.c
fix bug in G stats
[irc/quakenet/newserv.git] / chanserv / database / chanservdb_hash.c
CommitLineData
c86edd1d
Q
1/*
2 * chanservhash.c:
3 * Handles insertion and retrieval of various data structures
4 * from their respective hashes. Hopefully it's obvious from
5 * the name of each function what it does.
6 */
7
8#include <string.h>
76c8da69 9#include <strings.h>
c86edd1d 10
b263aa79 11#include "../chanserv.h"
12#include "../../lib/irc_string.h"
c86edd1d
Q
13
14reguser *regusernicktable[REGUSERHASHSIZE];
c86edd1d 15
e3805f60
P
16maildomain *maildomainnametable[MAILDOMAINHASHSIZE];
17maildomain *maildomainIDtable[MAILDOMAINHASHSIZE];
18
c86edd1d 19#define regusernickhash(x) ((crc32i(x))%REGUSERHASHSIZE)
e3805f60
P
20#define maildomainnamehash(x) ((crc32i(x))%MAILDOMAINHASHSIZE)
21#define maildomainIDhash(x) ((x)%MAILDOMAINHASHSIZE)
c86edd1d
Q
22
23void chanservhashinit() {
24 memset(regusernicktable,0,REGUSERHASHSIZE*sizeof(reguser *));
e3805f60
P
25 memset(maildomainnametable,0,MAILDOMAINHASHSIZE*sizeof(maildomain *));
26 memset(maildomainIDtable,0,MAILDOMAINHASHSIZE*sizeof(maildomain *));
c86edd1d
Q
27}
28
29void addregusertohash(reguser *rup) {
30 unsigned int hash;
316959c1 31 authname *anp;
32
c86edd1d
Q
33 hash=regusernickhash(rup->username);
34
35 rup->nextbyname=regusernicktable[hash];
36 regusernicktable[hash]=rup;
37
5a335041 38 anp=findorcreateauthname(rup->ID, rup->username);
316959c1 39 anp->exts[chanservaext]=rup;
c86edd1d
Q
40}
41
42reguser *findreguserbynick(const char *nick) {
43 unsigned int hashnick;
44 reguser *rup;
45
46 hashnick=regusernickhash(nick);
47 for (rup=regusernicktable[hashnick];rup;rup=rup->nextbyname) {
48 if (!ircd_strcmp(nick,rup->username)) {
49 return rup;
50 }
51 }
52
53 /* Not found */
54 return NULL;
55}
56
57reguser *findreguserbyID(unsigned int ID) {
316959c1 58 authname *anp;
c86edd1d 59
316959c1 60 anp=findauthname(ID);
61 if (anp)
62 return (reguser *)anp->exts[chanservaext];
63 else
64 return NULL;
c86edd1d 65}
c86edd1d
Q
66
67/*
68 * findreguserbyemail()
69 */
70reguser *findreguserbyemail(const char *email) {
71 int i;
72 reguser *rup;
73
74 for (i=0;i<REGUSERHASHSIZE;i++) {
75 for (rup=regusernicktable[i];rup;rup=rup->nextbyname) {
b7ae0f2c 76 if (rup->email && !strcasecmp(email,rup->email->content)) {
c86edd1d
Q
77 return rup;
78 }
79 }
80 }
81 /* Not found */
82 return NULL;
83}
84
85void removereguserfromhash(reguser *rup) {
86 unsigned int hash;
87 reguser **ruh;
316959c1 88 authname *anp;
89
c86edd1d
Q
90 int found;
91
92 hash=regusernickhash(rup->username);
93
94 found=0;
95 for (ruh=&(regusernicktable[hash]);*ruh;ruh=&((*ruh)->nextbyname)) {
96 if (*ruh==rup) {
97 *ruh=(rup->nextbyname);
98 found=1;
99 break;
100 }
101 }
102
103 if (found==0) {
104 Error("chanserv",ERR_ERROR,"Unable to remove reguser %s from nickhash",
105 rup->username);
106 }
c86edd1d 107
316959c1 108 anp=findauthname(rup->ID);
109
110 if (anp) {
111 anp->exts[chanservaext]=NULL;
112 releaseauthname(anp);
113 } else {
114 Error("chanserv",ERR_ERROR,"Unable to remove reguser %s from ID hash",rup->username);
c86edd1d
Q
115 }
116}
117
118void addregusertochannel(regchanuser *rcup) {
119 rcup->nextbyuser=(rcup->user->knownon);
120 rcup->nextbychan=(rcup->chan->regusers[(rcup->user->ID)%REGCHANUSERHASHSIZE]);
121
122 rcup->user->knownon=rcup;
123 rcup->chan->regusers[(rcup->user->ID)%REGCHANUSERHASHSIZE]=rcup;
124}
125
126regchanuser *findreguseronchannel(regchan *rcp, reguser *rup) {
127 regchanuser *rcup;
128
129 for (rcup=rcp->regusers[(rup->ID)%REGCHANUSERHASHSIZE];rcup;rcup=rcup->nextbychan) {
130 if (rcup->user==rup) {
131 return rcup;
132 }
133 }
134
135 /* Not found */
136 return NULL;
137}
138
139void delreguserfromchannel(regchan *rcp, reguser *rup) {
140 regchanuser **rcuh;
141 int found=0;
142
143 for (rcuh=&(rcp->regusers[(rup->ID)%REGCHANUSERHASHSIZE]);*rcuh;
144 rcuh=&((*rcuh)->nextbychan)) {
145 if ((*rcuh)->user==rup) {
146 /* Found the user */
147 freesstring((*rcuh)->info);
052247fa 148 (*rcuh)->info=NULL;
c86edd1d
Q
149 *rcuh=(*rcuh)->nextbychan;
150 found=1;
151 break;
152 }
153 }
154
155 if (found==0) {
156 Error("chanserv",ERR_ERROR,"Unable to remove user %s from channel %s",
157 rup->username,rcp->index->name->content);
158 return;
159 }
160
161 for (rcuh=&(rup->knownon);*rcuh;rcuh=&((*rcuh)->nextbyuser)) {
162 if ((*rcuh)->chan==rcp) {
163 /* Found the channel */
164 *rcuh=(*rcuh)->nextbyuser;
165 return;
166 }
167 }
168
169 Error("chanserv",ERR_ERROR,"Unable to remove channel %s from user %s",
170 rcp->index->name->content,rup->username);
171}
e3805f60
P
172
173void addmaildomaintohash(maildomain *mdp) {
174 unsigned int hash;
175
176 hash=maildomainnamehash(mdp->name->content);
177
178 mdp->nextbyname=maildomainnametable[hash];
179 maildomainnametable[hash]=mdp;
180
181 hash=maildomainIDhash(mdp->ID);
182
183 mdp->nextbyID=maildomainIDtable[hash];
184 maildomainIDtable[hash]=mdp;
185}
186
187maildomain *findmaildomainbyID(unsigned int ID) {
188 unsigned int hash;
189 maildomain *mdp;
190
191 hash=maildomainIDhash(ID);
192 for (mdp=maildomainIDtable[hash]; mdp; mdp=mdp->nextbyID)
193 if (mdp->ID==ID)
194 return mdp;
195
196 return NULL;
197}
198
199maildomain *findmaildomainbydomain(char *domain) {
200 unsigned int hash;
201 maildomain *mdp;
202
203 hash=maildomainnamehash(domain);
204 for (mdp=maildomainnametable[hash]; mdp; mdp=mdp->nextbyname)
96e1f81d 205 if (!strcasecmp(mdp->name->content, domain))
e3805f60
P
206 return mdp;
207
208 return NULL;
209}
210
96e1f81d
CP
211maildomain *findnearestmaildomain(char *domain) {
212 maildomain *m = findmaildomainbydomain(domain);
213 char *p;
214
215 if(!m && (p=strchr(domain, '.')))
216 return findnearestmaildomain(++p);
a03c04b3 217
f27862a4 218 return m;
96e1f81d
CP
219}
220
e3805f60
P
221maildomain *findmaildomainbyemail(char *email) {
222 char *domain;
223
224 if (!(domain=strchr(email, '@')))
225 domain=email;
226 else
227 domain++;
228
229 return findmaildomainbydomain(domain);
230}
231
232maildomain *findorcreatemaildomain(char *email) {
233 unsigned int hash;
234 char *domain,*pdomain;
a03c04b3 235 maildomain *mdp;
e3805f60
P
236
237 if (!(domain=strchr(email, '@')))
238 domain=email;
239 else
240 domain++;
241
242 if( domain[0] == '.' )
243 domain++;
244
245 hash=maildomainnamehash(domain);
246 for (mdp=maildomainnametable[hash]; mdp; mdp=mdp->nextbyname)
96e1f81d 247 if (!strcasecmp(mdp->name->content, domain))
e3805f60
P
248 return mdp;
249
250 mdp=getmaildomain();
251 mdp->ID=0;
252 mdp->name=getsstring(domain, EMAILLEN);
253 mdp->count=0;
254 mdp->limit=0;
96e1f81d
CP
255 mdp->actlimit=MD_DEFAULTACTLIMIT;
256 mdp->flags=MDFLAG_DEFAULT;
e3805f60
P
257 mdp->users=NULL;
258 addmaildomaintohash(mdp);
259
96e1f81d
CP
260 pdomain=strchr(domain, '.');
261
262 if(pdomain) {
e3805f60 263 pdomain++;
96e1f81d
CP
264 mdp->parent = findorcreatemaildomain(pdomain);
265 } else {
e3805f60
P
266 mdp->parent = NULL;
267 }
96e1f81d 268
e3805f60
P
269 return mdp;
270}
271
272void removemaildomainfromhash(maildomain *mdp) {
273 unsigned int hash;
274 maildomain **mdh;
275 int found;
276
277 hash=maildomainnamehash(mdp->name->content);
278
279 found=0;
280 for (mdh=&(maildomainnametable[hash]);*mdh;mdh=&((*mdh)->nextbyname)) {
281 if (*mdh==mdp) {
282 *mdh=(mdp->nextbyname);
283 found=1;
284 break;
285 }
286 }
287
288 if (found==0) {
289 Error("chanserv",ERR_ERROR,"Unable to remove maildomain %s from namehash",
290 mdp->name->content);
291 }
292
293 hash=maildomainIDhash(mdp->ID);
294 found=0;
295
296 for (mdh=&(maildomainIDtable[hash]);*mdh;mdh=&((*mdh)->nextbyID)) {
297 if (*mdh==mdp) {
298 *mdh=(mdp->nextbyID);
299 found=1;
300 break;
301 }
302 }
303
304 if (found==0) {
305 Error("chanserv",ERR_ERROR,"Unable to remove maildomain %s from ID hash",mdp->name->content);
306 }
307}
308
309void addregusertomaildomain(reguser *rup, maildomain *mdp) {
310 maildomain *smdp;
311 rup->nextbydomain=mdp->users;
312 mdp->users=rup;
313 for(smdp=mdp;smdp;smdp=smdp->parent) {
314 smdp->count++;
315 }
316}
317
318void delreguserfrommaildomain(reguser *rup, maildomain *mdp) {
0b64d3ac 319 maildomain *smdp, *nmdp;
e3805f60
P
320 reguser *ruh, *pruh=NULL;
321 int found=0;
322
c497df19
CP
323 if(!mdp)
324 return;
325
e3805f60
P
326 for (ruh=mdp->users; ruh; ruh=ruh->nextbydomain) {
327 if (ruh==rup) {
328 /* Found the user */
329 if (pruh)
330 pruh->nextbydomain=ruh->nextbydomain;
331 else
332 mdp->users=ruh->nextbydomain;
333 found=1;
334 break;
335 }
336 pruh=ruh;
337 }
338
339 if (found==0) {
340 Error("chanserv",ERR_ERROR,"Unable to remove user %s from maildomain %s",
341 rup->username, mdp->name->content);
342 return;
343 }
344
0b64d3ac 345 /* Free it from all the parent domains, cleaning up as we go.. */
346 for(smdp=mdp;smdp;smdp=nmdp) {
347 nmdp=smdp->parent;
348
349 /* Keep it if there are users left or we're remembering something about it. */
350 if (--smdp->count || (smdp->flags != MDFLAG_DEFAULT) || (smdp->actlimit != MD_DEFAULTACTLIMIT))
351 continue;
352
353 removemaildomainfromhash(smdp);
354 freesstring(smdp->name);
355 freemaildomain(smdp);
e3805f60 356 }
0b64d3ac 357
e3805f60
P
358 rup->domain=NULL;
359 freesstring(rup->localpart);
360 rup->localpart=NULL;
e3805f60
P
361}
362