/* * main.cpp * * Created on: 10.06.2014 * Author: matzman */ #include #include "GrowControl.h" #include "GCException.h" #include "IPCManager.h" #include "third-party/daemon.h" #include "third-party/pidfile.h" #include #include #include #include #include #include #include #include #include using namespace tfcppsimple; using namespace growcontrol; static log4cpp::Category& logger = log4cpp::Category::getInstance("growcontrol"); std::string pidFile = "/var/run/growcontrold.pid"; std::string socketPath = "/opt/growcontrol/growcontrold.socket"; std::string log4cppConfig = "log4cpp.config"; std::string host = "localhost"; std::string workDir = "/opt/growcontrol"; std::string heartBeatFile = "/opt/growcontrol/growcontrold.heartbeat"; uint16_t port = 4223; bool daemonMode = false; int pid_fd = 0; GrowControl controller; IPCManager ipcManager; bool termSignalCaught = false; void signalHandler(int signum) { signal (signum, signalHandler); switch (signum) { case SIGHUP: case SIGINT: case SIGTERM: logger << log4cpp::Priority::WARN << "Caught term signal, exiting ..."; termSignalCaught = true; controller.shutdownController(); break; default: break; } } void printUsage(std::ostream& stream, std::string name) { stream << "Usage: " << name << " [-d] [-pid pid-file] [-s socket-path] [-l log4cpp-config] [-h host] [-p port] [-w work-dir]" << std::endl << "\t-d ... daemon mode" << std::endl << "\t-pid ... pid-file" << std::endl << "\t-s ... path of ipc socket" << std::endl << "\t-l ... path to log4cpp config file" << std::endl << "\t-h ... brickd address" << std::endl << "\t-p ... brickd port" << std::endl << "\t-hb ... heartbeat file" << std::endl << "\t-w ... working directory" << std::endl; } int main(int argc, char **argv) { for (int t = 1; t < argc; t++) { if (strcmp(argv[t], "-d") == 0) { daemonMode = true; } else if (strcmp(argv[t], "--help") == 0) { printUsage(std::cerr, argv[0]); exit(0); } else if (strcmp(argv[t], "-pid") == 0) { if (t+1 < argc && argv[t+1][0] != '-') { t++; pidFile = argv[t]; } else { std::cerr << "Option -pid is missing an argument." << std::endl << std::endl; printUsage(std::cerr, argv[0]); exit(1); } } else if (strcmp(argv[t], "-s") == 0) { if (t+1 < argc && argv[t+1][0] != '-') { t++; socketPath = argv[t]; } else { std::cerr << "Option -s is missing an argument." << std::endl << std::endl; printUsage(std::cerr, argv[0]); exit(1); } } else if (strcmp(argv[t], "-l") == 0) { if (t+1 < argc && argv[t+1][0] != '-') { t++; log4cppConfig = argv[t]; } else { std::cerr << "Option -l is missing an argument." << std::endl << std::endl; printUsage(std::cerr, argv[0]); exit(1); } } else if (strcmp(argv[t], "-w") == 0) { if (t+1 < argc && argv[t+1][0] != '-') { t++; workDir = argv[t]; } else { std::cerr << "Option -w is missing an argument." << std::endl << std::endl; printUsage(std::cerr, argv[0]); exit(1); } } else if (strcmp(argv[t], "-h") == 0) { if (t+1 < argc && argv[t+1][0] != '-') { t++; host = argv[t]; } else { std::cerr << "Option -h is missing an argument." << std::endl << std::endl; printUsage(std::cerr, argv[0]); exit(1); } } else if (strcmp(argv[t], "-hb") == 0) { if (t+1 < argc && argv[t+1][0] != '-') { t++; heartBeatFile = argv[t]; } else { std::cerr << "Option -hb is missing an argument." << std::endl << std::endl; printUsage(std::cerr, argv[0]); exit(1); } } else if (strcmp(argv[t], "-p") == 0) { if (t+1 < argc && argv[t+1][0] != '-') { t++; port = std::atoi(argv[t]); if (port == 0) { std::cerr << "Option -p has invalid argument \"" << argv[t] << "\"." << std::endl << std::endl; printUsage(std::cerr, argv[0]); exit(1); } } else { std::cerr << "Option -p is missing an argument." << std::endl << std::endl; printUsage(std::cerr, argv[0]); exit(1); } } else { std::cerr << "Unknown argument \"" << argv[t] << "\"." << std::endl << std::endl; printUsage(std::cerr, argv[0]); exit(1); } } TfUtils::configureLog4CPP(log4cppConfig); logger << log4cpp::Priority::INFO << "Daemon Mode: " << daemonMode; logger << log4cpp::Priority::INFO << "Pid-File: " << pidFile; logger << log4cpp::Priority::INFO << "socket-path: " << socketPath; logger << log4cpp::Priority::INFO << "log4cpp-config: " << log4cppConfig; logger << log4cpp::Priority::INFO << "Brickd-Address: " << host << ":" << port; if (daemonMode) { pid_fd = daemon_start(pidFile.c_str()); } else { pid_fd = pidfile_acquire(pidFile.c_str(), getpid()); } if (pid_fd >= 0) { signal(SIGTERM, signalHandler); signal(SIGINT, signalHandler); signal(SIGHUP, signalHandler); controller.connect(workDir, host, port); if (!termSignalCaught) { sleep(2); try { ipcManager.init(controller, socketPath); } catch (GCException &e) { } controller.mainLoop(heartBeatFile); logger << log4cpp::Priority::WARN << "Shutting down ipc ..."; ipcManager.shutdown(); } } else { logger << log4cpp::Priority::WARN << "Problems while forking/writing pid-file."; } logger << log4cpp::Priority::WARN << "Shutting down ..."; if (pid_fd >= 0) { pidfile_release(pidFile.c_str(), pid_fd); } }