2 The software in this package is distributed under the GNU General
3 Public License version 2 (with a special exception described below).
5 A copy of GNU General Public License (GPL) is included in this distribution,
6 in the file COPYING.GPL.
8 As a special exception, if other files instantiate templates or use macros
9 or inline functions from this file, or you compile this file and link it
10 with other works to produce a work based on this file, this file
11 does not by itself cause the resulting work to be covered
12 by the GNU General Public License.
14 However the source code for this file must still be made available
15 in accordance with section (3) of the GNU General Public License.
17 This exception does not invalidate any other reasons why a work based
18 on this file might be covered by the GNU General Public License.
21 #include "config/configurationoptions.h"
25 #include <boost/foreach.hpp>
27 #include <logfunc.hpp>
29 #include "boost_assert_handler.h"
30 #include "config/option/configfileoption.h"
31 #include "config/option/daemonoption.h"
32 #include "config/option/hostsdownlimitoption.h"
33 #include "config/option/hostnameoption.h"
34 #include "config/option/hostportoption.h"
35 #include "config/option/hostpingprotocoloption.h"
36 #include "config/option/hostpingintervaloption.h"
37 #include "config/option/hostsourcenetworkinterfaceoption.h"
38 #include "config/option/linkdownintervaloption.h"
39 #include "config/option/linkupintervaloption.h"
40 #include "config/option/logleveloption.h"
41 #include "config/option/logoutputoption.h"
42 #include "config/option/logfileoption.h"
43 #include "config/option/nameserveroption.h"
44 #include "config/option/pingfaillimitoption.h"
45 #include "config/option/sourcenetworkinterfaceoption.h"
46 #include "config/option/statusnotifiercmdoption.h"
47 #include "config/option/versionoption.h"
48 #include "config/option/ratiorandomhostsoption.h"
49 #include "config/option/pingreplytimeoutoption.h"
50 #include "config/option/maxaddressresolutionattemptsoption.h"
51 #include "config/option/resolvedipttlthresholdoption.h"
52 #include "config/option/mintimebetweenresolvesoption.h"
53 #include "config/option/dnscachefileoption.h"
56 using boost::program_options::option_description;
57 using boost::program_options::options_description;
58 using boost::program_options::value;
59 using boost::program_options::variables_map;
60 using boost::shared_ptr;
61 using I2n::Logger::GlobalLogger;
63 //-----------------------------------------------------------------------------
64 // ConfigurationOptions
65 //-----------------------------------------------------------------------------
68 * @brief Default constructor.
70 ConfigurationOptions::ConfigurationOptions() :
75 HelpCmdDesc( "Print this help and exit." )
77 ConfigurationOptionItem config_file( new ConfigFileOption );
78 GenericOptions.push_back( config_file );
80 ConfigurationOptionItem daemon( new DaemonOption );
81 GenericOptions.push_back( daemon );
83 ConfigurationOptionItem version( new VersionOption );
84 GenericOptions.push_back( version );
86 ConfigurationOptionItem log_level( new LogLevelOption );
87 GenericOptions.push_back( log_level );
89 ConfigurationOptionItem log_output( new LogOutputOption );
90 GenericOptions.push_back( log_output );
92 ConfigurationOptionItem log_file( new LogFileOption );
93 GenericOptions.push_back( log_file );
95 ConfigurationOptionItem hosts_down_limit( new HostsDownLimitOption );
96 ConfigOptions.push_back( hosts_down_limit );
98 ConfigurationOptionItem link_down_interval( new LinkDownIntervalOption );
99 ConfigOptions.push_back( link_down_interval );
101 ConfigurationOptionItem link_up_interval( new LinkUpIntervalOption );
102 ConfigOptions.push_back( link_up_interval );
104 ConfigurationOptionItem nameserver( new NameserverOption );
105 ConfigOptions.push_back( nameserver );
107 ConfigurationOptionItem ping_fail_limit( new PingFailLimitOption );
108 ConfigOptions.push_back( ping_fail_limit );
110 ConfigurationOptionItem source_network_interface( new SourceNetworkInterfaceOption );
111 ConfigOptions.push_back( source_network_interface );
113 ConfigurationOptionItem status_notifier_cmd( new StatusNotifierCmdOption );
114 ConfigOptions.push_back( status_notifier_cmd );
116 ConfigurationOptionItem ping_reply_timeout( new PingReplyTimeoutOption );
117 ConfigOptions.push_back( ping_reply_timeout );
119 ConfigurationOptionItem max_address_resolution_attempts( new MaxAddressResolutionAttemptsOption );
120 ConfigOptions.push_back( max_address_resolution_attempts );
122 ConfigurationOptionItem resolved_ip_ttl_threshold( new ResolvedIpTtlThresholdOption );
123 ConfigOptions.push_back( resolved_ip_ttl_threshold );
125 ConfigurationOptionItem min_time_between_resolves( new MinTimeBetweenResolvesOption );
126 ConfigOptions.push_back( min_time_between_resolves );
128 ConfigurationOptionItem ratio_random_hosts( new RatioRandomHostsOption );
129 ConfigOptions.push_back( ratio_random_hosts );
131 ConfigurationOptionItem dns_cache_file( new DnsCacheFileOption );
132 ConfigOptions.push_back( dns_cache_file );
134 HostConfigurationOptionItem host_name( new HostNameOption );
135 HostOptions.push_back( host_name );
137 HostConfigurationOptionItem host_port( new HostPortOption );
138 HostOptions.push_back( host_port );
140 HostConfigurationOptionItem host_source_network_interface( new HostSourceNetworkInterfaceOption );
141 HostOptions.push_back( host_source_network_interface );
143 HostConfigurationOptionItem host_protocol( new HostPingProtocolOption );
144 HostOptions.push_back( host_protocol );
146 HostConfigurationOptionItem host_interval( new HostPingIntervalOption );
147 HostOptions.push_back( host_interval );
153 ConfigurationOptions::~ConfigurationOptions()
158 * @return The options which are common to all kinds of applications.
160 options_description ConfigurationOptions::get_generic_options() const
162 options_description options( "Generic options" );
164 options.add_options()
165 ( HelpCmdStr.c_str(), HelpCmdDesc.c_str() )
168 BOOST_FOREACH( ConfigurationOptionItem generic_option, GenericOptions )
170 // Do not pass the the underlying boost::program_options::option_description
171 // object from ConfigurationOption to the
172 // boost::program_options::options_description::add() method, because it
173 // deletes the boost::program_options::option_description, causing
174 // multiple freed when ConfigurationOption try to delete it.
175 option_description option = generic_option->get_option_description();
176 shared_ptr< option_description > ptr( new option_description( option ) );
184 * @return The options which are specific to this application.
186 options_description ConfigurationOptions::get_configuration_options() const
188 options_description options( "Configuration" );
190 BOOST_FOREACH( ConfigurationOptionItem configuration_option, ConfigOptions )
192 option_description option = configuration_option->get_option_description();
193 shared_ptr< option_description > ptr( new option_description( option ) );
197 BOOST_FOREACH( ConfigurationOptionItem host_option, HostOptions )
199 option_description option = host_option->get_option_description();
200 shared_ptr< option_description > ptr( new option_description( option ) );
208 * @brief Parse the options common to all kinds of applications.
210 * @param vm The input @c boost::program_options::variables_map.
211 * @param configuration The output @c Configuration filled with the parsed
214 * @return @c true if it was parsed at least one option, or @c false if there
215 * were no options available in this category.
217 bool ConfigurationOptions::parse_generic_options(
218 const variables_map& vm,
219 Configuration *configuration
222 BOOST_ASSERT(configuration != NULL);
225 if ( vm.count( HelpCmdStr ) > 0 )
227 options_description generic = get_generic_options();
228 options_description config = get_configuration_options();
230 options_description visible_options( "Allowed options" );
231 visible_options.add( generic ).add( config );
233 // TODO GlobalOutput::print( help )
234 cout << visible_options << endl;
238 BOOST_FOREACH( ConfigurationOptionItem generic_option, GenericOptions )
240 generic_option->parse( vm, configuration );
247 * @brief Parse the options specific to this application.
249 * @param vm The input @c boost::program_options::variables_map.
250 * @param configuration The output @c Configuration filled with the parsed
251 * configuration options.
253 * @return @c true if it was parsed at least one option, or @c false if there
254 * were no options available in this category.
256 bool ConfigurationOptions::parse_configuration_options(
257 const variables_map &vm,
258 Configuration *configuration
261 BOOST_ASSERT(configuration != NULL);
263 BOOST_FOREACH( ConfigurationOptionItem configuration_option, ConfigOptions )
265 configuration_option->parse( vm, configuration );
268 bool hosts_parsed = parse_hosts_options(vm, configuration);
274 * @brief Parse the hosts section options.
276 * @param vm The input @c boost::program_options::variables_map.
277 * @param configuration The output @c Configuration filled with the parsed
280 * @return @c true if the hosts were parsed correctly, or @c false otherwise.
282 bool ConfigurationOptions::parse_hosts_options(
283 const variables_map &vm,
284 Configuration *configuration
287 BOOST_ASSERT(configuration != NULL);
289 size_t host_down_limit_count = static_cast<size_t>( configuration->get_hosts_down_limit() );
291 BOOST_FOREACH( HostConfigurationOptionItem host_option, HostOptions )
293 bool parsed = host_option->parse( vm, configuration );
296 // The set_hosts_count() method is called in parse() method, that is
297 // why we must parse before check the number of host options
298 size_t hosts_parsed_count = host_option->get_hosts_count();
299 bool have_minimum_hosts = ( host_down_limit_count <= hosts_parsed_count );
300 // Ensure we have all options for each host
301 if ( !have_minimum_hosts ) {
302 // TODO GlobalOutput::print()
303 GlobalLogger.error() << "Could not parse configuration file." <<
304 " Missing an entry for one of the hosts." << endl;
305 // TODO Assume default value for a missing option
309 BOOST_ASSERT( hosts_parsed_count >= static_cast<size_t>( host_down_limit_count ) );
317 * @return which options must abort the application. Like the --version.
319 bool ConfigurationOptions::halt_on_generic_options( const variables_map &vm ) const
323 bool is_help = ( vm.count( HelpCmdStr ) > 0 );
324 bool is_version = ( vm.count( v.get_command_string() ) > 0 );
325 bool terminate_app = is_help || is_version;
327 return terminate_app;