]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/inspircd.cpp
Change cmd_*.so to use the Module object API
[user/henk/code/inspircd.git] / src / inspircd.cpp
index a921db193514338a9a0bdb31adefe6680f2d4f98..810c477f8e8ab721d6fc96c895674a87efdf8dbf 100644 (file)
@@ -3,7 +3,7 @@
  *       +------------------------------------+
  *
  *  InspIRCd: (C) 2002-2009 InspIRCd Development Team
- * See: http://www.inspircd.org/wiki/index.php/Credits
+ * See: http://wiki.inspircd.org/Credits
  *
  * This program is free but copyrighted software; see
  *         the file COPYING for details.
@@ -11,8 +11,9 @@
  * ---------------------------------------------------
  */
 
-/* $Install: src/inspircd $(BINPATH) */
+/* $Core */
 #include "inspircd.h"
+#include "inspircd_version.h"
 #include <signal.h>
 
 #ifndef WIN32
@@ -81,7 +82,7 @@ const char* ExitCodes[] =
                "CreateEvent failed" /* 19 */
 };
 
-template<typename T> static void DeleteZero(T* n)
+template<typename T> static void DeleteZero(T*&n)
 {
        if (n != NULL)
        {
@@ -94,13 +95,13 @@ void InspIRCd::Cleanup()
 {
        if (Config)
        {
-               for (unsigned int i = 0; i < Config->ports.size(); i++)
+               for (unsigned int i = 0; i < ports.size(); i++)
                {
                        /* This calls the constructor and closes the listening socket */
-                       delete Config->ports[i];
+                       delete ports[i];
                }
 
-               Config->ports.clear();
+               ports.clear();
        }
 
        /* Close all client sockets, or the new process inherits them */
@@ -125,8 +126,6 @@ void InspIRCd::Cleanup()
                        this->Modules->Unload(k->c_str());
                }
        }
-       /* Remove core commands */
-       Parser->RemoveCommands("<core>");
 
        /* Cleanup Server Names */
        for(servernamelist::iterator itr = servernames.begin(); itr != servernames.end(); ++itr)
@@ -134,6 +133,7 @@ void InspIRCd::Cleanup()
 
        /* Delete objects dynamically allocated in constructor (destructor would be more appropriate, but we're likely exiting) */
        /* Must be deleted before modes as it decrements modelines */
+       DeleteZero(this->FakeClient);
        DeleteZero(this->Users);
        DeleteZero(this->Modes);
        DeleteZero(this->XLines);
@@ -148,11 +148,10 @@ void InspIRCd::Cleanup()
        DeleteZero(this->PI);
        DeleteZero(this->Threads);
        DeleteZero(this->Timers);
+       DeleteZero(this->SE);
        /* Close logging */
        this->Logs->CloseLogs();
        DeleteZero(this->Logs);
-
-       delete RehashFinishMutex;
 }
 
 void InspIRCd::Restart(const std::string &reason)
@@ -316,9 +315,7 @@ void InspIRCd::WritePID(const std::string &filename)
        }
 }
 
-InspIRCd::InspIRCd(int argc, char** argv)
-       : GlobalCulls(this),
-
+InspIRCd::InspIRCd(int argc, char** argv) :
         /* Functor initialisation. Note that the ordering here is very important.
          *
          * THIS MUST MATCH ORDER OF DECLARATION OF THE HandleWhateverFunc classes
@@ -327,7 +324,6 @@ InspIRCd::InspIRCd(int argc, char** argv)
         HandleProcessUser(this),
         HandleIsNick(this),
         HandleIsIdent(this),
-        HandleFindDescriptor(this),
         HandleFloodQuitUser(this),
         HandleIsChannel(this),
         HandleIsSID(this),
@@ -344,7 +340,6 @@ InspIRCd::InspIRCd(int argc, char** argv)
         Rehash(&HandleRehash),
         IsNick(&HandleIsNick),
         IsIdent(&HandleIsIdent),
-        FindDescriptor(&HandleFindDescriptor),
         FloodQuitUser(&HandleFloodQuitUser)
 
 {
@@ -355,11 +350,10 @@ InspIRCd::InspIRCd(int argc, char** argv)
        // Avoid erroneous frees on early exit
        WindowsIPC = 0;
 #endif
-       int found_ports = 0;
        FailedPortList pl;
        int do_version = 0, do_nofork = 0, do_debug = 0,
            do_nolog = 0, do_root = 0, do_testsuite = 0;    /* flag variables */
-       char c = 0;
+       int c = 0;
 
        // Initialize so that if we exit before proper initialization they're not deleted
        this->Logs = 0;
@@ -377,13 +371,11 @@ InspIRCd::InspIRCd(int argc, char** argv)
        this->XLines = 0;
        this->Modes = 0;
        this->Res = 0;
+       this->ConfigThread = NULL;
 
        // Initialise TIME
        this->TIME = time(NULL);
 
-       memset(&server, 0, sizeof(server));
-       memset(&client, 0, sizeof(client));
-
        // This must be created first, so other parts of Insp can use it while starting up
        this->Logs = new LogManager(this);
 
@@ -391,10 +383,7 @@ InspIRCd::InspIRCd(int argc, char** argv)
        SE = SEF->Create(this);
        delete SEF;
 
-       ThreadEngineFactory* tef = new ThreadEngineFactory();
-       this->Threads = tef->Create(this);
-       delete tef;
-       this->Mutexes = new MutexFactory(this);
+       this->Threads = new ThreadEngine(this);
 
        /* Default implementation does nothing */
        this->PI = new ProtocolInterface(this);
@@ -450,7 +439,8 @@ InspIRCd::InspIRCd(int argc, char** argv)
                { 0, 0, 0, 0 }
        };
 
-       while ((c = getopt_long_only(argc, argv, ":f:", longopts, NULL)) != -1)
+       int index;
+       while ((c = getopt_long_only(argc, argv, ":f:", longopts, &index)) != -1)
        {
                switch (c)
                {
@@ -465,10 +455,12 @@ InspIRCd::InspIRCd(int argc, char** argv)
                        case 0:
                                /* getopt_long_only() set an int variable, just keep going */
                        break;
+                       case '?':
+                               /* Unknown parameter */
                        default:
-                               /* Unknown parameter! DANGER, INTRUDER.... err.... yeah. */
-                               printf("Usage: %s [--nofork] [--nolog] [--debug] [--logfile <filename>]\n\
-                                                 [--runasroot] [--version] [--config <config>] [--testsuite]\n", argv[0]);
+                               /* Fall through to handle other weird values too */
+                               printf("Unknown parameter '%s'\n", argv[optind-1]);
+                               printf("Usage: %s [--nofork] [--nolog] [--debug] [--logfile <filename>]\n%*s[--runasroot] [--version] [--config <config>] [--testsuite]\n", argv[0], static_cast<int>(8+strlen(argv[0])), " ");
                                Exit(EXIT_STATUS_ARGV);
                        break;
                }
@@ -498,7 +490,7 @@ InspIRCd::InspIRCd(int argc, char** argv)
        WSAStartup(MAKEWORD(2,0), &wsadata);
        ChangeWindowsSpecificPointers(this);
 #endif
-       strlcpy(Config->MyExecutable,argv[0],MAXBUF);
+       Config->MyExecutable = argv[0];
 
        /* Set the finished argument values */
        Config->nofork = do_nofork;
@@ -539,8 +531,6 @@ InspIRCd::InspIRCd(int argc, char** argv)
        printf_c("\t\033[1;32mpeavey, aquanight, psychon, dz, danieldg\033[0m\n\n");
        printf_c("Others:\t\t\t\033[1;32mSee /INFO Output\033[0m\n");
 
-       Config->ClearStack();
-
        this->Modes = new ModeParser(this);
 
        if (!do_root)
@@ -575,16 +565,10 @@ InspIRCd::InspIRCd(int argc, char** argv)
        /* During startup we don't actually initialize this
         * in the thread engine.
         */
-       this->ConfigThread = new ConfigReaderThread(this, true, "");
-       ConfigThread->Run();
-       delete ConfigThread;
-       this->ConfigThread = NULL;
-        /* Switch over logfiles */
+       this->Config->Read();
+       this->Config->Apply(NULL, "");
        Logs->OpenFileLogs();
 
-       /** Note: This is safe, the method checks for user == NULL */
-       this->Parser->SetupCommandTable();
-
        this->Res = new DNS(this);
 
        this->AddServerName(Config->ServerName);
@@ -612,15 +596,14 @@ InspIRCd::InspIRCd(int argc, char** argv)
        }
 
        /* set up fake client again this time with the correct uid */
-       this->FakeClient = new User(this, "#INVALID");
-       this->FakeClient->SetFd(FD_MAGIC_NUMBER);
+       this->FakeClient = new FakeUser(this, "!");
+       this->FakeClient->SetFakeServer(Config->ServerName);
 
        // Get XLine to do it's thing.
        this->XLines->CheckELines();
        this->XLines->ApplyLines();
 
-       CheckDie();
-       int bounditems = BindPorts(true, found_ports, pl);
+       int bounditems = BindPorts(pl);
 
        printf("\n");
 
@@ -628,11 +611,12 @@ InspIRCd::InspIRCd(int argc, char** argv)
 
        /* Just in case no modules were loaded - fix for bug #101 */
        this->BuildISupport();
-       InitializeDisabledCommands(Config->DisabledCommands, this);
+       Config->ApplyDisabledCommands(Config->DisabledCommands);
 
-       if (Config->ports.size() != (unsigned int)found_ports)
+       if (!pl.empty())
        {
-               printf("\nWARNING: Not all your client ports could be bound --\nstarting anyway with %d of %d client ports bound.\n\n", bounditems, found_ports);
+               printf("\nWARNING: Not all your client ports could be bound --\nstarting anyway with %d of %d client ports bound.\n\n",
+                       bounditems, bounditems + (int)pl.size());
                printf("The following port(s) failed to bind:\n");
                printf("Hint: Try using a public IP instead of blank or *\n\n");
                int j = 1;
@@ -756,8 +740,6 @@ int InspIRCd::Run()
                Exit(0);
        }
 
-       RehashFinishMutex = Mutexes->CreateMutex();
-
        while (true)
        {
 #ifndef WIN32
@@ -769,43 +751,17 @@ int InspIRCd::Run()
 #endif
 
                /* Check if there is a config thread which has finished executing but has not yet been freed */
-               RehashFinishMutex->Lock();
-               if (this->ConfigThread && this->ConfigThread->GetExitFlag())
+               if (this->ConfigThread && this->ConfigThread->IsDone())
                {
                        /* Rehash has completed */
-
-                       /* Switch over logfiles */
-                       Logs->CloseLogs();
-                       Logs->OpenFileLogs();
-
                        this->Logs->Log("CONFIG",DEBUG,"Detected ConfigThread exiting, tidying up...");
 
-                       /* These are currently not known to be threadsafe, so they are executed outside
-                        * of the thread. It would be pretty simple to move them to the thread Run method
-                        * once they are known threadsafe with all the correct mutexes in place. This might
-                        * not be worth the effort however as these functions execute relatively quickly
-                        * and would not benefit from being within the config read thread.
-                        *
-                        * XXX: The order of these is IMPORTANT, do not reorder them without testing
-                        * thoroughly!!!
-                        */
-                       this->XLines->CheckELines();
-                       this->XLines->ApplyLines();
-                       this->Res->Rehash();
-                       this->ResetMaxBans();
-                       InitializeDisabledCommands(Config->DisabledCommands, this);
-                       User* user = !Config->RehashUserUID.empty() ? FindNick(Config->RehashUserUID) : NULL;
-                       FOREACH_MOD_I(this, I_OnRehash, OnRehash(user, Config->RehashParameter));
-                       this->BuildISupport();
-
-                       /* IMPORTANT: This delete may hang if you fuck up your thread syncronization.
-                        * It will hang waiting for the ConfigThread to 'join' to avoid race conditons,
-                        * until the other thread is completed.
-                        */
+                       this->ConfigThread->Finish();
+
+                       ConfigThread->join();
                        delete ConfigThread;
                        ConfigThread = NULL;
                }
-               RehashFinishMutex->Unlock();
 
                /* time() seems to be a pretty expensive syscall, so avoid calling it too much.
                 * Once per loop iteration is pleanty.
@@ -905,12 +861,9 @@ void InspIRCd::BufferedSocketCull()
  */
 bool InspIRCd::AllModulesReportReady(User* user)
 {
-       for (EventHandlerIter i = Modules->EventHandlers[I_OnCheckReady].begin(); i != Modules->EventHandlers[I_OnCheckReady].end(); ++i)
-       {
-               if (!(*i)->OnCheckReady(user))
-                       return false;
-       }
-       return true;
+       ModResult res;
+       FIRST_MOD_RESULT(this, OnCheckReady, res, (user));
+       return (res == MOD_RES_PASSTHRU);
 }
 
 time_t InspIRCd::Time()