]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/inspircd_io.cpp
EXPERIMENTAL new socket engine code
[user/henk/code/inspircd.git] / src / inspircd_io.cpp
index 03596b4bc055698abba9e9e2e3696fda39a28496..4a83abc223672b28549e9f874992fef0b53fa31a 100644 (file)
@@ -14,6 +14,9 @@
  * ---------------------------------------------------
  */
 
+using namespace std;
+
+#include "inspircd_config.h"
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <sys/types.h>
 #include "inspircd_io.h"
 #include "inspircd_util.h"
 #include "inspstring.h"
-
-using namespace std;
+#include "helperfuncs.h"
 
 extern FILE *log_file;
 extern int boundPortCount;
 extern int openSockfd[MAXSOCKS];
 extern time_t TIME;
 extern bool unlimitcore;
+extern int MaxConn;
+std::vector<std::string> include_stack;
 
 void WriteOpers(char* text, ...);
 
@@ -63,12 +67,12 @@ void Rehash(int status)
 
 void Start (void)
 {
-       printf("\033[1mInspire Internet Relay Chat Server, compiled " __DATE__ " at " __TIME__ "\n");
-       printf("(C) ChatSpike Development team.\033[0;37m\n\n");
-       printf("Developers:\033[1m     Brain, FrostyCoolSlug\n");
-       printf("Documentation:\033[1m  FrostyCoolSlug, w00t\n");
-       printf("Testers:\033[1m        typobox43, piggles, Lord_Zathras, CC\n");
-       printf("Name concept:\033[1m   Lord_Zathras\n\n");
+       printf("\033[1;32mInspire Internet Relay Chat Server, compiled %s at %s\n",__DATE__,__TIME__);
+       printf("(C) ChatSpike Development team.\033[0m\n\n");
+       printf("Developers:\033[1;32m     Brain, FrostyCoolSlug\033[0m\n");
+       printf("Documentation:\033[1;32m  FrostyCoolSlug, w00t\033[0m\n");
+       printf("Testers:\033[1;32m        typobox43, piggles, Lord_Zathras, CC\033[0m\n");
+       printf("Name concept:\033[1;32m   Lord_Zathras\033[0m\n\n");
 }
 
 void WritePID(std::string filename)
@@ -87,34 +91,26 @@ void WritePID(std::string filename)
        }
 }
 
-void DeadPipe(int status)
-{
-  signal (SIGPIPE, DeadPipe);
-}
 
 int DaemonSeed (void)
 {
        int childpid;
        signal (SIGALRM, SIG_IGN);
        signal (SIGHUP, Rehash);
-       signal (SIGPIPE, DeadPipe);
+       signal (SIGPIPE, SIG_IGN);
        signal (SIGTERM, Exit);
-       signal (SIGABRT, Exit);
        signal (SIGSEGV, Error);
-       signal (SIGURG, Exit);
-       signal (SIGKILL, Exit);
        if ((childpid = fork ()) < 0)
                return (ERROR);
        else if (childpid > 0)
                exit (0);
        setsid ();
        umask (007);
-       printf("InspIRCd PID: %d\n",getpid());
-       /* close stdin, stdout, stderr */
+       printf("InspIRCd Process ID: \033[1;32m%lu\033[0m\n",(unsigned long)getpid());
        freopen("/dev/null","w",stdout);
        freopen("/dev/null","w",stderr);
        
-       setpriority(PRIO_PROCESS,(int)getpid(),15); /* ircd sets to low process priority so it doesnt hog the box */
+       setpriority(PRIO_PROCESS,(int)getpid(),15);
 
        if (unlimitcore)
        {
@@ -183,17 +179,17 @@ std::string ConfProcess(char* buffer, long linenumber, std::stringstream* errors
                return "";
        }
        // firstly clean up the line by stripping spaces from the start and end and converting tabs to spaces
-       for (int d = 0; d < strlen(buffer); d++)
+       for (unsigned int d = 0; d < strlen(buffer); d++)
                if ((buffer[d]) == 9)
                        buffer[d] = ' ';
        while ((buffer[0] == ' ') && (strlen(buffer)>0)) buffer++;
        while ((buffer[strlen(buffer)-1] == ' ') && (strlen(buffer)>0)) buffer[strlen(buffer)-1] = '\0';
-       // empty lines are syntactically valid
-       if (!strcmp(buffer,""))
-               return "";
-       else if (buffer[0] == '#')
+
+       // empty lines are syntactically valid, as are comments
+       if (!(*buffer) || buffer[0] == '#')
                return "";
-       for (int c = 0; c < strlen(buffer); c++)
+
+       for (unsigned int c = 0; c < strlen(buffer); c++)
        {
                // convert all spaces that are OUTSIDE quotes into hardspace (0xA0) as this will make them easier to
                // search and replace later :)
@@ -280,7 +276,7 @@ std::string ConfProcess(char* buffer, long linenumber, std::stringstream* errors
        }
 
        // turn our hardspace back into softspace
-       for (int d = 0; d < parsedata.length(); d++)
+       for (unsigned int d = 0; d < parsedata.length(); d++)
        {
                if (parsedata[d] == '\xA0')
                        parsedata[d] = ' ';
@@ -290,6 +286,20 @@ std::string ConfProcess(char* buffer, long linenumber, std::stringstream* errors
        return parsedata;
 }
 
+int fgets_safe(char* buffer, size_t maxsize, FILE* &file)
+{
+       char c_read = '\0';
+       unsigned int bufptr = 0;
+       while ((!feof(file)) && (c_read != '\n') && (c_read != '\r') && (bufptr < maxsize))
+       {
+               c_read = fgetc(file);
+               if ((c_read != '\n') && (c_read != '\r'))
+                       buffer[bufptr++] = c_read;
+       }
+       buffer[bufptr] = '\0';
+       return bufptr;
+}
+
 bool LoadConf(const char* filename, std::stringstream *target, std::stringstream* errorstream)
 {
        target->str("");
@@ -303,6 +313,15 @@ bool LoadConf(const char* filename, std::stringstream *target, std::stringstream
        }
        // Fix the chmod of the file to restrict it to the current user and group
        chmod(filename,0600);
+       for (unsigned int t = 0; t < include_stack.size(); t++)
+       {
+               if (std::string(filename) == include_stack[t])
+               {
+                       *errorstream << "File " << filename << " is included recursively (looped inclusion)." << endl;
+                       return false;
+               }
+       }
+       include_stack.push_back(filename);
        // now open it
        FILE* conf = fopen(filename,"r");
        char buffer[MAXBUF];
@@ -310,19 +329,66 @@ bool LoadConf(const char* filename, std::stringstream *target, std::stringstream
        {
                while (!feof(conf))
                {
-                       if (fgets(buffer, MAXBUF, conf))
+                       if (fgets_safe(buffer, MAXBUF, conf))
                        {
                                if ((!feof(conf)) && (buffer) && (strlen(buffer)))
                                {
                                        if ((buffer[0] != '#') && (buffer[0] != '\r')  && (buffer[0] != '\n'))
                                        {
-                                               bool error = false;
-                                               std::string data = ConfProcess(buffer,linenumber++,errorstream,error,filename);
-                                               if (error)
+                                               if (!strncmp(buffer,"<include file=\"",15))
+                                               {
+                                                       char* buf = buffer;
+                                                       char confpath[10240],newconf[10240];
+                                                       // include file directive
+                                                       buf += 15;      // advance to filename
+                                                       for (unsigned int j = 0; j < strlen(buf); j++)
+                                                       {
+                                                               if (buf[j] == '\\')
+                                                                       buf[j] = '/';
+                                                               if (buf[j] == '"')
+                                                               {
+                                                                       buf[j] = '\0';
+                                                                       break;
+                                                               }
+                                                       }
+                                                       log(DEFAULT,"Opening included file '%s'",buf);
+                                                       if (*buf != '/')
+                                                       {
+                                                               strlcpy(confpath,CONFIG_FILE,10240);
+                                                               if (strstr(confpath,"/inspircd.conf"))
+                                                               {
+                                                                       // leaves us with just the path
+                                                                       *(strstr(confpath,"/inspircd.conf")) = '\0';
+                                                               }
+                                                               snprintf(newconf,10240,"%s/%s",confpath,buf);
+                                                       }
+                                                       else snprintf(newconf,10240,"%s",buf);
+                                                       std::stringstream merge(stringstream::in | stringstream::out);
+                                                       // recursively call LoadConf and get the new data, use the same errorstream
+                                                       if (LoadConf(newconf, &merge, errorstream))
+                                                       {
+                                                               // append to the end of the file
+                                                               std::string newstuff = merge.str();
+                                                               *target << newstuff;
+                                                       }
+                                                       else
+                                                       {
+                                                               // the error propogates up to its parent recursively
+                                                               // causing the config reader to bail at the top level.
+                                                               fclose(conf);
+                                                               return false;
+                                                       }
+                                               }
+                                               else
                                                {
-                                                       return false;
+                                                       bool error = false;
+                                                       std::string data = ConfProcess(buffer,linenumber++,errorstream,error,filename);
+                                                       if (error)
+                                                       {
+                                                               return false;
+                                                       }
+                                                       *target << data;
                                                }
-                                               *target << data;
                                        }
                                        else linenumber++;
                                }
@@ -508,12 +574,12 @@ int ReadConf(std::stringstream *config, const char* tag, const char* var, int in
 {
        int ptr = 0;
        char buffer[65535], c_tag[MAXBUF], c, lastc;
-       int in_token, in_quotes, tptr, j, idx = 0;
+       int in_token, in_quotes, tptr, idx = 0;
        char* key;
 
        const char* buf = config->str().c_str();
        long bptr = 0;
-       long len = strlen(buf);
+       long len = config->str().length();
        
        ptr = 0;
        in_token = 0;
@@ -576,7 +642,7 @@ int ReadConf(std::stringstream *config, const char* tag, const char* var, int in
                                                                key++;
                                                        }
                                                        key++;
-                                                       for (j = 0; j < strlen(key); j++)
+                                                       for (unsigned j = 0; j < strlen(key); j++)
                                                        {
                                                                if (key[j] == '"')
                                                                {
@@ -625,7 +691,7 @@ int ConfValue(char* tag, char* var, int index, char *result,std::stringstream *c
 // This will bind a socket to a port. It works for UDP/TCP
 int BindSocket (int sockfd, struct sockaddr_in client, struct sockaddr_in server, int port, char* addr)
 {
-       bzero((char *)&server,sizeof(server));
+       memset((char *)&server,0,sizeof(server));
        struct in_addr addy;
        inet_aton(addr,&addy);
        server.sin_family = AF_INET;
@@ -644,7 +710,7 @@ int BindSocket (int sockfd, struct sockaddr_in client, struct sockaddr_in server
        }
        else
        {
-               listen(sockfd,5);
+               listen(sockfd, MaxConn);
                return(TRUE);
        }
 }
@@ -669,4 +735,3 @@ int OpenTCPSocket (void)
                return (sockfd);
        }
 }
-