]> jfr.im git - irc/quakenet/newserv.git/blobdiff - nick/nick.c
NICK: Add "away" functionality.
[irc/quakenet/newserv.git] / nick / nick.c
index 2b949d971f4e872adda4db9a73c13b66a440e1e5..3b9dead2bb69ae4e3cae2bd34edc4588792a2ac7 100644 (file)
@@ -12,6 +12,8 @@
 #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>
@@ -32,6 +34,15 @@ const flag umodeflags[] = {
    { 'h', UMODE_SETHOST },
    { 'R', UMODE_REGPRIV },
    { 'I', UMODE_HIDEIDLE },
+   { 'P', UMODE_PARANOID },
+   { '\0', 0 } };
+
+const flag accountflags[] = {
+   { 'q', AFLAG_STAFF },
+   { 'h', AFLAG_SUPPORT },
+   { 'o', AFLAG_OPER },
+   { 'a', AFLAG_ADMIN },
+   { 'd', AFLAG_DEVELOPER },
    { '\0', 0 } };
 
 #define nickhash(x)       ((crc32i(x))%NICKHASHSIZE)
@@ -40,17 +51,31 @@ nick *nicktable[NICKHASHSIZE];
 nick **servernicks[MAXSERVERS];
 
 sstring *nickextnames[MAXNICKEXTS];
-sstring *nodeextnames[PATRICIA_MAXSLOTS];
-patricia_tree_t *iptree;
-sstring *authnameextnames[MAXAUTHNAMEEXTS];
 
 void nickstats(int hooknum, void *arg);
 
+char *NULLAUTHNAME = "";
+
 void _init() {
+  unsigned int i;
+  authname *anp;
+
+  /* Clear up the nicks in authext */
+  for (i=0;i<AUTHNAMEHASHSIZE;i++) 
+    for (anp=authnametable[i];anp;anp=anp->next)
+      anp->nicks=NULL;  
+
   initnickalloc();
   initnickhelpers();
   memset(nicktable,0,sizeof(nicktable));
   memset(servernicks,0,sizeof(servernicks));
+
+  /* If we're connected to IRC, force a disconnect.  This needs to be done
+   * before we register all our hooks which would otherwise get called
+   * during the disconnect. */
+  if (connected) {
+    irc_send("%s SQ %s 0 :Resync [adding nick support]",mynumeric->content,myserver->content); irc_disconnected();
+  }
   
   /* Register our hooks */
   registerhook(HOOK_SERVER_NEWSERVER,&handleserverchange);
@@ -65,11 +90,46 @@ void _init() {
   registerserverhandler("W",&handlewhoismsg,2);
   registerserverhandler("AC",&handleaccountmsg,4);
   registerserverhandler("R",&handlestatsmsg,2);
+  registerserverhandler("P",&handleprivmsg,2);
+  registerserverhandler("A",&handleawaymsg,1);
   
   /* Fake the addition of our own server */
   handleserverchange(HOOK_SERVER_NEWSERVER,(void *)numerictolong(mynumeric->content,2));
+}
 
-  iptree = patricia_new_tree(PATRICIA_MAXBITS);
+void _fini() {
+  nick *np;
+  int i;
+
+  fininickhelpers();
+
+  for (i=0;i<NICKHASHSIZE;i++) {
+    for (np=nicktable[i];np;np=np->next) {
+      freesstring(np->shident);
+      freesstring(np->sethost);
+      freesstring(np->opername);
+      if(!np->auth && np->authname && (np->authname != NULLAUTHNAME))
+        free(np->authname);
+    }
+  }
+
+  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);  
+  deregisterserverhandler("P",&handleprivmsg);
+  deregisterserverhandler("A",&handleawaymsg);
 }
 
 /*
@@ -86,7 +146,7 @@ void handleserverchange(int hooknum, void *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;
       
@@ -96,7 +156,7 @@ void handleserverchange(int hooknum, void *arg) {
           deletenick(servernicks[servernum][i]);        
         }
       }
-      free(servernicks[servernum]);
+      nsfree(POOL_NICK,servernicks[servernum]);
       break;
   }
 }
@@ -132,23 +192,29 @@ void deletenick(nick *np) {
   releaserealname(np->realname);
   releasehost(np->host);
   
-  if(IsAccount(np) && np->auth)
-  {
-    np->auth->usercount--;
+  if(IsAccount(np)) {
+    if(!np->auth) {
+      if(np->authname && (np->authname != NULLAUTHNAME))
+        free(np->authname);
+    } else {
+      np->auth->usercount--;
     
-    for (nh=&(np->auth->nicks);*nh;nh=&((*nh)->nextbyauthname)) {
-      if (*nh==np) {
-        *nh=np->nextbyauthname;
-        break;
+      for (nh=&(np->auth->nicks);*nh;nh=&((*nh)->nextbyauthname)) {
+        if (*nh==np) {
+          *nh=np->nextbyauthname;
+          break;
+        }
       }
-    }
     
-    releaseauthname(np->auth);
+      releaseauthname(np->auth);
+    }
   }
   
   freesstring(np->shident); /* freesstring(NULL) is OK */
   freesstring(np->sethost); 
+  freesstring(np->opername); 
 
+  node_decrement_usercount(np->ipnode);
   derefnode(iptree, np->ipnode);
   
   /* TODO: figure out how to cleanly remove nodes without affecting other modules */
@@ -267,56 +333,24 @@ void releasenickext(int index) {
   }
 }
 
-int registerauthnameext(const char *name) {
-  int i;
-  
-  if (findauthnameext(name)!=-1) {
-    Error("nick",ERR_WARNING,"Tried to register duplicate authname extension %s",name);
-    return -1;
-  }
-  
-  for (i=0;i<MAXAUTHNAMEEXTS;i++) {
-    if (authnameextnames[i]==NULL) {
-      authnameextnames[i]=getsstring(name,100);
-      return i;
-    }
-  }
-  
-  Error("nick",ERR_WARNING,"Tried to register too many authname extensions: %s",name);
-  return -1;
-}
+/* visiblehostmask
+ *  Produces the "apparent" hostmask as seen by network users.
+ */
 
-int findauthnameext(const char *name) {
-  int i;
-  
-  for (i=0;i<MAXAUTHNAMEEXTS;i++) {
-    if (authnameextnames[i]!=NULL && !ircd_strcmp(name,authnameextnames[i]->content)) {
-      return i;
-    }
-  }
+char *visiblehostmask(nick *np, char *buf) {
+  char uhbuf[USERLEN+HOSTLEN+2];
   
-  return -1;
-}
+  visibleuserhost(np, uhbuf);
+  sprintf(buf,"%s!%s",np->nick,uhbuf);
 
-void releaseauthnameext(int index) {
-  int i;
-  authname *anp;
-  
-  freesstring(authnameextnames[index]);
-  authnameextnames[index]=NULL;
-  
-  for (i=0;i<AUTHNAMEHASHSIZE;i++) {
-    for (anp=authnametable[i];anp;anp=anp->next) {
-      anp->exts[index]=NULL;
-    }
-  }
+  return buf;
 }
 
-/* visiblehostmask
- *  Produces the "apparent" hostmask as seen by network users.
+/* visibleuserhost
+ *  As above without nick
  */
 
-char *visiblehostmask(nick *np, char *buf) {
+char *visibleuserhost(nick *np, char *buf) {
   char hostbuf[HOSTLEN+1];
   char *ident, *host;
 
@@ -335,7 +369,7 @@ char *visiblehostmask(nick *np, char *buf) {
     host=hostbuf;
   }
 
-  sprintf(buf,"%s!%s@%s",np->nick,ident,host);
+  sprintf(buf,"%s@%s",ident,host);
 
   return buf;
 }
@@ -395,47 +429,3 @@ 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;
-}