void gtBaseOpts::checkForIllegalOverrides (bpo::variables_map& res_vm, bpo::variables_map& final_vm) { // Check if there are any variables in restrictedConfig that: // 1. Are in the final map (they all should be) -and- // 2. Have different values in the two maps // These values were overridden from the settings in the restricted // config file, which is not allowed for (bpo::variables_map::iterator it = res_vm.begin(); it != res_vm.end(); ++it) { vectOfStr restValues = gtBaseOpts::vmValueToStrings (it->second); // Get variable values from final var map bpo::variable_value finalVv = final_vm[it->first]; vectOfStr finalValues = gtBaseOpts::vmValueToStrings (finalVv); // We don't care about order of vector elements std::sort(restValues.begin(), restValues.end()); std::sort(finalValues.begin(), finalValues.end()); if (restValues != finalValues) commandLineError ("Configuration file or CLI options may not" " override the options present in " + m_sys_restrict_cfg_file + ". Please check " "your settings for the program option \"" + it->first + "\". You specified \"" + finalValues[0] + "\" " + "but the restricted " "configuration value is \"" + restValues[0] + "\"."); } }
void PrintVariableMap(po::variables_map vm) { cout << "#############################################################" << endl; cout << "Parameters Using Default Values: " << endl; cout << "-------------------------------------------------------------" << endl; for (po::variables_map::iterator it = vm.begin(); it != vm.end(); ++it) if (vm[it->first].defaulted() || it->second.defaulted()) { int isString, isInt, isDouble; cout << std::right << std::setw(15) << it->first << " = " << setw(30) << std::left; try { cout << vm[it->first].as<string>() << " (string)" << std::endl; } catch (const boost::bad_any_cast &) { isString = false; } try { cout << vm[it->first].as<int>() << " (int)" << std::endl; } catch (const boost::bad_any_cast &) { isInt = false; } try { cout << vm[it->first].as<double>() << " (double)" << std::endl; } catch (const boost::bad_any_cast &) { isDouble = false; } } cout << "-------------------------------------------------------------" << endl; cout << "User Defined Parameters: " << endl; cout << "-------------------------------------------------------------" << endl; for (po::variables_map::iterator it = vm.begin(); it != vm.end(); ++it) if (! vm[it->first].defaulted() && ! it->second.defaulted() ) { int isString, isInt, isDouble; cout << std::right << setw(15) << it->first << " = " << setw(30) << std::left; try { cout << vm[it->first].as<string>() << " (string)" << std::endl; } catch (const boost::bad_any_cast &) { isString = false; } try { cout << vm[it->first].as<int>() << " (int)" << std::endl; } catch (const boost::bad_any_cast &) { isInt = false; } try { cout << vm[it->first].as<double>() << " (double)" << std::endl; } catch (const boost::bad_any_cast &) { isDouble = false; } } cout << "#############################################################" << endl; cout << endl; }
std::string serializeOptions(const po::variables_map &vm) { std::string s; for (po::variables_map::const_iterator it = vm.begin(); it != vm.end(); ++it) { if (it->second.value().type() == typeid(bool)) s += it->first + '=' + boost::lexical_cast<std::string>(boost::any_cast<bool>(it->second.value())); else if (it->second.value().type() == typeid(unsigned)) s += it->first + '=' + boost::lexical_cast<std::string>(boost::any_cast<unsigned>(it->second.value())); else if (it->second.value().type() == typeid(float)) s += it->first + '=' + boost::lexical_cast<std::string>(boost::any_cast<float>(it->second.value())); else if (it->second.value().type() == typeid(double)) s += it->first + '=' + boost::lexical_cast<std::string>(boost::any_cast<double>(it->second.value())); else if (it->second.value().type() == typeid(std::string)) s += it->first + '=' + boost::any_cast<std::string>(it->second.value()); s += ";;;"; } return s; }
void options_print(boost::program_options::variables_map &vm) { /** Populate this map with actions that will correctly * print each type of program option */ map<const type_info*, boost::function<void(const po::variable_value&)>, type_info_compare> action_map; action_map[&typeid(string)] = output_value<string>(); action_map[&typeid(int)] = output_value<int>(); action_map[&typeid(bool)] = output_value<bool>(); action_map[&typeid(float)] = output_value<float>(); po::variables_map::iterator it; cout << endl; for (it = vm.begin(); it != vm.end(); ++it) { // cout << setw(20) << left << it->first << ": "; const po::variable_value& v = it->second; if (!v.empty()) { cout << setw(20) << left << it->first << ": "; action_map[&v.value().type()](v); } } }
bool CmdLine::store( int argc , char ** argv , boost::program_options::options_description& visible, boost::program_options::options_description& hidden, boost::program_options::positional_options_description& positional, boost::program_options::variables_map ¶ms ) { { // setup binary name cmdLine.binaryName = argv[0]; size_t i = cmdLine.binaryName.rfind( '/' ); if ( i != string::npos ) cmdLine.binaryName = cmdLine.binaryName.substr( i + 1 ); // setup cwd char buffer[1024]; #ifdef _WIN32 verify( _getcwd( buffer , 1000 ) ); #else verify( getcwd( buffer , 1000 ) ); #endif cmdLine.cwd = buffer; } /* don't allow guessing - creates ambiguities when some options are * prefixes of others. allow long disguises and don't allow guessing * to get away with our vvvvvvv trick. */ int style = (((po::command_line_style::unix_style ^ po::command_line_style::allow_guessing) | po::command_line_style::allow_long_disguise) ^ po::command_line_style::allow_sticky); try { po::options_description all; all.add( visible ); all.add( hidden ); po::store( po::command_line_parser(argc, argv) .options( all ) .positional( positional ) .style( style ) .run(), params ); if ( params.count("config") ) { ifstream f( params["config"].as<string>().c_str() ); if ( ! f.is_open() ) { cout << "ERROR: could not read from config file" << endl << endl; cout << visible << endl; return false; } stringstream ss; CmdLine::parseConfigFile( f, ss ); po::store( po::parse_config_file( ss , all ) , params ); f.close(); } po::notify(params); } catch (po::error &e) { cout << "error command line: " << e.what() << endl; cout << "use --help for help" << endl; //cout << visible << endl; return false; } if (params.count("verbose")) { logLevel = 1; } for (string s = "vv"; s.length() <= 12; s.append("v")) { if (params.count(s)) { logLevel = s.length(); } } if (params.count("quiet")) { cmdLine.quiet = true; } if (params.count("traceExceptions")) { DBException::traceExceptions = true; } if ( params.count( "maxConns" ) ) { int newSize = params["maxConns"].as<int>(); if ( newSize < 5 ) { out() << "maxConns has to be at least 5" << endl; ::_exit( EXIT_BADOPTIONS ); } else if ( newSize >= 10000000 ) { out() << "maxConns can't be greater than 10000000" << endl; ::_exit( EXIT_BADOPTIONS ); } connTicketHolder.resize( newSize ); } if (params.count("objcheck")) { cmdLine.objcheck = true; } if (params.count("bind_ip")) { // passing in wildcard is the same as default behavior; remove and warn if ( cmdLine.bind_ip == "0.0.0.0" ) { cout << "warning: bind_ip of 0.0.0.0 is unnecessary; listens on all ips by default" << endl; cmdLine.bind_ip = ""; } } string logpath; #ifndef _WIN32 if (params.count("unixSocketPrefix")) { cmdLine.socket = params["unixSocketPrefix"].as<string>(); if (!fs::is_directory(cmdLine.socket)) { cout << cmdLine.socket << " must be a directory" << endl; ::_exit(-1); } } if (params.count("nounixsocket")) { cmdLine.noUnixSocket = true; } if (params.count("fork") && !params.count("shutdown")) { cmdLine.doFork = true; if ( ! params.count( "logpath" ) && ! params.count( "syslog" ) ) { cout << "--fork has to be used with --logpath or --syslog" << endl; ::_exit(EXIT_BADOPTIONS); } if ( params.count( "logpath" ) ) { // test logpath logpath = params["logpath"].as<string>(); verify( logpath.size() ); if ( logpath[0] != '/' ) { logpath = cmdLine.cwd + "/" + logpath; } bool exists = boost::filesystem::exists( logpath ); FILE * test = fopen( logpath.c_str() , "a" ); if ( ! test ) { cout << "can't open [" << logpath << "] for log file: " << errnoWithDescription() << endl; ::_exit(-1); } fclose( test ); // if we created a file, unlink it (to avoid confusing log rotation code) if ( ! exists ) { unlink( logpath.c_str() ); } } cout.flush(); cerr.flush(); cmdLine.parentProc = getpid(); // facilitate clean exit when child starts successfully setupLaunchSignals(); pid_t c = fork(); if ( c ) { int pstat; waitpid(c, &pstat, 0); if ( WIFEXITED(pstat) ) { if ( ! WEXITSTATUS(pstat) ) { cout << "child process started successfully, parent exiting" << endl; } _exit( WEXITSTATUS(pstat) ); } _exit(50); } if ( chdir("/") < 0 ) { cout << "Cant chdir() while forking server process: " << strerror(errno) << endl; ::_exit(-1); } setsid(); cmdLine.leaderProc = getpid(); pid_t c2 = fork(); if ( c2 ) { int pstat; cout << "forked process: " << c2 << endl; waitpid(c2, &pstat, 0); if ( WIFEXITED(pstat) ) { _exit( WEXITSTATUS(pstat) ); } _exit(51); } // stdout handled in initLogging //fclose(stdout); //freopen("/dev/null", "w", stdout); fclose(stderr); fclose(stdin); FILE* f = freopen("/dev/null", "w", stderr); if ( f == NULL ) { cout << "Cant reassign stderr while forking server process: " << strerror(errno) << endl; ::_exit(-1); } f = freopen("/dev/null", "r", stdin); if ( f == NULL ) { cout << "Cant reassign stdin while forking server process: " << strerror(errno) << endl; ::_exit(-1); } } setupSignals( true ); if (params.count("syslog")) { StringBuilder sb; sb << cmdLine.binaryName << "." << cmdLine.port; Logstream::useSyslog( sb.str().c_str() ); } #endif if (params.count("logpath") && !params.count("shutdown")) { if ( params.count("syslog") ) { cout << "Cant use both a logpath and syslog " << endl; ::_exit(EXIT_BADOPTIONS); } if ( logpath.size() == 0 ) logpath = params["logpath"].as<string>(); uassert( 10033 , "logpath has to be non-zero" , logpath.size() ); initLogging( logpath , params.count( "logappend" ) ); } if ( params.count("pidfilepath")) { writePidFile( params["pidfilepath"].as<string>() ); } if (params.count("keyFile")) { const string f = params["keyFile"].as<string>(); if (!setUpSecurityKey(f)) { // error message printed in setUpPrivateKey ::_exit(EXIT_BADOPTIONS); } cmdLine.keyFile = true; noauth = false; } else { cmdLine.keyFile = false; } #ifdef MONGO_SSL if (params.count("sslOnNormalPorts") ) { cmdLine.sslOnNormalPorts = true; if ( cmdLine.sslPEMKeyPassword.size() == 0 ) { log() << "need sslPEMKeyPassword" << endl; ::_exit(EXIT_BADOPTIONS); } if ( cmdLine.sslPEMKeyFile.size() == 0 ) { log() << "need sslPEMKeyFile" << endl; ::_exit(EXIT_BADOPTIONS); } cmdLine.sslServerManager = new SSLManager( false ); if ( ! cmdLine.sslServerManager->setupPEM( cmdLine.sslPEMKeyFile , cmdLine.sslPEMKeyPassword ) ) { ::_exit(EXIT_BADOPTIONS); } } else if ( cmdLine.sslPEMKeyFile.size() || cmdLine.sslPEMKeyPassword.size() ) { log() << "need to enable sslOnNormalPorts" << endl; ::_exit(EXIT_BADOPTIONS); } #endif { BSONObjBuilder b; for (po::variables_map::const_iterator it(params.begin()), end(params.end()); it != end; it++){ if (!it->second.defaulted()){ const string& key = it->first; const po::variable_value& value = it->second; const type_info& type = value.value().type(); if (type == typeid(string)){ if (value.as<string>().empty()) b.appendBool(key, true); // boost po uses empty string for flags like --quiet else { if ( key == "servicePassword" || key == "sslPEMKeyPassword" ) { b.append( key, "<password>" ); } else { b.append( key, value.as<string>() ); } } } else if (type == typeid(int)) b.append(key, value.as<int>()); else if (type == typeid(double)) b.append(key, value.as<double>()); else if (type == typeid(bool)) b.appendBool(key, value.as<bool>()); else if (type == typeid(long)) b.appendNumber(key, (long long)value.as<long>()); else if (type == typeid(unsigned)) b.appendNumber(key, (long long)value.as<unsigned>()); else if (type == typeid(unsigned long long)) b.appendNumber(key, (long long)value.as<unsigned long long>()); else if (type == typeid(vector<string>)) b.append(key, value.as<vector<string> >()); else b.append(key, "UNKNOWN TYPE: " + demangleName(type)); } } parsedOpts = b.obj(); } { BSONArrayBuilder b; for (int i=0; i < argc; i++) { b << argv[i]; if ( mongoutils::str::equals(argv[i], "--sslPEMKeyPassword") || mongoutils::str::equals(argv[i], "-sslPEMKeyPassword") || mongoutils::str::equals(argv[i], "--servicePassword") || mongoutils::str::equals(argv[i], "-servicePassword")) { b << "<password>"; i++; // hide password from ps output char* arg = argv[i]; while (*arg) { *arg++ = 'x'; } } } argvArray = b.arr(); } return true; }
bool CmdLine::store( const std::vector<std::string>& argv, boost::program_options::options_description& visible, boost::program_options::options_description& hidden, boost::program_options::positional_options_description& positional, boost::program_options::variables_map ¶ms ) { if (argv.empty()) return false; { // setup binary name cmdLine.binaryName = argv[0]; size_t i = cmdLine.binaryName.rfind( '/' ); if ( i != string::npos ) cmdLine.binaryName = cmdLine.binaryName.substr( i + 1 ); // setup cwd char buffer[1024]; #ifdef _WIN32 verify( _getcwd( buffer , 1000 ) ); #else verify( getcwd( buffer , 1000 ) ); #endif cmdLine.cwd = buffer; } /* don't allow guessing - creates ambiguities when some options are * prefixes of others. allow long disguises and don't allow guessing * to get away with our vvvvvvv trick. */ int style = (((po::command_line_style::unix_style ^ po::command_line_style::allow_guessing) | po::command_line_style::allow_long_disguise) ^ po::command_line_style::allow_sticky); try { po::options_description all; all.add( visible ); all.add( hidden ); po::store( po::command_line_parser(std::vector<std::string>(argv.begin() + 1, argv.end())) .options( all ) .positional( positional ) .style( style ) .run(), params ); if ( params.count("config") ) { ifstream f( params["config"].as<string>().c_str() ); if ( ! f.is_open() ) { cout << "ERROR: could not read from config file" << endl << endl; cout << visible << endl; return false; } stringstream ss; CmdLine::parseConfigFile( f, ss ); po::store( po::parse_config_file( ss , all ) , params ); f.close(); } po::notify(params); } catch (po::error &e) { cout << "error command line: " << e.what() << endl; cout << "use --help for help" << endl; //cout << visible << endl; return false; } { BSONArrayBuilder b; std::vector<std::string> censoredArgv = argv; censor(&censoredArgv); for (size_t i=0; i < censoredArgv.size(); i++) { b << censoredArgv[i]; } argvArray = b.arr(); } { BSONObjBuilder b; for (po::variables_map::const_iterator it(params.begin()), end(params.end()); it != end; it++){ if (!it->second.defaulted()){ const string& key = it->first; const po::variable_value& value = it->second; const type_info& type = value.value().type(); if (type == typeid(string)){ if (value.as<string>().empty()) b.appendBool(key, true); // boost po uses empty string for flags like --quiet else { if ( _isPasswordArgument(key.c_str()) ) { b.append( key, "<password>" ); } else { b.append( key, value.as<string>() ); } } } else if (type == typeid(int)) b.append(key, value.as<int>()); else if (type == typeid(double)) b.append(key, value.as<double>()); else if (type == typeid(bool)) b.appendBool(key, value.as<bool>()); else if (type == typeid(long)) b.appendNumber(key, (long long)value.as<long>()); else if (type == typeid(unsigned)) b.appendNumber(key, (long long)value.as<unsigned>()); else if (type == typeid(unsigned long long)) b.appendNumber(key, (long long)value.as<unsigned long long>()); else if (type == typeid(vector<string>)) b.append(key, value.as<vector<string> >()); else b.append(key, "UNKNOWN TYPE: " + demangleName(type)); } } parsedOpts = b.obj(); } if (params.count("verbose")) { logLevel = 1; } for (string s = "vv"; s.length() <= 12; s.append("v")) { if (params.count(s)) { logLevel = s.length(); } } if (params.count("quiet")) { cmdLine.quiet = true; } if (params.count("traceExceptions")) { DBException::traceExceptions = true; } if (params.count("maxConns")) { cmdLine.maxConns = params["maxConns"].as<int>(); if ( cmdLine.maxConns < 5 ) { out() << "maxConns has to be at least 5" << endl; return false; } else if ( cmdLine.maxConns > MAX_MAX_CONN ) { out() << "maxConns can't be greater than " << MAX_MAX_CONN << endl; return false; } } if (params.count("objcheck")) { cmdLine.objcheck = true; } if (params.count("noobjcheck")) { if (params.count("objcheck")) { out() << "can't have both --objcheck and --noobjcheck" << endl; return false; } cmdLine.objcheck = false; } if (params.count("bind_ip")) { // passing in wildcard is the same as default behavior; remove and warn if ( cmdLine.bind_ip == "0.0.0.0" ) { cout << "warning: bind_ip of 0.0.0.0 is unnecessary; listens on all ips by default" << endl; cmdLine.bind_ip = ""; } } #ifndef _WIN32 if (params.count("unixSocketPrefix")) { cmdLine.socket = params["unixSocketPrefix"].as<string>(); } if (params.count("nounixsocket")) { cmdLine.noUnixSocket = true; } if (params.count("fork") && !params.count("shutdown")) { cmdLine.doFork = true; } #endif // _WIN32 if (params.count("logpath")) { cmdLine.logpath = params["logpath"].as<string>(); if (cmdLine.logpath.empty()) { cout << "logpath cannot be empty if supplied" << endl; return false; } } cmdLine.logWithSyslog = params.count("syslog"); cmdLine.logAppend = params.count("logappend"); if (!cmdLine.logpath.empty() && cmdLine.logWithSyslog) { cout << "Cant use both a logpath and syslog " << endl; return false; } if (cmdLine.doFork && cmdLine.logpath.empty() && !cmdLine.logWithSyslog) { cout << "--fork has to be used with --logpath or --syslog" << endl; return false; } if (params.count("keyFile")) { cmdLine.keyFile = params["keyFile"].as<string>(); } if ( params.count("pidfilepath")) { cmdLine.pidFile = params["pidfilepath"].as<string>(); } if (params.count("setParameter")) { std::vector<std::string> parameters = params["setParameter"].as<std::vector<std::string> >(); for (size_t i = 0, length = parameters.size(); i < length; ++i) { std::string name; std::string value; if (!mongoutils::str::splitOn(parameters[i], '=', name, value)) { cout << "Illegal option assignment: \"" << parameters[i] << "\"" << endl; return false; } ServerParameter* parameter = mapFindWithDefault( ServerParameterSet::getGlobal()->getMap(), name, static_cast<ServerParameter*>(NULL)); if (NULL == parameter) { cout << "Illegal --option parameter: \"" << name << "\"" << endl; return false; } Status status = parameter->setFromString(value); if (!status.isOK()) { cout << "Bad value for parameter \"" << name << "\": " << status.reason() << endl; return false; } } } #ifdef MONGO_SSL if (params.count("sslWeakCertificateValidation")) { cmdLine.sslWeakCertificateValidation = true; } if (params.count("sslOnNormalPorts")) { cmdLine.sslOnNormalPorts = true; if ( cmdLine.sslPEMKeyFile.size() == 0 ) { log() << "need sslPEMKeyFile" << endl; return false; } if (cmdLine.sslWeakCertificateValidation && cmdLine.sslCAFile.empty()) { log() << "need sslCAFile with sslWeakCertificateValidation" << endl; return false; } } else if (cmdLine.sslPEMKeyFile.size() || cmdLine.sslPEMKeyPassword.size() || cmdLine.sslCAFile.size() || cmdLine.sslCRLFile.size() || cmdLine.sslWeakCertificateValidation) { log() << "need to enable sslOnNormalPorts" << endl; return false; } #endif return true; }
void WorldRouter::registerConfig( boost::program_options::variables_map& v ) { /* * Primary Toggle * */ if( v.count("primary") ) { std::string s = v["primary"].as<std::string>(); if ( boost::iequals(s,"true") ) { m_Primary = true; } else if ( boost::iequals(s,"false") ) { m_Primary = false; } } std::cout << " m_Primary: " << m_Primary << std::endl; /* * Broker URI */ if( v.count("global.broker") ) { m_Broker = v["global.broker"].as<std::string>(); std::cout << "globl.broker taken" << std::endl; } std::cout << " m_Broker: " << m_Broker << std::endl; /* * What's my name */ if ( v.count("name") ) { m_Name = v["name"].as<std::string>(); } std::cout << " m_Name: " << m_Name << std::endl; /* * Broker inqueue */ if( v.count( (m_Name+".master.q").c_str() ) ) { m_MasterQueue = v[(m_Name+".master.q").c_str()].as<std::string>(); } std::cout << " m_MasterQueue: " << m_MasterQueue << std::endl; /* * Internal queue */ if( v.count( (m_Name+".internal.wrq").c_str() ) ) { m_InternalQueue = v[(m_Name+".internal.wrq").c_str()].as<std::string>(); } /* * Just dump the fully known config out */ for (boost::program_options::variables_map::iterator it=v.begin(); it!=v.end(); ++it ) { if ( it->second.value().type() == typeid(int) ) { std::cout << " " << it->first.c_str() << " = " << it->second.as<int>() << std::endl; } else if (it->second.value().type() == typeid(std::string) ) { std::cout << " " << it->first.c_str() << " = " << it->second.as<std::string>().c_str() << std::endl; } } }
void MetaServer::registerConfig( boost::program_options::variables_map & vm ) { /* * All configuration items passed in must be converted to local type * member variables, or are ignored. We do not want to reference a * variable_map during operation as a bad_cast exception could cause * server failure during the run loop. */ if( vm.count("performance.server_session_expiry_seconds") ) m_sessionExpirySeconds = vm["performance.server_session_expiry_seconds"].as<int>(); if( vm.count("performance.client_session_expiry_seconds") ) m_clientExpirySeconds = vm["performance.client_session_expiry_seconds"].as<int>(); if ( vm.count("performance.max_client_sessions") ) m_maxClientSessions = vm["performance.max_client_sessions"].as<int>(); if ( vm.count("performance.max_server_sessions") ) m_maxServerSessions = vm["performance.max_server_sessions"].as<int>(); if( vm.count("server.client_stats") ) { std::string s = vm["server.client_stats"].as<std::string>(); if ( boost::iequals(s,"true") ) { m_keepClientStats = true; } else if ( boost::iequals(s,"false") ) { m_keepClientStats = false; } } if( vm.count("server.server_stats") ) { std::string s = vm["server.server_stats"].as<std::string>(); if ( boost::iequals(s,"true") ) { m_keepServerStats = true; } else if ( boost::iequals(s,"false") ) { m_keepServerStats = false; } } if( vm.count("server.daemon") ) { std::string s = vm["server.daemon"].as<std::string>(); if ( boost::iequals(s,"true") ) { m_isDaemon = true; } else if ( boost::iequals(s,"false") ) { m_isDaemon = false; } } if( vm.count("logging.server_sessions") ) { std::string s = vm["logging.server_sessions"].as<std::string>(); if ( boost::iequals(s,"true") ) { m_logServerSessions = true; } else if ( boost::iequals(s,"false") ) { m_logServerSessions = false; } } if( vm.count("logging.client_sessions") ) { std::string s = vm["logging.client_sessions"].as<std::string>(); if ( boost::iequals(s,"true") ) { m_logClientSessions = true; } else if ( boost::iequals(s,"false") ) { m_logClientSessions = false; } } if ( vm.count("logging.packet_logging") ) { std::string s = vm["logging.packet_logging"].as<std::string>(); if ( boost::iequals(s,"true") ) { m_logPackets = true; } else if ( boost::iequals(s,"false") ) { m_logPackets = false; } } if( vm.count("logging.packet_logfile") ) { m_PacketLogfile = vm["logging.packet_logfile"].as<std::string>(); std::cout << "logging.packet_logfile: " << m_PacketLogfile << std::endl; /* * Set a hard default if it's not specified */ if( m_PacketLogfile.length() == 0 ) { m_PacketLogfile = "~/.metaserver-ng/packetdefault.bin"; } if ( m_PacketLogfile.substr(0,1) == "~") { m_PacketLogfile.replace(0,1, std::getenv("HOME") ); } } if ( vm.count("logging.packet_logging_flush_seconds")) m_packetLoggingFlushSeconds = vm["logging.packet_logging_flush_seconds"].as<unsigned int>(); if( vm.count("server.logfile") ) { m_Logfile = vm["server.logfile"].as<std::string>(); /** * I tried to use boost::filesystem here, but it is so very stupid * that I have opted for the more brittle way, because at least it works. * * TODO: add ifdef WIN32 here if/when metserver needs to run on windows */ if ( m_Logfile.substr(0,1) == "~") { m_Logfile.replace(0,1, std::getenv("HOME") ); } } /** * Initialise the logger to appropriately */ initLogger(); /** * Initialise the packet logger */ if ( m_logPackets ) { m_PacketLogger = new PacketLogger(m_PacketLogfile); } /** * Print out the startup values */ m_Logger.info("WorldForge MetaServer Runtime Configuration"); for (boost::program_options::variables_map::iterator it=vm.begin(); it!=vm.end(); ++it ) { if ( it->second.value().type() == typeid(int) ) { m_Logger.info( "%s = %u", it->first.c_str(), it->second.as<int>()); } else if (it->second.value().type() == typeid(std::string) ) { m_Logger.info( "%s = %s", it->first.c_str(), it->second.as<std::string>().c_str() ); } } }