Update pingcheck to work with cmake 3.28
[pingcheck] / src / config / configurationoptions.cpp
... / ...
CommitLineData
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
25#include <boost/foreach.hpp>
26
27#include <logfunc.hpp>
28
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"
54
55using namespace std;
56using boost::program_options::option_description;
57using boost::program_options::options_description;
58using boost::program_options::value;
59using boost::program_options::variables_map;
60using boost::shared_ptr;
61using I2n::Logger::GlobalLogger;
62
63//-----------------------------------------------------------------------------
64// ConfigurationOptions
65//-----------------------------------------------------------------------------
66
67/**
68 * @brief Default constructor.
69 */
70ConfigurationOptions::ConfigurationOptions() :
71 GenericOptions(),
72 ConfigOptions(),
73 HostOptions(),
74 HelpCmdStr( "help" ),
75 HelpCmdDesc( "Print this help and exit." )
76{
77 ConfigurationOptionItem config_file( new ConfigFileOption );
78 GenericOptions.push_back( config_file );
79
80 ConfigurationOptionItem daemon( new DaemonOption );
81 GenericOptions.push_back( daemon );
82
83 ConfigurationOptionItem version( new VersionOption );
84 GenericOptions.push_back( version );
85
86 ConfigurationOptionItem log_level( new LogLevelOption );
87 GenericOptions.push_back( log_level );
88
89 ConfigurationOptionItem log_output( new LogOutputOption );
90 GenericOptions.push_back( log_output );
91
92 ConfigurationOptionItem log_file( new LogFileOption );
93 GenericOptions.push_back( log_file );
94
95 ConfigurationOptionItem hosts_down_limit( new HostsDownLimitOption );
96 ConfigOptions.push_back( hosts_down_limit );
97
98 ConfigurationOptionItem link_down_interval( new LinkDownIntervalOption );
99 ConfigOptions.push_back( link_down_interval );
100
101 ConfigurationOptionItem link_up_interval( new LinkUpIntervalOption );
102 ConfigOptions.push_back( link_up_interval );
103
104 ConfigurationOptionItem nameserver( new NameserverOption );
105 ConfigOptions.push_back( nameserver );
106
107 ConfigurationOptionItem ping_fail_limit( new PingFailLimitOption );
108 ConfigOptions.push_back( ping_fail_limit );
109
110 ConfigurationOptionItem source_network_interface( new SourceNetworkInterfaceOption );
111 ConfigOptions.push_back( source_network_interface );
112
113 ConfigurationOptionItem status_notifier_cmd( new StatusNotifierCmdOption );
114 ConfigOptions.push_back( status_notifier_cmd );
115
116 ConfigurationOptionItem ping_reply_timeout( new PingReplyTimeoutOption );
117 ConfigOptions.push_back( ping_reply_timeout );
118
119 ConfigurationOptionItem max_address_resolution_attempts( new MaxAddressResolutionAttemptsOption );
120 ConfigOptions.push_back( max_address_resolution_attempts );
121
122 ConfigurationOptionItem resolved_ip_ttl_threshold( new ResolvedIpTtlThresholdOption );
123 ConfigOptions.push_back( resolved_ip_ttl_threshold );
124
125 ConfigurationOptionItem min_time_between_resolves( new MinTimeBetweenResolvesOption );
126 ConfigOptions.push_back( min_time_between_resolves );
127
128 ConfigurationOptionItem ratio_random_hosts( new RatioRandomHostsOption );
129 ConfigOptions.push_back( ratio_random_hosts );
130
131 ConfigurationOptionItem dns_cache_file( new DnsCacheFileOption );
132 ConfigOptions.push_back( dns_cache_file );
133
134 HostConfigurationOptionItem host_name( new HostNameOption );
135 HostOptions.push_back( host_name );
136
137 HostConfigurationOptionItem host_port( new HostPortOption );
138 HostOptions.push_back( host_port );
139
140 HostConfigurationOptionItem host_source_network_interface( new HostSourceNetworkInterfaceOption );
141 HostOptions.push_back( host_source_network_interface );
142
143 HostConfigurationOptionItem host_protocol( new HostPingProtocolOption );
144 HostOptions.push_back( host_protocol );
145
146 HostConfigurationOptionItem host_interval( new HostPingIntervalOption );
147 HostOptions.push_back( host_interval );
148}
149
150/**
151 * @brief Destructor.
152 */
153ConfigurationOptions::~ConfigurationOptions()
154{
155}
156
157/**
158 * @return The options which are common to all kinds of applications.
159 */
160options_description ConfigurationOptions::get_generic_options() const
161{
162 options_description options( "Generic options" );
163
164 options.add_options()
165 ( HelpCmdStr.c_str(), HelpCmdDesc.c_str() )
166 ;
167
168 BOOST_FOREACH( ConfigurationOptionItem generic_option, GenericOptions )
169 {
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 ) );
177 options.add( ptr );
178 }
179
180 return options;
181}
182
183/**
184 * @return The options which are specific to this application.
185 */
186options_description ConfigurationOptions::get_configuration_options() const
187{
188 options_description options( "Configuration" );
189
190 BOOST_FOREACH( ConfigurationOptionItem configuration_option, ConfigOptions )
191 {
192 option_description option = configuration_option->get_option_description();
193 shared_ptr< option_description > ptr( new option_description( option ) );
194 options.add( ptr );
195 }
196
197 BOOST_FOREACH( ConfigurationOptionItem host_option, HostOptions )
198 {
199 option_description option = host_option->get_option_description();
200 shared_ptr< option_description > ptr( new option_description( option ) );
201 options.add( ptr );
202 }
203
204 return options;
205}
206
207/**
208 * @brief Parse the options common to all kinds of applications.
209 *
210 * @param vm The input @c boost::program_options::variables_map.
211 * @param configuration The output @c Configuration filled with the parsed
212 * generic options.
213 *
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.
216 */
217bool ConfigurationOptions::parse_generic_options(
218 const variables_map& vm,
219 Configuration *configuration
220)
221{
222 BOOST_ASSERT(configuration != NULL);
223
224 // help
225 if ( vm.count( HelpCmdStr ) > 0 )
226 {
227 options_description generic = get_generic_options();
228 options_description config = get_configuration_options();
229
230 options_description visible_options( "Allowed options" );
231 visible_options.add( generic ).add( config );
232
233 // TODO GlobalOutput::print( help )
234 cout << visible_options << endl;
235 return true;
236 }
237
238 BOOST_FOREACH( ConfigurationOptionItem generic_option, GenericOptions )
239 {
240 generic_option->parse( vm, configuration );
241 }
242
243 return false;
244}
245
246/**
247 * @brief Parse the options specific to this application.
248 *
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.
252 *
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.
255 */
256bool ConfigurationOptions::parse_configuration_options(
257 const variables_map &vm,
258 Configuration *configuration
259)
260{
261 BOOST_ASSERT(configuration != NULL);
262
263 BOOST_FOREACH( ConfigurationOptionItem configuration_option, ConfigOptions )
264 {
265 configuration_option->parse( vm, configuration );
266 }
267
268 bool hosts_parsed = parse_hosts_options(vm, configuration);
269
270 return hosts_parsed;
271}
272
273/**
274 * @brief Parse the hosts section options.
275 *
276 * @param vm The input @c boost::program_options::variables_map.
277 * @param configuration The output @c Configuration filled with the parsed
278 * hosts options.
279 *
280 * @return @c true if the hosts were parsed correctly, or @c false otherwise.
281 */
282bool ConfigurationOptions::parse_hosts_options(
283 const variables_map &vm,
284 Configuration *configuration
285)
286{
287 BOOST_ASSERT(configuration != NULL);
288
289 size_t host_down_limit_count = static_cast<size_t>( configuration->get_hosts_down_limit() );
290
291 BOOST_FOREACH( HostConfigurationOptionItem host_option, HostOptions )
292 {
293 bool parsed = host_option->parse( vm, configuration );
294 if ( parsed )
295 {
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
306 return false;
307 }
308
309 BOOST_ASSERT( hosts_parsed_count >= static_cast<size_t>( host_down_limit_count ) );
310 }
311 }
312
313 return true;
314}
315
316/**
317 * @return which options must abort the application. Like the --version.
318 */
319bool ConfigurationOptions::halt_on_generic_options( const variables_map &vm ) const
320{
321 VersionOption v;
322
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;
326
327 return terminate_app;
328}