]> jfr.im git - irc/quakenet/newserv.git/blame - authext/authext.c
Add name to authext authname structure.
[irc/quakenet/newserv.git] / authext / authext.c
CommitLineData
57583275 1#include "authext.h"
2#include "../core/nsmalloc.h"
3#include "../core/error.h"
4#include "../lib/sstring.h"
5#include "../lib/irc_string.h"
5a335041 6#include "../nick/nick.h"
d40ae845 7#include "../core/hooks.h"
1a96a370 8#include "../lib/strlfunc.h"
57583275 9
10#include <string.h>
d40ae845 11#include <stdio.h>
57583275 12
13#define ALLOCUNIT 100
14
15#define authnamehash(x) ((x)%AUTHNAMEHASHSIZE)
5a335041 16#define authnamehashbyname(x) (crc32i(x)%AUTHNAMEHASHSIZE)
57583275 17
18authname *freeauthnames;
19authname *authnametable[AUTHNAMEHASHSIZE];
20
5a335041
CP
21/* internal access only */
22static authname *authnametablebyname[AUTHNAMEHASHSIZE];
23
57583275 24sstring *authnameextnames[MAXAUTHNAMEEXTS];
25
d40ae845
CP
26static void authextstats(int hooknum, void *arg);
27
5a335041 28void _init(void) {
57583275 29 freeauthnames=NULL;
30 memset(authnametable,0,sizeof(authnametable));
5a335041 31 memset(authnametablebyname,0,sizeof(authnametablebyname));
d40ae845 32 registerhook(HOOK_CORE_STATSREQUEST, &authextstats);
57583275 33}
34
5a335041 35void _fini(void) {
d40ae845 36 deregisterhook(HOOK_CORE_STATSREQUEST, &authextstats);
57583275 37 nsfreeall(POOL_AUTHEXT);
38}
39
5a335041 40authname *newauthname(void) {
57583275 41 authname *anp;
42 int i;
43
44 if (freeauthnames==NULL) {
45 freeauthnames=(authname *)nsmalloc(POOL_AUTHEXT, ALLOCUNIT*sizeof(authname));
46 for (i=0;i<(ALLOCUNIT-1);i++) {
47 freeauthnames[i].next=&(freeauthnames[i+1]);
48 }
49 freeauthnames[ALLOCUNIT-1].next=NULL;
50 }
51
52 anp=freeauthnames;
53 freeauthnames=anp->next;
54
55 return anp;
56}
57
58void freeauthname (authname *anp) {
59 anp->next=freeauthnames;
60 freeauthnames=anp;
61}
62
63int registerauthnameext(const char *name) {
64 int i;
65
66 if (findauthnameext(name)!=-1) {
67 Error("nick",ERR_WARNING,"Tried to register duplicate authname extension %s",name);
68 return -1;
69 }
70
71 for (i=0;i<MAXAUTHNAMEEXTS;i++) {
72 if (authnameextnames[i]==NULL) {
73 authnameextnames[i]=getsstring(name,100);
74 return i;
75 }
76 }
77
78 Error("nick",ERR_WARNING,"Tried to register too many authname extensions: %s",name);
79 return -1;
80}
81
82int findauthnameext(const char *name) {
83 int i;
84
85 for (i=0;i<MAXAUTHNAMEEXTS;i++) {
86 if (authnameextnames[i]!=NULL && !ircd_strcmp(name,authnameextnames[i]->content)) {
87 return i;
88 }
89 }
90
91 return -1;
92}
93
94void releaseauthnameext(int index) {
95 int i;
96 authname *anp;
97
98 freesstring(authnameextnames[index]);
99 authnameextnames[index]=NULL;
100
101 for (i=0;i<AUTHNAMEHASHSIZE;i++) {
102 for (anp=authnametable[i];anp;anp=anp->next) {
103 anp->exts[index]=NULL;
104 }
105 }
5a335041
CP
106
107 /* the contents of authnametablebyname should be identical */
57583275 108}
109
110authname *findauthname(unsigned long userid) {
111 authname *anp;
112
113 if(!userid)
114 return NULL;
115
116 for (anp=authnametable[authnamehash(userid)];anp;anp=(authname *)anp->next)
117 if (userid==anp->userid)
118 return anp;
119
120 return NULL;
121}
122
5a335041 123authname *findauthnamebyname(const char *name) {
57583275 124 authname *anp;
57583275 125
5a335041
CP
126 if(!name)
127 return NULL;
128
d40ae845 129 for (anp=authnametablebyname[authnamehashbyname(name)];anp;anp=(authname *)anp->nextbyname)
1a96a370 130 if (!ircd_strcmp(anp->name, name))
5a335041
CP
131 return anp;
132
133 return NULL;
134}
135
136authname *findorcreateauthname(unsigned long userid, const char *name) {
137 authname *anp;
138 unsigned int thehash=authnamehash(userid), secondhash = authnamehashbyname(name);
139
140 if(!userid || !name)
57583275 141 return NULL;
142
143 for (anp=authnametable[thehash];anp;anp=(authname *)anp->next)
144 if (userid==anp->userid)
145 return anp;
146
147 anp=newauthname();
148 anp->userid=userid;
1a96a370 149 strlcpy(anp->name, name, sizeof(anp->name));
57583275 150 anp->usercount=0;
151 anp->marker=0;
0b0fb773 152 anp->flags=0;
57583275 153 anp->nicks=NULL;
154 memset(anp->exts, 0, MAXAUTHNAMEEXTS * sizeof(void *));
155 anp->next=(struct authname *)authnametable[thehash];
156 authnametable[thehash]=anp;
157
5a335041
CP
158 anp->namebucket=secondhash;
159 anp->nextbyname=(struct authname *)authnametablebyname[secondhash];
160 authnametablebyname[secondhash]=anp;
161
57583275 162 return anp;
163}
164
165void releaseauthname(authname *anp) {
166 authname **manp;
5a335041 167 int i, found;
57583275 168 if (anp->usercount==0) {
1cf62143
CP
169 anp->nicks = NULL;
170
57583275 171 for(i=0;i<MAXAUTHNAMEEXTS;i++)
172 if(anp->exts[i]!=NULL)
173 return;
174
5a335041 175 found = 0;
57583275 176 for(manp=&(authnametable[authnamehash(anp->userid)]);*manp;manp=(authname **)&((*manp)->next)) {
5a335041
CP
177 if ((*manp)==anp) {
178 (*manp)=(authname *)anp->next;
179 found = 1;
180 break;
181 }
182 }
183 if(!found) {
184 Error("nick",ERR_ERROR,"Unable to remove authname %lu from hashtable",anp->userid);
185 return;
186 }
187
4884107a 188 for(manp=&(authnametablebyname[anp->namebucket]);*manp;manp=(authname **)&((*manp)->nextbyname)) {
57583275 189 if ((*manp)==anp) {
4884107a 190 (*manp)=(authname *)anp->nextbyname;
57583275 191 freeauthname(anp);
192 return;
193 }
194 }
5a335041 195
4884107a 196 Error("nick",ERR_STOP,"Unable to remove authname %lu from byname hashtable, TABLES ARE INCONSISTENT -- DYING",anp->userid);
57583275 197 }
198}
199
5a335041 200unsigned int nextauthnamemarker(void) {
57583275 201 int i;
202 authname *anp;
203 static unsigned int authnamemarker=0;
204
205 authnamemarker++;
206 if (!authnamemarker) {
207 /* If we wrapped to zero, zap the marker on all records */
208 for (i=0;i<AUTHNAMEHASHSIZE;i++)
209 for (anp=authnametable[i];anp;anp=anp->next)
210 anp->marker=0;
211 authnamemarker++;
212 }
213
214 return authnamemarker;
215}
1cf62143
CP
216
217authname *getauthbyname(const char *name) {
218 authname *a = findauthnamebyname(name);
219 if(!a || !a->nicks)
220 return NULL;
221
222 return a;
223}
224
cdc9e13c 225static char *genstats(authname **hashtable, authname *(nextfn)(authname *)) {
d40ae845
CP
226 int i,curchain,maxchain=0,total=0,buckets=0;
227 authname *ap;
228 static char buf[100];
229
230 for (i=0;i<AUTHNAMEHASHSIZE;i++) {
231 if (hashtable[i]!=NULL) {
232 buckets++;
233 curchain=0;
cdc9e13c 234 for (ap=hashtable[i];ap;ap=nextfn(ap)) {
d40ae845
CP
235 total++;
236 curchain++;
237 }
238 if (curchain>maxchain) {
239 maxchain=curchain;
240 }
241 }
242 }
243
244 snprintf(buf, sizeof(buf), "%6d authexts (HASH: %6d/%6d, chain %3d)",total,buckets,AUTHNAMEHASHSIZE,maxchain);
245 return buf;
246}
247
cdc9e13c
CP
248static authname *nextbynext(authname *in) {
249 return in->next;
250}
251
252static authname *nextbyname(authname *in) {
253 return in->nextbyname;
254}
255
d40ae845
CP
256static void authextstats(int hooknum, void *arg) {
257 long level=(long)arg;
258 char buf[100];
259
260 if (level>5) {
261 /* Full stats */
cdc9e13c 262 snprintf(buf,sizeof(buf),"Authext : by id: %s", genstats(authnametable, nextbynext));
d40ae845
CP
263 triggerhook(HOOK_CORE_STATSREPLY,buf);
264
cdc9e13c 265 snprintf(buf,sizeof(buf),"Authext : by name: %s", genstats(authnametablebyname, nextbyname));
d40ae845
CP
266 triggerhook(HOOK_CORE_STATSREPLY,buf);
267 }
268}
269