X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Finspircd.cpp;h=aa3fb961231739a593cc4de41798b79fb43be319;hb=58a0a7e01422e62de1565a8eb0a1febdc463d04d;hp=eb24cdea0a2b0d924e8a116f6e4bbd7639c17bd5;hpb=0b63ccd0b5cb26883d6becb196fb98e4f95d0397;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/inspircd.cpp b/src/inspircd.cpp index eb24cdea0..aa3fb9612 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -35,12 +35,6 @@ #include #include #include - - /* Some systems don't define RUSAGE_SELF. This should fix them. */ - #ifndef RUSAGE_SELF - #define RUSAGE_SELF 0 - #endif - #include // setuid #include // setgid #else @@ -138,15 +132,10 @@ void InspIRCd::SetSignals() signal(SIGTERM, InspIRCd::SetSignal); } -void InspIRCd::QuickExit(int status) -{ - exit(status); -} - // Required for returning the proper value of EXIT_SUCCESS for the parent process static void VoidSignalHandler(int signalreceived) { - exit(0); + exit(EXIT_STATUS_NOERROR); } bool InspIRCd::DaemonSeed() @@ -155,7 +144,7 @@ bool InspIRCd::DaemonSeed() std::cout << "InspIRCd Process ID: " << con_green << GetCurrentProcessId() << con_reset << std::endl; return true; #else - // Do not use QuickExit here: It will exit with status SIGTERM which would break e.g. daemon scripts + // Do not use exit() here: It will exit with status SIGTERM which would break e.g. daemon scripts signal(SIGTERM, VoidSignalHandler); int childpid = fork(); @@ -172,7 +161,7 @@ bool InspIRCd::DaemonSeed() */ while (kill(childpid, 0) != -1) sleep(1); - exit(0); + exit(EXIT_STATUS_NOERROR); } setsid (); std::cout << "InspIRCd Process ID: " << con_green << getpid() << con_reset << std::endl; @@ -194,9 +183,15 @@ bool InspIRCd::DaemonSeed() #endif } -void InspIRCd::WritePID(const std::string &filename) +void InspIRCd::WritePID(const std::string& filename, bool exitonfail) { #ifndef _WIN32 + if (!ServerInstance->Config->cmdline.writepid) + { + this->Logs->Log("STARTUP", LOG_DEFAULT, "--nopid specified on command line; PID file not written."); + return; + } + std::string fname(filename); if (fname.empty()) fname = ServerInstance->Config->Paths.PrependData("inspircd.pid"); @@ -208,9 +203,11 @@ void InspIRCd::WritePID(const std::string &filename) } else { - std::cout << "Failed to write PID-file '" << fname << "', exiting." << std::endl; - this->Logs->Log("STARTUP", LOG_DEFAULT, "Failed to write PID-file '%s', exiting.",fname.c_str()); - Exit(EXIT_STATUS_PID); + if (exitonfail) + std::cout << "Failed to write PID-file '" << fname << "', exiting." << std::endl; + this->Logs->Log("STARTUP", LOG_DEFAULT, "Failed to write PID-file '%s'%s", fname.c_str(), (exitonfail ? ", exiting." : "")); + if (exitonfail) + Exit(EXIT_STATUS_PID); } #endif } @@ -224,21 +221,17 @@ InspIRCd::InspIRCd(int argc, char** argv) : * THIS MUST MATCH THE ORDER OF DECLARATION OF THE FUNCTORS, e.g. the methods * themselves within the class. */ - OperQuit("operquit", ExtensionItem::EXT_USER, NULL), - GenRandom(&HandleGenRandom), - IsChannel(&HandleIsChannel), - IsNick(&HandleIsNick), - IsIdent(&HandleIsIdent), - OnCheckExemption(&HandleOnCheckExemption) + GenRandom(&DefaultGenRandom), + IsChannel(&DefaultIsChannel), + IsNick(&DefaultIsNick), + IsIdent(&DefaultIsIdent) { ServerInstance = this; - Extensions.Register(&OperQuit); - FailedPortList pl; // Flag variables passed to getopt_long() later int do_version = 0, do_nofork = 0, do_debug = 0, - do_nolog = 0, do_root = 0; + do_nolog = 0, do_nopid = 0, do_root = 0; // Initialize so that if we exit before proper initialization they're not deleted this->Config = 0; @@ -278,12 +271,23 @@ InspIRCd::InspIRCd(int argc, char** argv) : srandom(TIME.tv_nsec ^ TIME.tv_sec); #endif + { + ServiceProvider* provs[] = + { + &rfcevents.numeric, &rfcevents.join, &rfcevents.part, &rfcevents.kick, &rfcevents.quit, &rfcevents.nick, + &rfcevents.mode, &rfcevents.topic, &rfcevents.privmsg, &rfcevents.invite, &rfcevents.ping, &rfcevents.pong, + &rfcevents.error + }; + Modules.AddServices(provs, sizeof(provs)/sizeof(provs[0])); + } + struct option longopts[] = { { "nofork", no_argument, &do_nofork, 1 }, { "config", required_argument, NULL, 'c' }, { "debug", no_argument, &do_debug, 1 }, { "nolog", no_argument, &do_nolog, 1 }, + { "nopid", no_argument, &do_nopid, 1 }, { "runasroot", no_argument, &do_root, 1 }, { "version", no_argument, &do_version, 1 }, #ifdef INSPIRCD_ENABLE_TESTSUITE @@ -300,7 +304,16 @@ InspIRCd::InspIRCd(int argc, char** argv) : { case 'c': /* Config filename was set */ - ConfigFileName = ServerInstance->Config->Paths.PrependConfig(optarg); + ConfigFileName = optarg; +#ifdef _WIN32 + TCHAR configPath[MAX_PATH + 1]; + if (GetFullPathName(optarg, MAX_PATH, configPath, NULL) > 0) + ConfigFileName = configPath; +#else + char configPath[PATH_MAX + 1]; + if (realpath(optarg, configPath)) + ConfigFileName = configPath; +#endif break; case 0: /* getopt_long_only() set an int variable, just keep going */ @@ -310,8 +323,8 @@ InspIRCd::InspIRCd(int argc, char** argv) : default: /* Fall through to handle other weird values too */ std::cout << "Unknown parameter '" << argv[optind-1] << "'" << std::endl; - std::cout << "Usage: " << argv[0] << " [--nofork] [--nolog] [--debug] [--config ]" << std::endl << - std::string(static_cast(8+strlen(argv[0])), ' ') << "[--runasroot] [--version]" << std::endl; + std::cout << "Usage: " << argv[0] << " [--nofork] [--nolog] [--nopid] [--debug] [--config ]" << std::endl << + std::string(static_cast(8+strlen(argv[0])), ' ') << "[--runasroot] [--version]" << std::endl; Exit(EXIT_STATUS_ARGV); break; } @@ -324,7 +337,7 @@ InspIRCd::InspIRCd(int argc, char** argv) : if (do_version) { - std::cout << std::endl << INSPIRCD_VERSION << " " << INSPIRCD_REVISION << std::endl; + std::cout << std::endl << INSPIRCD_VERSION << std::endl; Exit(EXIT_STATUS_NOERROR); } @@ -338,10 +351,11 @@ InspIRCd::InspIRCd(int argc, char** argv) : Config->cmdline.nofork = (do_nofork != 0); Config->cmdline.forcedebug = (do_debug != 0); Config->cmdline.writelog = !do_nolog; + Config->cmdline.writepid = !do_nopid; if (do_debug) { - FileWriter* fw = new FileWriter(stdout); + FileWriter* fw = new FileWriter(stdout, 1); FileLogStream* fls = new FileLogStream(LOG_RAWIO, fw); Logs->AddLogTypes("*", fls, true); } @@ -366,7 +380,7 @@ InspIRCd::InspIRCd(int argc, char** argv) : } } - std::cout << con_green << "InspIRCd - Internet Relay Chat Daemon" << con_reset << ", compiled on " __DATE__ " at " __TIME__ << std::endl; + std::cout << con_green << "InspIRCd - Internet Relay Chat Daemon" << con_reset << std::endl; std::cout << "For contributors & authors: " << con_green << "See /INFO Output" << con_reset << std::endl; #ifndef _WIN32 @@ -406,7 +420,6 @@ InspIRCd::InspIRCd(int argc, char** argv) : this->Config->Read(); this->Config->Apply(NULL, ""); Logs->OpenFileLogs(); - ModeParser::InitBuiltinModes(); // If we don't have a SID, generate one based on the server name and the server description if (Config->sid.empty()) @@ -429,7 +442,7 @@ InspIRCd::InspIRCd(int argc, char** argv) : // Build ISupport as ModuleManager::LoadAll() does not do it this->ISupport.Build(); - Config->ApplyDisabledCommands(Config->DisabledCommands); + Config->ApplyDisabledCommands(); if (!pl.empty()) { @@ -439,7 +452,7 @@ InspIRCd::InspIRCd(int argc, char** argv) : int j = 1; for (FailedPortList::iterator i = pl.begin(); i != pl.end(); i++, j++) { - std::cout << j << ".\tAddress: " << (i->first.empty() ? "" : i->first) << " \tReason: " << i->second << std::endl; + std::cout << j << ".\tAddress: " << i->first.str() << " \tReason: " << strerror(i->second) << std::endl; } std::cout << std::endl << "Hint: Try using a public IP instead of blank or *" << std::endl; @@ -500,65 +513,50 @@ InspIRCd::InspIRCd(int argc, char** argv) : QueryPerformanceFrequency(&stats.QPFrequency); #endif - Logs->Log("STARTUP", LOG_DEFAULT, "Startup complete as '%s'[%s], %d max open sockets", Config->ServerName.c_str(),Config->GetSID().c_str(), SocketEngine::GetMaxFds()); + Logs->Log("STARTUP", LOG_DEFAULT, "Startup complete as '%s'[%s], %lu max open sockets", Config->ServerName.c_str(),Config->GetSID().c_str(), SocketEngine::GetMaxFds()); #ifndef _WIN32 - std::string SetUser = Config->ConfValue("security")->getString("runasuser"); - std::string SetGroup = Config->ConfValue("security")->getString("runasgroup"); + ConfigTag* security = Config->ConfValue("security"); + + const std::string SetGroup = security->getString("runasgroup"); if (!SetGroup.empty()) { - int ret; - - // setgroups - ret = setgroups(0, NULL); - - if (ret == -1) + errno = 0; + if (setgroups(0, NULL) == -1) { this->Logs->Log("STARTUP", LOG_DEFAULT, "setgroups() failed (wtf?): %s", strerror(errno)); - this->QuickExit(0); + exit(EXIT_STATUS_CONFIG); } - // setgid - struct group *g; - - errno = 0; - g = getgrnam(SetGroup.c_str()); - + struct group* g = getgrnam(SetGroup.c_str()); if (!g) { this->Logs->Log("STARTUP", LOG_DEFAULT, "getgrnam(%s) failed (wrong group?): %s", SetGroup.c_str(), strerror(errno)); - this->QuickExit(0); + exit(EXIT_STATUS_CONFIG); } - ret = setgid(g->gr_gid); - - if (ret == -1) + if (setgid(g->gr_gid) == -1) { - this->Logs->Log("STARTUP", LOG_DEFAULT, "setgid() failed (wrong group?): %s", strerror(errno)); - this->QuickExit(0); + this->Logs->Log("STARTUP", LOG_DEFAULT, "setgid(%d) failed (wrong group?): %s", g->gr_gid, strerror(errno)); + exit(EXIT_STATUS_CONFIG); } } + const std::string SetUser = security->getString("runasuser"); if (!SetUser.empty()) { - // setuid - struct passwd *u; - errno = 0; - u = getpwnam(SetUser.c_str()); - + struct passwd* u = getpwnam(SetUser.c_str()); if (!u) { this->Logs->Log("STARTUP", LOG_DEFAULT, "getpwnam(%s) failed (wrong user?): %s", SetUser.c_str(), strerror(errno)); - this->QuickExit(0); + exit(EXIT_STATUS_CONFIG); } - int ret = setuid(u->pw_uid); - - if (ret == -1) + if (setuid(u->pw_uid) == -1) { - this->Logs->Log("STARTUP", LOG_DEFAULT, "setuid() failed (wrong user?): %s", strerror(errno)); - this->QuickExit(0); + this->Logs->Log("STARTUP", LOG_DEFAULT, "setuid(%d) failed (wrong user?): %s", u->pw_uid, strerror(errno)); + exit(EXIT_STATUS_CONFIG); } } @@ -649,18 +647,25 @@ void InspIRCd::Run() /* Allow a buffer of two seconds drift on this so that ntpdate etc dont harass admins */ if (TIME.tv_sec < OLDTIME - 2) { - SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is flowing BACKWARDS in this dimension! Clock drifted backwards %lu secs.", (unsigned long)(OLDTIME-TIME.tv_sec)); + SNO->WriteToSnoMask('a', "\002EH?!\002 -- Time is flowing BACKWARDS in this dimension! Clock drifted backwards %lu secs.", (unsigned long)(OLDTIME-TIME.tv_sec)); } else if (TIME.tv_sec > OLDTIME + 2) { - SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is jumping FORWARDS! Clock skipped %lu secs.", (unsigned long)(TIME.tv_sec - OLDTIME)); + SNO->WriteToSnoMask('a', "\002EH?!\002 -- Time is jumping FORWARDS! Clock skipped %lu secs.", (unsigned long)(TIME.tv_sec - OLDTIME)); } OLDTIME = TIME.tv_sec; if ((TIME.tv_sec % 3600) == 0) + { FOREACH_MOD(OnGarbageCollect, ()); + // HACK: ELines are not expired properly at the moment but it can't be fixed as + // the 2.0 XLine system is a spaghetti nightmare. Instead we skip over expired + // ELines in XLineManager::CheckELines() and expire them here instead. + XLines->GetAll("E"); + } + Timers.TickTimers(TIME.tv_sec); Users->DoBackgroundUserStuff();