]> jfr.im git - irc/quakenet/newserv.git/blame - authext/authext.c
Merge.
[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"
57583275 7
8#include <string.h>
9
10#define ALLOCUNIT 100
11
12#define authnamehash(x) ((x)%AUTHNAMEHASHSIZE)
5a335041 13#define authnamehashbyname(x) (crc32i(x)%AUTHNAMEHASHSIZE)
57583275 14
15authname *freeauthnames;
16authname *authnametable[AUTHNAMEHASHSIZE];
17
5a335041
CP
18/* internal access only */
19static authname *authnametablebyname[AUTHNAMEHASHSIZE];
20
57583275 21sstring *authnameextnames[MAXAUTHNAMEEXTS];
22
5a335041 23void _init(void) {
57583275 24 freeauthnames=NULL;
25 memset(authnametable,0,sizeof(authnametable));
5a335041 26 memset(authnametablebyname,0,sizeof(authnametablebyname));
57583275 27}
28
5a335041 29void _fini(void) {
57583275 30 nsfreeall(POOL_AUTHEXT);
31}
32
5a335041 33authname *newauthname(void) {
57583275 34 authname *anp;
35 int i;
36
37 if (freeauthnames==NULL) {
38 freeauthnames=(authname *)nsmalloc(POOL_AUTHEXT, ALLOCUNIT*sizeof(authname));
39 for (i=0;i<(ALLOCUNIT-1);i++) {
40 freeauthnames[i].next=&(freeauthnames[i+1]);
41 }
42 freeauthnames[ALLOCUNIT-1].next=NULL;
43 }
44
45 anp=freeauthnames;
46 freeauthnames=anp->next;
47
48 return anp;
49}
50
51void freeauthname (authname *anp) {
52 anp->next=freeauthnames;
53 freeauthnames=anp;
54}
55
56int registerauthnameext(const char *name) {
57 int i;
58
59 if (findauthnameext(name)!=-1) {
60 Error("nick",ERR_WARNING,"Tried to register duplicate authname extension %s",name);
61 return -1;
62 }
63
64 for (i=0;i<MAXAUTHNAMEEXTS;i++) {
65 if (authnameextnames[i]==NULL) {
66 authnameextnames[i]=getsstring(name,100);
67 return i;
68 }
69 }
70
71 Error("nick",ERR_WARNING,"Tried to register too many authname extensions: %s",name);
72 return -1;
73}
74
75int findauthnameext(const char *name) {
76 int i;
77
78 for (i=0;i<MAXAUTHNAMEEXTS;i++) {
79 if (authnameextnames[i]!=NULL && !ircd_strcmp(name,authnameextnames[i]->content)) {
80 return i;
81 }
82 }
83
84 return -1;
85}
86
87void releaseauthnameext(int index) {
88 int i;
89 authname *anp;
90
91 freesstring(authnameextnames[index]);
92 authnameextnames[index]=NULL;
93
94 for (i=0;i<AUTHNAMEHASHSIZE;i++) {
95 for (anp=authnametable[i];anp;anp=anp->next) {
96 anp->exts[index]=NULL;
97 }
98 }
5a335041
CP
99
100 /* the contents of authnametablebyname should be identical */
57583275 101}
102
103authname *findauthname(unsigned long userid) {
104 authname *anp;
105
106 if(!userid)
107 return NULL;
108
109 for (anp=authnametable[authnamehash(userid)];anp;anp=(authname *)anp->next)
110 if (userid==anp->userid)
111 return anp;
112
113 return NULL;
114}
115
5a335041 116authname *findauthnamebyname(const char *name) {
57583275 117 authname *anp;
57583275 118
5a335041
CP
119 if(!name)
120 return NULL;
121
122 for (anp=authnametable[authnamehashbyname(name)];anp;anp=(authname *)anp->nextbyname)
123 if (!ircd_strcmp(anp->nicks->authname, name))
124 return anp;
125
126 return NULL;
127}
128
129authname *findorcreateauthname(unsigned long userid, const char *name) {
130 authname *anp;
131 unsigned int thehash=authnamehash(userid), secondhash = authnamehashbyname(name);
132
133 if(!userid || !name)
57583275 134 return NULL;
135
136 for (anp=authnametable[thehash];anp;anp=(authname *)anp->next)
137 if (userid==anp->userid)
138 return anp;
139
140 anp=newauthname();
141 anp->userid=userid;
142 anp->usercount=0;
143 anp->marker=0;
144 anp->nicks=NULL;
145 memset(anp->exts, 0, MAXAUTHNAMEEXTS * sizeof(void *));
146 anp->next=(struct authname *)authnametable[thehash];
147 authnametable[thehash]=anp;
148
5a335041
CP
149 anp->namebucket=secondhash;
150 anp->nextbyname=(struct authname *)authnametablebyname[secondhash];
151 authnametablebyname[secondhash]=anp;
152
57583275 153 return anp;
154}
155
156void releaseauthname(authname *anp) {
157 authname **manp;
5a335041 158 int i, found;
57583275 159 if (anp->usercount==0) {
160 for(i=0;i<MAXAUTHNAMEEXTS;i++)
161 if(anp->exts[i]!=NULL)
162 return;
163
5a335041 164 found = 0;
57583275 165 for(manp=&(authnametable[authnamehash(anp->userid)]);*manp;manp=(authname **)&((*manp)->next)) {
5a335041
CP
166 if ((*manp)==anp) {
167 (*manp)=(authname *)anp->next;
168 found = 1;
169 break;
170 }
171 }
172 if(!found) {
173 Error("nick",ERR_ERROR,"Unable to remove authname %lu from hashtable",anp->userid);
174 return;
175 }
176
177 for(manp=&(authnametable[anp->namebucket]);*manp;manp=(authname **)&((*manp)->next)) {
57583275 178 if ((*manp)==anp) {
179 (*manp)=(authname *)anp->next;
180 freeauthname(anp);
181 return;
182 }
183 }
5a335041
CP
184
185 Error("nick",ERR_FATAL,"Unable to remove authname %lu from byname hashtable, TABLES ARE INCONSISTENT -- DYING",anp->userid);
57583275 186 }
187}
188
5a335041 189unsigned int nextauthnamemarker(void) {
57583275 190 int i;
191 authname *anp;
192 static unsigned int authnamemarker=0;
193
194 authnamemarker++;
195 if (!authnamemarker) {
196 /* If we wrapped to zero, zap the marker on all records */
197 for (i=0;i<AUTHNAMEHASHSIZE;i++)
198 for (anp=authnametable[i];anp;anp=anp->next)
199 anp->marker=0;
200 authnamemarker++;
201 }
202
203 return authnamemarker;
204}