]> jfr.im git - irc/quakenet/newserv.git/blob - chanserv/chanservhash.c
Add jupe support
[irc/quakenet/newserv.git] / chanserv / chanservhash.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 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);
191 (*rcuh)->info=NULL;
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 }