X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/4271ab433cd55bbd2612292bcf39e4dc3d7274f1..0907aa4037b12b6b88ee24495d4577a064d4f8db:/stargazer/main.cpp diff --git a/stargazer/main.cpp b/stargazer/main.cpp deleted file mode 100644 index 825cba58..00000000 --- a/stargazer/main.cpp +++ /dev/null @@ -1,405 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Author : Boris Mikhailenko - */ - -#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 "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 // srandom, exit - -#include -#include -#include -#include -#include -#include // S_IRUSR -#include // create - -#ifdef DEBUG - #define NO_DAEMON (1) -#endif - -#define START_FILE "/._ST_ART_ED_" - -using STG::SettingsImpl; -using STG::AdminsImpl; -using STG::TraffCounterImpl; -using STG::UsersImpl; -using STG::TariffsImpl; -using STG::ServicesImpl; -using STG::CorporationsImpl; -using STG::StoreLoader; - -namespace -{ -std::set executers; - -void StartTimer(); -int StartScriptExecuter(char* procName, int msgKey, int* msgID); -int ForkAndWait(const std::string& confDir); -void KillExecuters(); - -//----------------------------------------------------------------------------- -void StartTimer() -{ - auto& WriteServLog = STG::Logger::get(); - - if (RunStgTimer()) - { - WriteServLog("Cannot start timer. Fatal."); - exit(1); - } - else - WriteServLog("Timer thread started successfully."); -} -//----------------------------------------------------------------------------- -#if defined(LINUX) || defined(DARWIN) -int StartScriptExecuter(char* procName, int msgKey, int* msgID) -#else -int StartScriptExecuter(char*, int msgKey, int* msgID) -#endif -{ - auto& WriteServLog = STG::Logger::get(); - - if (*msgID == -11) // If msgID == -11 - first call. Create queue - { - for (int i = 0; i < 2; i++) - { - *msgID = msgget(msgKey, IPC_CREAT | IPC_EXCL | 0600); - - if (*msgID == -1) - { - *msgID = msgget(msgKey, 0); - if (*msgID == -1) - { - WriteServLog("Message queue not created."); - return -1; - } - else - msgctl(*msgID, IPC_RMID, NULL); - } - else - { - WriteServLog("Message queue created successfully. msgKey=%d msgID=%d", msgKey, *msgID); - break; - } - } - } - - const auto pid = fork(); - - switch (pid) - { - case -1: - WriteServLog("Fork error!"); - return -1; - - case 0: -#if defined(LINUX) || defined(DARWIN) - Executer(*msgID, pid, procName); -#else - Executer(*msgID, pid); -#endif - return 1; - - default: - if (executers.empty()) { -#if defined(LINUX) || defined(DARWIN) - Executer(*msgID, pid, NULL); -#else - Executer(*msgID, pid); -#endif - } - executers.insert(pid); - } - return 0; -} -//----------------------------------------------------------------------------- -#ifndef NO_DAEMON -int ForkAndWait(const std::string& confDir) -#else -int ForkAndWait(const std::string&) -#endif -{ -#ifndef NO_DAEMON - const auto pid = fork(); - const auto startFile = confDir + START_FILE; - unlink(startFile.c_str()); - - switch (pid) - { - case -1: - return -1; - break; - - case 0: - close(1); - close(2); - setsid(); - break; - - default: - struct timespec ts = {0, 200000000}; - for (int i = 0; i < 120 * 5; i++) - { - if (access(startFile.c_str(), F_OK) == 0) - { - unlink(startFile.c_str()); - exit(0); - } - - nanosleep(&ts, NULL); - } - unlink(startFile.c_str()); - exit(1); - break; - } -#endif - return 0; -} -//----------------------------------------------------------------------------- -void KillExecuters() -{ - auto pid = executers.begin(); - while (pid != executers.end()) - { - printfd(__FILE__, "KillExecuters pid=%d\n", *pid); - kill(*pid, SIGUSR1); - ++pid; - } -} -//----------------------------------------------------------------------------- -} // namespace anonymous -//----------------------------------------------------------------------------- -int main(int argc, char* argv[]) -{ - int msgID = -11; - - STG::Logger::get().setFileName("/var/log/stargazer.log"); - - if (getuid()) - { - printf("You must be root. Exit.\n"); - return 1; - } - - SettingsImpl settings(argc == 2 ? argv[1] : ""); - - if (settings.ReadSettings()) - { - auto& WriteServLog = STG::Logger::get(); - - if (settings.GetLogFileName() != "") - WriteServLog.setFileName(settings.GetLogFileName()); - - WriteServLog("ReadSettings error. %s", settings.GetStrError().c_str()); - return -1; - } - -#ifndef NO_DAEMON - const auto startFile = settings.GetConfDir() + START_FILE; -#endif - - if (ForkAndWait(settings.GetConfDir()) < 0) - { - STG::Logger::get()("Fork error!"); - return -1; - } - - auto& WriteServLog = STG::Logger::get(); - WriteServLog.setFileName(settings.GetLogFileName()); - WriteServLog("Stg v. %s", SERVER_VERSION); - - for (size_t i = 0; i < settings.GetExecutersNum(); i++) - { - auto ret = StartScriptExecuter(argv[0], settings.GetExecMsgKey(), &msgID); - if (ret < 0) - { - STG::Logger::get()("Start Script Executer error!"); - return -1; - } - if (ret == 1) - return 0; - } - - PIDFile pidFile(settings.GetPIDFileName()); - - 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. - - sigset_t signalSet; - sigfillset(&signalSet); - pthread_sigmask(SIG_BLOCK, &signalSet, NULL); - - StartTimer(); - WaitTimer(); - if (!IsStgTimerRunning()) - { - printfd(__FILE__, "Timer thread not started in 1 sec!\n"); - WriteServLog("Timer thread not started in 1 sec!"); - return -1; - } - - auto& loop = EVENT_LOOP_SINGLETON::GetInstance(); - - StoreLoader storeLoader(settings); - if (storeLoader.load()) - { - printfd(__FILE__, "Storage plugin: '%s'\n", storeLoader.GetStrError().c_str()); - WriteServLog("Storage plugin: '%s'", storeLoader.GetStrError().c_str()); - return -1; - } - - if (loop.Start()) - { - printfd(__FILE__, "Event loop not started.\n"); - WriteServLog("Event loop not started."); - return -1; - } - - auto& store = storeLoader.get(); - WriteServLog("Storage plugin: %s. Loading successfull.", store.GetVersion().c_str()); - - AdminsImpl admins(store); - TariffsImpl tariffs(&store); - ServicesImpl services(&store); - CorporationsImpl corps(&store); - UsersImpl users(&settings, &store, &tariffs, services, admins.sysAdmin()); - TraffCounterImpl traffCnt(&users, settings.GetRulesFileName()); - traffCnt.SetMonitorDir(settings.GetMonitorDir()); - - if (users.Start()) - return -1; - - WriteServLog("Users started successfully."); - - if (traffCnt.Start()) - return -1; - - WriteServLog("Traffcounter started successfully."); - - STG::PluginManager manager(settings, store, admins, tariffs, services, corps, users, traffCnt); - - srandom(static_cast(stgTime)); - - WriteServLog("Stg started successfully."); - WriteServLog("+++++++++++++++++++++++++++++++++++++++++++++"); - -#ifndef NO_DAEMON - creat(startFile.c_str(), S_IRUSR); -#endif - - bool running = true; - while (running) - { - sigfillset(&signalSet); - int sig = 0; - sigwait(&signalSet, &sig); - int status; - switch (sig) - { - case SIGHUP: - { - 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; - } - } - - WriteServLog("+++++++++++++++++++++++++++++++++++++++++++++"); - - manager.stop(); - - if (loop.Stop()) - WriteServLog("Event loop not stopped."); - - if (!traffCnt.Stop()) - WriteServLog("Traffcounter: Stop successfull."); - - if (!users.Stop()) - WriteServLog("Users: Stop successfull."); - - sleep(1); - int res = msgctl(msgID, IPC_RMID, NULL); - if (res) - WriteServLog("Queue was not removed. id=%d", msgID); - else - WriteServLog("Queue removed successfully."); - - KillExecuters(); - - StopStgTimer(); - WriteServLog("StgTimer: Stop successfull."); - - WriteServLog("Stg stopped successfully."); - WriteServLog("---------------------------------------------"); - - return 0; -} -//-----------------------------------------------------------------------------