#include "../lib/sstring.h"
#include "../lib/irc_string.h"
#include "../nick/nick.h"
+#include "../core/hooks.h"
+#include "../lib/strlfunc.h"
+#include "../lib/version.h"
+#include "../lib/ccassert.h"
#include <string.h>
+#include <stdio.h>
-#define ALLOCUNIT 100
+MODULE_VERSION("")
+
+/* checking to see that u_int64_t == unsigned long long for strtoull */
+CCASSERT(sizeof(unsigned long long) == sizeof(u_int64_t))
#define authnamehash(x) ((x)%AUTHNAMEHASHSIZE)
-#define authnamehashbyname(x) (crc32i(x)%AUTHNAMEHASHSIZE)
+#define authnamehashbyname(x) (irc_crc32i(x)%AUTHNAMEHASHSIZE)
-authname *freeauthnames;
authname *authnametable[AUTHNAMEHASHSIZE];
/* internal access only */
static authname *authnametablebyname[AUTHNAMEHASHSIZE];
-sstring *authnameextnames[MAXAUTHNAMEEXTS];
+static struct {
+ sstring *name;
+ int persistent;
+} authnameexts[MAXAUTHNAMEEXTS];
+
+static void authextstats(int hooknum, void *arg);
void _init(void) {
- freeauthnames=NULL;
memset(authnametable,0,sizeof(authnametable));
memset(authnametablebyname,0,sizeof(authnametablebyname));
+ registerhook(HOOK_CORE_STATSREQUEST, &authextstats);
}
void _fini(void) {
+ deregisterhook(HOOK_CORE_STATSREQUEST, &authextstats);
nsfreeall(POOL_AUTHEXT);
}
authname *newauthname(void) {
- authname *anp;
- int i;
-
- if (freeauthnames==NULL) {
- freeauthnames=(authname *)nsmalloc(POOL_AUTHEXT, ALLOCUNIT*sizeof(authname));
- for (i=0;i<(ALLOCUNIT-1);i++) {
- freeauthnames[i].next=&(freeauthnames[i+1]);
- }
- freeauthnames[ALLOCUNIT-1].next=NULL;
- }
-
- anp=freeauthnames;
- freeauthnames=anp->next;
-
- return anp;
+ return nsmalloc(POOL_AUTHEXT, sizeof(authname));
}
void freeauthname (authname *anp) {
- anp->next=freeauthnames;
- freeauthnames=anp;
+ nsfree(POOL_AUTHEXT, anp);
}
-int registerauthnameext(const char *name) {
+int registerauthnameext(const char *name, int persistent) {
int i;
if (findauthnameext(name)!=-1) {
}
for (i=0;i<MAXAUTHNAMEEXTS;i++) {
- if (authnameextnames[i]==NULL) {
- authnameextnames[i]=getsstring(name,100);
+ if (authnameexts[i].name==NULL) {
+ authnameexts[i].name=getsstring(name,100);
+ authnameexts[i].persistent=persistent;
return i;
}
}
int i;
for (i=0;i<MAXAUTHNAMEEXTS;i++) {
- if (authnameextnames[i]!=NULL && !ircd_strcmp(name,authnameextnames[i]->content)) {
+ if (authnameexts[i].name!=NULL && !ircd_strcmp(name,authnameexts[i].name->content)) {
return i;
}
}
int i;
authname *anp;
- freesstring(authnameextnames[index]);
- authnameextnames[index]=NULL;
+ freesstring(authnameexts[index].name);
+ authnameexts[index].name=NULL;
for (i=0;i<AUTHNAMEHASHSIZE;i++) {
for (anp=authnametable[i];anp;anp=anp->next) {
if(!name)
return NULL;
- for (anp=authnametable[authnamehashbyname(name)];anp;anp=(authname *)anp->nextbyname)
- if (!ircd_strcmp(anp->nicks->authname, name))
+ for (anp=authnametablebyname[authnamehashbyname(name)];anp;anp=(authname *)anp->nextbyname)
+ if (!ircd_strcmp(anp->name, name))
return anp;
return NULL;
anp=newauthname();
anp->userid=userid;
+ strlcpy(anp->name, name, sizeof(anp->name));
anp->usercount=0;
anp->marker=0;
+ anp->flags=0;
anp->nicks=NULL;
memset(anp->exts, 0, MAXAUTHNAMEEXTS * sizeof(void *));
anp->next=(struct authname *)authnametable[thehash];
anp->nicks = NULL;
for(i=0;i<MAXAUTHNAMEEXTS;i++)
- if(anp->exts[i]!=NULL)
+ if(authnameexts[i].persistent && anp->exts[i]!=NULL)
return;
+ triggerhook(HOOK_AUTH_LOSTAUTHNAME, (void *)anp);
found = 0;
for(manp=&(authnametable[authnamehash(anp->userid)]);*manp;manp=(authname **)&((*manp)->next)) {
if ((*manp)==anp) {
return a;
}
+static char *genstats(authname **hashtable, authname *(nextfn)(authname *)) {
+ int i,curchain,maxchain=0,total=0,buckets=0;
+ authname *ap;
+ static char buf[100];
+
+ for (i=0;i<AUTHNAMEHASHSIZE;i++) {
+ if (hashtable[i]!=NULL) {
+ buckets++;
+ curchain=0;
+ for (ap=hashtable[i];ap;ap=nextfn(ap)) {
+ total++;
+ curchain++;
+ }
+ if (curchain>maxchain) {
+ maxchain=curchain;
+ }
+ }
+ }
+
+ snprintf(buf, sizeof(buf), "%6d authexts (HASH: %6d/%6d, chain %3d)",total,buckets,AUTHNAMEHASHSIZE,maxchain);
+ return buf;
+}
+
+static authname *nextbynext(authname *in) {
+ return in->next;
+}
+
+static authname *nextbyname(authname *in) {
+ return in->nextbyname;
+}
+
+static void authextstats(int hooknum, void *arg) {
+ long level=(long)arg;
+ char buf[100];
+
+ if (level>5) {
+ /* Full stats */
+ snprintf(buf,sizeof(buf),"Authext : by id: %s", genstats(authnametable, nextbynext));
+ triggerhook(HOOK_CORE_STATSREPLY,buf);
+
+ snprintf(buf,sizeof(buf),"Authext : by name: %s", genstats(authnametablebyname, nextbyname));
+ triggerhook(HOOK_CORE_STATSREPLY,buf);
+ }
+}
+