]>
jfr.im git - irc/quakenet/newserv.git/blob - authext/authext.c
2 #include "../core/nsmalloc.h"
3 #include "../core/error.h"
4 #include "../lib/sstring.h"
5 #include "../lib/irc_string.h"
6 #include "../nick/nick.h"
7 #include "../core/hooks.h"
8 #include "../lib/strlfunc.h"
9 #include "../lib/version.h"
18 #define authnamehash(x) ((x)%AUTHNAMEHASHSIZE)
19 #define authnamehashbyname(x) (crc32i(x)%AUTHNAMEHASHSIZE)
21 authname
*freeauthnames
;
22 authname
*authnametable
[AUTHNAMEHASHSIZE
];
24 /* internal access only */
25 static authname
*authnametablebyname
[AUTHNAMEHASHSIZE
];
30 } authnameexts
[MAXAUTHNAMEEXTS
];
32 static void authextstats(int hooknum
, void *arg
);
36 memset(authnametable
,0,sizeof(authnametable
));
37 memset(authnametablebyname
,0,sizeof(authnametablebyname
));
38 registerhook(HOOK_CORE_STATSREQUEST
, &authextstats
);
42 deregisterhook(HOOK_CORE_STATSREQUEST
, &authextstats
);
43 nsfreeall(POOL_AUTHEXT
);
46 authname
*newauthname(void) {
50 if (freeauthnames
==NULL
) {
51 freeauthnames
=(authname
*)nsmalloc(POOL_AUTHEXT
, ALLOCUNIT
*sizeof(authname
));
52 for (i
=0;i
<(ALLOCUNIT
-1);i
++) {
53 freeauthnames
[i
].next
=&(freeauthnames
[i
+1]);
55 freeauthnames
[ALLOCUNIT
-1].next
=NULL
;
59 freeauthnames
=anp
->next
;
64 void freeauthname (authname
*anp
) {
65 anp
->next
=freeauthnames
;
69 int registerauthnameext(const char *name
, int persistant
) {
72 if (findauthnameext(name
)!=-1) {
73 Error("nick",ERR_WARNING
,"Tried to register duplicate authname extension %s",name
);
77 for (i
=0;i
<MAXAUTHNAMEEXTS
;i
++) {
78 if (authnameexts
[i
].name
==NULL
) {
79 authnameexts
[i
].name
=getsstring(name
,100);
80 authnameexts
[i
].persistant
=persistant
;
85 Error("nick",ERR_WARNING
,"Tried to register too many authname extensions: %s",name
);
89 int findauthnameext(const char *name
) {
92 for (i
=0;i
<MAXAUTHNAMEEXTS
;i
++) {
93 if (authnameexts
[i
].name
!=NULL
&& !ircd_strcmp(name
,authnameexts
[i
].name
->content
)) {
101 void releaseauthnameext(int index
) {
105 freesstring(authnameexts
[index
].name
);
106 authnameexts
[index
].name
=NULL
;
108 for (i
=0;i
<AUTHNAMEHASHSIZE
;i
++) {
109 for (anp
=authnametable
[i
];anp
;anp
=anp
->next
) {
110 anp
->exts
[index
]=NULL
;
114 /* the contents of authnametablebyname should be identical */
117 authname
*findauthname(unsigned long userid
) {
123 for (anp
=authnametable
[authnamehash(userid
)];anp
;anp
=(authname
*)anp
->next
)
124 if (userid
==anp
->userid
)
130 authname
*findauthnamebyname(const char *name
) {
136 for (anp
=authnametablebyname
[authnamehashbyname(name
)];anp
;anp
=(authname
*)anp
->nextbyname
)
137 if (!ircd_strcmp(anp
->name
, name
))
143 authname
*findorcreateauthname(unsigned long userid
, const char *name
) {
145 unsigned int thehash
=authnamehash(userid
), secondhash
= authnamehashbyname(name
);
150 for (anp
=authnametable
[thehash
];anp
;anp
=(authname
*)anp
->next
)
151 if (userid
==anp
->userid
)
156 strlcpy(anp
->name
, name
, sizeof(anp
->name
));
161 memset(anp
->exts
, 0, MAXAUTHNAMEEXTS
* sizeof(void *));
162 anp
->next
=(struct authname
*)authnametable
[thehash
];
163 authnametable
[thehash
]=anp
;
165 anp
->namebucket
=secondhash
;
166 anp
->nextbyname
=(struct authname
*)authnametablebyname
[secondhash
];
167 authnametablebyname
[secondhash
]=anp
;
172 void releaseauthname(authname
*anp
) {
175 if (anp
->usercount
==0) {
178 for(i
=0;i
<MAXAUTHNAMEEXTS
;i
++)
179 if(authnameexts
[i
].persistant
&& anp
->exts
[i
]!=NULL
)
182 triggerhook(HOOK_AUTH_LOSTAUTHNAME
, (void *)anp
);
184 for(manp
=&(authnametable
[authnamehash(anp
->userid
)]);*manp
;manp
=(authname
**)&((*manp
)->next
)) {
186 (*manp
)=(authname
*)anp
->next
;
192 Error("nick",ERR_ERROR
,"Unable to remove authname %lu from hashtable",anp
->userid
);
196 for(manp
=&(authnametablebyname
[anp
->namebucket
]);*manp
;manp
=(authname
**)&((*manp
)->nextbyname
)) {
198 (*manp
)=(authname
*)anp
->nextbyname
;
204 Error("nick",ERR_STOP
,"Unable to remove authname %lu from byname hashtable, TABLES ARE INCONSISTENT -- DYING",anp
->userid
);
208 unsigned int nextauthnamemarker(void) {
211 static unsigned int authnamemarker
=0;
214 if (!authnamemarker
) {
215 /* If we wrapped to zero, zap the marker on all records */
216 for (i
=0;i
<AUTHNAMEHASHSIZE
;i
++)
217 for (anp
=authnametable
[i
];anp
;anp
=anp
->next
)
222 return authnamemarker
;
225 authname
*getauthbyname(const char *name
) {
226 authname
*a
= findauthnamebyname(name
);
233 static char *genstats(authname
**hashtable
, authname
*(nextfn
)(authname
*)) {
234 int i
,curchain
,maxchain
=0,total
=0,buckets
=0;
236 static char buf
[100];
238 for (i
=0;i
<AUTHNAMEHASHSIZE
;i
++) {
239 if (hashtable
[i
]!=NULL
) {
242 for (ap
=hashtable
[i
];ap
;ap
=nextfn(ap
)) {
246 if (curchain
>maxchain
) {
252 snprintf(buf
, sizeof(buf
), "%6d authexts (HASH: %6d/%6d, chain %3d)",total
,buckets
,AUTHNAMEHASHSIZE
,maxchain
);
256 static authname
*nextbynext(authname
*in
) {
260 static authname
*nextbyname(authname
*in
) {
261 return in
->nextbyname
;
264 static void authextstats(int hooknum
, void *arg
) {
265 long level
=(long)arg
;
270 snprintf(buf
,sizeof(buf
),"Authext : by id: %s", genstats(authnametable
, nextbynext
));
271 triggerhook(HOOK_CORE_STATSREPLY
,buf
);
273 snprintf(buf
,sizeof(buf
),"Authext : by name: %s", genstats(authnametablebyname
, nextbyname
));
274 triggerhook(HOOK_CORE_STATSREPLY
,buf
);