X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/8c98969b4f3f73167a31d195ed792c35f82e9566..8c7a6befad791ac242f15233365893b18953a627:/projects/stargazer/main.cpp diff --git a/projects/stargazer/main.cpp b/projects/stargazer/main.cpp index aa8bdef5..bcf7af77 100644 --- a/projects/stargazer/main.cpp +++ b/projects/stargazer/main.cpp @@ -18,744 +18,389 @@ * Author : Boris Mikhailenko */ - /* - $Revision: 1.124 $ - $Date: 2010/10/04 20:19:12 $ - $Author: faust $ - */ +#include "store_loader.h" +#include "plugin_mgr.h" +#include "plugin_runner.h" +#include "users_impl.h" +#include "admins_impl.h" +#include "tariffs_impl.h" +#include "services_impl.h" +#include "corps_impl.h" +#include "traffcounter_impl.h" +#include "settings_impl.h" +#include "pidfile.h" +#include "eventloop.h" +#include "stg_timer.h" -//#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "stg/user.h" +#include "stg/common.h" +#include "stg/plugin.h" +#include "stg/logger.h" +#include "stg/scriptexecuter.h" +#include "stg/version.h" -#include -#include #include #include #include -#include - -#include "settings.h" -#include "user.h" -#include "users.h" -#include "admins.h" -#include "common.h" -#include "traffcounter.h" -#include "base_plugin.h" -#include "stg_logger.h" -#include "stg_timer.h" -#include "plugin_runner.h" -#include "script_executer.h" -#include "conffiles.h" -#include "version.h" -#include "store_loader.h" -#include "pidfile.h" -#include "eventloop.h" +#include +#include +#include +#include // srandom, exit -using namespace std; -uint32_t eip; +#include +#include +#include +#include +#include +#include // S_IRUSR +#include // create #ifdef DEBUG - #define MAIN_DEBUG (1) #define NO_DAEMON (1) #endif #define START_FILE "/._ST_ART_ED_" -static bool needRulesReloading = false; -static bool childExited = false; -//static pid_t executerPid; -set executersPid; -static pid_t stgChildPid; +using STG::SettingsImpl; +using STG::AdminsImpl; +using STG::TraffCounterImpl; +using STG::UsersImpl; +using STG::TariffsImpl; +using STG::ServicesImpl; +using STG::CorporationsImpl; +using STG::StoreLoader; -#include "pinger.h" - -//----------------------------------------------------------------------------- -bool StartModCmp(const PLUGIN_RUNNER & lhs, const PLUGIN_RUNNER & rhs) -{ -return lhs.GetStartPosition() < rhs.GetStartPosition(); -} -//----------------------------------------------------------------------------- -bool StopModCmp(const PLUGIN_RUNNER & lhs, const PLUGIN_RUNNER & rhs) -{ -return lhs.GetStopPosition() > rhs.GetStopPosition(); -} -//----------------------------------------------------------------------------- -class STG_STOPPER +namespace { -public: - STG_STOPPER() { nonstop = true; } - bool GetStatus() const { return nonstop; }; - #ifdef NO_DAEMON - void Stop(const char * __file__, int __line__) - #else - void Stop(const char *, int) - #endif - { - #ifdef NO_DAEMON - printfd(__FILE__, "Stg stopped at %s:%d\n", __file__, __line__); - #endif - nonstop = false; - } -private: - bool nonstop; -}; -//----------------------------------------------------------------------------- -STG_STOPPER nonstop; -//----------------------------------------------------------------------------- -static void StartTimer() -{ -STG_LOGGER & WriteServLog = GetStgLogger(); +std::set executers; -if (RunStgTimer()) - { - WriteServLog("Cannot start timer. Fatal."); - //printfd(__FILE__, "Cannot start timer. Fatal.\n"); - exit(1); - } -else - { - WriteServLog("Timer thread started successfully."); - //printfd(__FILE__, "Timer thread started successfully.\n"); - } -} -//----------------------------------------------------------------------------- -void CatchUSR1(int) -{ +void StartTimer(); +int StartScriptExecuter(char* procName, int msgKey, int* msgID); +int ForkAndWait(const std::string& confDir); +void KillExecuters(); -} -//----------------------------------------------------------------------------- -void CatchTERM(int sig) -{ -/* - *Function Name:CatchINT - *Parameters: sig_num - ÎÏÍÅÒ ÓÉÇÎÁÌÁ - *Description: ïÂÒÁÂÏÔÞÉË ÓÉÇÎÁÌÁ INT - *Returns: îÉÞÅÇÏ - */ -STG_LOGGER & WriteServLog = GetStgLogger(); -WriteServLog("Shutting down... %d", sig); - -//nonstop = false; -nonstop.Stop(__FILE__, __LINE__); - -struct sigaction newsa, oldsa; -sigset_t sigmask; - -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGTERM); -newsa.sa_handler = SIG_IGN; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGTERM, &newsa, &oldsa); - -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGINT); -newsa.sa_handler = SIG_IGN; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGINT, &newsa, &oldsa); -} -//----------------------------------------------------------------------------- -void CatchPIPE(int) -{ -STG_LOGGER & WriteServLog = GetStgLogger(); -WriteServLog("Broken pipe!"); -} //----------------------------------------------------------------------------- -void CatchHUP(int) +void StartTimer() { -needRulesReloading = true; -} -//----------------------------------------------------------------------------- -void CatchCHLD(int) -{ -int status; -pid_t childPid; -childPid = waitpid(-1, &status, WNOHANG); + auto& WriteServLog = STG::Logger::get(); -set::iterator pid; -pid = executersPid.find(childPid); -if (pid != executersPid.end()) + if (RunStgTimer()) { - executersPid.erase(pid); - if (executersPid.empty() && nonstop.GetStatus()) - { - nonstop.Stop(__FILE__, __LINE__); - } - } -if (childPid == stgChildPid) - { - childExited = true; + WriteServLog("Cannot start timer. Fatal."); + exit(1); } -} -/*//----------------------------------------------------------------------------- -void CatchSEGV(int, siginfo_t *, void *) -{ -char fileName[50]; -sprintf(fileName, "/tmp/stg_segv.%d", getpid()); -FILE * f = fopen(fileName, "wt"); -if (f) - { - fprintf(f, "\nSignal info:\n~~~~~~~~~~~~\n"); - fprintf(f, "numb:\t %d (%d)\n", sinfo->si_signo, sig); - fprintf(f, "errn:\t %d\n", sinfo->si_errno); - fprintf(f, "code:\t %d ", sinfo->si_code); - - switch (sinfo->si_code) - { - case SEGV_MAPERR: - fprintf(f, "(SEGV_MAPERR - address not mapped to object)\n"); - break; - - case SEGV_ACCERR: - fprintf(f, "(SEGV_ACCERR - invalid permissions for mapped object)\n"); - break; - - default: - fprintf(f, "???\n"); - } - - fprintf(f, "addr:\t 0x%.8X\n", - (unsigned int)sinfo->si_addr); - - Dl_info dlinfo; - //asm("movl %eip, eip"); - if (dladdr((void*)CatchCHLD, &dlinfo)) - { - fprintf(f, "SEGV point: %s %s\n", dlinfo.dli_fname, dlinfo.dli_sname); - } else - { - fprintf(f, "Cannot find SEGV point\n"); - } - - fclose(f); - } - -struct sigaction segv_action, segv_action_old; - -segv_action.sa_handler = SIG_DFL; -segv_action.sa_sigaction = NULL; -segv_action.sa_flags = SA_SIGINFO; -segv_action.sa_restorer = NULL; - -sigaction(SIGSEGV, &segv_action, &segv_action_old); -}*/ -//----------------------------------------------------------------------------- -static void SetSignalHandlers() -{ -struct sigaction newsa, oldsa; -sigset_t sigmask; -/////// -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGTERM); -newsa.sa_handler = CatchTERM; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGTERM, &newsa, &oldsa); -/////// -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGUSR1); -newsa.sa_handler = CatchUSR1; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGUSR1, &newsa, &oldsa); -/////// -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGINT); -newsa.sa_handler = CatchTERM; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGINT, &newsa, &oldsa); -////// -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGPIPE); -newsa.sa_handler = CatchPIPE; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGPIPE, &newsa, &oldsa); -////// -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGHUP); -newsa.sa_handler = CatchHUP; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGHUP, &newsa, &oldsa); -////// -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGCHLD); -newsa.sa_handler = CatchCHLD; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGCHLD, &newsa, &oldsa); - -/*newsa.sa_handler = NULL; -newsa.sa_sigaction = CatchSEGV; -newsa.sa_flags = SA_SIGINFO; -newsa.sa_restorer = NULL; -sigaction(SIGSEGV, &newsa, &oldsa);*/ - -return; + WriteServLog("Timer thread started successfully."); } //----------------------------------------------------------------------------- -int StartScriptExecuter(char * procName, int msgKey, int * msgID, SETTINGS * settings) +#if defined(LINUX) || defined(DARWIN) +int StartScriptExecuter(char* procName, int msgKey, int* msgID) +#else +int StartScriptExecuter(char*, int msgKey, int* msgID) +#endif { -STG_LOGGER & WriteServLog = GetStgLogger(); + auto& WriteServLog = STG::Logger::get(); -if (*msgID == -11) // If msgID == -11 - first call. Create queue + if (*msgID == -11) // If msgID == -11 - first call. Create queue { - for (int i = 0; i < 2; i++) + for (int i = 0; i < 2; i++) { - //WriteServLog("Creating queue with key=%d ...", msgKey); - *msgID = msgget(msgKey, IPC_CREAT | IPC_EXCL | 0600); + *msgID = msgget(msgKey, IPC_CREAT | IPC_EXCL | 0600); - if (*msgID == -1) - { - *msgID = msgget(msgKey, 0); if (*msgID == -1) + { + *msgID = msgget(msgKey, 0); + if (*msgID == -1) { - WriteServLog("Message queue not created."); - return -1; - } - else - { - msgctl(*msgID, IPC_RMID, NULL); - //printfd(__FILE__, "Queue removed!"); + WriteServLog("Message queue not created."); + return -1; } + else + msgctl(*msgID, IPC_RMID, NULL); } - else + else { - WriteServLog("Message queue created successfully. msgKey=%d msgID=%d", msgKey, *msgID); - break; + WriteServLog("Message queue created successfully. msgKey=%d msgID=%d", msgKey, *msgID); + break; } } } -pid_t executerPid = fork(); + const auto pid = fork(); -switch (executerPid) + switch (pid) { - case -1: // ìÁÖÁ - WriteServLog("Fork error!"); - return -1; + case -1: + WriteServLog("Fork error!"); + return -1; - case 0: // ðÏÔÏÍÏË - //close(0); - //close(1); - //close(2); - //setsid(); - delete settings; - Executer(msgKey, *msgID, executerPid, procName); - return 1; + case 0: +#if defined(LINUX) || defined(DARWIN) + Executer(*msgID, pid, procName); +#else + Executer(*msgID, pid); +#endif + return 1; - default: // ïÓÎÏ×ÎÏÊ ÐÒÏÃÅÓÓ - if (executersPid.empty()) { - Executer(msgKey, *msgID, executerPid, NULL); - } - executersPid.insert(executerPid); + default: + if (executers.empty()) { +#if defined(LINUX) || defined(DARWIN) + Executer(*msgID, pid, NULL); +#else + Executer(*msgID, pid); +#endif + } + executers.insert(pid); } -return 0; + return 0; } //----------------------------------------------------------------------------- #ifndef NO_DAEMON -int ForkAndWait(const string & confDir) +int ForkAndWait(const std::string& confDir) #else -int ForkAndWait(const string &) +int ForkAndWait(const std::string&) #endif { #ifndef NO_DAEMON -stgChildPid = fork(); -string startFile = confDir + START_FILE; -unlink(startFile.c_str()); + const auto pid = fork(); + const auto startFile = confDir + START_FILE; + unlink(startFile.c_str()); -switch (stgChildPid) + switch (pid) { - case -1: // ìÁÖÁ - return -1; - break; + case -1: + return -1; + break; - case 0: // ðÏÔÏÍÏË - //close(0); - close(1); - close(2); - setsid(); - break; + case 0: + close(1); + close(2); + setsid(); + break; - default: // ïÓÎÏ×ÎÏÊ ÐÒÏÃÅÓÓ - for (int i = 0; i < 120 * 5; i++) + default: + struct timespec ts = {0, 200000000}; + for (int i = 0; i < 120 * 5; i++) { - if (access(startFile.c_str(), F_OK) == 0) + if (access(startFile.c_str(), F_OK) == 0) { - //printf("Fork successfull. Exit.\n"); - unlink(startFile.c_str()); - exit(0); + unlink(startFile.c_str()); + exit(0); } - if (childExited) - { - unlink(startFile.c_str()); - exit(1); - } - usleep(200000); + nanosleep(&ts, NULL); } - unlink(startFile.c_str()); - exit(1); - break; + unlink(startFile.c_str()); + exit(1); + break; } #endif -return 0; + return 0; } //----------------------------------------------------------------------------- void KillExecuters() { -set::iterator pid; -pid = executersPid.begin(); -while (pid != executersPid.end()) + auto pid = executers.begin(); + while (pid != executers.end()) { - printfd(__FILE__, "KillExecuters pid=%d\n", *pid); - kill(*pid, SIGUSR1); - ++pid; + printfd(__FILE__, "KillExecuters pid=%d\n", *pid); + kill(*pid, SIGUSR1); + ++pid; } } //----------------------------------------------------------------------------- -int main(int argc, char * argv[]) +} // namespace anonymous +//----------------------------------------------------------------------------- +int main(int argc, char* argv[]) { + int msgID = -11; -/* - Initialization order: - - Logger - - Stg timer - - Settings - - Plugins - - Plugins settings - - Read Admins - - Read Tariffs - - Read Users - - Start Users - - Start Traffcounter - - Start Plugins - - Start pinger - - Set signal nandlers - - Fork and exit - * */ - -SETTINGS * settings = NULL; -BASE_STORE * dataStore = NULL; -TARIFFS * tariffs = NULL; -ADMINS * admins = NULL; -USERS * users = NULL; -TRAFFCOUNTER * traffCnt = NULL; -int msgID = -11; - - { - STG_LOGGER & WriteServLog = GetStgLogger(); - WriteServLog.SetLogFileName("/var/log/stargazer.log"); - } - -vector modSettings; -list modules; - -list::iterator modIter; + STG::Logger::get().setFileName("/var/log/stargazer.log"); -if (getuid()) + if (getuid()) { - printf("You must be root. Exit.\n"); - exit(1); + printf("You must be root. Exit.\n"); + return 1; } -if (argc == 2) - settings = new SETTINGS(argv[1]); -else - settings = new SETTINGS(); + SettingsImpl settings(argc == 2 ? argv[1] : ""); -if (settings->ReadSettings()) + if (settings.ReadSettings()) { - //printfd(__FILE__, "ReadSettings error.\n"); - STG_LOGGER & WriteServLog = GetStgLogger(); + auto& WriteServLog = STG::Logger::get(); - if (settings->GetLogFileName() != "") - WriteServLog.SetLogFileName(settings->GetLogFileName()); + if (settings.GetLogFileName() != "") + WriteServLog.setFileName(settings.GetLogFileName()); - WriteServLog("ReadSettings error. %s", settings->GetStrError().c_str()); - exit(1); + WriteServLog("ReadSettings error. %s", settings.GetStrError().c_str()); + return -1; } #ifndef NO_DAEMON -string startFile(settings->GetConfDir() + START_FILE); + const auto startFile = settings.GetConfDir() + START_FILE; #endif -if (ForkAndWait(settings->GetConfDir()) < 0) + if (ForkAndWait(settings.GetConfDir()) < 0) { - STG_LOGGER & WriteServLog = GetStgLogger(); - WriteServLog("Fork error!"); - exit(1); + STG::Logger::get()("Fork error!"); + return -1; } -STG_LOGGER & WriteServLog = GetStgLogger(); -WriteServLog.SetLogFileName(settings->GetLogFileName()); -WriteServLog("Stg v. %s", SERVER_VERSION); + auto& WriteServLog = STG::Logger::get(); + WriteServLog.setFileName(settings.GetLogFileName()); + WriteServLog("Stg v. %s", SERVER_VERSION); -for (size_t i = 0; i < settings->GetExecutersNum(); i++) + for (size_t i = 0; i < settings.GetExecutersNum(); i++) { - int ret = StartScriptExecuter(argv[0], settings->GetExecMsgKey(), &msgID, settings); - if (ret < 0) - { - STG_LOGGER & WriteServLog = GetStgLogger(); - WriteServLog("Start Script Executer error!"); - return 1; - } - if (ret == 1) + auto ret = StartScriptExecuter(argv[0], settings.GetExecMsgKey(), &msgID); + if (ret < 0) { - // Stopping child - return 0; + STG::Logger::get()("Start Script Executer error!"); + return -1; } + if (ret == 1) + return 0; } -PIDFile pidFile(settings->GetPIDFileName()); + PIDFile pidFile(settings.GetPIDFileName()); -StartTimer(); -WaitTimer(); -if (!IsStgTimerRunning()) - { - printfd(__FILE__, "Timer thread not started in 1 sec!\n"); - WriteServLog("Timer thread not started in 1 sec!"); - } + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_DFL; + sigaction(SIGHUP, &sa, NULL); // Apparently FreeBSD ignores SIGHUP by default when launched from rc.d at bot time. -EVENT_LOOP & loop(EVENT_LOOP_SINGLETON::GetInstance()); + sigset_t signalSet; + sigfillset(&signalSet); + pthread_sigmask(SIG_BLOCK, &signalSet, NULL); -STORE_LOADER storeLoader(*settings); -if (storeLoader.Load()) + StartTimer(); + WaitTimer(); + if (!IsStgTimerRunning()) { - WriteServLog("Storage plugin: '%s'", storeLoader.GetStrError().c_str()); - goto exitLblNotStarted; + printfd(__FILE__, "Timer thread not started in 1 sec!\n"); + WriteServLog("Timer thread not started in 1 sec!"); + return -1; } -if (loop.Start()) + auto& loop = EVENT_LOOP::instance(); + + StoreLoader storeLoader(settings); + if (storeLoader.load()) { - WriteServLog("Event loop not started."); - goto exitLblNotStarted; + printfd(__FILE__, "Storage plugin: '%s'\n", storeLoader.GetStrError().c_str()); + WriteServLog("Storage plugin: '%s'", storeLoader.GetStrError().c_str()); + return -1; } -dataStore = storeLoader.GetStore(); -WriteServLog("Storage plugin: %s. Loading successfull.", dataStore->GetVersion().c_str()); - -tariffs = new TARIFFS(dataStore); -admins = new ADMINS(dataStore); -users = new USERS(settings, dataStore, tariffs, admins->GetSysAdmin()); -traffCnt = new TRAFFCOUNTER(users, tariffs, settings->GetRulesFileName()); -traffCnt->SetMonitorDir(settings->GetMonitorDir()); - -modSettings = settings->GetModulesSettings(); - -for (unsigned i = 0; i < modSettings.size(); i++) + if (loop.Start()) { - string modulePath = settings->GetModulesPath(); - modulePath += "/mod_"; - modulePath += modSettings[i].moduleName; - modulePath += ".so"; - printfd(__FILE__, "Module: %s\n", modulePath.c_str()); - modules.push_back( - PLUGIN_RUNNER(modulePath, - modSettings[i], - admins, - tariffs, - users, - traffCnt, - dataStore, - settings) - ); + printfd(__FILE__, "Event loop not started.\n"); + WriteServLog("Event loop not started."); + return -1; } -modIter = modules.begin(); + auto& store = storeLoader.get(); + WriteServLog("Storage plugin: %s. Loading successfull.", store.GetVersion().c_str()); -while (modIter != modules.end()) - { - //Loading modules - if (modIter->Load()) - { - WriteServLog("Error: %s", - modIter->GetStrError().c_str()); - goto exitLblNotStarted; - } - ++modIter; - } + AdminsImpl admins(store); + TariffsImpl tariffs(&store); + tariffs.ReadTariffs(); + ServicesImpl services(&store); + CorporationsImpl corps(&store); + UsersImpl users(&settings, &store, &tariffs, services, admins.sysAdmin()); + TraffCounterImpl traffCnt(&users, settings.GetRulesFileName()); + traffCnt.SetMonitorDir(settings.GetMonitorDir()); -//Start section -if (users->Start()) - { - goto exitLblNotStarted; - } -WriteServLog("Users started successfully."); + if (users.Start()) + return -1; -if (traffCnt->Start()) - { - goto exitLblNotStarted; - } -WriteServLog("Traffcounter started successfully."); + WriteServLog("Users started successfully."); -//Sort by start order -modules.sort(StartModCmp); -modIter = modules.begin(); + if (traffCnt.Start()) + return -1; -while (modIter != modules.end()) - { - if (modIter->Start()) - { - WriteServLog("Error: %s", - modIter->GetStrError().c_str()); - //printfd(__FILE__, "Error: %s\n", capRunner.GetStrError().c_str()); - goto exitLbl; - } - WriteServLog("Module: \'%s\'. Start successfull. %d", modIter->GetPlugin()->GetVersion().c_str(), - modIter->GetPlugin()->GetStartPosition()); - ++modIter; - } -SetSignalHandlers(); + WriteServLog("Traffcounter started successfully."); -srandom(stgTime); + STG::PluginManager manager(settings, store, admins, tariffs, services, corps, users, traffCnt); -/* - * Note that an implementation in which nice returns the new nice value - * can legitimately return -1. To reliably detect an error, set - * errno to 0 before the call, and check its value when nice returns -1. - * - * - * (c) man 2 nice - */ -errno = 0; -if (nice(-19) && errno) { - printfd(__FILE__, "nice failed: '%s'\n", strerror(errno)); - WriteServLog("nice failed: '%s'", strerror(errno)); -} + srandom(static_cast(stgTime)); -WriteServLog("Stg started successfully."); -WriteServLog("+++++++++++++++++++++++++++++++++++++++++++++"); + WriteServLog("Stg started successfully."); + WriteServLog("+++++++++++++++++++++++++++++++++++++++++++++"); #ifndef NO_DAEMON -creat(startFile.c_str(), S_IRUSR); + creat(startFile.c_str(), S_IRUSR); #endif -while (nonstop.GetStatus()) + bool running = true; + while (running) { - if (needRulesReloading) + sigfillset(&signalSet); + int sig = 0; + sigwait(&signalSet, &sig); + int status; + switch (sig) { - needRulesReloading = false; - traffCnt->Reload(); - - modIter = modules.begin(); - for (; modIter != modules.end(); ++modIter) + case SIGHUP: { - if (modIter->Reload()) - { - WriteServLog("Error reloading %s ('%s')", modIter->GetPlugin()->GetVersion().c_str(), - modIter->GetStrError().c_str()); - printfd(__FILE__, "Error reloading %s ('%s')\n", modIter->GetPlugin()->GetVersion().c_str(), - modIter->GetStrError().c_str()); - } + SettingsImpl newSettings(settings); + if (newSettings.ReadSettings()) + WriteServLog("ReadSettings error. %s", newSettings.GetStrError().c_str()); + else + settings = newSettings; + WriteServLog.setFileName(settings.GetLogFileName()); + traffCnt.Reload(); + manager.reload(settings); + break; } + case SIGTERM: + running = false; + break; + case SIGINT: + running = false; + break; + case SIGPIPE: + WriteServLog("Broken pipe!"); + break; + case SIGCHLD: + executers.erase(waitpid(-1, &status, WNOHANG)); + if (executers.empty()) + running = false; + break; + default: + WriteServLog("Ignore signal %d", sig); + break; } - stgUsleep(100000); } -exitLbl: + WriteServLog("+++++++++++++++++++++++++++++++++++++++++++++"); -WriteServLog("+++++++++++++++++++++++++++++++++++++++++++++"); + manager.stop(); -//Sort by start order -modules.sort(StopModCmp); -modIter = modules.begin(); -while (modIter != modules.end()) - { - std::string name = modIter->GetFileName(); - printfd(__FILE__, "Stopping module '%s'\n", name.c_str()); - if (modIter->Stop()) - { - WriteServLog("Module \'%s\': Error: %s", - modIter->GetPlugin()->GetVersion().c_str(), - modIter->GetStrError().c_str()); - printfd(__FILE__, "Failed to stop module '%s'\n", name.c_str()); - //printfd(__FILE__, "Error: %s\n", capRunner.GetStrError().c_str()); - //goto exitLbl; - } - WriteServLog("Module: \'%s\'. Stop successfull.", modIter->GetPlugin()->GetVersion().c_str()); - ++modIter; - } + if (loop.Stop()) + WriteServLog("Event loop not stopped."); -if (loop.Stop()) - { - WriteServLog("Event loop not stopped."); - } + if (!traffCnt.Stop()) + WriteServLog("Traffcounter: Stop successfull."); -exitLblNotStarted: + if (!users.Stop()) + WriteServLog("Users: Stop successfull."); -modIter = modules.begin(); -while (modIter != modules.end()) - { - std::string name = modIter->GetFileName(); - printfd(__FILE__, "Unloading module '%s'\n", name.c_str()); - if (modIter->Unload()) - { - WriteServLog("Module \'%s\': Error: %s", - name.c_str(), - modIter->GetStrError().c_str()); - printfd(__FILE__, "Failed to unload module '%s'\n", name.c_str()); - } - ++modIter; - } + sleep(1); + int res = msgctl(msgID, IPC_RMID, NULL); + if (res) + WriteServLog("Queue was not removed. id=%d", msgID); + else + WriteServLog("Queue removed successfully."); -if (traffCnt) - { - traffCnt->Stop(); - WriteServLog("Traffcounter: Stop successfull."); - } + KillExecuters(); -if (users) - { - users->Stop(); - WriteServLog("Users: Stop successfull."); - } + StopStgTimer(); + WriteServLog("StgTimer: Stop successfull."); + + WriteServLog("Stg stopped successfully."); + WriteServLog("---------------------------------------------"); -sleep(1); -int res = msgctl(msgID, IPC_RMID, NULL); -if (res) - WriteServLog("Queue was not removed. id=%d", msgID); -else - WriteServLog("Queue removed successfully."); - -/*struct sigaction newsa, oldsa; -sigset_t sigmask; -sigemptyset(&sigmask); -sigaddset(&sigmask, SIGCHLD); -newsa.sa_handler = SIG_IGN; -newsa.sa_mask = sigmask; -newsa.sa_flags = 0; -sigaction(SIGCHLD, &newsa, &oldsa);*/ - -KillExecuters(); - -StopStgTimer(); -WriteServLog("StgTimer: Stop successfull."); - -WriteServLog("Stg stopped successfully."); -sleep(1); -WriteServLog("---------------------------------------------"); - -delete traffCnt; -delete users; -delete admins; -delete tariffs; -delete settings; - -return 0; + return 0; } //-----------------------------------------------------------------------------