#define ELPP_DISABLE_DEFAULT_CRASH_HANDLING 1 #define ELPP_DEFAULT_LOG_FILE "logs/swgchat.log" #include "easylogging++.h" #include "StationChatApp.hpp" #include #include #include #include #include #ifdef __GNUC__ #include #endif INITIALIZE_EASYLOGGINGPP StationChatConfig BuildConfiguration(int argc, const char* argv[]); #ifdef __GNUC__ void SignalHandler(int sig); #endif int main(int argc, const char* argv[]) { #ifdef __GNUC__ signal(SIGSEGV, SignalHandler); #endif auto config = BuildConfiguration(argc, argv); el::Loggers::setDefaultConfigurations(config.loggerConfig, true); START_EASYLOGGINGPP(argc, argv); StationChatApp app{config}; while (app.IsRunning()) { app.Tick(); std::this_thread::sleep_for(std::chrono::milliseconds(1)); } return 0; } StationChatConfig BuildConfiguration(int argc, const char* argv[]) { namespace po = boost::program_options; StationChatConfig config; std::string configFile; // Declare a group of options that will be // allowed only on command line po::options_description generic("Generic options"); generic.add_options() ("help,h", "produces help message") ("config,c", po::value(&configFile)->default_value("etc/stationapi/swgchat.cfg"), "sets path to the configuration file") ("logger_config", po::value(&config.loggerConfig)->default_value("etc/stationapi/logger.cfg"), "sets path to the logger configuration file") ; po::options_description options("Configuration"); options.add_options() ("gateway_address", po::value(&config.gatewayAddress)->default_value("127.0.0.1"), "address for gateway connections") ("gateway_port", po::value(&config.gatewayPort)->default_value(5001), "port for gateway connections") ("registrar_address", po::value(&config.registrarAddress)->default_value("127.0.0.1"), "address for registrar connections") ("registrar_port", po::value(&config.registrarPort)->default_value(5000), "port for registrar connections") ("bind_to_ip", po::value(&config.bindToIp)->default_value(false), "when set to true, binds to the config address; otherwise, binds on any interface") ("database_path", po::value(&config.chatDatabasePath)->default_value("var/stationapi/stationchat.db"), "path to the sqlite3 database file") ; po::options_description cmdline_options; cmdline_options.add(generic).add(options); po::options_description config_file_options; config_file_options.add(options); po::variables_map vm; po::store(po::command_line_parser(argc, argv).options(cmdline_options).allow_unregistered().run(), vm); po::notify(vm); std::ifstream ifs(configFile.c_str()); if (!ifs) { throw std::runtime_error("Cannot open configuration file: " + configFile); } po::store(po::parse_config_file(ifs, config_file_options), vm); po::notify(vm); if (vm.count("help")) { std::cout << cmdline_options << "\n"; exit(EXIT_SUCCESS); } return config; } #ifdef __GNUC__ void SignalHandler(int sig) { const int BACKTRACE_LIMIT = 10; void *arr[BACKTRACE_LIMIT]; auto size = backtrace(arr, BACKTRACE_LIMIT); fprintf(stderr, "Error: signal %d:\n", sig); backtrace_symbols_fd(arr, size, STDERR_FILENO); exit(1); } #endif