+#include <iostream>
+#include <fstream>
+#include <iterator>
+
#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<class T>
+ ostream& operator<<( ostream& os, const vector<T>& v )
+ {
+ copy( v.begin(), v.end(), ostream_iterator<T> ( 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<string>()->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<int>()->default_value( 4 ), "Limit of host that have to be down in order to notify." )
+ ( "host", value< vector<string> >(), "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<string> ();
+ }
+
+ 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;
}
#ifndef CONFIGURATIONREADER_H_
#define CONFIGURATIONREADER_H_
+#include <string>
+#include <boost/program_options.hpp>
+
#include "configuration.h"
class ConfigurationReader
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_ */
#include <iostream>
#include <ostream>
+#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 <host>" << 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;
}