]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/inspircd.cpp
Cache channel max bans value to save an O(n) loop of match() on every ban (etc) add
[user/henk/code/inspircd.git] / src / inspircd.cpp
index c8be0d019a3c8f8bcf3733d96456611432850f69..b75a91715c8ffeb613f4ab17d8b97d960402565e 100644 (file)
@@ -17,6 +17,7 @@
 #include <dirent.h>
 #include <exception>
 #include <fstream>
+#include <unistd.h>
 #include "modules.h"
 #include "mode.h"
 #include "xline.h"
@@ -27,6 +28,8 @@
 #include "command_parse.h"
 #include "exitcodes.h"
 #include <dlfcn.h>
+#include <getopt.h>
+
 
 using irc::sockets::NonBlocking;
 using irc::sockets::Blocking;
@@ -78,8 +81,12 @@ void InspIRCd::Cleanup()
        int MyModCount = this->GetModuleCount();
 
        for (unsigned int i = 0; i < stats->BoundPortCount; i++)
+       {
                /* This calls the constructor and closes the listening socket */
                delete Config->openSockfd[i];
+               Config->openSockfd[i] = NULL;
+       }
+       stats->BoundPortCount = 0;
 
        /* We do this more than once, so that any service providers get a
         * chance to be unhooked by the modules using them, but then get
@@ -137,12 +144,22 @@ void InspIRCd::Rehash(int status)
 {
        SI->WriteOpers("Rehashing config file %s due to SIGHUP",ServerConfig::CleanFilename(CONFIG_FILE));
        SI->CloseLog();
-       SI->OpenLog(NULL,0);
+       SI->OpenLog(SI->Config->argv, SI->Config->argc);
        SI->RehashUsersAndChans();
+       FOREACH_MOD_I(SI, I_OnGarbageCollect, OnGarbageCollect());
        SI->Config->Read(false,NULL);
-       FOREACH_MOD_I(SI,I_OnRehash,OnRehash(""));
+       SI->ResetMaxBans();
+       SI->Res->Rehash();
+       FOREACH_MOD_I(SI,I_OnRehash,OnRehash(NULL,""));
+}
+
+void InspIRCd::ResetMaxBans()
+{
+       for (chan_hash::const_iterator i = chanlist->begin(); i != chanlist->end(); i++)
+               i->second->ResetMaxBans();
 }
 
+
 /** Because hash_map doesnt free its buckets when we delete items (this is a 'feature')
  * we must occasionally rehash the hash (yes really).
  * We do this by copying the entries from the old hash to a new hash, causing all
@@ -258,10 +275,14 @@ InspIRCd::InspIRCd(int argc, char** argv)
 {
        int found_ports = 0;
        FailedPortList pl;
+       int do_nofork = 0, do_debug = 0, do_nolog = 0;    /* flag variables */
+       char c = 0;
 
        modules.resize(255);
        factory.resize(255);
 
+       this->unregistered_count = 0;
+
        this->clientlist = new user_hash();
        this->chanlist = new chan_hash();
 
@@ -278,7 +299,7 @@ InspIRCd::InspIRCd(int argc, char** argv)
        this->time_delta = 0;
        this->next_call = this->TIME + 3;
        srand(this->TIME);
-       this->Log(DEBUG,"*** InspIRCd starting up!");
+
        if (!ServerConfig::FileExists(CONFIG_FILE))
        {
                printf("ERROR: Cannot open config file: %s\nExiting...\n",CONFIG_FILE);
@@ -286,54 +307,49 @@ InspIRCd::InspIRCd(int argc, char** argv)
                printf("ERROR: Your config file is missing, this IRCd will self destruct in 10 seconds!\n");
                Exit(EXIT_STATUS_CONFIG);
        }
+
        *this->LogFileName = 0;
-       if (argc > 1) {
-               for (int i = 1; i < argc; i++)
+
+       struct option longopts[] =
+       {
+               { "nofork",     no_argument,            &do_nofork,     1       },
+               { "logfile",    required_argument,      NULL,           'f'     },
+               { "debug",      no_argument,            &do_debug,      1       },
+               { "nolog",      no_argument,            &do_nolog,      1       },
+               { 0, 0, 0, 0 }
+       };
+
+       while ((c = getopt_long_only(argc, argv, ":f:", longopts, NULL)) != -1)
+       {
+               switch (c)
                {
-                       if (!strcmp(argv[i],"-nofork"))
-                       {
-                               Config->nofork = true;
-                       }
-                       else if(!strcmp(argv[i],"-debug"))
-                       {
-                               Config->forcedebug = true;
-                       }
-                       else if(!strcmp(argv[i],"-nolog"))
-                       {
-                               Config->writelog = false;
-                       }
-                       else if (!strcmp(argv[i],"-wait"))
-                       {
-                               sleep(6);
-                       }
-                       else if (!strcmp(argv[i],"-logfile"))
-                       {
-                               if (argc > i+1)
-                               {
-                                       strlcpy(LogFileName,argv[i+1],MAXBUF);
-                                       printf("LOG: Setting logfile to %s\n",LogFileName);
-                               }
-                               else
-                               {
-                                       printf("ERROR: The -logfile parameter must be followed by a log file name and path.\n");
-                                       Exit(EXIT_STATUS_CONFIG);
-                               }
-                               i++;
-                       }
-                       else
-                       {
-                               printf("Usage: %s [-nofork] [-nolog] [-debug] [-wait] [-logfile <filename>]\n",argv[0]);
+                       case 'f':
+                               /* Log filename was set */
+                               strlcpy(LogFileName, optarg, MAXBUF);
+                               printf("LOG: Setting logfile to %s\n", LogFileName);
+                       break;
+                       case 0:
+                               /* getopt_long_only() set an int variable, just keep going */
+                       break;
+                       default:
+                               /* Unknown parameter! DANGER, INTRUDER.... err.... yeah. */
+                               printf("Usage: %s [--nofork] [--nolog] [--debug] [--logfile <filename>]\n", argv[0]);
                                Exit(EXIT_STATUS_ARGV);
-                       }
+                       break;
                }
        }
 
+       /* Set the finished argument values */
+       Config->nofork = do_nofork;
+       Config->forcedebug = do_debug;
+       Config->writelog = !do_nolog;
+
        strlcpy(Config->MyExecutable,argv[0],MAXBUF);
 
        this->OpenLog(argv, argc);
        this->stats = new serverstats();
-       this->Parser = new CommandParser(this);
        this->Timers = new TimerManager();
+       this->Parser = new CommandParser(this);
        this->XLines = new XLineManager(this);
        Config->ClearStack();
        Config->Read(true, NULL);
@@ -813,7 +829,8 @@ void InspIRCd::DoOneIteration(bool process_module_sockets)
                        WriteOpers("*** \002EH?!\002 -- Time is flowing BACKWARDS in this dimension! Clock drifted backwards %d secs.",abs(OLDTIME-TIME));
                if ((TIME % 3600) == 0)
                {
-                       irc::whowas::MaintainWhoWas(this, TIME);
+                       this->RehashUsersAndChans();
+                       FOREACH_MOD_I(this, I_OnGarbageCollect, OnGarbageCollect());
                }
                Timers->TickTimers(TIME);
                this->DoBackgroundUserStuff(TIME);
@@ -959,7 +976,8 @@ bool FileLogger::Readable()
 void FileLogger::HandleEvent(EventType et, int errornum)
 {
        this->WriteLogLine("");
-       ServerInstance->SE->DelFd(this);
+       if (log)
+               ServerInstance->SE->DelFd(this);
 }
 
 void FileLogger::WriteLogLine(const std::string &line)
@@ -1000,18 +1018,24 @@ void FileLogger::Close()
                fcntl(fileno(log), F_SETFL, flags ^ O_NONBLOCK);
                if (buffer.size())
                        fprintf(log,"%s",buffer.c_str());
+
+               ServerInstance->SE->DelFd(this);
+
                fflush(log);
                fclose(log);
        }
+
        buffer = "";
-       ServerInstance->SE->DelFd(this);
 }
 
 FileLogger::FileLogger(InspIRCd* Instance, FILE* logfile) : ServerInstance(Instance), log(logfile), writeops(0)
 {
-       irc::sockets::NonBlocking(fileno(log));
-       this->SetFd(fileno(log));
-       buffer = "";
+       if (log)
+       {
+               irc::sockets::NonBlocking(fileno(log));
+               this->SetFd(fileno(log));
+               buffer = "";
+       }
 }
 
 FileLogger::~FileLogger()