From: Guilherme Maciel Ferreira Date: Mon, 21 Feb 2011 09:49:10 +0000 (+0100) Subject: First version of command line and config file parsing X-Git-Tag: v1.0~200 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=aa48371a44945b8ebedca8d7ee283b3b794ccddc;p=pingcheck First version of command line and config file parsing --- diff --git a/src/config/configuration.cpp b/src/config/configuration.cpp index ce1bab4..9e1ec28 100644 --- a/src/config/configuration.cpp +++ b/src/config/configuration.cpp @@ -1,9 +1,36 @@ +#include + #include "configuration.h" -Configuration::Configuration() +using namespace std; +using namespace boost::program_options; + +Configuration::Configuration() : + limit_to_notify( 0 ) { } Configuration::~Configuration() { } + +bool Configuration::read( variables_map vm ) +{ + if ( vm.count( "limit-to-notify" ) ) + { + limit_to_notify = vm[ "limit-to-notify" ].as (); + cout << "limit-to-notify:" << limit_to_notify << endl; + } + + return true; +} + +uint32_t Configuration::get_limit_to_notify() const +{ + return limit_to_notify; +} + +void Configuration::set_limit_to_notify( uint32_t limit_to_notify ) +{ + this->limit_to_notify = limit_to_notify; +} diff --git a/src/config/configuration.h b/src/config/configuration.h index af72f76..984fc59 100644 --- a/src/config/configuration.h +++ b/src/config/configuration.h @@ -1,9 +1,10 @@ #ifndef CONFIGURATION_H_ #define CONFIGURATION_H_ +#include #include #include -#include +#include #include "host.h" @@ -13,14 +14,13 @@ public: Configuration(); virtual ~Configuration(); - virtual void read() = 0; + bool read( boost::program_options::variables_map vm ); + + uint32_t get_limit_to_notify() const; + void set_limit_to_notify( uint32_t limit_to_notify ); private: - std::string call_fail_command; - std::string logfile; - bool daemonize; - uint32_t limit_down_hosts_to_notify; - std::vector hosts; + uint32_t limit_to_notify; }; diff --git a/src/config/configurationreader.cpp b/src/config/configurationreader.cpp index c213753..648a806 100644 --- a/src/config/configurationreader.cpp +++ b/src/config/configurationreader.cpp @@ -1,30 +1,150 @@ +#include +#include +#include + #include "configurationreader.h" -ConfigurationReader::ConfigurationReader() +using namespace std; +using namespace boost::program_options; + +ConfigurationReader::ConfigurationReader() : + configuration(), + default_config_file_name( "pingcheck.cfg" ) { - // TODO how to select the source? Shall the main pass the command line? } ConfigurationReader::~ConfigurationReader() { } -void ConfigurationReader::read() +// A helper function to simplify the main part. +template + ostream& operator<<( ostream& os, const vector& v ) + { + copy( v.begin(), v.end(), ostream_iterator ( cout, " " ) ); + return os; + } + +options_description ConfigurationReader::get_generic_options() const +{ + options_description options( "Generic options" ); + options.add_options() + ( "version,v", "Print the version string and exit." ) + ( "help,h", "Print this help and exit." ) + ( "config-file", value()->default_value( default_config_file_name ), "Name of the configuration file." ); + + return options; +} + +options_description ConfigurationReader::get_configuration_options() const +{ + options_description options( "Configuration" ); + options.add_options() + ( "limit-to-notify", value()->default_value( 4 ), "Limit of host that have to be down in order to notify." ) + ( "host", value< vector >(), "Host address" ); + + return options; +} + +bool ConfigurationReader::parse_command_line( + const int argc, + char* argv[], + variables_map& vm +) { - // if user provides parameters to command line - // parse and use the parameters - // configuration = new ConfigurationCommandLine - // if user provides a file path to command line - // read the given configuration file - // configuration = new ConfigurationFile( file from command line ) - // if user doesn't provide any file or parameters - // read the default file at the default location - // configuration = new ConfigurationFile( default file ) - // - // configuration->read(); + try + { + options_description generic = get_generic_options(); + options_description config = get_configuration_options(); + + options_description cmdline_options; + cmdline_options.add( generic ).add( config ); + + options_description visible( "Allowed options" ); + visible.add( generic ).add( config ); + + positional_options_description p; + p.add( "host", -1 ); + + store( command_line_parser( argc, argv ). + options( cmdline_options ). + positional( p ).run(), vm ); + notify( vm ); + + if ( vm.count( "help" ) ) + { + cout << visible << endl; + return false; + } + + if ( vm.count( "version" ) ) + { + cout << "pingcheck version " << VERSION_STRING << endl; + return false; + } + } + catch ( exception& e ) + { + cout << e.what() << endl; + return false; + } + + return true; +} + +bool ConfigurationReader::parse_configuration_file( variables_map& vm ) +{ + string config_file_name; + if ( vm.count( "config-file" ) ) + { + config_file_name = vm[ "config-file" ].as (); + } + + return parse_configuration_file( config_file_name, vm ); +} + +bool ConfigurationReader::parse_configuration_file( + const string& config_file_name, + variables_map& vm +) +{ + ifstream ifs( config_file_name.c_str() ); + if ( !ifs ) + { + cout << "Can not open " << config_file_name << " file\n"; + return false; + } + else + { + options_description config = get_configuration_options(); + options_description config_file_options; + config_file_options.add( config ); + + store( parse_config_file( ifs, config_file_options ), vm ); + notify( vm ); + } + + return true; +} + +bool ConfigurationReader::read( const int argc, char* argv[] ) +{ + variables_map vm; + bool command_line_parsed = parse_command_line( argc, argv, vm ); + bool configuration_file_parsed = parse_configuration_file( vm ); + + bool parser_success = command_line_parsed && configuration_file_parsed; + if (parser_success) + { + return configuration.read( vm ); + } + else + { + return false; + } } -Configuration *ConfigurationReader::getConfiguration() const +Configuration ConfigurationReader::getConfiguration() const { return configuration; } diff --git a/src/config/configurationreader.h b/src/config/configurationreader.h index 11a9767..dce0c01 100644 --- a/src/config/configurationreader.h +++ b/src/config/configurationreader.h @@ -1,6 +1,9 @@ #ifndef CONFIGURATIONREADER_H_ #define CONFIGURATIONREADER_H_ +#include +#include + #include "configuration.h" class ConfigurationReader @@ -9,11 +12,26 @@ public: ConfigurationReader(); virtual ~ConfigurationReader(); - void read(); - Configuration *getConfiguration() const; + bool read( const int argc, char* argv[] ); + Configuration getConfiguration() const; + +private: + boost::program_options::options_description get_generic_options() const; + boost::program_options::options_description get_configuration_options() const; + bool parse_command_line( + const int argc, + char* argv[], + boost::program_options::variables_map& vm + ); + bool parse_configuration_file( boost::program_options::variables_map& vm ); + bool parse_configuration_file( + const std::string& config_file_name, + boost::program_options::variables_map& vm + ); private: - Configuration *configuration; + Configuration configuration; + const std::string default_config_file_name; }; #endif /* CONFIGURATIONREADER_H_ */ diff --git a/src/main.cpp b/src/main.cpp index 2aff178..7613610 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,28 +4,33 @@ #include #include +#include "configurationreader.h" #include "host.h" #include "boostpinger.h" int main( int argc, char* argv[] ) { - if (argc != 2) + // sends the program command line to be parsed by the configuration reader + ConfigurationReader config_reader; + bool read_success = config_reader.read( argc, argv ); + if ( read_success ) { - std::cerr << "Usage: ping " << std::endl; - std::cerr << "(You may need to run this program as root.)" << std::endl; - return 1; + try + { + boost::asio::io_service io_service; + BoostPinger p( io_service ); +// Configuration configuration = config_reader.getConfiguration(); +// Host host( configuration.get_hosts().at(0) ); // TODO pass Configuration object + Host host( argv[1] ); + p.ping( host ); + io_service.run(); + } + catch ( std::exception& e ) + { + std::cerr << "Exception: " << e.what() << std::endl; + return -1; + } } - try - { - boost::asio::io_service io_service; - BoostPinger p( io_service ); - Host host( argv[ 1 ] ); - p.ping( host ); - io_service.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << std::endl; - } + return 0; } diff --git a/uml/libpingcheck.vpp b/uml/libpingcheck.vpp index afb4256..3c637d9 100644 Binary files a/uml/libpingcheck.vpp and b/uml/libpingcheck.vpp differ