added option log-file and option FILE to log-output; use in main and adjusted unit...
[pingcheck] / src / config / configurationoptions.cpp
CommitLineData
aab6eaa1
GMF
1/*
2 The software in this package is distributed under the GNU General
3 Public License version 2 (with a special exception described below).
4
5 A copy of GNU General Public License (GPL) is included in this distribution,
6 in the file COPYING.GPL.
7
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.
13
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.
16
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.
19 */
20
21#include "config/configurationoptions.h"
22
23#include <iostream>
24
aab6eaa1
GMF
25#include <boost/foreach.hpp>
26
27#include <logfunc.hpp>
28
780b0bca 29#include "boost_assert_handler.h"
6c5bdffd
GMF
30#include "config/option/configfileoption.h"
31#include "config/option/daemonoption.h"
5596767b 32#include "config/option/hostsdownlimitoption.h"
6c5bdffd
GMF
33#include "config/option/hostnameoption.h"
34#include "config/option/hostportoption.h"
35#include "config/option/hostpingprotocoloption.h"
36#include "config/option/hostpingintervaloption.h"
74dd30e1 37#include "config/option/hostsourcenetworkinterfaceoption.h"
6c5bdffd
GMF
38#include "config/option/linkdownintervaloption.h"
39#include "config/option/linkupintervaloption.h"
2c40f493 40#include "config/option/logleveloption.h"
5ba17410 41#include "config/option/logoutputoption.h"
fda777ea 42#include "config/option/logfileoption.h"
6c5bdffd
GMF
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"
096b06ef 48#include "config/option/ratiorandomhostsoption.h"
079d19ab
CH
49#include "config/option/pingreplytimeoutoption.h"
50#include "config/option/maxaddressresolutionattemptsoption.h"
51#include "config/option/resolvedipttlthresholdoption.h"
a901aed6 52#include "config/option/dnscachefileoption.h"
6c5bdffd 53
aab6eaa1 54using namespace std;
6c5bdffd 55using boost::program_options::option_description;
aab6eaa1
GMF
56using boost::program_options::options_description;
57using boost::program_options::value;
58using boost::program_options::variables_map;
6c5bdffd 59using boost::shared_ptr;
aab6eaa1
GMF
60using I2n::Logger::GlobalLogger;
61
62//-----------------------------------------------------------------------------
63// ConfigurationOptions
64//-----------------------------------------------------------------------------
65
66/**
67 * @brief Default constructor.
68 */
69ConfigurationOptions::ConfigurationOptions() :
6c5bdffd
GMF
70 GenericOptions(),
71 ConfigOptions(),
72 HostOptions(),
aab6eaa1 73 HelpCmdStr( "help" ),
6c5bdffd 74 HelpCmdDesc( "Print this help and exit." )
aab6eaa1 75{
6c5bdffd
GMF
76 ConfigurationOptionItem config_file( new ConfigFileOption );
77 GenericOptions.push_back( config_file );
78
79 ConfigurationOptionItem daemon( new DaemonOption );
80 GenericOptions.push_back( daemon );
81
82 ConfigurationOptionItem version( new VersionOption );
83 GenericOptions.push_back( version );
84
2c40f493
GMF
85 ConfigurationOptionItem log_level( new LogLevelOption );
86 GenericOptions.push_back( log_level );
87
5ba17410
GMF
88 ConfigurationOptionItem log_output( new LogOutputOption );
89 GenericOptions.push_back( log_output );
90
fda777ea
CH
91 ConfigurationOptionItem log_file( new LogFileOption );
92 GenericOptions.push_back( log_file );
93
5596767b
GMF
94 ConfigurationOptionItem hosts_down_limit( new HostsDownLimitOption );
95 ConfigOptions.push_back( hosts_down_limit );
6c5bdffd
GMF
96
97 ConfigurationOptionItem link_down_interval( new LinkDownIntervalOption );
98 ConfigOptions.push_back( link_down_interval );
99
100 ConfigurationOptionItem link_up_interval( new LinkUpIntervalOption );
101 ConfigOptions.push_back( link_up_interval );
102
103 ConfigurationOptionItem nameserver( new NameserverOption );
104 ConfigOptions.push_back( nameserver );
105
106 ConfigurationOptionItem ping_fail_limit( new PingFailLimitOption );
107 ConfigOptions.push_back( ping_fail_limit );
108
109 ConfigurationOptionItem source_network_interface( new SourceNetworkInterfaceOption );
110 ConfigOptions.push_back( source_network_interface );
111
112 ConfigurationOptionItem status_notifier_cmd( new StatusNotifierCmdOption );
113 ConfigOptions.push_back( status_notifier_cmd );
114
079d19ab
CH
115 ConfigurationOptionItem ping_reply_timeout( new PingReplyTimeoutOption );
116 ConfigOptions.push_back( ping_reply_timeout );
117
118 ConfigurationOptionItem max_address_resolution_attempts( new MaxAddressResolutionAttemptsOption );
119 ConfigOptions.push_back( max_address_resolution_attempts );
120
121 ConfigurationOptionItem resolved_ip_ttl_threshold( new ResolvedIpTtlThresholdOption );
122 ConfigOptions.push_back( resolved_ip_ttl_threshold );
123
096b06ef
CH
124 ConfigurationOptionItem ratio_random_hosts( new RatioRandomHostsOption );
125 ConfigOptions.push_back( ratio_random_hosts );
126
a901aed6
CH
127 ConfigurationOptionItem dns_cache_file( new DnsCacheFileOption );
128 ConfigOptions.push_back( dns_cache_file );
129
6c5bdffd
GMF
130 HostConfigurationOptionItem host_name( new HostNameOption );
131 HostOptions.push_back( host_name );
132
133 HostConfigurationOptionItem host_port( new HostPortOption );
134 HostOptions.push_back( host_port );
135
74dd30e1
GMF
136 HostConfigurationOptionItem host_source_network_interface( new HostSourceNetworkInterfaceOption );
137 HostOptions.push_back( host_source_network_interface );
138
6c5bdffd
GMF
139 HostConfigurationOptionItem host_protocol( new HostPingProtocolOption );
140 HostOptions.push_back( host_protocol );
141
142 HostConfigurationOptionItem host_interval( new HostPingIntervalOption );
143 HostOptions.push_back( host_interval );
aab6eaa1
GMF
144}
145
146/**
147 * @brief Destructor.
148 */
149ConfigurationOptions::~ConfigurationOptions()
150{
151}
152
153/**
6c5bdffd 154 * @return The options which are common to all kinds of applications.
aab6eaa1
GMF
155 */
156options_description ConfigurationOptions::get_generic_options() const
157{
158 options_description options( "Generic options" );
6c5bdffd 159
aab6eaa1
GMF
160 options.add_options()
161 ( HelpCmdStr.c_str(), HelpCmdDesc.c_str() )
aab6eaa1
GMF
162 ;
163
6c5bdffd
GMF
164 BOOST_FOREACH( ConfigurationOptionItem generic_option, GenericOptions )
165 {
166 // Do not pass the the underlying boost::program_options::option_description
167 // object from ConfigurationOption to the
168 // boost::program_options::options_description::add() method, because it
169 // deletes the boost::program_options::option_description, causing
170 // multiple freed when ConfigurationOption try to delete it.
171 option_description option = generic_option->get_option_description();
172 shared_ptr< option_description > ptr( new option_description( option ) );
173 options.add( ptr );
174 }
175
aab6eaa1
GMF
176 return options;
177}
178
179/**
6c5bdffd 180 * @return The options which are specific to this application.
aab6eaa1
GMF
181 */
182options_description ConfigurationOptions::get_configuration_options() const
183{
184 options_description options( "Configuration" );
6c5bdffd
GMF
185
186 BOOST_FOREACH( ConfigurationOptionItem configuration_option, ConfigOptions )
187 {
188 option_description option = configuration_option->get_option_description();
189 shared_ptr< option_description > ptr( new option_description( option ) );
190 options.add( ptr );
191 }
192
193 BOOST_FOREACH( ConfigurationOptionItem host_option, HostOptions )
194 {
195 option_description option = host_option->get_option_description();
196 shared_ptr< option_description > ptr( new option_description( option ) );
197 options.add( ptr );
198 }
aab6eaa1
GMF
199
200 return options;
201}
202
203/**
6c5bdffd 204 * @brief Parse the options common to all kinds of applications.
aab6eaa1 205 *
6c5bdffd
GMF
206 * @param vm The input @c boost::program_options::variables_map.
207 * @param configuration The output @c Configuration filled with the parsed
208 * generic options.
aab6eaa1 209 *
6c5bdffd
GMF
210 * @return @c true if it was parsed at least one option, or @c false if there
211 * were no options available in this category.
aab6eaa1
GMF
212 */
213bool ConfigurationOptions::parse_generic_options(
214 const variables_map& vm,
215 Configuration *configuration
216)
217{
10af47fc
GMF
218 BOOST_ASSERT(configuration != NULL);
219
aab6eaa1 220 // help
6c5bdffd 221 if ( vm.count( HelpCmdStr ) > 0 )
aab6eaa1
GMF
222 {
223 options_description generic = get_generic_options();
224 options_description config = get_configuration_options();
225
226 options_description visible_options( "Allowed options" );
227 visible_options.add( generic ).add( config );
228
6c5bdffd 229 // TODO GlobalOutput::print( help )
aab6eaa1
GMF
230 cout << visible_options << endl;
231 return true;
232 }
233
6c5bdffd 234 BOOST_FOREACH( ConfigurationOptionItem generic_option, GenericOptions )
aab6eaa1 235 {
d3384e36 236 generic_option->parse( vm, configuration );
aab6eaa1
GMF
237 }
238
aab6eaa1
GMF
239 return false;
240}
241
242/**
6c5bdffd 243 * @brief Parse the options specific to this application.
aab6eaa1 244 *
6c5bdffd
GMF
245 * @param vm The input @c boost::program_options::variables_map.
246 * @param configuration The output @c Configuration filled with the parsed
247 * configuration options.
aab6eaa1 248 *
6c5bdffd
GMF
249 * @return @c true if it was parsed at least one option, or @c false if there
250 * were no options available in this category.
aab6eaa1
GMF
251 */
252bool ConfigurationOptions::parse_configuration_options(
253 const variables_map &vm,
254 Configuration *configuration
255)
256{
10af47fc
GMF
257 BOOST_ASSERT(configuration != NULL);
258
6c5bdffd 259 BOOST_FOREACH( ConfigurationOptionItem configuration_option, ConfigOptions )
aab6eaa1 260 {
d3384e36 261 configuration_option->parse( vm, configuration );
aab6eaa1
GMF
262 }
263
10af47fc
GMF
264 bool hosts_parsed = parse_hosts_options(vm, configuration);
265
266 return hosts_parsed;
267}
268
269/**
270 * @brief Parse the hosts section options.
271 *
272 * @param vm The input @c boost::program_options::variables_map.
273 * @param configuration The output @c Configuration filled with the parsed
274 * hosts options.
275 *
276 * @return @c true if the hosts were parsed correctly, or @c false otherwise.
277 */
278bool ConfigurationOptions::parse_hosts_options(
279 const variables_map &vm,
280 Configuration *configuration
281)
282{
283 BOOST_ASSERT(configuration != NULL);
284
6c5bdffd 285 size_t host_down_limit_count = static_cast<size_t>( configuration->get_hosts_down_limit() );
aab6eaa1 286
6c5bdffd 287 BOOST_FOREACH( HostConfigurationOptionItem host_option, HostOptions )
c9e981f6 288 {
6c5bdffd 289 bool parsed = host_option->parse( vm, configuration );
d3384e36 290 if ( parsed )
c9e981f6 291 {
6c5bdffd
GMF
292 // The set_hosts_count() method is called in parse() method, that is
293 // why we must parse before check the number of host options
294 size_t hosts_parsed_count = host_option->get_hosts_count();
295 bool have_minimum_hosts = ( host_down_limit_count <= hosts_parsed_count );
296 // Ensure we have all options for each host
297 if ( !have_minimum_hosts ) {
298 // TODO GlobalOutput::print()
299 GlobalLogger.error() << "Could not parse configuration file." <<
300 " Missing an entry for one of the hosts." << endl;
301 // TODO Assume default value for a missing option
302 return false;
303 }
304
305 BOOST_ASSERT( hosts_parsed_count >= static_cast<size_t>( host_down_limit_count ) );
c9e981f6 306 }
c9e981f6
GMF
307 }
308
aab6eaa1
GMF
309 return true;
310}
311
312/**
313 * @return which options must abort the application. Like the --version.
aab6eaa1
GMF
314 */
315bool ConfigurationOptions::halt_on_generic_options( const variables_map &vm ) const
316{
6c5bdffd
GMF
317 VersionOption v;
318
aab6eaa1 319 bool is_help = ( vm.count( HelpCmdStr ) > 0 );
6c5bdffd 320 bool is_version = ( vm.count( v.get_command_string() ) > 0 );
aab6eaa1
GMF
321 bool terminate_app = is_help || is_version;
322
323 return terminate_app;
324}