]>
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"
14 #define authnamehash(x) ((x)%AUTHNAMEHASHSIZE)
15 #define authnamehashbyname(x) (crc32i(x)%AUTHNAMEHASHSIZE)
17 authname
*freeauthnames
;
18 authname
*authnametable
[AUTHNAMEHASHSIZE
];
20 /* internal access only */
21 static authname
*authnametablebyname
[AUTHNAMEHASHSIZE
];
23 sstring
*authnameextnames
[MAXAUTHNAMEEXTS
];
25 static void authextstats(int hooknum
, void *arg
);
29 memset(authnametable
,0,sizeof(authnametable
));
30 memset(authnametablebyname
,0,sizeof(authnametablebyname
));
31 registerhook(HOOK_CORE_STATSREQUEST
, &authextstats
);
35 deregisterhook(HOOK_CORE_STATSREQUEST
, &authextstats
);
36 nsfreeall(POOL_AUTHEXT
);
39 authname
*newauthname(void) {
43 if (freeauthnames
==NULL
) {
44 freeauthnames
=(authname
*)nsmalloc(POOL_AUTHEXT
, ALLOCUNIT
*sizeof(authname
));
45 for (i
=0;i
<(ALLOCUNIT
-1);i
++) {
46 freeauthnames
[i
].next
=&(freeauthnames
[i
+1]);
48 freeauthnames
[ALLOCUNIT
-1].next
=NULL
;
52 freeauthnames
=anp
->next
;
57 void freeauthname (authname
*anp
) {
58 anp
->next
=freeauthnames
;
62 int registerauthnameext(const char *name
) {
65 if (findauthnameext(name
)!=-1) {
66 Error("nick",ERR_WARNING
,"Tried to register duplicate authname extension %s",name
);
70 for (i
=0;i
<MAXAUTHNAMEEXTS
;i
++) {
71 if (authnameextnames
[i
]==NULL
) {
72 authnameextnames
[i
]=getsstring(name
,100);
77 Error("nick",ERR_WARNING
,"Tried to register too many authname extensions: %s",name
);
81 int findauthnameext(const char *name
) {
84 for (i
=0;i
<MAXAUTHNAMEEXTS
;i
++) {
85 if (authnameextnames
[i
]!=NULL
&& !ircd_strcmp(name
,authnameextnames
[i
]->content
)) {
93 void releaseauthnameext(int index
) {
97 freesstring(authnameextnames
[index
]);
98 authnameextnames
[index
]=NULL
;
100 for (i
=0;i
<AUTHNAMEHASHSIZE
;i
++) {
101 for (anp
=authnametable
[i
];anp
;anp
=anp
->next
) {
102 anp
->exts
[index
]=NULL
;
106 /* the contents of authnametablebyname should be identical */
109 authname
*findauthname(unsigned long userid
) {
115 for (anp
=authnametable
[authnamehash(userid
)];anp
;anp
=(authname
*)anp
->next
)
116 if (userid
==anp
->userid
)
122 authname
*findauthnamebyname(const char *name
) {
128 for (anp
=authnametablebyname
[authnamehashbyname(name
)];anp
;anp
=(authname
*)anp
->nextbyname
)
129 if (!ircd_strcmp(anp
->nicks
->authname
, name
))
135 authname
*findorcreateauthname(unsigned long userid
, const char *name
) {
137 unsigned int thehash
=authnamehash(userid
), secondhash
= authnamehashbyname(name
);
142 for (anp
=authnametable
[thehash
];anp
;anp
=(authname
*)anp
->next
)
143 if (userid
==anp
->userid
)
152 memset(anp
->exts
, 0, MAXAUTHNAMEEXTS
* sizeof(void *));
153 anp
->next
=(struct authname
*)authnametable
[thehash
];
154 authnametable
[thehash
]=anp
;
156 anp
->namebucket
=secondhash
;
157 anp
->nextbyname
=(struct authname
*)authnametablebyname
[secondhash
];
158 authnametablebyname
[secondhash
]=anp
;
163 void releaseauthname(authname
*anp
) {
166 if (anp
->usercount
==0) {
169 for(i
=0;i
<MAXAUTHNAMEEXTS
;i
++)
170 if(anp
->exts
[i
]!=NULL
)
174 for(manp
=&(authnametable
[authnamehash(anp
->userid
)]);*manp
;manp
=(authname
**)&((*manp
)->next
)) {
176 (*manp
)=(authname
*)anp
->next
;
182 Error("nick",ERR_ERROR
,"Unable to remove authname %lu from hashtable",anp
->userid
);
186 for(manp
=&(authnametablebyname
[anp
->namebucket
]);*manp
;manp
=(authname
**)&((*manp
)->nextbyname
)) {
188 (*manp
)=(authname
*)anp
->nextbyname
;
194 Error("nick",ERR_STOP
,"Unable to remove authname %lu from byname hashtable, TABLES ARE INCONSISTENT -- DYING",anp
->userid
);
198 unsigned int nextauthnamemarker(void) {
201 static unsigned int authnamemarker
=0;
204 if (!authnamemarker
) {
205 /* If we wrapped to zero, zap the marker on all records */
206 for (i
=0;i
<AUTHNAMEHASHSIZE
;i
++)
207 for (anp
=authnametable
[i
];anp
;anp
=anp
->next
)
212 return authnamemarker
;
215 authname
*getauthbyname(const char *name
) {
216 authname
*a
= findauthnamebyname(name
);
223 static char *genstats(authname
**hashtable
, authname
*(nextfn
)(authname
*)) {
224 int i
,curchain
,maxchain
=0,total
=0,buckets
=0;
226 static char buf
[100];
228 for (i
=0;i
<AUTHNAMEHASHSIZE
;i
++) {
229 if (hashtable
[i
]!=NULL
) {
232 for (ap
=hashtable
[i
];ap
;ap
=nextfn(ap
)) {
236 if (curchain
>maxchain
) {
242 snprintf(buf
, sizeof(buf
), "%6d authexts (HASH: %6d/%6d, chain %3d)",total
,buckets
,AUTHNAMEHASHSIZE
,maxchain
);
246 static authname
*nextbynext(authname
*in
) {
250 static authname
*nextbyname(authname
*in
) {
251 return in
->nextbyname
;
254 static void authextstats(int hooknum
, void *arg
) {
255 long level
=(long)arg
;
260 snprintf(buf
,sizeof(buf
),"Authext : by id: %s", genstats(authnametable
, nextbynext
));
261 triggerhook(HOOK_CORE_STATSREPLY
,buf
);
263 snprintf(buf
,sizeof(buf
),"Authext : by name: %s", genstats(authnametablebyname
, nextbyname
));
264 triggerhook(HOOK_CORE_STATSREPLY
,buf
);