]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/inspircd.cpp
Tidied up zline stuff
[user/henk/code/inspircd.git] / src / inspircd.cpp
index cd32f861c7b7c57d5c4fd08ae3ea9272635ccfba..c42306a30302408c7a979556ff8b7db550da59c1 100644 (file)
@@ -213,7 +213,26 @@ void AddWhoWas(userrec* u);
 std::vector<long> auth_cookies;
 std::stringstream config_f(stringstream::in | stringstream::out);
 
+std::vector<userrec*> all_opers;
 
+void AddOper(userrec* user)
+{
+       log(DEBUG,"Oper added to optimization list");
+       all_opers.push_back(user);
+}
+
+void DeleteOper(userrec* user)
+{
+        for (std::vector<userrec*>::iterator a = all_opers.begin(); a < all_opers.end(); a++)
+        {
+                if (*a == user)
+                {
+                        log(DEBUG,"Oper removed from optimization list");
+                        all_opers.erase(a);
+                        return;
+                }
+        }
+}
 
 long GetRevision()
 {
@@ -277,7 +296,7 @@ void log(int level,char *text, ...)
                vsnprintf(textbuffer, MAXBUF, text, argsPtr);
                va_end(argsPtr);
                strlcpy(b,asctime(timeinfo),MAXBUF);
-               b[strlen(b)-1] = ':';
+               b[24] = ':';    // we know this is the end of the time string
                fprintf(log_file,"%s %s\n",b,textbuffer);
                if (nofork)
                {
@@ -301,7 +320,7 @@ void readfile(file_cache &F, const char* fname)
                {
                        fgets(linebuf,sizeof(linebuf),file);
                        linebuf[strlen(linebuf)-1]='\0';
-                       if (!strcmp(linebuf,""))
+                       if (linebuf[0] == 0)
                        {
                                strcpy(linebuf,"  ");
                        }
@@ -316,7 +335,7 @@ void readfile(file_cache &F, const char* fname)
        {
                log(DEBUG,"readfile: failed to load file: %s",fname);
        }
-       log(DEBUG,"readfile: loaded %s, %d lines",fname,F.size());
+       log(DEBUG,"readfile: loaded %s, %lu lines",fname,(unsigned long)F.size());
 }
 
 void ReadConfig(bool bail, userrec* user)
@@ -388,9 +407,9 @@ void ReadConfig(bool bail, userrec* user)
        dns_timeout = atoi(DNT);
        if (!dns_timeout)
                dns_timeout = 5;
-       if (!strcmp(DNSServer,""))
+       if (!DNSServer[0])
                strlcpy(DNSServer,"127.0.0.1",MAXBUF);
-       if (!strcmp(ModPath,""))
+       if (!ModPath[0])
                strlcpy(ModPath,MOD_PATH,MAXBUF);
        AllowHalfop = ((!strcasecmp(AH,"true")) || (!strcasecmp(AH,"1")) || (!strcasecmp(AH,"yes")));
        AllowProtect = ((!strcasecmp(AP,"true")) || (!strcasecmp(AP,"1")) || (!strcasecmp(AP,"yes")));
@@ -427,7 +446,7 @@ void ReadConfig(bool bail, userrec* user)
                ConfValue("connect","timeout",i,timeout,&config_f);
                ConfValue("connect","flood",i,flood,&config_f);
                ConfValue("connect","pingfreq",i,pfreq,&config_f);
-               if (strcmp(Value,""))
+               if (Value[0])
                {
                        strlcpy(c.host,Value,MAXBUF);
                        c.type = CC_ALLOW;
@@ -446,7 +465,7 @@ void ReadConfig(bool bail, userrec* user)
                                c.pingtime = atoi(pfreq);
                        }
                        Classes.push_back(c);
-                       log(DEBUG,"Read connect class type ALLOW, host=%s password=%s timeout=%d flood=%d",c.host,c.pass,c.registration_timeout,c.flood);
+                       log(DEBUG,"Read connect class type ALLOW, host=%s password=%s timeout=%lu flood=%lu",c.host,c.pass,(unsigned long)c.registration_timeout,(unsigned long)c.flood);
                }
                else
                {
@@ -537,7 +556,7 @@ void ReadConfig(bool bail, userrec* user)
                                WriteServ(user->fd,"974 %s %s :Failed to load module %s: %s",user->nick, adding->c_str(), adding->c_str(), ModuleError());
                        }
                }
-               log(DEFAULT,"Successfully unloaded %d of %d modules and loaded %d of %d modules.",rem,removed_modules.size(),add,added_modules.size());
+               log(DEFAULT,"Successfully unloaded %lu of %lu modules and loaded %lu of %lu modules.",(unsigned long)rem,(unsigned long)removed_modules.size(),(unsigned long)add,(unsigned long)added_modules.size());
        }
 }
 
@@ -670,16 +689,6 @@ void WriteChannel(chanrec* Ptr, userrec* user, char* text, ...)
                if (otheruser->fd != FD_MAGIC_NUMBER)
                        WriteTo(user,otheruser,"%s",textbuffer);
        }
-
-
-       //for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
-       //{
-       //      if (has_channel(i->second,Ptr))
-       //      {
-       //              if (i->second->fd != FD_MAGIC_NUMBER)
-       //                      WriteTo(user,i->second,"%s",textbuffer);
-       //      }
-       //}
 }
 
 /* write formatted text from a source user to all users on a channel
@@ -719,9 +728,9 @@ void WriteChannelLocal(chanrec* Ptr, userrec* user, char* text, ...)
 }
 
 
-void WriteChannelWithServ(char* ServName, chanrec* Ptr, userrec* user, char* text, ...)
+void WriteChannelWithServ(char* ServName, chanrec* Ptr, char* text, ...)
 {
-       if ((!Ptr) || (!user) || (!text))
+       if ((!Ptr) || (!text))
        {
                log(DEFAULT,"*** BUG *** WriteChannelWithServ was given an invalid parameter");
                return;
@@ -741,17 +750,6 @@ void WriteChannelWithServ(char* ServName, chanrec* Ptr, userrec* user, char* tex
                 if (otheruser->fd != FD_MAGIC_NUMBER)
                         WriteServ(otheruser->fd,"%s",textbuffer);
         }
-
-       //for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
-       //{
-       //      if (i->second)
-       //      {
-       //              if ((has_channel(i->second,Ptr)) && (i->second->fd != FD_MAGIC_NUMBER))
-       //              {
-       //                      WriteServ(i->second->fd,"%s",textbuffer);
-       //              }
-       //      }
-       //}
 }
 
 
@@ -823,7 +821,8 @@ void WriteCommon(userrec *u, char* text, ...)
        vsnprintf(textbuffer, MAXBUF, text, argsPtr);
        va_end(argsPtr);
 
-       WriteFrom(u->fd,u,"%s",textbuffer);
+       // FIX: Stops a message going to the same person more than once
+       std::vector<int> already_sent;
 
         for (int i = 0; i < MAXCHANS; i++)
         {
@@ -834,21 +833,29 @@ void WriteCommon(userrec *u, char* text, ...)
                         {
                                 char* o = (*ulist)[j];
                                 userrec* otheruser = (userrec*)o;
-                                WriteFrom(otheruser->fd,u,"%s",textbuffer);
+                               bool do_send = true;
+                               for (int t = 0; t < already_sent.size(); t++)
+                               {
+                                       if (already_sent[t] == otheruser->fd)
+                                       {
+                                               do_send = false;
+                                               break;
+                                       }
+                               }
+                               if (do_send)
+                               {
+                                       already_sent.push_back(otheruser->fd);
+                                       WriteFrom(otheruser->fd,u,"%s",textbuffer);
+                               }
                         }
                 }
         }
-
-       //for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
-       //{
-       //      if (i->second)
-       //      {
-       //              if ((common_channels(u,i->second) && (i->second != u)) && (i->second->fd != FD_MAGIC_NUMBER))
-       //              {
-       //                      WriteFrom(i->second->fd,u,"%s",textbuffer);
-       //              }
-       //      }
-       //}
+       // if the user was not in any channels, no users will receive the text. Make sure the user
+       // receives their OWN message for WriteCommon
+       if (!already_sent.size())
+       {
+               WriteFrom(u->fd,u,"%s",textbuffer);
+       }
 }
 
 /* write a formatted string to all users who share at least one common
@@ -873,6 +880,8 @@ void WriteCommonExcept(userrec *u, char* text, ...)
        vsnprintf(textbuffer, MAXBUF, text, argsPtr);
        va_end(argsPtr);
 
+       std::vector<int> already_sent;
+
         for (int i = 0; i < MAXCHANS; i++)
         {
                 if (u->chans[i].channel)
@@ -883,21 +892,25 @@ void WriteCommonExcept(userrec *u, char* text, ...)
                                 char* o = (*ulist)[j];
                                 userrec* otheruser = (userrec*)o;
                                if (u != otheruser)
-                                       WriteFrom(otheruser->fd,u,"%s",textbuffer);
+                               {
+                                       bool do_send = true;
+                                       for (int t = 0; t < already_sent.size(); t++)
+                                       {
+                                               if (already_sent[t] == otheruser->fd)
+                                               {
+                                                       do_send = false;
+                                                       break;
+                                               }
+                                       }
+                                       if (do_send)
+                                       {
+                                               already_sent.push_back(otheruser->fd);
+                                               WriteFrom(otheruser->fd,u,"%s",textbuffer);
+                                       }
+                               }
                         }
                 }
         }
-
-       //for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
-       //{
-       //      if (i->second)
-       //      {
-       //              if ((common_channels(u,i->second)) && (u != i->second))
-       //              {
-       //                      WriteFrom(i->second->fd,u,"%s",textbuffer);
-       //              }
-       //      }
-       //}
 }
 
 void WriteOpers(char* text, ...)
@@ -914,18 +927,15 @@ void WriteOpers(char* text, ...)
        vsnprintf(textbuffer, MAXBUF, text, argsPtr);
        va_end(argsPtr);
 
-       for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
+       for (std::vector<userrec*>::iterator i = all_opers.begin(); i != all_opers.end(); i++)
        {
-               if ((i->second) && (i->second->fd != FD_MAGIC_NUMBER))
+               userrec* a = *i;
+               if ((a) && (a->fd != FD_MAGIC_NUMBER))
                {
-                       if (strchr(i->second->modes,'o'))
+                       if (strchr(a->modes,'s'))
                        {
-                               if (strchr(i->second->modes,'s'))
-                               {
-                                       // send server notices to all with +s
-                                       // (TODO: needs SNOMASKs)
-                                       WriteServ(i->second->fd,"NOTICE %s :%s",i->second->nick,textbuffer);
-                               }
+                               // send server notices to all with +s
+                               WriteServ(a->fd,"NOTICE %s :%s",a->nick,textbuffer);
                        }
                }
        }
@@ -946,18 +956,6 @@ bool ChanAnyOnThisServer(chanrec *c,char* servername)
                        return true;
         }
        return false;
-
-       //for (user_hash::iterator i = clientlist.begin(); i != clientlist.end(); i++)
-       //{
-       //      if (has_channel(i->second,c))
-       //      {
-       //              if (!strcasecmp(i->second->server,servername))
-       //              {
-       //                      return true;
-       //              }
-       //      }
-       //}
-       return false;
 }
 
 // returns true if user 'u' shares any common channels with any users on server 'servername'
@@ -981,19 +979,6 @@ bool CommonOnThisServer(userrec* u,const char* servername)
                 }
         }
        return false;
-
-       //for (user_hash::iterator i = clientlist.begin(); i != clientlist.end(); i++)
-       //{
-       //      if ((common_channels(u,i->second)) && (u != i->second))
-       //      {
-       //              if (!strcasecmp(i->second->server,servername))
-       //              {
-       //                      log(DEBUG,"%s is common to %s sharing with %s",i->second->nick,servername,u->nick);
-       //                      return true;
-       //              }
-       //      }
-       //}
-       //return false;
 }
 
 
@@ -1305,11 +1290,13 @@ void purge_empty_chans(userrec* u)
 
        // firstly decrement the count on each channel
        for (int f = 0; f < MAXCHANS; f++)
+       {
                if (u->chans[f].channel)
                {
                        u->chans[f].channel->DecUserCounter();
                        u->chans[f].channel->DelUser((char*)u);
                }
+       }
 
        for (int i = 0; i < MAXCHANS; i++)
        {
@@ -1336,7 +1323,9 @@ void purge_empty_chans(userrec* u)
                        }
                }
        }
-       log(DEBUG,"completed channel purge, killed %d",purge);
+       log(DEBUG,"completed channel purge, killed %lu",(unsigned long)purge);
+
+       DeleteOper(u);
 }
 
 
@@ -1362,7 +1351,7 @@ char* chanmodes(chanrec *chan)
        {
                strlcat(scratch,"t",MAXMODES);
        }
-       if (strcmp(chan->key,""))
+       if (chan->key[0])
        {
                strlcat(scratch,"k",MAXMODES);
        }
@@ -1386,7 +1375,7 @@ char* chanmodes(chanrec *chan)
        {
                strlcat(scratch,"p",MAXMODES);
        }
-       if (strcmp(chan->key,""))
+       if (chan->key[0])
        {
                strlcat(sparam," ",MAXBUF);
                strlcat(sparam,chan->key,MAXBUF);
@@ -1394,13 +1383,13 @@ char* chanmodes(chanrec *chan)
        if (chan->limit)
        {
                char foo[24];
-               sprintf(foo," %d",chan->limit);
+               sprintf(foo," %lu",(unsigned long)chan->limit);
                strlcat(sparam,foo,MAXBUF);
        }
-       if (strlen(chan->custom_modes))
+       if (*chan->custom_modes)
        {
                strlcat(scratch,chan->custom_modes,MAXMODES);
-               for (int z = 0; z < strlen(chan->custom_modes); z++)
+               for (int z = 0; chan->custom_modes[z] != 0; z++)
                {
                        std::string extparam = chan->GetModeParameter(chan->custom_modes[z]);
                        if (extparam != "")
@@ -1492,7 +1481,7 @@ int usercount_i(chanrec *c)
                        }
                }
        }
-       log(DEBUG,"usercount_i: %s %d",c->name,count);
+       log(DEBUG,"usercount_i: %s %lu",c->name,(unsigned long)count);
        return count;
 }
 
@@ -1505,7 +1494,7 @@ int usercount(chanrec *c)
                return 0;
        }
        int count = c->GetUserCounter();
-       log(DEBUG,"usercount: %s %d",c->name,count);
+       log(DEBUG,"usercount: %s %lu",c->name,(unsigned long)count);
        return count;
 }
 
@@ -1598,7 +1587,7 @@ chanrec* add_channel(userrec *user, const char* cn, const char* key, bool overri
                                        FOREACH_RESULT(OnCheckKey(user, Ptr, key ? key : ""));
                                        if (MOD_RESULT == 0)
                                        {
-                                               if (strcmp(Ptr->key,""))
+                                               if (Ptr->key[0])
                                                {
                                                        log(DEBUG,"add_channel: %s has key %s",Ptr->name,Ptr->key);
                                                        if (!key)
@@ -1739,12 +1728,12 @@ chanrec* add_channel(userrec *user, const char* cn, const char* key, bool overri
                        if (Ptr->topicset)
                        {
                                WriteServ(user->fd,"332 %s %s :%s", user->nick, Ptr->name, Ptr->topic);
-                               WriteServ(user->fd,"333 %s %s %s %d", user->nick, Ptr->name, Ptr->setby, Ptr->topicset);
+                               WriteServ(user->fd,"333 %s %s %s %lu", user->nick, Ptr->name, Ptr->setby, (unsigned long)Ptr->topicset);
                        }
                        userlist(user,Ptr);
                        WriteServ(user->fd,"366 %s %s :End of /NAMES list.", user->nick, Ptr->name);
                        //WriteServ(user->fd,"324 %s %s +%s",user->nick, Ptr->name,chanmodes(Ptr));
-                       //WriteServ(user->fd,"329 %s %s %d", user->nick, Ptr->name, Ptr->created);
+                       //WriteServ(user->fd,"329 %s %s %lu", user->nick, Ptr->name, (unsigned long)Ptr->created);
                        FOREACH_MOD OnUserJoin(user,Ptr);
                        return Ptr;
                }
@@ -2105,7 +2094,7 @@ void kill_link(userrec *user,const char* r)
 
        log(DEBUG,"kill_link: %s '%s'",user->nick,reason);
        Write(user->fd,"ERROR :Closing link (%s@%s) [%s]",user->ident,user->host,reason);
-       log(DEBUG,"closing fd %d",user->fd);
+       log(DEBUG,"closing fd %lu",(unsigned long)user->fd);
 
        /* bugfix, cant close() a nonblocking socket (sux!) */
        if (user->registered == 7) {
@@ -2131,19 +2120,18 @@ void kill_link(userrec *user,const char* r)
                AddWhoWas(user);
        }
 
+        if (user->registered == 7) {
+                purge_empty_chans(user);
+        }
+
        if (iter != clientlist.end())
        {
-               log(DEBUG,"deleting user hash value %d",iter->second);
+               log(DEBUG,"deleting user hash value %lu",(unsigned long)iter->second);
                if ((iter->second) && (user->registered == 7)) {
                        if (iter->second) delete iter->second;
                }
                clientlist.erase(iter);
        }
-
-       if (user->registered == 7) {
-               purge_empty_chans(user);
-       }
-       //user = NULL;
 }
 
 void kill_link_silent(userrec *user,const char* r)
@@ -2161,7 +2149,7 @@ void kill_link_silent(userrec *user,const char* r)
 
        log(DEBUG,"kill_link: %s '%s'",user->nick,reason);
        Write(user->fd,"ERROR :Closing link (%s@%s) [%s]",user->ident,user->host,reason);
-       log(DEBUG,"closing fd %d",user->fd);
+       log(DEBUG,"closing fd %lu",(unsigned long)user->fd);
 
        /* bugfix, cant close() a nonblocking socket (sux!) */
        if (user->registered == 7) {
@@ -2181,19 +2169,19 @@ void kill_link_silent(userrec *user,const char* r)
                 shutdown(user->fd,2);
                 close(user->fd);
         }
+
+        if (user->registered == 7) {
+                purge_empty_chans(user);
+        }
        
        if (iter != clientlist.end())
        {
-               log(DEBUG,"deleting user hash value %d",iter->second);
+               log(DEBUG,"deleting user hash value %lu",(unsigned long)iter->second);
                if ((iter->second) && (user->registered == 7)) {
                        if (iter->second) delete iter->second;
                }
                clientlist.erase(iter);
        }
-
-       if (user->registered == 7) {
-               purge_empty_chans(user);
-       }
 }
 
 
@@ -2312,7 +2300,7 @@ template<typename T> inline string ConvToStr(const T &in)
 
 userrec* ReHashNick(char* Old, char* New)
 {
-       user_hash::iterator newnick;
+       //user_hash::iterator newnick;
        user_hash::iterator oldnick = clientlist.find(Old);
 
        log(DEBUG,"ReHashNick: %s %s",Old,New);
@@ -2393,7 +2381,7 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip)
        user_hash::iterator iter;
 
        tempnick = ConvToStr(socket) + "-unknown";
-       sprintf(tn2,"%d-unknown",socket);
+       sprintf(tn2,"%lu-unknown",(unsigned long)socket);
 
        iter = clientlist.find(tempnick);
 
@@ -2409,7 +2397,7 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip)
        clientlist[tempnick] = new userrec();
 
        NonBlocking(socket);
-       log(DEBUG,"AddClient: %d %s %d %s",socket,host,port,ip);
+       log(DEBUG,"AddClient: %lu %s %d %s",(unsigned long)socket,host,port,ip);
 
        clientlist[tempnick]->fd = socket;
        strncpy(clientlist[tempnick]->nick, tn2,NICKMAX);
@@ -2597,7 +2585,7 @@ void FullConnectUser(userrec* user)
         user->idle_lastmsg = TIME;
         log(DEBUG,"ConnectUser: %s",user->nick);
 
-        if (strcmp(Passwd(user),"") && (!user->haspassed))
+        if ((strcmp(Passwd(user),"")) && (!user->haspassed))
         {
                 kill_link(user,"Invalid password");
                 return;
@@ -2664,10 +2652,10 @@ void FullConnectUser(userrec* user)
         }
         ShowMOTD(user);
         FOREACH_MOD OnUserConnect(user);
-        WriteOpers("*** Client connecting on port %d: %s!%s@%s [%s]",user->port,user->nick,user->ident,user->host,user->ip);
+        WriteOpers("*** Client connecting on port %lu: %s!%s@%s [%s]",(unsigned long)user->port,user->nick,user->ident,user->host,user->ip);
 
         char buffer[MAXBUF];
-       snprintf(buffer,MAXBUF,"N %d %s %s %s %s +%s %s %s :%s",user->age,user->nick,user->host,user->dhost,user->ident,user->modes,user->ip,ServerName,user->fullname);
+       snprintf(buffer,MAXBUF,"N %lu %s %s %s %s +%s %s %s :%s",(unsigned long)user->age,user->nick,user->host,user->dhost,user->ident,user->modes,user->ip,ServerName,user->fullname);
         NetSendToAll(buffer);
 }
 
@@ -2696,18 +2684,45 @@ void ConnectUser(userrec *user)
        }
 }
 
-void handle_version(char **parameters, int pcnt, userrec *user)
+std::string GetVersionString()
 {
-       char Revision[] = "$Revision$";
+        char Revision[] = "$Revision$";
+       char versiondata[MAXBUF];
+        char *s1 = Revision;
+        char *savept;
+        char *v2 = strtok_r(s1," ",&savept);
+        s1 = savept;
+        v2 = strtok_r(s1," ",&savept);
+        s1 = savept;
+       snprintf(versiondata,MAXBUF,"%s Rev. %s %s :%s (O=%lu)",VERSION,v2,ServerName,SYSTEM,(unsigned long)OPTIMISATION);
+       return versiondata;
+}
 
-       char *s1 = Revision;
-       char *savept;
-       char *v2 = strtok_r(s1," ",&savept);
-       s1 = savept;
-       v2 = strtok_r(s1," ",&savept);
-       s1 = savept;
-       
-       WriteServ(user->fd,"351 %s :%s Rev. %s %s :%s (O=%d)",user->nick,VERSION,v2,ServerName,SYSTEM,OPTIMISATION);
+void handle_version(char **parameters, int pcnt, userrec *user)
+{
+       if (!pcnt)
+       {
+               WriteServ(user->fd,"351 %s :%s",user->nick,GetVersionString().c_str());
+       }
+       else
+       {
+                for (int j = 0; j < 32; j++)
+                {
+                        if (me[j] != NULL)
+                        {
+                                for (int x = 0; x < me[j]->connectors.size(); x++)
+                                {
+                                        if (match(me[j]->connectors[x].GetServerName().c_str(),parameters[0]))
+                                        {
+                                               WriteServ(user->fd,"351 %s :%s",user->nick,me[j]->connectors[x].GetVersionString().c_str());
+                                               return;
+                                       }
+                               }
+                       }
+               }
+               WriteServ(user->fd,"402 %s %s :No such server",user->nick,parameters[0]);
+       }
+       return;
 }
 
 
@@ -2916,7 +2931,7 @@ void process_command(userrec *user, char* cmd)
        {
                return;
        }
-       if (!strcmp(cmd,""))
+       if (!cmd[0])
        {
                return;
        }
@@ -2975,7 +2990,6 @@ void process_command(userrec *user, char* cmd)
                {
                        cmd[i] = toupper(cmd[i]);
                }
-               log(DEBUG,"Preprocess done length=%d",strlen(cmd));
                command = cmd;
        }
        else
@@ -3045,15 +3059,13 @@ void process_command(userrec *user, char* cmd)
 
        for (int i = 0; i != cmdlist.size(); i++)
        {
-               if (strcmp(cmdlist[i].command,""))
+               if (cmdlist[i].command[0])
                {
                        if (strlen(command)>=(strlen(cmdlist[i].command))) if (!strncmp(command, cmdlist[i].command,MAXCOMMAND))
                        {
-                               log(DEBUG,"Found matching command");
-
                                if (parameters)
                                {
-                                       if (strcmp(parameters,""))
+                                       if (parameters[0])
                                        {
                                                items = process_parameters(command_p,parameters);
                                        }
@@ -3071,8 +3083,6 @@ void process_command(userrec *user, char* cmd)
                                
                                if (user)
                                {
-                                       log(DEBUG,"Processing command");
-                                       
                                        /* activity resets the ping pending timer */
                                        user->nping = TIME + user->pingmax;
                                        if ((items) < cmdlist[i].min_params)
@@ -3124,9 +3134,8 @@ void process_command(userrec *user, char* cmd)
         
 
                                        }
-                                       if ((user->registered == 7) || (!strcmp(command,"USER")) || (!strcmp(command,"NICK")) || (!strcmp(command,"PASS")))
+                                       if ((user->registered == 7) || (!strncmp(command,"USER",4)) || (!strncmp(command,"NICK",4)) || (!strncmp(command,"PASS",4)))
                                        {
-                                               log(DEBUG,"process_command: handler: %s %s %d",user->nick,command,items);
                                                if (cmdlist[i].handler_function)
                                                {
                                                        
@@ -3160,7 +3169,6 @@ void process_command(userrec *user, char* cmd)
                                        }
                                        else
                                        {
-                                               log(DEBUG,"process_command: not registered: %s %s",user->nick,command);
                                                WriteServ(user->fd,"451 %s :You have not registered",command);
                                                return;
                                        }
@@ -3171,7 +3179,6 @@ void process_command(userrec *user, char* cmd)
        }
        if ((!cmd_found) && (user))
        {
-               log(DEBUG,"process_command: not in table: %s %s",user->nick,command);
                WriteServ(user->fd,"421 %s %s :Unknown command",user->nick,command);
        }
 }
@@ -3189,7 +3196,7 @@ void createcommand(char* cmd, handlerfunc f, char flags, int minparams,char* sou
        comm.use_count = 0;
        comm.total_bytes = 0;
        cmdlist.push_back(comm);
-       log(DEBUG,"Added command %s (%d parameters)",cmd,minparams);
+       log(DEBUG,"Added command %s (%lu parameters)",cmd,(unsigned long)minparams);
 }
 
 bool removecommands(const char* source)
@@ -3281,36 +3288,39 @@ void process_buffer(const char* cmdbuf,userrec *user)
                log(DEFAULT,"*** BUG *** process_buffer was given an invalid parameter");
                return;
        }
-       if (!strcmp(cmdbuf,""))
+       if (!cmdbuf[0])
        {
                return;
        }
-       while ((cmdbuf[0] == ' ') && (strlen(cmdbuf)>0)) cmdbuf++; // strip leading spaces
+       while (*cmdbuf == ' ') cmdbuf++; // strip leading spaces
 
        strlcpy(cmd,cmdbuf,MAXBUF);
-       if (!strcmp(cmd,""))
+       if (!cmd[0])
        {
                return;
        }
-       if ((cmd[strlen(cmd)-1] == 13) || (cmd[strlen(cmd)-1] == 10))
+       int sl = strlen(cmd)-1;
+       if ((cmd[sl] == 13) || (cmd[sl] == 10))
        {
-               cmd[strlen(cmd)-1] = '\0';
+               cmd[sl] = '\0';
        }
-       if ((cmd[strlen(cmd)-1] == 13) || (cmd[strlen(cmd)-1] == 10))
+       sl = strlen(cmd)-1;
+       if ((cmd[sl] == 13) || (cmd[sl] == 10))
        {
-               cmd[strlen(cmd)-1] = '\0';
+               cmd[sl] = '\0';
        }
-
-       while ((cmd[strlen(cmd)-1] == ' ') && (strlen(cmd)>0)) // strip trailing spaces
+       sl = strlen(cmd)-1;
+       while (cmd[sl] == ' ') // strip trailing spaces
        {
-               cmd[strlen(cmd)-1] = '\0';
+               cmd[sl] = '\0';
+               sl = strlen(cmd)-1;
        }
 
-       if (!strcmp(cmd,""))
+       if (!cmd[0])
        {
                return;
        }
-        log(DEBUG,"InspIRCd: processing: %s %s",user->nick,cmd);
+        log(DEBUG,"CMDIN: %s %s",user->nick,cmd);
        tidystring(cmd);
        if ((user) && (cmd))
        {
@@ -3325,12 +3335,36 @@ void DoSync(serverrec* serv, char* tcp_host)
        // send start of sync marker: Y <timestamp>
        // at this point the ircd receiving it starts broadcasting this netburst to all ircds
        // except the ones its receiving it from.
-       snprintf(data,MAXBUF,"Y %d",TIME);
+       snprintf(data,MAXBUF,"Y %lu",(unsigned long)TIME);
        serv->SendPacket(data,tcp_host);
        // send users and channels
+
+       NetSendMyRoutingTable();
+
+       // send all routing table and uline voodoo. The ordering of these commands is IMPORTANT!
+        for (int j = 0; j < 32; j++)
+        {
+                if (me[j] != NULL)
+                {
+                        for (int k = 0; k < me[j]->connectors.size(); k++)
+                        {
+                                if (is_uline(me[j]->connectors[k].GetServerName().c_str()))
+                                {
+                                        snprintf(data,MAXBUF,"H %s",me[j]->connectors[k].GetServerName().c_str());
+                                        serv->SendPacket(data,tcp_host);
+                                }
+                        }
+                }
+        }
+
+       // send our version for the remote side to cache
+       snprintf(data,MAXBUF,"v %s %s",ServerName,GetVersionString().c_str());
+       serv->SendPacket(data,tcp_host);
+
+       // sync the users and channels, give the modules a look-in.
        for (user_hash::iterator u = clientlist.begin(); u != clientlist.end(); u++)
        {
-               snprintf(data,MAXBUF,"N %d %s %s %s %s +%s %s %s :%s",u->second->age,u->second->nick,u->second->host,u->second->dhost,u->second->ident,u->second->modes,u->second->ip,u->second->server,u->second->fullname);
+               snprintf(data,MAXBUF,"N %lu %s %s %s %s +%s %s %s :%s",(unsigned long)u->second->age,u->second->nick,u->second->host,u->second->dhost,u->second->ident,u->second->modes,u->second->ip,u->second->server,u->second->fullname);
                serv->SendPacket(data,tcp_host);
                if (strchr(u->second->modes,'o'))
                {
@@ -3346,9 +3380,10 @@ void DoSync(serverrec* serv, char* tcp_host)
                                serv->SendPacket(data,tcp_host);
                        }
                }
-               if (strcmp(chlist(u->second),""))
+               char* chl = chlist(u->second);
+               if (strcmp(chl,""))
                {
-                       snprintf(data,MAXBUF,"J %s %s",u->second->nick,chlist(u->second));
+                       snprintf(data,MAXBUF,"J %s %s",u->second->nick,chl);
                        serv->SendPacket(data,tcp_host);
                }
        }
@@ -3366,9 +3401,9 @@ void DoSync(serverrec* serv, char* tcp_host)
                                serv->SendPacket(data,tcp_host);
                        }
                }
-               if (strcmp(c->second->topic,""))
+               if (c->second->topic[0])
                {
-                       snprintf(data,MAXBUF,"T %d %s %s :%s",c->second->topicset,c->second->setby,c->second->name,c->second->topic);
+                       snprintf(data,MAXBUF,"T %lu %s %s :%s",(unsigned long)c->second->topicset,c->second->setby,c->second->name,c->second->topic);
                        serv->SendPacket(data,tcp_host);
                }
                // send current banlist
@@ -3382,23 +3417,7 @@ void DoSync(serverrec* serv, char* tcp_host)
        // sync global zlines, glines, etc
        sync_xlines(serv,tcp_host);
 
-       for (int j = 0; j < 32; j++)
-       {
-               if (me[j] != NULL)
-               {
-                       for (int k = 0; k < me[j]->connectors.size(); k++)
-                       {
-                               if (is_uline(me[j]->connectors[k].GetServerName().c_str()))
-                               {
-                                       snprintf(data,MAXBUF,"H %s",me[j]->connectors[k].GetServerName().c_str());
-                                       serv->SendPacket(data,tcp_host);
-                                       NetSendMyRoutingTable();
-                               }
-                       }
-               }
-       }
-
-       snprintf(data,MAXBUF,"F %d",TIME);
+       snprintf(data,MAXBUF,"F %lu",(unsigned long)TIME);
        serv->SendPacket(data,tcp_host);
        log(DEBUG,"Sent sync");
        // ircd sends its serverlist after the end of sync here
@@ -3604,7 +3623,6 @@ bool DirValid(char* dirandfile)
                }
                work[p--] = '\0';
        }
-       log(DEBUG,"Dir valid: %s",work);
        char buffer[MAXBUF], otherdir[MAXBUF];
        // Get the current working directory
        if( getcwd( buffer, MAXBUF ) == NULL )
@@ -3613,17 +3631,13 @@ bool DirValid(char* dirandfile)
        if( getcwd( otherdir, MAXBUF ) == NULL )
                return false;
        chdir(buffer);
-       log(DEBUG,"Dir is really: %s",otherdir);
        if (strlen(otherdir) >= strlen(work))
        {
                otherdir[strlen(work)] = '\0';
-               log(DEBUG,"Compare: '%s' -> '%s'",otherdir,work);
                if (!strcmp(otherdir,work))
                {
-                       log(DEBUG,"Match ok");
                        return true;
                }
-               log(DEBUG,"No match");
                return false;
        }
        else return false;
@@ -3704,8 +3718,7 @@ int InspIRCd(void)
                Exit(ERROR);
        }
 
-       log(DEBUG,"InspIRCd: startup: begin");
-       log(DEBUG,"$Id$");
+       log(DEFAULT,"$Id$");
        if (geteuid() == 0)
        {
                printf("WARNING!!! You are running an irc server as ROOT!!! DO NOT DO THIS!!!\n\n");
@@ -3716,7 +3729,7 @@ int InspIRCd(void)
        log(DEBUG,"InspIRCd: startup: default command table set up");
        
        ReadConfig(true,NULL);
-       if (strcmp(DieValue,"")) 
+       if (DieValue[0])
        { 
                printf("WARNING: %s\n\n",DieValue);
                log(DEFAULT,"Ut-Oh, somebody didn't read their config file: '%s'",DieValue);
@@ -3744,8 +3757,8 @@ int InspIRCd(void)
                        me[serverportcount] = new serverrec(ServerName,100L,false);
                        if (!me[serverportcount]->CreateListener(Addr,atoi(configToken)))
                        {
-                               log(DEFAULT,"Warning: Failed to bind port %d",atoi(configToken));
-                               printf("Warning: Failed to bind port %d\n",atoi(configToken));
+                               log(DEFAULT,"Warning: Failed to bind port %lu",(unsigned long)atoi(configToken));
+                               printf("Warning: Failed to bind port %lu\n",(unsigned long)atoi(configToken));
                        }
                        else
                        {
@@ -3763,7 +3776,7 @@ int InspIRCd(void)
        portCount = clientportcount;
        UDPportCount = serverportcount;
          
-       log(DEBUG,"InspIRCd: startup: read %d total client ports and %d total server ports",portCount,UDPportCount);
+       log(DEBUG,"InspIRCd: startup: read %lu total client ports and %lu total server ports",(unsigned long)portCount,(unsigned long)UDPportCount);
        log(DEBUG,"InspIRCd: startup: InspIRCd is now starting!");
        
        printf("\n");
@@ -3773,15 +3786,15 @@ int InspIRCd(void)
        for (count = 0; count < ConfValueEnum("module",&config_f); count++)
        {
                ConfValue("module","name",count,configToken,&config_f);
-               printf("Loading module... \033[1;37m%s\033[0;37m\n",configToken);
+               printf("Loading module... \033[1;32m%s\033[0m\n",configToken);
                if (!LoadModule(configToken))
                {
-                       log(DEBUG,"Exiting due to a module loader error.");
+                       log(DEFAULT,"Exiting due to a module loader error.");
                        printf("\nThere was an error loading a module: %s\n\nYou might want to do './inspircd start' instead of 'bin/inspircd'\n\n",ModuleError());
                        Exit(0);
                }
        }
-       log(DEBUG,"Total loaded modules: %d",MODCOUNT+1);
+       log(DEFAULT,"Total loaded modules: %lu",(unsigned long)MODCOUNT+1);
        
        startup_time = time(NULL);
          
@@ -3793,18 +3806,18 @@ int InspIRCd(void)
        /* setup select call */
        FD_ZERO(&selectFds);
        log(DEBUG,"InspIRCd: startup: zero selects");
-       log(VERBOSE,"InspIRCd: startup: portCount = %d", portCount);
+       log(VERBOSE,"InspIRCd: startup: portCount = %lu", (unsigned long)portCount);
        
        for (count = 0; count < portCount; count++)
        {
                if ((openSockfd[boundPortCount] = OpenTCPSocket()) == ERROR)
                {
-                       log(DEBUG,"InspIRCd: startup: bad fd %d",openSockfd[boundPortCount]);
+                       log(DEBUG,"InspIRCd: startup: bad fd %lu",(unsigned long)openSockfd[boundPortCount]);
                        return(ERROR);
                }
                if (BindSocket(openSockfd[boundPortCount],client,server,ports[count],addrs[count]) == ERROR)
                {
-                       log(DEFAULT,"InspIRCd: startup: failed to bind port %d",ports[count]);
+                       log(DEFAULT,"InspIRCd: startup: failed to bind port %lu",(unsigned long)ports[count]);
                }
                else    /* well we at least bound to one socket so we'll continue */
                {
@@ -3812,13 +3825,13 @@ int InspIRCd(void)
                }
        }
        
-       log(DEBUG,"InspIRCd: startup: total bound ports %d",boundPortCount);
+       log(DEBUG,"InspIRCd: startup: total bound ports %lu",(unsigned long)boundPortCount);
          
        /* if we didn't bind to anything then abort */
        if (boundPortCount == 0)
        {
                log(DEFAULT,"InspIRCd: startup: no ports bound, bailing!");
-               printf("\nERROR: Was not able to bind any of %d ports! Please check your configuration.\n\n", portCount);
+               printf("\nERROR: Was not able to bind any of %lu ports! Please check your configuration.\n\n", (unsigned long)portCount);
                return (ERROR);
        }
        
@@ -3846,14 +3859,14 @@ int InspIRCd(void)
 
         fd_set serverfds;
         timeval tvs;
-        tvs.tv_usec = 7000L;
+        tvs.tv_usec = 10000L;
         tvs.tv_sec = 0;
        tv.tv_sec = 0;
-       tv.tv_usec = 7000L;
-        char data[10240];
+       tv.tv_usec = 10000L;
+        char data[65535];
        timeval tval;
        fd_set sfd;
-        tval.tv_usec = 7000L;
+        tval.tv_usec = 10000L;
         tval.tv_sec = 0;
         int total_in_this_set = 0;
        int v = 0;
@@ -3897,7 +3910,7 @@ int InspIRCd(void)
                
                // serverFds timevals went here
                
-               tvs.tv_usec = 7000L;
+               tvs.tv_usec = 30000L;
                tvs.tv_sec = 0;
                int servresult = select(32767, &serverfds, NULL, NULL, &tvs);
                if (servresult > 0)
@@ -3924,7 +3937,7 @@ int InspIRCd(void)
                        }
                }
      
-               for (int cycle = 0; cycle < 4; cycle++) for (int x = 0; x < UDPportCount; x++)
+               for (int x = 0; x < UDPportCount; x++)
                {
                        std::deque<std::string> msgs;
                        msgs.clear();
@@ -3934,9 +3947,9 @@ int InspIRCd(void)
                                {
                                        strlcpy(udp_msg,msgs[ctr].c_str(),MAXBUF);
                                        log(DEBUG,"Processing: %s",udp_msg);
-                                       if (strlen(udp_msg)<1)
+                                       if (!udp_msg[0])
                                        {
-                                               log(DEBUG,"Invalid string from %s [route%d]",tcp_host,x);
+                                               log(DEBUG,"Invalid string from %s [route%lu]",tcp_host,(unsigned long)x);
                                                break;
                                        }
                                        // during a netburst, send all data to all other linked servers
@@ -4037,7 +4050,7 @@ int InspIRCd(void)
 
                        // tvals defined here
 
-                       tval.tv_usec = 7000L;
+                       tval.tv_usec = 1000L;
                        selectResult2 = select(65535, &sfd, NULL, NULL, &tval);
                        
                        // now loop through all of the items in this pool if any are waiting
@@ -4052,9 +4065,7 @@ int InspIRCd(void)
                                result = EAGAIN;
                                if ((count2a->second->fd != FD_MAGIC_NUMBER) && (count2a->second->fd != -1) && (FD_ISSET (count2a->second->fd, &sfd)))
                                {
-                                       memset(data, 0, 10240);
-                                       result = read(count2a->second->fd, data, 10240);
-                                       
+                                       result = read(count2a->second->fd, data, 65535);
                                        if (result)
                                        {
                                                // perform a check on the raw buffer as an array (not a string!) to remove
@@ -4065,40 +4076,55 @@ int InspIRCd(void)
                                                        if ((data[checker] == 0) || (data[checker] == 7))
                                                                data[checker] = ' ';
                                                }
+                                               if (result > 0)
+                                                       data[result] = '\0';
                                                userrec* current = count2a->second;
                                                int currfd = current->fd;
-                                               char* l = strtok(data,"\n");
                                                int floodlines = 0;
-                                               while (l)
+                                               current->AddBuffer(data);
+                                               if (current->recvq.length() > NetBufferSize)
                                                {
-                                                       floodlines++;
-                                                       if ((floodlines > current->flood) && (current->flood != 0))
+                                                       if (current->registered == 7)
                                                        {
-                                                               log(DEFAULT,"Excess flood from: %s!%s@%s",current->nick,current->ident,current->host);
-                                                               WriteOpers("*** Excess flood from: %s!%s@%s",current->nick,current->ident,current->host);
-                                                               kill_link(current,"Excess flood");
-                                                               goto label;
+                                                               kill_link(current,"RecvQ exceeded");
                                                        }
-                                                       char sanitized[NetBufferSize];
-                                                       memset(sanitized, 0, NetBufferSize);
-                                                       int ptt = 0;
-                                                       for (int pt = 0; pt < strlen(l); pt++)
+                                                       else
+                                                       {
+                                                               WriteOpers("*** Excess flood from %s",current->ip);
+                                                               log(DEFAULT,"Excess flood from: %s",current->ip);
+                                                               add_zline(120,ServerName,"Flood from unregistered connection",current->ip);
+                                                               apply_lines();
+                                                       }
+                                                       goto label;
+                                               }
+                                               // while there are complete lines to process...
+                                               while (current->BufferIsReady())
+                                               {
+                                                       floodlines++;
+                                                       if ((floodlines > current->flood) && (current->flood != 0))
                                                        {
-                                                               if (l[pt] != '\r')
+                                                               if (current->registered == 7)
                                                                {
-                                                                       sanitized[ptt++] = l[pt];
+                                                                       log(DEFAULT,"Excess flood from: %s!%s@%s",current->nick,current->ident,current->host);
+                                                                       WriteOpers("*** Excess flood from: %s!%s@%s",current->nick,current->ident,current->host);
+                                                                       kill_link(current,"Excess flood");
                                                                }
+                                                               else
+                                                               {
+                                                                       add_zline(120,ServerName,"Flood from unregistered connection",current->ip);
+                                                                       apply_lines();
+                                                               }
+                                                               goto label;
                                                        }
-                                                       sanitized[ptt] = '\0';
-                                                       if (strlen(sanitized))
+                                                       char sanitized[MAXBUF];
+                                                       // use GetBuffer to copy single lines into the sanitized string
+                                                       strlcpy(sanitized,current->GetBuffer().c_str(),MAXBUF);
+                                                       if (*sanitized)
                                                        {
-
-
                                                                // we're gonna re-scan to check if the nick is gone, after every
                                                                // command - if it has, we're gonna bail
                                                                bool find_again = false;
                                                                process_buffer(sanitized,current);
-       
                                                                // look for the user's record in case it's changed
                                                                for (user_hash::iterator c2 = clientlist.begin(); c2 != clientlist.end(); c2++)
                                                                {
@@ -4114,7 +4140,6 @@ int InspIRCd(void)
                                                                        goto label;
 
                                                        }
-                                                       l = strtok(NULL,"\n");
                                                }
                                                goto label;
                                        }
@@ -4149,13 +4174,13 @@ int InspIRCd(void)
                }
                for (int q = 0; q < total_in_this_set; q++)
                {
-                       // there is no iterator += operator :(
-                       //if (count2 != clientlist.end())
-                       //{
-                               count2++;
-                       //}
+                       count2++;
                }
        }
+
+#ifdef _POSIX_PRIORITY_SCHEDULING
+        sched_yield();
+#endif
        
        // set up select call
        for (count = 0; count < boundPortCount; count++)
@@ -4163,7 +4188,7 @@ int InspIRCd(void)
                FD_SET (openSockfd[count], &selectFds);
        }
 
-       tv.tv_usec = 7000L;
+       tv.tv_usec = 30000L;
        selectResult = select(MAXSOCKS, &selectFds, NULL, NULL, &tv);
 
        /* select is reporting a waiting socket. Poll them all to find out which */
@@ -4182,13 +4207,13 @@ int InspIRCd(void)
                        
                                if (incomingSockfd < 0)
                                {
-                                       WriteOpers("*** WARNING: Accept failed on port %d (%s)", ports[count],target);
-                                       log(DEBUG,"InspIRCd: accept failed: %d",ports[count]);
+                                       WriteOpers("*** WARNING: Accept failed on port %lu (%s)",(unsigned long)ports[count],target);
+                                       log(DEBUG,"InspIRCd: accept failed: %lu",(unsigned long)ports[count]);
                                }
                                else
                                {
                                        AddClient(incomingSockfd, resolved, ports[count], false, inet_ntoa (client.sin_addr));
-                                       log(DEBUG,"InspIRCd: adding client on port %d fd=%d",ports[count],incomingSockfd);
+                                       log(DEBUG,"InspIRCd: adding client on port %lu fd=%lu",(unsigned long)ports[count],(unsigned long)incomingSockfd);
                                }
                                goto label;
                        }
@@ -4196,6 +4221,9 @@ int InspIRCd(void)
        }
        label:
        if (0) {};
+#ifdef _POSIX_PRIORITY_SCHEDULING
+        sched_yield();
+#endif
 }
 /* not reached */
 close (incomingSockfd);