]>
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"
16 #define authnamehash(x) ((x)%AUTHNAMEHASHSIZE)
17 #define authnamehashbyname(x) (crc32i(x)%AUTHNAMEHASHSIZE)
19 authname
*authnametable
[AUTHNAMEHASHSIZE
];
21 /* internal access only */
22 static authname
*authnametablebyname
[AUTHNAMEHASHSIZE
];
27 } authnameexts
[MAXAUTHNAMEEXTS
];
29 static void authextstats(int hooknum
, void *arg
);
32 memset(authnametable
,0,sizeof(authnametable
));
33 memset(authnametablebyname
,0,sizeof(authnametablebyname
));
34 registerhook(HOOK_CORE_STATSREQUEST
, &authextstats
);
38 deregisterhook(HOOK_CORE_STATSREQUEST
, &authextstats
);
39 nsfreeall(POOL_AUTHEXT
);
42 authname
*newauthname(void) {
43 return nsmalloc(POOL_AUTHEXT
, sizeof(authname
));
46 void freeauthname (authname
*anp
) {
47 nsfree(POOL_AUTHEXT
, anp
);
50 int registerauthnameext(const char *name
, int persistent
) {
53 if (findauthnameext(name
)!=-1) {
54 Error("nick",ERR_WARNING
,"Tried to register duplicate authname extension %s",name
);
58 for (i
=0;i
<MAXAUTHNAMEEXTS
;i
++) {
59 if (authnameexts
[i
].name
==NULL
) {
60 authnameexts
[i
].name
=getsstring(name
,100);
61 authnameexts
[i
].persistent
=persistent
;
66 Error("nick",ERR_WARNING
,"Tried to register too many authname extensions: %s",name
);
70 int findauthnameext(const char *name
) {
73 for (i
=0;i
<MAXAUTHNAMEEXTS
;i
++) {
74 if (authnameexts
[i
].name
!=NULL
&& !ircd_strcmp(name
,authnameexts
[i
].name
->content
)) {
82 void releaseauthnameext(int index
) {
86 freesstring(authnameexts
[index
].name
);
87 authnameexts
[index
].name
=NULL
;
89 for (i
=0;i
<AUTHNAMEHASHSIZE
;i
++) {
90 for (anp
=authnametable
[i
];anp
;anp
=anp
->next
) {
91 anp
->exts
[index
]=NULL
;
95 /* the contents of authnametablebyname should be identical */
98 authname
*findauthname(unsigned long userid
) {
104 for (anp
=authnametable
[authnamehash(userid
)];anp
;anp
=(authname
*)anp
->next
)
105 if (userid
==anp
->userid
)
111 authname
*findauthnamebyname(const char *name
) {
117 for (anp
=authnametablebyname
[authnamehashbyname(name
)];anp
;anp
=(authname
*)anp
->nextbyname
)
118 if (!ircd_strcmp(anp
->name
, name
))
124 authname
*findorcreateauthname(unsigned long userid
, const char *name
) {
126 unsigned int thehash
=authnamehash(userid
), secondhash
= authnamehashbyname(name
);
131 for (anp
=authnametable
[thehash
];anp
;anp
=(authname
*)anp
->next
)
132 if (userid
==anp
->userid
)
137 strlcpy(anp
->name
, name
, sizeof(anp
->name
));
142 memset(anp
->exts
, 0, MAXAUTHNAMEEXTS
* sizeof(void *));
143 anp
->next
=(struct authname
*)authnametable
[thehash
];
144 authnametable
[thehash
]=anp
;
146 anp
->namebucket
=secondhash
;
147 anp
->nextbyname
=(struct authname
*)authnametablebyname
[secondhash
];
148 authnametablebyname
[secondhash
]=anp
;
153 void releaseauthname(authname
*anp
) {
156 if (anp
->usercount
==0) {
159 for(i
=0;i
<MAXAUTHNAMEEXTS
;i
++)
160 if(authnameexts
[i
].persistent
&& anp
->exts
[i
]!=NULL
)
163 triggerhook(HOOK_AUTH_LOSTAUTHNAME
, (void *)anp
);
165 for(manp
=&(authnametable
[authnamehash(anp
->userid
)]);*manp
;manp
=(authname
**)&((*manp
)->next
)) {
167 (*manp
)=(authname
*)anp
->next
;
173 Error("nick",ERR_ERROR
,"Unable to remove authname %lu from hashtable",anp
->userid
);
177 for(manp
=&(authnametablebyname
[anp
->namebucket
]);*manp
;manp
=(authname
**)&((*manp
)->nextbyname
)) {
179 (*manp
)=(authname
*)anp
->nextbyname
;
185 Error("nick",ERR_STOP
,"Unable to remove authname %lu from byname hashtable, TABLES ARE INCONSISTENT -- DYING",anp
->userid
);
189 unsigned int nextauthnamemarker(void) {
192 static unsigned int authnamemarker
=0;
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
)
203 return authnamemarker
;
206 authname
*getauthbyname(const char *name
) {
207 authname
*a
= findauthnamebyname(name
);
214 static char *genstats(authname
**hashtable
, authname
*(nextfn
)(authname
*)) {
215 int i
,curchain
,maxchain
=0,total
=0,buckets
=0;
217 static char buf
[100];
219 for (i
=0;i
<AUTHNAMEHASHSIZE
;i
++) {
220 if (hashtable
[i
]!=NULL
) {
223 for (ap
=hashtable
[i
];ap
;ap
=nextfn(ap
)) {
227 if (curchain
>maxchain
) {
233 snprintf(buf
, sizeof(buf
), "%6d authexts (HASH: %6d/%6d, chain %3d)",total
,buckets
,AUTHNAMEHASHSIZE
,maxchain
);
237 static authname
*nextbynext(authname
*in
) {
241 static authname
*nextbyname(authname
*in
) {
242 return in
->nextbyname
;
245 static void authextstats(int hooknum
, void *arg
) {
246 long level
=(long)arg
;
251 snprintf(buf
,sizeof(buf
),"Authext : by id: %s", genstats(authnametable
, nextbynext
));
252 triggerhook(HOOK_CORE_STATSREPLY
,buf
);
254 snprintf(buf
,sizeof(buf
),"Authext : by name: %s", genstats(authnametablebyname
, nextbyname
));
255 triggerhook(HOOK_CORE_STATSREPLY
,buf
);