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