]>
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"
15 #define authnamehash(x) ((x)%AUTHNAMEHASHSIZE)
16 #define authnamehashbyname(x) (crc32i(x)%AUTHNAMEHASHSIZE)
18 authname
*freeauthnames
;
19 authname
*authnametable
[AUTHNAMEHASHSIZE
];
21 /* internal access only */
22 static authname
*authnametablebyname
[AUTHNAMEHASHSIZE
];
24 sstring
*authnameextnames
[MAXAUTHNAMEEXTS
];
26 static void authextstats(int hooknum
, void *arg
);
30 memset(authnametable
,0,sizeof(authnametable
));
31 memset(authnametablebyname
,0,sizeof(authnametablebyname
));
32 registerhook(HOOK_CORE_STATSREQUEST
, &authextstats
);
36 deregisterhook(HOOK_CORE_STATSREQUEST
, &authextstats
);
37 nsfreeall(POOL_AUTHEXT
);
40 authname
*newauthname(void) {
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]);
49 freeauthnames
[ALLOCUNIT
-1].next
=NULL
;
53 freeauthnames
=anp
->next
;
58 void freeauthname (authname
*anp
) {
59 anp
->next
=freeauthnames
;
63 int registerauthnameext(const char *name
) {
66 if (findauthnameext(name
)!=-1) {
67 Error("nick",ERR_WARNING
,"Tried to register duplicate authname extension %s",name
);
71 for (i
=0;i
<MAXAUTHNAMEEXTS
;i
++) {
72 if (authnameextnames
[i
]==NULL
) {
73 authnameextnames
[i
]=getsstring(name
,100);
78 Error("nick",ERR_WARNING
,"Tried to register too many authname extensions: %s",name
);
82 int findauthnameext(const char *name
) {
85 for (i
=0;i
<MAXAUTHNAMEEXTS
;i
++) {
86 if (authnameextnames
[i
]!=NULL
&& !ircd_strcmp(name
,authnameextnames
[i
]->content
)) {
94 void releaseauthnameext(int index
) {
98 freesstring(authnameextnames
[index
]);
99 authnameextnames
[index
]=NULL
;
101 for (i
=0;i
<AUTHNAMEHASHSIZE
;i
++) {
102 for (anp
=authnametable
[i
];anp
;anp
=anp
->next
) {
103 anp
->exts
[index
]=NULL
;
107 /* the contents of authnametablebyname should be identical */
110 authname
*findauthname(unsigned long userid
) {
116 for (anp
=authnametable
[authnamehash(userid
)];anp
;anp
=(authname
*)anp
->next
)
117 if (userid
==anp
->userid
)
123 authname
*findauthnamebyname(const char *name
) {
129 for (anp
=authnametablebyname
[authnamehashbyname(name
)];anp
;anp
=(authname
*)anp
->nextbyname
)
130 if (!ircd_strcmp(anp
->name
, name
))
136 authname
*findorcreateauthname(unsigned long userid
, const char *name
) {
138 unsigned int thehash
=authnamehash(userid
), secondhash
= authnamehashbyname(name
);
143 for (anp
=authnametable
[thehash
];anp
;anp
=(authname
*)anp
->next
)
144 if (userid
==anp
->userid
)
149 strlcpy(anp
->name
, name
, sizeof(anp
->name
));
154 memset(anp
->exts
, 0, MAXAUTHNAMEEXTS
* sizeof(void *));
155 anp
->next
=(struct authname
*)authnametable
[thehash
];
156 authnametable
[thehash
]=anp
;
158 anp
->namebucket
=secondhash
;
159 anp
->nextbyname
=(struct authname
*)authnametablebyname
[secondhash
];
160 authnametablebyname
[secondhash
]=anp
;
165 void releaseauthname(authname
*anp
) {
168 if (anp
->usercount
==0) {
171 for(i
=0;i
<MAXAUTHNAMEEXTS
;i
++)
172 if(anp
->exts
[i
]!=NULL
)
176 for(manp
=&(authnametable
[authnamehash(anp
->userid
)]);*manp
;manp
=(authname
**)&((*manp
)->next
)) {
178 (*manp
)=(authname
*)anp
->next
;
184 Error("nick",ERR_ERROR
,"Unable to remove authname %lu from hashtable",anp
->userid
);
188 for(manp
=&(authnametablebyname
[anp
->namebucket
]);*manp
;manp
=(authname
**)&((*manp
)->nextbyname
)) {
190 (*manp
)=(authname
*)anp
->nextbyname
;
196 Error("nick",ERR_STOP
,"Unable to remove authname %lu from byname hashtable, TABLES ARE INCONSISTENT -- DYING",anp
->userid
);
200 unsigned int nextauthnamemarker(void) {
203 static unsigned int authnamemarker
=0;
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
)
214 return authnamemarker
;
217 authname
*getauthbyname(const char *name
) {
218 authname
*a
= findauthnamebyname(name
);
225 static char *genstats(authname
**hashtable
, authname
*(nextfn
)(authname
*)) {
226 int i
,curchain
,maxchain
=0,total
=0,buckets
=0;
228 static char buf
[100];
230 for (i
=0;i
<AUTHNAMEHASHSIZE
;i
++) {
231 if (hashtable
[i
]!=NULL
) {
234 for (ap
=hashtable
[i
];ap
;ap
=nextfn(ap
)) {
238 if (curchain
>maxchain
) {
244 snprintf(buf
, sizeof(buf
), "%6d authexts (HASH: %6d/%6d, chain %3d)",total
,buckets
,AUTHNAMEHASHSIZE
,maxchain
);
248 static authname
*nextbynext(authname
*in
) {
252 static authname
*nextbyname(authname
*in
) {
253 return in
->nextbyname
;
256 static void authextstats(int hooknum
, void *arg
) {
257 long level
=(long)arg
;
262 snprintf(buf
,sizeof(buf
),"Authext : by id: %s", genstats(authnametable
, nextbynext
));
263 triggerhook(HOOK_CORE_STATSREPLY
,buf
);
265 snprintf(buf
,sizeof(buf
),"Authext : by name: %s", genstats(authnametablebyname
, nextbyname
));
266 triggerhook(HOOK_CORE_STATSREPLY
,buf
);