CmdResult cmd_rehash::Handle (const char** parameters, int pcnt, userrec *user) { user->WriteServ("382 %s %s :Rehashing",user->nick,ServerConfig::CleanFilename(ServerInstance->ConfigFileName)); std::string parameter; std::string old_disabled = ServerInstance->Config->DisabledCommands; if (pcnt) { parameter = parameters[0]; } else { ServerInstance->WriteOpers("*** %s is rehashing config file %s",user->nick,ServerConfig::CleanFilename(ServerInstance->ConfigFileName)); ServerInstance->CloseLog(); ServerInstance->OpenLog(ServerInstance->Config->argv, ServerInstance->Config->argc); ServerInstance->RehashUsersAndChans(); FOREACH_MOD(I_OnGarbageCollect, OnGarbageCollect()); ServerInstance->Config->Read(false,user); ServerInstance->Res->Rehash(); ServerInstance->ResetMaxBans(); } if (old_disabled != ServerInstance->Config->DisabledCommands) InitializeDisabledCommands(ServerInstance->Config->DisabledCommands, ServerInstance); FOREACH_MOD(I_OnRehash,OnRehash(user, parameter)); ServerInstance->BuildISupport(); return CMD_SUCCESS; }
void RehashHandler::Call(const std::string &reason) { ServerInstance->SNO->WriteToSnoMask('a', "Rehashing config file %s %s",ServerConfig::CleanFilename(ServerInstance->ConfigFileName.c_str()), reason.c_str()); FOREACH_MOD(I_OnGarbageCollect, OnGarbageCollect()); if (!ServerInstance->ConfigThread) { ServerInstance->ConfigThread = new ConfigReaderThread(""); ServerInstance->Threads->Start(ServerInstance->ConfigThread); } }
int InspIRCd::Run() { /* See if we're supposed to be running the test suite rather than entering the mainloop */ if (Config->cmdline.TestSuite) { TestSuite* ts = new TestSuite; delete ts; Exit(0); } UpdateTime(); time_t OLDTIME = TIME.tv_sec; while (true) { #ifndef _WIN32 static rusage ru; #endif /* Check if there is a config thread which has finished executing but has not yet been freed */ if (this->ConfigThread && this->ConfigThread->IsDone()) { /* Rehash has completed */ this->Logs->Log("CONFIG",LOG_DEBUG,"Detected ConfigThread exiting, tidying up..."); this->ConfigThread->Finish(); ConfigThread->join(); delete ConfigThread; ConfigThread = NULL; } UpdateTime(); /* Run background module timers every few seconds * (the docs say modules shouldnt rely on accurate * timing using this event, so we dont have to * time this exactly). */ if (TIME.tv_sec != OLDTIME) { #ifndef _WIN32 getrusage(RUSAGE_SELF, &ru); stats->LastSampled = TIME; stats->LastCPU = ru.ru_utime; #else if(QueryPerformanceCounter(&stats->LastSampled)) { FILETIME CreationTime; FILETIME ExitTime; FILETIME KernelTime; FILETIME UserTime; GetProcessTimes(GetCurrentProcess(), &CreationTime, &ExitTime, &KernelTime, &UserTime); stats->LastCPU.dwHighDateTime = KernelTime.dwHighDateTime + UserTime.dwHighDateTime; stats->LastCPU.dwLowDateTime = KernelTime.dwLowDateTime + UserTime.dwLowDateTime; } #endif /* 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); } 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); } OLDTIME = TIME.tv_sec; if ((TIME.tv_sec % 3600) == 0) { Users->GarbageCollect(); FOREACH_MOD(I_OnGarbageCollect, OnGarbageCollect()); } Timers->TickTimers(TIME.tv_sec); this->DoBackgroundUserStuff(); if ((TIME.tv_sec % 5) == 0) { FOREACH_MOD(I_OnBackgroundTimer,OnBackgroundTimer(TIME.tv_sec)); SNO->FlushSnotices(); } } /* Call the socket engine to wait on the active * file descriptors. The socket engine has everything's * descriptors in its list... dns, modules, users, * servers... so its nice and easy, just one call. * This will cause any read or write events to be * dispatched to their handlers. */ this->SE->DispatchTrialWrites(); this->SE->DispatchEvents(); /* if any users were quit, take them out */ GlobalCulls.Apply(); AtomicActions.Run(); if (s_signal) { this->SignalHandler(s_signal); s_signal = 0; } } return 0; }
CmdResult CommandRehash::Handle (const std::vector<std::string>& parameters, User *user) { std::string param = parameters.size() ? parameters[0] : ""; FOREACH_MOD(I_OnPreRehash,OnPreRehash(user, param)); if (param.empty()) { // standard rehash of local server } else if (param.find_first_of("*.") != std::string::npos) { // rehash of servers by server name (with wildcard) if (!InspIRCd::Match(ServerInstance->Config->ServerName, parameters[0])) { // Doesn't match us. PreRehash is already done, nothing left to do return CMD_SUCCESS; } } else { // parameterized rehash // the leading "-" is optional; remove it if present. if (param[0] == '-') param = param.substr(1); FOREACH_MOD(I_OnModuleRehash,OnModuleRehash(user, param)); return CMD_SUCCESS; } // Rehash for me. Try to start the rehash thread if (!ServerInstance->ConfigThread) { std::string m = user->nick + " is rehashing config file " + ServerConfig::CleanFilename(ServerInstance->ConfigFileName.c_str()) + " on " + ServerInstance->Config->ServerName; ServerInstance->SNO->WriteGlobalSno('a', m); if (IS_LOCAL(user)) user->WriteNumeric(RPL_REHASHING, "%s %s :Rehashing", user->nick.c_str(),ServerConfig::CleanFilename(ServerInstance->ConfigFileName.c_str())); else ServerInstance->PI->SendUserNotice(user, std::string("*** Rehashing server ") + ServerConfig::CleanFilename(ServerInstance->ConfigFileName.c_str())); /* Don't do anything with the logs here -- logs are restarted * after the config thread has completed. */ FOREACH_MOD(I_OnGarbageCollect, OnGarbageCollect()); ServerInstance->ConfigThread = new ConfigReaderThread(user->uuid); ServerInstance->Threads->Start(ServerInstance->ConfigThread); } else { /* * A rehash is already in progress! ahh shit. * XXX, todo: we should find some way to kill runaway rehashes that are blocking, this is a major problem for unrealircd users */ if (IS_LOCAL(user)) user->WriteServ("NOTICE %s :*** Could not rehash: A rehash is already in progress.", user->nick.c_str()); else ServerInstance->PI->SendUserNotice(user, "*** Could not rehash: A rehash is already in progress."); } // Always return success so spanningtree forwards an incoming REHASH even if we failed return CMD_SUCCESS; }