]>
Commit | Line | Data |
---|---|---|
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> | |
9 | ||
10 | #include "chanserv.h" | |
11 | #include "../lib/irc_string.h" | |
12 | ||
13 | reguser *regusernicktable[REGUSERHASHSIZE]; | |
14 | reguser *reguserIDtable[REGUSERHASHSIZE]; | |
15 | ||
16 | #define regusernickhash(x) ((crc32i(x))%REGUSERHASHSIZE) | |
17 | #define reguserIDhash(x) ((x)%REGUSERHASHSIZE) | |
18 | ||
19 | void chanservhashinit() { | |
20 | memset(regusernicktable,0,REGUSERHASHSIZE*sizeof(reguser *)); | |
21 | memset(reguserIDtable,0,REGUSERHASHSIZE*sizeof(reguser *)); | |
22 | } | |
23 | ||
24 | void addregusertohash(reguser *rup) { | |
25 | unsigned int hash; | |
26 | ||
27 | hash=regusernickhash(rup->username); | |
28 | ||
29 | rup->nextbyname=regusernicktable[hash]; | |
30 | regusernicktable[hash]=rup; | |
31 | ||
32 | hash=reguserIDhash(rup->ID); | |
33 | ||
34 | rup->nextbyID=reguserIDtable[hash]; | |
35 | reguserIDtable[hash]=rup; | |
36 | } | |
37 | ||
38 | reguser *findreguserbynick(const char *nick) { | |
39 | unsigned int hashnick; | |
40 | reguser *rup; | |
41 | ||
42 | hashnick=regusernickhash(nick); | |
43 | for (rup=regusernicktable[hashnick];rup;rup=rup->nextbyname) { | |
44 | if (!ircd_strcmp(nick,rup->username)) { | |
45 | return rup; | |
46 | } | |
47 | } | |
48 | ||
49 | /* Not found */ | |
50 | return NULL; | |
51 | } | |
52 | ||
53 | reguser *findreguserbyID(unsigned int ID) { | |
54 | unsigned int hash; | |
55 | reguser *rup; | |
56 | ||
57 | hash=reguserIDhash(ID); | |
58 | for (rup=reguserIDtable[hash];rup;rup=rup->nextbyID) | |
59 | if (rup->ID==ID) | |
60 | return rup; | |
61 | ||
62 | /* Not found */ | |
63 | return NULL; | |
64 | } | |
65 | ||
66 | /* | |
67 | * findreguser: | |
68 | * This function does the standard "nick or #user" lookup. | |
69 | * If "sender" is not NULL, a suitable error message will | |
70 | * be sent if the lookup fails | |
71 | */ | |
72 | ||
73 | reguser *findreguser(nick *sender, const char *str) { | |
74 | reguser *rup; | |
75 | nick *np; | |
76 | ||
77 | if (!str || !*str) | |
78 | return NULL; | |
79 | ||
80 | if (*str=='#') { | |
81 | if (str[1]=='\0') { | |
82 | if (sender) | |
83 | chanservstdmessage(sender, QM_UNKNOWNUSER, str); | |
84 | return NULL; | |
85 | } | |
86 | if (!(rup=findreguserbynick(str+1)) && sender) | |
87 | chanservstdmessage(sender, QM_UNKNOWNUSER, str); | |
88 | } else { | |
89 | if (!(np=getnickbynick(str))) { | |
90 | if (sender) | |
91 | chanservstdmessage(sender, QM_UNKNOWNUSER, str); | |
92 | return NULL; | |
93 | } | |
94 | if (!(rup=getreguserfromnick(np)) && sender) | |
95 | chanservstdmessage(sender, QM_USERNOTAUTHED, str); | |
96 | } | |
97 | ||
98 | if (rup && (UIsSuspended(rup) || (rup->status & QUSTAT_DEAD))) { | |
99 | chanservstdmessage(sender, QM_USERHASBADAUTH, rup->username); | |
100 | return NULL; | |
101 | } | |
102 | ||
103 | return rup; | |
104 | } | |
105 | ||
106 | /* | |
107 | * findreguserbyemail() | |
108 | */ | |
109 | reguser *findreguserbyemail(const char *email) { | |
110 | int i; | |
111 | reguser *rup; | |
112 | ||
113 | for (i=0;i<REGUSERHASHSIZE;i++) { | |
114 | for (rup=regusernicktable[i];rup;rup=rup->nextbyname) { | |
115 | if (!ircd_strcmp(email,rup->email->content)) { | |
116 | return rup; | |
117 | } | |
118 | } | |
119 | } | |
120 | /* Not found */ | |
121 | return NULL; | |
122 | } | |
123 | ||
124 | void removereguserfromhash(reguser *rup) { | |
125 | unsigned int hash; | |
126 | reguser **ruh; | |
127 | int found; | |
128 | ||
129 | hash=regusernickhash(rup->username); | |
130 | ||
131 | found=0; | |
132 | for (ruh=&(regusernicktable[hash]);*ruh;ruh=&((*ruh)->nextbyname)) { | |
133 | if (*ruh==rup) { | |
134 | *ruh=(rup->nextbyname); | |
135 | found=1; | |
136 | break; | |
137 | } | |
138 | } | |
139 | ||
140 | if (found==0) { | |
141 | Error("chanserv",ERR_ERROR,"Unable to remove reguser %s from nickhash", | |
142 | rup->username); | |
143 | } | |
144 | ||
145 | hash=reguserIDhash(rup->ID); | |
146 | found=0; | |
147 | ||
148 | for (ruh=&(reguserIDtable[hash]);*ruh;ruh=&((*ruh)->nextbyID)) { | |
149 | if (*ruh==rup) { | |
150 | *ruh=(rup->nextbyID); | |
151 | found=1; | |
152 | break; | |
153 | } | |
154 | } | |
155 | ||
156 | if (found==0) { | |
157 | Error("chanserv",ERR_ERROR,"Unable to remove reguser %s from ID hash",rup->ID); | |
158 | } | |
159 | } | |
160 | ||
161 | void addregusertochannel(regchanuser *rcup) { | |
162 | rcup->nextbyuser=(rcup->user->knownon); | |
163 | rcup->nextbychan=(rcup->chan->regusers[(rcup->user->ID)%REGCHANUSERHASHSIZE]); | |
164 | ||
165 | rcup->user->knownon=rcup; | |
166 | rcup->chan->regusers[(rcup->user->ID)%REGCHANUSERHASHSIZE]=rcup; | |
167 | } | |
168 | ||
169 | regchanuser *findreguseronchannel(regchan *rcp, reguser *rup) { | |
170 | regchanuser *rcup; | |
171 | ||
172 | for (rcup=rcp->regusers[(rup->ID)%REGCHANUSERHASHSIZE];rcup;rcup=rcup->nextbychan) { | |
173 | if (rcup->user==rup) { | |
174 | return rcup; | |
175 | } | |
176 | } | |
177 | ||
178 | /* Not found */ | |
179 | return NULL; | |
180 | } | |
181 | ||
182 | void delreguserfromchannel(regchan *rcp, reguser *rup) { | |
183 | regchanuser **rcuh; | |
184 | int found=0; | |
185 | ||
186 | for (rcuh=&(rcp->regusers[(rup->ID)%REGCHANUSERHASHSIZE]);*rcuh; | |
187 | rcuh=&((*rcuh)->nextbychan)) { | |
188 | if ((*rcuh)->user==rup) { | |
189 | /* Found the user */ | |
190 | freesstring((*rcuh)->info); | |
052247fa | 191 | (*rcuh)->info=NULL; |
c86edd1d Q |
192 | *rcuh=(*rcuh)->nextbychan; |
193 | found=1; | |
194 | break; | |
195 | } | |
196 | } | |
197 | ||
198 | if (found==0) { | |
199 | Error("chanserv",ERR_ERROR,"Unable to remove user %s from channel %s", | |
200 | rup->username,rcp->index->name->content); | |
201 | return; | |
202 | } | |
203 | ||
204 | for (rcuh=&(rup->knownon);*rcuh;rcuh=&((*rcuh)->nextbyuser)) { | |
205 | if ((*rcuh)->chan==rcp) { | |
206 | /* Found the channel */ | |
207 | *rcuh=(*rcuh)->nextbyuser; | |
208 | return; | |
209 | } | |
210 | } | |
211 | ||
212 | Error("chanserv",ERR_ERROR,"Unable to remove channel %s from user %s", | |
213 | rcp->index->name->content,rup->username); | |
214 | } |