]> jfr.im git - irc/quakenet/newserv.git/blobdiff - nick/nickhandlers.c
Fix AC message.
[irc/quakenet/newserv.git] / nick / nickhandlers.c
index bd47ff889f7ee52ff67f9d9464d59e9ba162ed6d..62ef2b801d7d407f943b66b9232dd73497096c82 100644 (file)
@@ -27,6 +27,10 @@ int handlenickmsg(void *source, int cargc, char **cargv) {
   nick **nh;
   char *fakehost;
   char *accountts;
+  char *accountflags;
+  struct irc_in_addr ipaddress;
+  char *accountid;
+  unsigned long userid;
   
   if (cargc==2) { /* rename */
     /* Nyklon 1017697578 */
@@ -112,7 +116,13 @@ int handlenickmsg(void *source, int cargc, char **cargv) {
       Error("nick",ERR_WARNING,"Received NICK with invalid numeric %s from %s.",cargv[cargc-2],sender);
       return CMD_ERROR;
     }
-          
+
+    base64toip(cargv[cargc-3], &ipaddress);
+    if (!irc_in_addr_valid(&ipaddress)) {
+      Error("nick",ERR_ERROR,"Received NICK with invalid ipaddress for %s from %s.",cargv[0],sender);
+      return CMD_ERROR;
+    }
+
     /* At this stage the nick is cleared to proceed */
     np=newnick();
     strncpy(np->nick,cargv[0],NICKLEN);
@@ -127,29 +137,61 @@ int handlenickmsg(void *source, int cargc, char **cargv) {
     np->nextbyrealname=np->realname->nicks;
     np->realname->nicks=np;
     np->timestamp=timestamp;
-    np->ipaddress=numerictolong(cargv[cargc-3],6);
+
+    base64toip(cargv[cargc-3], &ipaddress);
+    np->ipnode = refnode(iptree, &ipaddress, PATRICIA_MAXBITS);
+    node_increment_usercount(np->ipnode);
+
     np->shident=NULL;
     np->sethost=NULL;
+    np->opername=NULL;
     np->umodes=0;
     np->marker=0;
     memset(np->exts, 0, MAXNICKEXTS * sizeof(void *));
-    np->authname[0]='\0';
+    np->authname=NULLAUTHNAME;
+    np->auth=NULL;
+    np->accountts=0;
     if(cargc>=9) {
+      int sethostarg = 6, opernamearg = 6, accountarg = 6;
+
       setflags(&(np->umodes),UMODE_ALL,cargv[5],umodeflags,REJECT_NONE);
+
+      if(IsOper(np) && (serverlist[myhub].flags & SMODE_OPERNAME)) {
+        accountarg++;
+        sethostarg++;
+
+        np->opername=getsstring(cargv[opernamearg],ACCOUNTLEN);
+      }
+
       if (IsAccount(np)) {
-        if ((accountts=strchr(cargv[6],':'))) {
+        sethostarg++;
+
+        if ((accountts=strchr(cargv[accountarg],':'))) {
+          userid=0;
           *accountts++='\0';
-          np->accountts=strtoul(accountts,NULL,10);
-        } else {
-          np->accountts=0;
+          np->accountts=strtoul(accountts,&accountid,10);
+          if(accountid) {
+            userid=strtoul(accountid + 1,&accountflags,10);
+            if(userid) {
+              np->auth=findorcreateauthname(userid, cargv[accountarg]);
+              np->authname=np->auth->name;
+              np->auth->usercount++;
+              np->nextbyauthname=np->auth->nicks;
+              np->auth->nicks=np;
+              if(accountflags)
+                np->auth->flags=strtoull(accountflags + 1,NULL,10);
+            }
+          }
+          if(!userid) {
+            np->authname=malloc(strlen(cargv[accountarg]) + 1);
+            strcpy(np->authname,cargv[accountarg]);
+          }
         }        
-        strncpy(np->authname,cargv[6],ACCOUNTLEN);
-        np->authname[ACCOUNTLEN]='\0';
       } 
-      if (IsSetHost(np) && (fakehost=strchr(cargv[cargc-4],'@'))) {
+      if (IsSetHost(np) && (fakehost=strchr(cargv[sethostarg],'@'))) {
        /* valid sethost */
        *fakehost++='\0';
-       np->shident=getsstring(cargv[cargc-4],USERLEN);
+       np->shident=getsstring(cargv[sethostarg],USERLEN);
        np->sethost=getsstring(fakehost,HOSTLEN);
       }
     }
@@ -182,8 +224,8 @@ int handlequitmsg(void *source, int cargc, char **cargv) {
   nick *np;
   void *harg[2];
   
-  if (cargc>1) {
-    harg[1]=(void *)cargv[1];
+  if (cargc>0) {
+    harg[1]=(void *)cargv[0];
   } else {
     harg[1]="";
   } 
@@ -201,13 +243,24 @@ int handlequitmsg(void *source, int cargc, char **cargv) {
 
 int handlekillmsg(void *source, int cargc, char **cargv) {
   nick *np;
-  
+  void *harg[2];
+#warning Fix me to use source
+
   if (cargc<1) {
     Error("nick",ERR_WARNING,"Kill message with too few parameters");
     return CMD_ERROR;  
   }
+
+  if (cargc>1) {
+    harg[1]=(void *)cargv[1];
+  } else {
+    harg[1]="";
+  } 
+  
   np=getnickbynumericstr(cargv[0]);
   if (np) {
+    harg[0]=(void *)np;
+    triggerhook(HOOK_NICK_KILL, harg);
     deletenick(np);
   } else {
     Error("nick",ERR_WARNING,"Kill for non-existant numeric %s",cargv[0]);
@@ -239,13 +292,20 @@ int handleusermodemsg(void *source, int cargc, char **cargv) {
       return CMD_OK;
     }
     oldflags=np->umodes;
-    if (strchr(cargv[1],'o')) {
-      void *harg[2];
-        harg[0]=np;
-        harg[1]=cargv[1];
-        triggerhook(HOOK_NICK_MODEOPER,harg);
-    }
     setflags(&(np->umodes),UMODE_ALL,cargv[1],umodeflags,REJECT_NONE);
+
+    if (strchr(cargv[1],'o')) { /* o always comes on its own when being set */
+      if(serverlist[myhub].flags & SMODE_OPERNAME) {
+        if((np->umodes & UMODE_OPER)) {
+          np->opername = getsstring(cargv[2], ACCOUNTLEN);
+        } else {
+          freesstring(np->opername);
+          np->opername = NULL;
+        }
+      }
+      if((np->umodes ^ oldflags) & UMODE_OPER)
+        triggerhook(HOOK_NICK_MODEOPER,np);
+    }
     if (strchr(cargv[1],'h')) { /* Have to allow +h twice.. */
       /* +-h: just the freesstring() calls for the -h case */
       freesstring(np->shident); /* freesstring(NULL) is OK */
@@ -312,11 +372,11 @@ int handlewhoismsg(void *source, int cargc, char **cargv) {
       irc_send(":%s 313 %s %s :is an IRC Operator",myserver->content,sender->nick,target->nick);
     }
     if (IsAccount(target)) {
-      irc_send(":%s 330 %s %s %s :is logged in as",myserver->content,sender->nick,target->nick,target->authname);
+      irc_send(":%s 330 %s %s %s :is authed as",myserver->content,sender->nick,target->nick,target->authname);
     }
-    if (homeserver(target->numeric)==mylongnum && !IsService(target)) {
+    if (homeserver(target->numeric)==mylongnum && !IsService(target) && !IsHideIdle(target)) {
       irc_send(":%s 317 %s %s %ld %ld :seconds idle, signon time",myserver->content,sender->nick,target->nick,
-         0,target->timestamp);
+         (getnettime() - target->timestamp) % (((target->numeric + target->timestamp) % 983) + 7),target->timestamp);
     }
   }
   
@@ -326,8 +386,11 @@ int handlewhoismsg(void *source, int cargc, char **cargv) {
 
 int handleaccountmsg(void *source, int cargc, char **cargv) {
   nick *target;
-  
-  if (cargc<2) {
+  unsigned long userid;
+  time_t accountts;
+  u_int64_t accountflags, oldflags;
+
+  if (cargc<4) {
     return CMD_OK;
   }
   
@@ -335,16 +398,50 @@ int handleaccountmsg(void *source, int cargc, char **cargv) {
     return CMD_OK;
   }
   
+  accountts=strtoul(cargv[2],NULL,10);
+  userid=strtoul(cargv[3],NULL,10);
+  if(cargc>=5)
+    accountflags=strtoull(cargv[4],NULL,10);
+
+  /* allow user flags to change if all fields match */
   if (IsAccount(target)) {
+    void *arg[2];
+
+    if (!target->auth || strcmp(target->auth->name,cargv[1]) || (target->auth->userid != userid) || (target->accountts != accountts)) {
+      return CMD_OK;
+    }
+
+    oldflags = target->auth->flags;
+    arg[0] = target->auth;
+    arg[1] = &oldflags;
+    
+    if (cargc>=5)
+      target->auth->flags=accountflags;
+
+    triggerhook(HOOK_AUTH_FLAGSUPDATED, (void *)arg);
+
     return CMD_OK;
   }
   
   SetAccount(target);
-  strncpy(target->authname,cargv[1],ACCOUNTLEN);
-  target->authname[ACCOUNTLEN]='\0';
+  target->accountts=accountts;
+
+  if(!userid) {
+    target->auth=NULL;
+    target->authname=malloc(strlen(cargv[1]) + 1);
+    strcpy(target->authname,cargv[1]);
+  } else {
+    target->auth=findorcreateauthname(userid, cargv[1]);
+    target->auth->usercount++;
+    target->authname=target->auth->name;
+    target->nextbyauthname = target->auth->nicks;
+    target->auth->nicks = target;
+    if (cargc>=5)
+      target->auth->flags=accountflags;
+  }
 
   triggerhook(HOOK_NICK_ACCOUNT, (void *)target);
-  
+
   return CMD_OK;
 }
 
@@ -398,3 +495,31 @@ int handlestatsmsg(void *source, int cargc, char **cargv) {
 
   return CMD_OK;
 }
+
+int handleprivmsg(void *source, int cargc, char **cargv) {
+  nick *sender;
+  char *message;
+  void *args[3];
+
+  if (cargc<2)
+    return CMD_OK;
+
+  if (cargv[0][0]!='$')
+    return CMD_OK;
+
+  sender=getnickbynumericstr((char *)source);
+
+  if (!match2strings(cargv[0] + 1,myserver->content))
+    return CMD_OK;
+
+  message=cargv[0];
+
+  args[0]=sender;
+  args[1]=cargv[0];
+  args[2]=cargv[1];
+
+  triggerhook(HOOK_NICK_MASKPRIVMSG, (void *)args);
+
+  return CMD_OK;
+}
+