#include "../server/server.h"
#include "../parser/parser.h"
#include "../lib/version.h"
+#include "../core/nsmalloc.h"
+
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
-MODULE_VERSION("$Id")
+MODULE_VERSION("");
const flag umodeflags[] = {
{ 'i', UMODE_INV },
nick **servernicks[MAXSERVERS];
sstring *nickextnames[MAXNICKEXTS];
+sstring *nodeextnames[PATRICIA_MAXSLOTS];
+patricia_tree_t *iptree;
void nickstats(int hooknum, void *arg);
registerserverhandler("Q",&handlequitmsg,1);
registerserverhandler("M",&handleusermodemsg,3);
registerserverhandler("W",&handlewhoismsg,2);
- registerserverhandler("AC",&handleaccountmsg,2);
+ registerserverhandler("AC",&handleaccountmsg,4);
registerserverhandler("R",&handlestatsmsg,2);
/* Fake the addition of our own server */
handleserverchange(HOOK_SERVER_NEWSERVER,(void *)numerictolong(mynumeric->content,2));
+
+ iptree = patricia_new_tree(PATRICIA_MAXBITS);
+}
+
+void _fini() {
+ nsfreeall(POOL_NICK);
+
+ /* Free the hooks */
+ deregisterhook(HOOK_SERVER_NEWSERVER,&handleserverchange);
+ deregisterhook(HOOK_SERVER_LOSTSERVER,&handleserverchange);
+ deregisterhook(HOOK_CORE_STATSREQUEST,&nickstats);
+
+ /* And our server handlers */
+ deregisterserverhandler("N",&handlenickmsg);
+ deregisterserverhandler("D",&handlekillmsg);
+ deregisterserverhandler("Q",&handlequitmsg);
+ deregisterserverhandler("M",&handleusermodemsg);
+ deregisterserverhandler("W",&handlewhoismsg);
+ deregisterserverhandler("AC",&handleaccountmsg);
+ deregisterserverhandler("R",&handlestatsmsg);
}
/*
*/
void handleserverchange(int hooknum, void *arg) {
- int servernum;
+ long servernum;
int i;
- servernum=(int)arg;
+ servernum=(long)arg;
switch(hooknum) {
case HOOK_SERVER_NEWSERVER:
- servernicks[servernum]=(nick **)malloc((serverlist[servernum].maxusernum+1)*sizeof(nick **));
+ servernicks[servernum]=(nick **)nsmalloc(POOL_NICK,(serverlist[servernum].maxusernum+1)*sizeof(nick **));
memset(servernicks[servernum],0,(serverlist[servernum].maxusernum+1)*sizeof(nick **));
break;
releaserealname(np->realname);
releasehost(np->host);
+ if(IsAccount(np) && np->auth)
+ {
+ np->auth->usercount--;
+
+ for (nh=&(np->auth->nicks);*nh;nh=&((*nh)->nextbyauthname)) {
+ if (*nh==np) {
+ *nh=np->nextbyauthname;
+ break;
+ }
+ }
+
+ releaseauthname(np->auth);
+ }
+
freesstring(np->shident); /* freesstring(NULL) is OK */
freesstring(np->sethost);
+ derefnode(iptree, np->ipnode);
+
+ /* TODO: figure out how to cleanly remove nodes without affecting other modules */
+
/* Delete the nick from the servernick table */
*(gethandlebynumericunsafe(np->numeric))=NULL;
}
}
- if ((int)arg>5) {
+ if ((long)arg>5) {
/* Full stats */
sprintf(buf,"Nick : %6d nicks (HASH: %6d/%6d, chain %3d)",total,buckets,NICKHASHSIZE,maxchain);
- } else if ((int)arg>2) {
+ } else if ((long)arg>2) {
sprintf(buf,"Nick : %6d users on network.",total);
}
- if ((int)arg>2) {
+ if ((long)arg>2) {
triggerhook(HOOK_CORE_STATSREPLY,buf);
}
}
}
}
- Error("channel",ERR_WARNING,"Tried to register too many extensions: %s",name);
+ Error("nick",ERR_WARNING,"Tried to register too many nick extensions: %s",name);
return -1;
}
}
#endif
+
+int registernodeext(const char *name) {
+ int i;
+
+ if (findnodeext(name)!=-1) {
+ Error("nick",ERR_WARNING,"Tried to register duplicate node extension %s",name);
+ return -1;
+ }
+
+ for (i=0;i<PATRICIA_MAXSLOTS;i++) {
+ if (nodeextnames[i]==NULL) {
+ nodeextnames[i]=getsstring(name,100);
+ return i;
+ }
+ }
+
+ Error("nick",ERR_WARNING,"Tried to register too many extensions: %s",name);
+ return -1;
+}
+
+int findnodeext(const char *name) {
+ int i;
+
+ for (i=0;i<PATRICIA_MAXSLOTS;i++) {
+ if (nodeextnames[i]!=NULL && !ircd_strcmp(name,nodeextnames[i]->content)) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+void releasenodeext(int index) {
+ patricia_node_t *head, *node;
+
+ freesstring(nodeextnames[index]);
+ nodeextnames[index]=NULL;
+
+ head = iptree->head;
+
+ PATRICIA_WALK_ALL(head, node)
+ {
+ node->slots[index]=NULL;
+ } PATRICIA_WALK_END;
+}