]> jfr.im git - irc/quakenet/newserv.git/blobdiff - nick/nick.c
Merge default into chanserv-live.
[irc/quakenet/newserv.git] / nick / nick.c
index bad21689be4ee93e66874e07581e359bc5fa3d96..f04f1df1a2597487bd3f5e1508b3f8b5330965ee 100644 (file)
@@ -12,6 +12,7 @@
 #include "../server/server.h"
 #include "../parser/parser.h"
 #include "../lib/version.h"
+#include "../lib/ccassert.h"
 #include "../core/nsmalloc.h"
 
 #include <stdlib.h>
@@ -20,6 +21,8 @@
 
 MODULE_VERSION("");
 
+CCASSERT(sizeof(host) == sizeof(realname));
+
 const flag umodeflags[] = {
    { 'i', UMODE_INV },
    { 'w', UMODE_WALLOPS },
@@ -35,14 +38,20 @@ const flag umodeflags[] = {
    { 'R', UMODE_REGPRIV },
    { 'I', UMODE_HIDEIDLE },
    { 'P', UMODE_PARANOID },
+   { 'q', UMODE_COMCHANS },
+   { 'Q', UMODE_COMCHANSRESTR },
+   { 'C', UMODE_CLOAKED },
    { '\0', 0 } };
 
 const flag accountflags[] = {
-   { 's', AFLAG_STAFF },
+   { 'q', AFLAG_STAFF },
+   { 'h', AFLAG_SUPPORT },
+   { 'o', AFLAG_OPER },
+   { 'a', AFLAG_ADMIN },
    { 'd', AFLAG_DEVELOPER },
    { '\0', 0 } };
 
-#define nickhash(x)       ((crc32i(x))%NICKHASHSIZE)
+#define nickhash(x)       ((irc_crc32i(x))%NICKHASHSIZE)
 
 nick *nicktable[NICKHASHSIZE];
 nick **servernicks[MAXSERVERS];
@@ -51,6 +60,8 @@ sstring *nickextnames[MAXNICKEXTS];
 
 void nickstats(int hooknum, void *arg);
 
+char *NULLAUTHNAME = "";
+
 void _init() {
   unsigned int i;
   authname *anp;
@@ -60,10 +71,16 @@ void _init() {
     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(0);
+  }
   
   /* Register our hooks */
   registerhook(HOOK_SERVER_NEWSERVER,&handleserverchange);
@@ -75,10 +92,11 @@ void _init() {
   registerserverhandler("D",&handlekillmsg,2);
   registerserverhandler("Q",&handlequitmsg,1);
   registerserverhandler("M",&handleusermodemsg,3);
-  registerserverhandler("W",&handlewhoismsg,2);
   registerserverhandler("AC",&handleaccountmsg,4);
-  registerserverhandler("R",&handlestatsmsg,2);
   registerserverhandler("P",&handleprivmsg,2);
+  registerserverhandler("A",&handleawaymsg,1);
+  registerserverhandler("CA",&handleaddcloak,1);
+  registerserverhandler("CU",&handleclearcloak,0);
   
   /* Fake the addition of our own server */
   handleserverchange(HOOK_SERVER_NEWSERVER,(void *)numerictolong(mynumeric->content,2));
@@ -94,6 +112,9 @@ void _fini() {
     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);
     }
   }
 
@@ -109,10 +130,11 @@ void _fini() {
   deregisterserverhandler("D",&handlekillmsg);
   deregisterserverhandler("Q",&handlequitmsg);
   deregisterserverhandler("M",&handleusermodemsg);
-  deregisterserverhandler("W",&handlewhoismsg);
-  deregisterserverhandler("AC",&handleaccountmsg);
-  deregisterserverhandler("R",&handlestatsmsg);  
+  deregisterserverhandler("AC",&handleaccountmsg); 
   deregisterserverhandler("P",&handleprivmsg);
+  deregisterserverhandler("A",&handleawaymsg);
+  deregisterserverhandler("CA",&handleaddcloak);
+  deregisterserverhandler("CU",&handleclearcloak);
 }
 
 /*
@@ -153,6 +175,9 @@ void handleserverchange(int hooknum, void *arg) {
 void deletenick(nick *np) {
   nick **nh;
 
+  /* Fire a pre-lostnick trigger to allow hooks to check the channels etc. of a lost nick */
+  triggerhook(HOOK_NICK_PRE_LOSTNICK, np);
+
   /* Fire the hook.  This will deal with removal from channels etc. */
   triggerhook(HOOK_NICK_LOSTNICK, np);
   
@@ -175,28 +200,38 @@ 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); 
+  freesstring(np->message);
 
   node_decrement_usercount(np->ipnode);
   derefnode(iptree, np->ipnode);
   
   /* TODO: figure out how to cleanly remove nodes without affecting other modules */
 
+  /* Remove cloak entries for the user */
+  removecloaktarget(np);
+  clearcloaktargets(np);
+
   /* Delete the nick from the servernick table */  
   *(gethandlebynumericunsafe(np->numeric))=NULL;
   
@@ -405,5 +440,45 @@ nick *getnickbynumericstr(char *numericstr) {
   return getnickbynumeric(numerictolong(numericstr,5));
 }
 
+
 #endif
 
+int canseeuser(nick *np, nick *cloaked)
+{
+  return (np == cloaked ||
+          !IsCloaked(cloaked) ||
+          np->cloak_extra == cloaked);
+}
+
+void addcloaktarget(nick *cloaked, nick *target)
+{
+  removecloaktarget(target);
+
+  target->cloak_extra = cloaked;
+  cloaked->cloak_count++;
+}
+
+void removecloaktarget(nick *target)
+{
+  if (target->cloak_extra) {
+    target->cloak_extra->cloak_count--;
+    target->cloak_extra = NULL;
+  }
+}
+
+void clearcloaktargets(nick *cloaked)
+{
+  nick *tnp;
+  int j;
+
+  if (cloaked->cloak_count == 0)
+    return;
+
+  for(j=0;j<NICKHASHSIZE;j++)
+    for(tnp=nicktable[j];tnp;tnp=tnp->next)
+      if (tnp->cloak_extra == cloaked)
+        tnp->cloak_extra = NULL;
+
+  cloaked->cloak_count = 0;
+}
+