]> jfr.im git - irc/quakenet/newserv.git/blobdiff - nick/nick.c
Make valgrind a bit happier.
[irc/quakenet/newserv.git] / nick / nick.c
index 8fe636f8c3ed7391a3a3f242316c6af3e2a5b20b..12efd036e37f76bd2280688bc6ab34d011a4f754 100644 (file)
 #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 },
@@ -40,6 +42,8 @@ nick *nicktable[NICKHASHSIZE];
 nick **servernicks[MAXSERVERS];
 
 sstring *nickextnames[MAXNICKEXTS];
+sstring *nodeextnames[PATRICIA_MAXSLOTS];
+patricia_tree_t *iptree;
 
 void nickstats(int hooknum, void *arg);
 
@@ -60,11 +64,31 @@ void _init() {
   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);  
 }
 
 /*
@@ -74,14 +98,14 @@ void _init() {
  */
 
 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;
       
@@ -127,9 +151,27 @@ void deletenick(nick *np) {
   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;
   
@@ -187,14 +229,14 @@ void nickstats(int hooknum, void *arg) {
     }
   }
     
-  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);
   }
 }
@@ -214,7 +256,7 @@ int registernickext(const char *name) {
     }
   }
   
-  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;
 }
 
@@ -326,3 +368,48 @@ nick *getnickbynumericstr(char *numericstr) {
 }
 
 #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;
+}