#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 <string.h>
+#include <stdio.h>
+
+MODULE_VERSION("")
#define ALLOCUNIT 100
/* internal access only */
static authname *authnametablebyname[AUTHNAMEHASHSIZE];
-sstring *authnameextnames[MAXAUTHNAMEEXTS];
+static struct {
+ sstring *name;
+ int persistant;
+} 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);
}
freeauthnames=anp;
}
-int registerauthnameext(const char *name) {
+int registerauthnameext(const char *name, int persistant) {
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].persistant=persistant;
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];
authname **manp;
int i, found;
if (anp->usercount==0) {
+ anp->nicks = NULL;
+
for(i=0;i<MAXAUTHNAMEEXTS;i++)
- if(anp->exts[i]!=NULL)
+ if(authnameexts[i].persistant && 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;
}
- for(manp=&(authnametable[anp->namebucket]);*manp;manp=(authname **)&((*manp)->next)) {
+ for(manp=&(authnametablebyname[anp->namebucket]);*manp;manp=(authname **)&((*manp)->nextbyname)) {
if ((*manp)==anp) {
- (*manp)=(authname *)anp->next;
+ (*manp)=(authname *)anp->nextbyname;
freeauthname(anp);
return;
}
}
- Error("nick",ERR_FATAL,"Unable to remove authname %lu from byname hashtable, TABLES ARE INCONSISTENT -- DYING",anp->userid);
+ Error("nick",ERR_STOP,"Unable to remove authname %lu from byname hashtable, TABLES ARE INCONSISTENT -- DYING",anp->userid);
}
}
return authnamemarker;
}
+
+authname *getauthbyname(const char *name) {
+ authname *a = findauthnamebyname(name);
+ if(!a || !a->nicks)
+ return NULL;
+
+ 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);
+ }
+}
+