]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/inspircd.cpp
Duplicate the stdout file handle when used for logging.
[user/henk/code/inspircd.git] / src / inspircd.cpp
index 2035960bd5bda1e6573df873590bb6762cbc5132..8cbb83d6fcab2b561de23cd41aacd34a10bda47a 100644 (file)
@@ -1,16 +1,21 @@
 /*
  * InspIRCd -- Internet Relay Chat Daemon
  *
+ *   Copyright (C) 2020 Matt Schatz <genius3000@g3k.solutions>
+ *   Copyright (C) 2018 Chris Novakovic <chrisnovakovic@users.noreply.github.com>
+ *   Copyright (C) 2013, 2017-2020 Sadie Powell <sadie@witchery.services>
+ *   Copyright (C) 2013 Adam <Adam@anope.org>
+ *   Copyright (C) 2012-2014, 2016, 2018 Attila Molnar <attilamolnar@hush.com>
  *   Copyright (C) 2012 William Pitcock <nenolod@dereferenced.org>
+ *   Copyright (C) 2012 Robby <robby@chatbelgie.be>
+ *   Copyright (C) 2012 ChrisTX <xpipe@hotmail.de>
  *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
- *   Copyright (C) 2003-2008 Craig Edwards <craigedwards@brainbox.cc>
- *   Copyright (C) 2008 Uli Schlachter <psychon@znc.in>
- *   Copyright (C) 2006-2008 Robin Burchell <robin+git@viroteck.net>
- *   Copyright (C) 2006-2007 Oliver Lupton <oliverlupton@gmail.com>
+ *   Copyright (C) 2009 Uli Schlachter <psychon@inspircd.org>
+ *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
+ *   Copyright (C) 2007-2008, 2010 Craig Edwards <brain@inspircd.org>
+ *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
+ *   Copyright (C) 2007 Oliver Lupton <om@inspircd.org>
  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
- *   Copyright (C) 2007 Burlex <???@???>
- *   Copyright (C) 2003 Craig McLure <craig@chatspike.net>
- *   Copyright (C) 2003 randomdan <???@???>
  *
  * This file is part of InspIRCd.  InspIRCd is free software: you can
  * redistribute it and/or modify it under the terms of the GNU General Public
@@ -32,7 +37,6 @@
 #ifndef _WIN32
        #include <unistd.h>
        #include <sys/resource.h>
-       #include <dlfcn.h>
        #include <getopt.h>
        #include <pwd.h> // setuid
        #include <grp.h> // setgid
@@ -49,7 +53,7 @@
 
 InspIRCd* ServerInstance = NULL;
 
-/** Seperate from the other casemap tables so that code *can* still exclusively rely on RFC casemapping
+/** Separate from the other casemap tables so that code *can* still exclusively rely on RFC casemapping
  * if it must.
  *
  * This is provided as a pointer so that modules can change it to their custom mapping tables,
@@ -132,13 +136,19 @@ namespace
 #endif
        }
 
-       // Deletes a pointer and then zeroes it.
-       template<typename T>
-       void DeleteZero(T*& pr)
+       // Checks whether the server clock has skipped too much and warn about it if it has.
+       void CheckTimeSkip(time_t oldtime, time_t newtime)
        {
-               T* p = pr;
-               pr = NULL;
-               delete p;
+               if (!ServerInstance->Config->TimeSkipWarn)
+                       return;
+
+               time_t timediff = newtime - oldtime;
+
+               if (timediff > ServerInstance->Config->TimeSkipWarn)
+                       ServerInstance->SNO->WriteToSnoMask('a', "\002Performance warning!\002 Server clock jumped forwards by %lu seconds!", timediff);
+
+               else if (timediff < -ServerInstance->Config->TimeSkipWarn)
+                       ServerInstance->SNO->WriteToSnoMask('a', "\002Performance warning!\002 Server clock jumped backwards by %lu seconds!", labs(timediff));
        }
 
        // Drops to the unprivileged user/group specified in <security:runas{user,group}>.
@@ -312,7 +322,7 @@ namespace
 
                                default:
                                        // An unknown option was specified.
-                                       std::cout << con_red << "Error:" <<  con_reset << " unknown option '" << argv[optind - 1] << "'." << std::endl
+                                       std::cout << con_red << "Error:" <<  con_reset << " unknown option '" << argv[optind] << "'." << std::endl
                                                << con_bright << "Usage: " << con_reset << argv[0] << " [--config <file>] [--debug] [--nofork] [--nolog]" << std::endl
                                                << std::string(strlen(argv[0]) + 8, ' ') << "[--nopid] [--runasroot] [--version]" << std::endl;
                                        ServerInstance->Exit(EXIT_STATUS_ARGV);
@@ -322,7 +332,7 @@ namespace
 
                if (do_version)
                {
-                       std::cout << std::endl << INSPIRCD_VERSION << std::endl;
+                       std::cout << INSPIRCD_VERSION << std::endl;
                        ServerInstance->Exit(EXIT_STATUS_NOERROR);
                }
 
@@ -378,7 +388,7 @@ namespace
 
                        std::cout << con_bright << "Hints:" << con_reset << std::endl
                                << "- For TCP/IP listeners try using a public IP address in <bind:address> instead" << std::endl
-                               << "  of * of leaving it blank." << std::endl
+                               << "  of * or leaving it blank." << std::endl
                                << "- For UNIX socket listeners try enabling <bind:rewrite> to replace old sockets." << std::endl;
                }
        }
@@ -419,9 +429,9 @@ void InspIRCd::Cleanup()
                delete FakeClient->server;
                FakeClient->cull();
        }
-       DeleteZero(this->FakeClient);
-       DeleteZero(this->XLines);
-       DeleteZero(this->Config);
+       stdalgo::delete_zero(this->FakeClient);
+       stdalgo::delete_zero(this->XLines);
+       stdalgo::delete_zero(this->Config);
        SocketEngine::Deinit();
        Logs->CloseLogs();
 }
@@ -435,7 +445,7 @@ void InspIRCd::WritePID(const std::string& filename, bool exitonfail)
                return;
        }
 
-       std::string fname = ServerInstance->Config->Paths.PrependData(filename.empty() ? "inspircd.pid" : filename);
+       std::string fname = ServerInstance->Config->Paths.PrependRuntime(filename.empty() ? "inspircd.pid" : filename);
        std::ofstream outfile(fname.c_str());
        if (outfile.is_open())
        {
@@ -480,6 +490,7 @@ InspIRCd::InspIRCd(int argc, char** argv)
 
        this->Config->cmdline.argv = argv;
        this->Config->cmdline.argc = argc;
+       ParseOptions();
 
 #ifdef _WIN32
        // Initialize the console values
@@ -511,10 +522,10 @@ InspIRCd::InspIRCd(int argc, char** argv)
                << "See " << con_green << "/INFO" << con_reset << " for contributors & authors" << std::endl
                << std::endl;
 
-       ParseOptions();
        if (Config->cmdline.forcedebug)
        {
-               FileWriter* fw = new FileWriter(stdout, 1);
+               FILE* newstdout = fdopen(dup(STDOUT_FILENO), "w");
+               FileWriter* fw = new FileWriter(newstdout, 1);
                FileLogStream* fls = new FileLogStream(LOG_RAWIO, fw);
                Logs->AddLogTypes("*", fls, true);
        }
@@ -535,7 +546,7 @@ InspIRCd::InspIRCd(int argc, char** argv)
        std::cout << "InspIRCd Process ID: " << con_green << getpid() << con_reset << std::endl;
 
        /* During startup we read the configuration now, not in
-        * a seperate thread
+        * a separate thread
         */
        this->Config->Read();
        this->Config->Apply(NULL, "");
@@ -556,13 +567,13 @@ InspIRCd::InspIRCd(int argc, char** argv)
 
        std::cout << std::endl;
 
+       TryBindPorts();
+
        this->Modules->LoadAll();
 
        // Build ISupport as ModuleManager::LoadAll() does not do it
        this->ISupport.Build();
 
-       TryBindPorts();
-
        std::cout << "InspIRCd is now running as '" << Config->ServerName << "'[" << Config->GetSID() << "] with " << SocketEngine::GetMaxFds() << " max open sockets" << std::endl;
 
 #ifndef _WIN32
@@ -666,24 +677,14 @@ void InspIRCd::Run()
                UpdateTime();
 
                /* Run background module timers every few seconds
-                * (the docs say modules shouldnt rely on accurate
+                * (the docs say modules should not rely on accurate
                 * timing using this event, so we dont have to
                 * time this exactly).
                 */
                if (TIME.tv_sec != OLDTIME)
                {
                        CollectStats();
-
-                       if (Config->TimeSkipWarn)
-                       {
-                               time_t timediff = TIME.tv_sec - OLDTIME;
-
-                               if (timediff > Config->TimeSkipWarn)
-                                       SNO->WriteToSnoMask('a', "\002Performance warning!\002 Server clock jumped forwards by %lu seconds!", timediff);
-
-                               else if (timediff < -Config->TimeSkipWarn)
-                                       SNO->WriteToSnoMask('a', "\002Performance warning!\002 Server clock jumped backwards by %lu seconds!", labs(timediff));
-                       }
+                       CheckTimeSkip(OLDTIME, TIME.tv_sec);
 
                        OLDTIME = TIME.tv_sec;