]>
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"
10 #include "../lib/ccassert.h"
17 /* checking to see that u_int64_t == unsigned long long for strtoull */
18 CCASSERT(sizeof(unsigned long long) == sizeof(u_int64_t
))
20 #define authnamehash(x) ((x)%AUTHNAMEHASHSIZE)
21 #define authnamehashbyname(x) (irc_crc32i(x)%AUTHNAMEHASHSIZE)
23 authname
*authnametable
[AUTHNAMEHASHSIZE
];
25 /* internal access only */
26 static authname
*authnametablebyname
[AUTHNAMEHASHSIZE
];
31 } authnameexts
[MAXAUTHNAMEEXTS
];
33 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) {
47 return nsmalloc(POOL_AUTHEXT
, sizeof(authname
));
50 void freeauthname (authname
*anp
) {
51 nsfree(POOL_AUTHEXT
, anp
);
54 int registerauthnameext(const char *name
, int persistent
) {
57 if (findauthnameext(name
)!=-1) {
58 Error("nick",ERR_WARNING
,"Tried to register duplicate authname extension %s",name
);
62 for (i
=0;i
<MAXAUTHNAMEEXTS
;i
++) {
63 if (authnameexts
[i
].name
==NULL
) {
64 authnameexts
[i
].name
=getsstring(name
,100);
65 authnameexts
[i
].persistent
=persistent
;
70 Error("nick",ERR_WARNING
,"Tried to register too many authname extensions: %s",name
);
74 int findauthnameext(const char *name
) {
77 for (i
=0;i
<MAXAUTHNAMEEXTS
;i
++) {
78 if (authnameexts
[i
].name
!=NULL
&& !ircd_strcmp(name
,authnameexts
[i
].name
->content
)) {
86 void releaseauthnameext(int index
) {
90 freesstring(authnameexts
[index
].name
);
91 authnameexts
[index
].name
=NULL
;
93 for (i
=0;i
<AUTHNAMEHASHSIZE
;i
++) {
94 for (anp
=authnametable
[i
];anp
;anp
=anp
->next
) {
95 anp
->exts
[index
]=NULL
;
99 /* the contents of authnametablebyname should be identical */
102 authname
*findauthname(unsigned long userid
) {
108 for (anp
=authnametable
[authnamehash(userid
)];anp
;anp
=(authname
*)anp
->next
)
109 if (userid
==anp
->userid
)
115 authname
*findauthnamebyname(const char *name
) {
121 for (anp
=authnametablebyname
[authnamehashbyname(name
)];anp
;anp
=(authname
*)anp
->nextbyname
)
122 if (!ircd_strcmp(anp
->name
, name
))
128 authname
*findorcreateauthname(unsigned long userid
, const char *name
) {
130 unsigned int thehash
=authnamehash(userid
), secondhash
= authnamehashbyname(name
);
135 for (anp
=authnametable
[thehash
];anp
;anp
=(authname
*)anp
->next
)
136 if (userid
==anp
->userid
)
141 strlcpy(anp
->name
, name
, sizeof(anp
->name
));
146 memset(anp
->exts
, 0, MAXAUTHNAMEEXTS
* sizeof(void *));
147 anp
->next
=(struct authname
*)authnametable
[thehash
];
148 authnametable
[thehash
]=anp
;
150 anp
->namebucket
=secondhash
;
151 anp
->nextbyname
=(struct authname
*)authnametablebyname
[secondhash
];
152 authnametablebyname
[secondhash
]=anp
;
157 void releaseauthname(authname
*anp
) {
160 if (anp
->usercount
==0) {
163 for(i
=0;i
<MAXAUTHNAMEEXTS
;i
++)
164 if(authnameexts
[i
].persistent
&& anp
->exts
[i
]!=NULL
)
167 triggerhook(HOOK_AUTH_LOSTAUTHNAME
, (void *)anp
);
169 for(manp
=&(authnametable
[authnamehash(anp
->userid
)]);*manp
;manp
=(authname
**)&((*manp
)->next
)) {
171 (*manp
)=(authname
*)anp
->next
;
177 Error("nick",ERR_ERROR
,"Unable to remove authname %lu from hashtable",anp
->userid
);
181 for(manp
=&(authnametablebyname
[anp
->namebucket
]);*manp
;manp
=(authname
**)&((*manp
)->nextbyname
)) {
183 (*manp
)=(authname
*)anp
->nextbyname
;
189 Error("nick",ERR_STOP
,"Unable to remove authname %lu from byname hashtable, TABLES ARE INCONSISTENT -- DYING",anp
->userid
);
193 unsigned int nextauthnamemarker(void) {
196 static unsigned int authnamemarker
=0;
199 if (!authnamemarker
) {
200 /* If we wrapped to zero, zap the marker on all records */
201 for (i
=0;i
<AUTHNAMEHASHSIZE
;i
++)
202 for (anp
=authnametable
[i
];anp
;anp
=anp
->next
)
207 return authnamemarker
;
210 authname
*getauthbyname(const char *name
) {
211 authname
*a
= findauthnamebyname(name
);
218 static char *genstats(authname
**hashtable
, authname
*(nextfn
)(authname
*)) {
219 int i
,curchain
,maxchain
=0,total
=0,buckets
=0;
221 static char buf
[100];
223 for (i
=0;i
<AUTHNAMEHASHSIZE
;i
++) {
224 if (hashtable
[i
]!=NULL
) {
227 for (ap
=hashtable
[i
];ap
;ap
=nextfn(ap
)) {
231 if (curchain
>maxchain
) {
237 snprintf(buf
, sizeof(buf
), "%6d authexts (HASH: %6d/%6d, chain %3d)",total
,buckets
,AUTHNAMEHASHSIZE
,maxchain
);
241 static authname
*nextbynext(authname
*in
) {
245 static authname
*nextbyname(authname
*in
) {
246 return in
->nextbyname
;
249 static void authextstats(int hooknum
, void *arg
) {
250 long level
=(long)arg
;
255 snprintf(buf
,sizeof(buf
),"Authext : by id: %s", genstats(authnametable
, nextbynext
));
256 triggerhook(HOOK_CORE_STATSREPLY
,buf
);
258 snprintf(buf
,sizeof(buf
),"Authext : by name: %s", genstats(authnametablebyname
, nextbyname
));
259 triggerhook(HOOK_CORE_STATSREPLY
,buf
);