]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/inspircd_io.cpp
Fix to prevent adding empty phrases to +g list
[user/henk/code/inspircd.git] / src / inspircd_io.cpp
index 9fc1bd410014e4f398db87006ac4304a3dce4d22..a405ed4bf735ae02c90d0564e4c88197d103d9c6 100644 (file)
@@ -35,7 +35,7 @@ using namespace std;
 
 extern ServerConfig *Config;
 extern InspIRCd* ServerInstance;
-extern int openSockfd[MAXSOCKS];
+extern int openSockfd[MAX_DESCRIPTORS];
 extern time_t TIME;
 
 extern int MODCOUNT;
@@ -523,36 +523,37 @@ void ServerConfig::Read(bool bail, userrec* user)
 
        /* These tags can occur ONCE or not at all */
        static InitialConfig Values[] = {
-               {"options",     "softlimit",            &this->SoftLimit,               DT_INTEGER, ValidateSoftLimit},
-               {"options",     "somaxconn",            &this->MaxConn,                 DT_INTEGER, ValidateMaxConn},
-               {"server",      "name",                 &this->ServerName,              DT_CHARPTR, ValidateServerName},
-               {"server",      "description",          &this->ServerDesc,              DT_CHARPTR, NoValidation},
-               {"server",      "network",              &this->Network,                 DT_CHARPTR, NoValidation},
-               {"admin",       "name",                 &this->AdminName,               DT_CHARPTR, NoValidation},
-               {"admin",       "email",                &this->AdminEmail,              DT_CHARPTR, NoValidation},
-               {"admin",       "nick",                 &this->AdminNick,               DT_CHARPTR, NoValidation},
-               {"files",       "motd",                 &this->motd,                    DT_CHARPTR, ValidateMotd},
-               {"files",       "rules",                &this->rules,                   DT_CHARPTR, ValidateRules},
-               {"power",       "diepass",              &this->diepass,                 DT_CHARPTR, NoValidation},      
-               {"power",       "pauseval",             &this->DieDelay,                DT_INTEGER, NoValidation},
-               {"power",       "restartpass",          &this->restartpass,             DT_CHARPTR, NoValidation},
-               {"options",     "prefixquit",           &this->PrefixQuit,              DT_CHARPTR, NoValidation},
-               {"die",         "value",                &this->DieValue,                DT_CHARPTR, NoValidation},
-               {"options",     "loglevel",             &debug,                         DT_CHARPTR, ValidateLogLevel},
-               {"options",     "netbuffersize",        &this->NetBufferSize,           DT_INTEGER, ValidateNetBufferSize},
-               {"options",     "maxwho",               &this->MaxWhoResults,           DT_INTEGER, ValidateMaxWho},
-               {"options",     "allowhalfop",          &this->AllowHalfop,             DT_BOOLEAN, NoValidation},
-               {"dns",         "server",               &this->DNSServer,               DT_CHARPTR, ValidateDnsServer},
-               {"dns",         "timeout",              &this->dns_timeout,             DT_INTEGER, ValidateDnsTimeout},
-               {"options",     "moduledir",            &this->ModPath,                 DT_CHARPTR, ValidateModPath},
-               {"disabled",    "commands",             &this->DisabledCommands,        DT_CHARPTR, NoValidation},
-               {"options",     "operonlystats",        &this->OperOnlyStats,           DT_CHARPTR, NoValidation},
-               {"options",     "customversion",        &this->CustomVersion,           DT_CHARPTR, NoValidation},
-               {"options",     "hidesplits",           &this->HideSplits,              DT_BOOLEAN, NoValidation},
-               {"options",     "hidebans",             &this->HideBans,                DT_BOOLEAN, NoValidation},
-               {"options",     "hidewhois",            &this->HideWhoisServer,         DT_CHARPTR, NoValidation},
-               {"options",     "tempdir",              &this->TempDir,                 DT_CHARPTR, ValidateTempDir},
-               {"pid",         "file",                 &this->PID,                     DT_CHARPTR, NoValidation},
+               {"options",             "softlimit",            &this->SoftLimit,               DT_INTEGER, ValidateSoftLimit},
+               {"options",             "somaxconn",            &this->MaxConn,                 DT_INTEGER, ValidateMaxConn},
+               {"server",              "name",                         &this->ServerName,              DT_CHARPTR, ValidateServerName},
+               {"server",              "description",          &this->ServerDesc,              DT_CHARPTR, NoValidation},
+               {"server",              "network",                      &this->Network,                 DT_CHARPTR, NoValidation},
+               {"admin",               "name",                         &this->AdminName,               DT_CHARPTR, NoValidation},
+               {"admin",               "email",                        &this->AdminEmail,              DT_CHARPTR, NoValidation},
+               {"admin",               "nick",                         &this->AdminNick,               DT_CHARPTR, NoValidation},
+               {"files",               "motd",                         &this->motd,                    DT_CHARPTR, ValidateMotd},
+               {"files",               "rules",                        &this->rules,                   DT_CHARPTR, ValidateRules},
+               {"power",               "diepass",                      &this->diepass,                 DT_CHARPTR, NoValidation},      
+               {"power",               "pauseval",                     &this->DieDelay,                DT_INTEGER, NoValidation},
+               {"power",               "restartpass",          &this->restartpass,             DT_CHARPTR, NoValidation},
+               {"options",             "prefixquit",           &this->PrefixQuit,              DT_CHARPTR, NoValidation},
+               {"die",                 "value",                        &this->DieValue,                DT_CHARPTR, NoValidation},
+               {"options",             "loglevel",                     &debug,                                 DT_CHARPTR, ValidateLogLevel},
+               {"options",             "netbuffersize",        &this->NetBufferSize,   DT_INTEGER, ValidateNetBufferSize},
+               {"options",             "maxwho",                       &this->MaxWhoResults,   DT_INTEGER, ValidateMaxWho},
+               {"options",             "allowhalfop",          &this->AllowHalfop,             DT_BOOLEAN, NoValidation},
+               {"dns",                 "server",                       &this->DNSServer,               DT_CHARPTR, ValidateDnsServer},
+               {"dns",                 "timeout",                      &this->dns_timeout,             DT_INTEGER, ValidateDnsTimeout},
+               {"options",             "moduledir",            &this->ModPath,                 DT_CHARPTR, ValidateModPath},
+               {"disabled",    "commands",             &this->DisabledCommands,DT_CHARPTR, NoValidation},
+               {"options",             "operonlystats",        &this->OperOnlyStats,   DT_CHARPTR, NoValidation},
+               {"options",             "customversion",        &this->CustomVersion,   DT_CHARPTR, NoValidation},
+               {"options",             "hidesplits",           &this->HideSplits,              DT_BOOLEAN, NoValidation},
+               {"options",             "hidebans",                     &this->HideBans,                DT_BOOLEAN, NoValidation},
+               {"options",             "hidewhois",            &this->HideWhoisServer, DT_CHARPTR, NoValidation},
+               {"options",             "operspywhois",         &this->OperSpyWhois,    DT_BOOLEAN, NoValidation},
+               {"options",             "tempdir",                      &this->TempDir,                 DT_CHARPTR, ValidateTempDir},
+               {"pid",                 "file",                         &this->PID,                             DT_CHARPTR, NoValidation},
                {NULL}
        };
 
@@ -753,6 +754,8 @@ void ServerConfig::Read(bool bail, userrec* user)
         */
        if (!bail)
        {
+               ServerInstance->stats->BoundPortCount = BindPorts(false);
+
                if (!removed_modules.empty())
                        for (std::vector<std::string>::iterator removing = removed_modules.begin(); removing != removed_modules.end(); removing++)
                        {
@@ -1466,7 +1469,7 @@ int ServerConfig::ConfValueInteger(char* tag, char* var, int index, std::strings
  * a maximum of one second before it times out, using the DNS
  * server specified in the configuration file.
  */ 
-bool BindSocket (int sockfd, struct sockaddr_in client, struct sockaddr_in server, int port, char* addr)
+bool BindSocket(int sockfd, struct sockaddr_in client, struct sockaddr_in server, int port, char* addr)
 {
        memset((char *)&server,0,sizeof(server));
        struct in_addr addy;
@@ -1519,6 +1522,7 @@ bool BindSocket (int sockfd, struct sockaddr_in client, struct sockaddr_in serve
                }
                else
                {
+                       NonBlocking(sockfd);
                        return true;
                }
        }
@@ -1548,13 +1552,77 @@ int OpenTCPSocket()
        }
 }
 
-int BindPorts()
+bool HasPort(int port, char* addr)
+{
+       for (int count = 0; count < ServerInstance->stats->BoundPortCount; count++)
+       {
+               if ((port == Config->ports[count]) && (!strcasecmp(Config->addrs[count],addr)))
+               {
+                       return true;
+               }
+       }
+       return false;
+}
+
+int BindPorts(bool bail)
 {
        char configToken[MAXBUF], Addr[MAXBUF], Type[MAXBUF];
        sockaddr_in client,server;
        int clientportcount = 0;
        int BoundPortCount = 0;
 
+       if (!bail)
+       {
+               int InitialPortCount = ServerInstance->stats->BoundPortCount;
+               log(DEBUG,"Initial port count: %d",InitialPortCount);
+
+               for (int count = 0; count < Config->ConfValueEnum("bind",&Config->config_f); count++)
+               {
+                       Config->ConfValue("bind","port",count,configToken,&Config->config_f);
+                       Config->ConfValue("bind","address",count,Addr,&Config->config_f);
+                       Config->ConfValue("bind","type",count,Type,&Config->config_f);
+                       if (((!*Type) || (!strcmp(Type,"clients"))) && (!HasPort(atoi(configToken),Addr)))
+                       {
+                               // modules handle server bind types now
+                               Config->ports[clientportcount+InitialPortCount] = atoi(configToken);
+                               if (*Addr == '*')
+                                       *Addr = 0;
+
+                               strlcpy(Config->addrs[clientportcount+InitialPortCount],Addr,256);
+                               clientportcount++;
+                               log(DEBUG,"NEW binding %s:%s [%s] from config",Addr,configToken, Type);
+                       }
+               }
+               int PortCount = clientportcount;
+               if (PortCount)
+               {
+                       for (int count = InitialPortCount; count < InitialPortCount + PortCount; count++)
+                       {
+                               if ((openSockfd[count] = OpenTCPSocket()) == ERROR)
+                               {
+                                       log(DEBUG,"Bad fd %d binding port [%s:%d]",openSockfd[count],Config->addrs[count],Config->ports[count]);
+                                       return ERROR;
+                               }
+                               if (!BindSocket(openSockfd[count],client,server,Config->ports[count],Config->addrs[count]))
+                               {
+                                       log(DEFAULT,"Failed to bind port [%s:%d]: %s",Config->addrs[count],Config->ports[count],strerror(errno));
+                               }
+                               else
+                               {
+                                       /* Associate the new open port with a slot in the socket engine */
+                                       ServerInstance->SE->AddFd(openSockfd[count],true,X_LISTEN);
+                                       BoundPortCount++;
+                               }
+                       }
+                       return InitialPortCount + BoundPortCount;
+               }
+               else
+               {
+                       log(DEBUG,"There is nothing new to bind!");
+               }
+               return InitialPortCount;
+       }
+
        for (int count = 0; count < Config->ConfValueEnum("bind",&Config->config_f); count++)
        {
                Config->ConfValue("bind","port",count,configToken,&Config->config_f);
@@ -1575,7 +1643,7 @@ int BindPorts()
 
                        strlcpy(Config->addrs[clientportcount],Addr,256);
                        clientportcount++;
-                       log(DEBUG,"InspIRCd: startup: read binding %s:%s [%s] from config",Addr,configToken, Type);
+                       log(DEBUG,"Binding %s:%s [%s] from config",Addr,configToken, Type);
                }
        }
 
@@ -1585,13 +1653,13 @@ int BindPorts()
        {
                if ((openSockfd[BoundPortCount] = OpenTCPSocket()) == ERROR)
                {
-                       log(DEBUG,"InspIRCd: startup: bad fd %lu binding port [%s:%d]",(unsigned long)openSockfd[BoundPortCount],Config->addrs[count],(unsigned long)Config->ports[count]);
-                       return(ERROR);
+                       log(DEBUG,"Bad fd %d binding port [%s:%d]",openSockfd[BoundPortCount],Config->addrs[count],Config->ports[count]);
+                       return ERROR;
                }
 
                if (!BindSocket(openSockfd[BoundPortCount],client,server,Config->ports[count],Config->addrs[count]))
                {
-                       log(DEFAULT,"InspIRCd: startup: failed to bind port [%s:%lu]: %s",Config->addrs[count],(unsigned long)Config->ports[count],strerror(errno));
+                       log(DEFAULT,"Failed to bind port [%s:%d]: %s",Config->addrs[count],Config->ports[count],strerror(errno));
                }
                else
                {
@@ -1603,11 +1671,10 @@ int BindPorts()
        /* if we didn't bind to anything then abort */
        if (!BoundPortCount)
        {
-               log(DEFAULT,"InspIRCd: startup: no ports bound, bailing!");
-               printf("\nERROR: Was not able to bind any of %lu ports! Please check your configuration.\n\n", (unsigned long)PortCount);
-               return (ERROR);
+               log(DEFAULT,"No ports bound, bailing!");
+               printf("\nERROR: Could not bind any of %d ports! Please check your configuration.\n\n", PortCount);
+               return ERROR;
        }
 
        return BoundPortCount;
 }
-