diff -Nru unpatched/S/serverhandlers.c patched/S/serverhandlers.c
--- S/serverhandlers.c        Sat Aug 24 00:24:02 2002
+++ S/serverhandlers.c        Sat Jun 28 11:42:29 2003
@@ -39,7 +39,6 @@
 void handlenickmsg() {
   unsigned long tmpl;
   int slen; userdata *a;
-  int k=0;
   slen=strlen(sender);
   if (slen==5) {
     // Nickchange
@@ -74,9 +73,19 @@
       sprintf(logline,"!!! Nick introduction failed (wrong # args): %s !!!",lastline); putlog();
       return;
     }
-    if (params[7][0]=='+') { rnstart=10; } else { rnstart=9; }
-    if ((rnstart==10) && (paramcount<11)) {
-      sprintf(logline,"!!! Nick introduction failed (no realname at all?!): %s !!!",lastline);
+  if (params[7][0]=='+') {
+       rnstart=10;
+      if (ischarinstr('r',params[7]))
+        rnstart++;
+      if (ischarinstr('h',params[7]))
+        rnstart++;
+      } else {
+       rnstart=9;
+     }
+
+    if (paramcount<(rnstart+1)) {
+
+sprintf(logline,"!!! Nick introduction failed (no realname at all?!): %s !!!",lastline); putlog();
       putlog();
       return;
     }
@@ -87,11 +96,11 @@
     for (;(*c!='\0');c++) { realname[ipa]=*c; ipa++; }
     realname[ipa]='\0';
     if (rnstart==9) { strcpy(umode,"+"); } else { strcpy(umode,params[7]); }
-    if (strstr(params[7], "r")) { k = 9; }else{ k = 8; }
-    if (rnstart==9) { strcpy(numtmp,params[k]); } else { strcpy(numtmp,params[k+1]); }
-    if (rnstart==9) { strcpy(realiptmp,params[7]); } else { strcpy(realiptmp,params[8]); }
-    normnum(numtmp);
-    tmpl=tokentolong(realiptmp);
+ strcpy(numtmp,params[rnstart-1]);
+    strcpy(realiptmp,params[rnstart-2]);
+normnum(numtmp);
+
+tmpl=tokentolong(realiptmp);
     toLowerCase(params[2]);
     if (nicktonu2(params[2])>=0) { /* Nick collission */
       long thisisnotgood; long ting2; userdata *ting3;
@@ -148,6 +157,17 @@
     a->connectat=strtoul(params[4],NULL,10);
     a->realip=tokentolong(realiptmp);
     a->numeric=tokentolong(numtmp);
+    if (rnstart>=11) { /* authed user */
+    if (params[7][0]=='+') {
+    if (ischarinstr('r',params[7]))
+      if (strlen(params[8])>NICKLEN) {
+        sprintf(logline,"!!! Authname exceeds NICKLEN: %s !!!",lastline); putlog();
+        free(a); return;
+      } }
+      strcpy(a->authname,params[8]);
+    } else { /* not authed */
+      a->authname[0]='\0';
+    }
     if (strlen(params[2])>NICKLEN) {
       sprintf(logline,"!!! Nick exceeds NICKLEN: %s !!!",lastline); putlog();
       free(a); return;
@@ -182,7 +202,8 @@
     // Add warning if this realname is there too often
     addnicktoul(a);
     addtonicklist(a);
-  }
+
+}
 }

 void handlequitmsg() {
@@ -196,6 +217,32 @@
   }
 }

+ void handleaccountmsg() {
+  long unum; userdata *up;
+  if (paramcount<4) {
+    sprintf(logline,"!!! Failed to parse ACCOUNT message: %s !!!",lastline); putlog();
+    return;
+  }
+  unum=tokentolong(params[2]);
+  up=getudptr(unum);
+  if (up==NULL) {
+    sprintf(logline,"!!! ACCOUNT for bad numeric %s !!!",lastline); putlog();
+    return;
+  }
+  if (strlen(params[3])>NICKLEN) {
+    sprintf(logline,"!!! ACCOUNT with authname too long: %s !!!",lastline); putlog();
+    return;
+  }
+  if (up->authname[0]!='\0') {
+    sprintf(logline,"!!! ACCOUNT for already authed user: %s !!!",lastline); putlog();
+    return;
+  }
+  strcpy(up->authname,params[3]);
+  strcat(up->umode,"r");
+
+}
+
+
 void handleservermsg(int firsts) {
   int xofs; char tmpconnectedto[TMPSSIZE], tmps2[TMPSSIZE];
   if (firsts==1) {
@@ -288,14 +335,15 @@
     a=uls[ulhash(sendnum)];
     while(a!=NULL) {
       if (a->numeric==sendnum) {
-        t1=0; t2=1;
+        t1=1; t2=0;
         while (params[3][t2]!='\0') {
+        if (params[3][t2]==':') continue;
           if ((params[3][t2]=='+') || (params[3][t2]=='-')) {
             if (params[3][t2]=='+') { t1=1; } else { t1=0; }
           } else {
             if (t1==1) {
               if (strlen(a->umode)<(MAXUMODES-1)) {
-                appchar(a->umode,params[3][t2]);
+              if (!ischarinstr(params[3][t2],a->umode)) { appchar(a->umode,params[3][t2]); }
               }
             } else {
               delchar(a->umode,params[3][t2]);
diff -Nru unpatched/S/Spamservice.c patched/S/Spamservice.c
--- S/Spamservice.c   Sat Aug 24 00:24:02 2002
+++ S/Spamservice.c   Fri Jun 27 15:42:47 2003
@@ -1161,6 +1161,7 @@
   longtotoken(iptolong(127,0,0,1),tmps1,6);
   fprintf(sockout,"SERVER %s 1 %ld %ld J10 %sA]] :This is spamservice %s\r\n",myname,starttime,starttime,servernumeric,spamservversion);
   fprintf(sockout,"%s N %s 1 %ld spamserv %s +ok %s %sAAB :This is spamservice %s\r\n",servernumeric,mynick,starttime,myname,tmps1,servernumeric,spamservversion);
+  fprintf(sockout,"%s AC %sAAB %s\r\n",servernumeric,servernumeric,mynick);
   fprintf(sockout,"%s EB\r\n",servernumeric);
   fflush(sockout);
   do {
@@ -1240,6 +1241,9 @@
         if (strcmp(command,"217")==0) { handlestatsPreply(); }
         if ((strcmp(command,"EOB_ACK")==0) || (strcmp(command,"EA")==0)) { handleeoback(); }
         if ((strcmp(command,"TOPIC")==0) || (strcmp(command,"T")==0)) { handletopic(); }
+        if (strcmp(command,"ACCOUNT")==0){ handleaccountmsg(); }
+        if (strcmp(command,"AC")==0) { handleaccountmsg(); }
+
       }
     }
   } while (lastline[0]!='\0');
diff -Nru unpatched/S/globals.h patched/S/globals.h
--- S/globals.h       Sat Aug 24 00:24:14 2002
+++ S/globals.h       Tue Jul  8 13:09:34 2003
@@ -86,6 +86,7 @@
   char host[HOSTLEN+1];
   char umode[MAXUMODES+1];
   char realname[REALLEN+1];
+  char authname[NICKLEN+1];
   array chans;
   unsigned long realip;     /* The real IP of the client as a 32 bit integer */
                             /* Obviously this is only compatible with IPv4! */

