Commit | Line | Data |
---|---|---|
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" | |
f833126b | 52 | #include "config/option/mintimebetweenresolvesoption.h" |
a901aed6 | 53 | #include "config/option/dnscachefileoption.h" |
6c5bdffd | 54 | |
aab6eaa1 | 55 | using namespace std; |
6c5bdffd | 56 | using boost::program_options::option_description; |
aab6eaa1 GMF |
57 | using boost::program_options::options_description; |
58 | using boost::program_options::value; | |
59 | using boost::program_options::variables_map; | |
6c5bdffd | 60 | using boost::shared_ptr; |
aab6eaa1 GMF |
61 | using I2n::Logger::GlobalLogger; |
62 | ||
63 | //----------------------------------------------------------------------------- | |
64 | // ConfigurationOptions | |
65 | //----------------------------------------------------------------------------- | |
66 | ||
67 | /** | |
68 | * @brief Default constructor. | |
69 | */ | |
70 | ConfigurationOptions::ConfigurationOptions() : | |
6c5bdffd GMF |
71 | GenericOptions(), |
72 | ConfigOptions(), | |
73 | HostOptions(), | |
aab6eaa1 | 74 | HelpCmdStr( "help" ), |
6c5bdffd | 75 | HelpCmdDesc( "Print this help and exit." ) |
aab6eaa1 | 76 | { |
6c5bdffd GMF |
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 | ||
2c40f493 GMF |
86 | ConfigurationOptionItem log_level( new LogLevelOption ); |
87 | GenericOptions.push_back( log_level ); | |
88 | ||
5ba17410 GMF |
89 | ConfigurationOptionItem log_output( new LogOutputOption ); |
90 | GenericOptions.push_back( log_output ); | |
91 | ||
fda777ea CH |
92 | ConfigurationOptionItem log_file( new LogFileOption ); |
93 | GenericOptions.push_back( log_file ); | |
94 | ||
5596767b GMF |
95 | ConfigurationOptionItem hosts_down_limit( new HostsDownLimitOption ); |
96 | ConfigOptions.push_back( hosts_down_limit ); | |
6c5bdffd GMF |
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 | ||
079d19ab CH |
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 | ||
f833126b CH |
125 | ConfigurationOptionItem min_time_between_resolves( new MinTimeBetweenResolvesOption ); |
126 | ConfigOptions.push_back( min_time_between_resolves ); | |
127 | ||
096b06ef CH |
128 | ConfigurationOptionItem ratio_random_hosts( new RatioRandomHostsOption ); |
129 | ConfigOptions.push_back( ratio_random_hosts ); | |
130 | ||
a901aed6 CH |
131 | ConfigurationOptionItem dns_cache_file( new DnsCacheFileOption ); |
132 | ConfigOptions.push_back( dns_cache_file ); | |
133 | ||
6c5bdffd GMF |
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 | ||
74dd30e1 GMF |
140 | HostConfigurationOptionItem host_source_network_interface( new HostSourceNetworkInterfaceOption ); |
141 | HostOptions.push_back( host_source_network_interface ); | |
142 | ||
6c5bdffd GMF |
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 ); | |
aab6eaa1 GMF |
148 | } |
149 | ||
150 | /** | |
151 | * @brief Destructor. | |
152 | */ | |
153 | ConfigurationOptions::~ConfigurationOptions() | |
154 | { | |
155 | } | |
156 | ||
157 | /** | |
6c5bdffd | 158 | * @return The options which are common to all kinds of applications. |
aab6eaa1 GMF |
159 | */ |
160 | options_description ConfigurationOptions::get_generic_options() const | |
161 | { | |
162 | options_description options( "Generic options" ); | |
6c5bdffd | 163 | |
aab6eaa1 GMF |
164 | options.add_options() |
165 | ( HelpCmdStr.c_str(), HelpCmdDesc.c_str() ) | |
aab6eaa1 GMF |
166 | ; |
167 | ||
6c5bdffd GMF |
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 | ||
aab6eaa1 GMF |
180 | return options; |
181 | } | |
182 | ||
183 | /** | |
6c5bdffd | 184 | * @return The options which are specific to this application. |
aab6eaa1 GMF |
185 | */ |
186 | options_description ConfigurationOptions::get_configuration_options() const | |
187 | { | |
188 | options_description options( "Configuration" ); | |
6c5bdffd GMF |
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 | } | |
aab6eaa1 GMF |
203 | |
204 | return options; | |
205 | } | |
206 | ||
207 | /** | |
6c5bdffd | 208 | * @brief Parse the options common to all kinds of applications. |
aab6eaa1 | 209 | * |
6c5bdffd GMF |
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. | |
aab6eaa1 | 213 | * |
6c5bdffd GMF |
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. | |
aab6eaa1 GMF |
216 | */ |
217 | bool ConfigurationOptions::parse_generic_options( | |
218 | const variables_map& vm, | |
219 | Configuration *configuration | |
220 | ) | |
221 | { | |
10af47fc GMF |
222 | BOOST_ASSERT(configuration != NULL); |
223 | ||
aab6eaa1 | 224 | // help |
6c5bdffd | 225 | if ( vm.count( HelpCmdStr ) > 0 ) |
aab6eaa1 GMF |
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 | ||
6c5bdffd | 233 | // TODO GlobalOutput::print( help ) |
aab6eaa1 GMF |
234 | cout << visible_options << endl; |
235 | return true; | |
236 | } | |
237 | ||
6c5bdffd | 238 | BOOST_FOREACH( ConfigurationOptionItem generic_option, GenericOptions ) |
aab6eaa1 | 239 | { |
d3384e36 | 240 | generic_option->parse( vm, configuration ); |
aab6eaa1 GMF |
241 | } |
242 | ||
aab6eaa1 GMF |
243 | return false; |
244 | } | |
245 | ||
246 | /** | |
6c5bdffd | 247 | * @brief Parse the options specific to this application. |
aab6eaa1 | 248 | * |
6c5bdffd GMF |
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. | |
aab6eaa1 | 252 | * |
6c5bdffd GMF |
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. | |
aab6eaa1 GMF |
255 | */ |
256 | bool ConfigurationOptions::parse_configuration_options( | |
257 | const variables_map &vm, | |
258 | Configuration *configuration | |
259 | ) | |
260 | { | |
10af47fc GMF |
261 | BOOST_ASSERT(configuration != NULL); |
262 | ||
6c5bdffd | 263 | BOOST_FOREACH( ConfigurationOptionItem configuration_option, ConfigOptions ) |
aab6eaa1 | 264 | { |
d3384e36 | 265 | configuration_option->parse( vm, configuration ); |
aab6eaa1 GMF |
266 | } |
267 | ||
10af47fc GMF |
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 | */ | |
282 | bool ConfigurationOptions::parse_hosts_options( | |
283 | const variables_map &vm, | |
284 | Configuration *configuration | |
285 | ) | |
286 | { | |
287 | BOOST_ASSERT(configuration != NULL); | |
288 | ||
6c5bdffd | 289 | size_t host_down_limit_count = static_cast<size_t>( configuration->get_hosts_down_limit() ); |
aab6eaa1 | 290 | |
6c5bdffd | 291 | BOOST_FOREACH( HostConfigurationOptionItem host_option, HostOptions ) |
c9e981f6 | 292 | { |
6c5bdffd | 293 | bool parsed = host_option->parse( vm, configuration ); |
d3384e36 | 294 | if ( parsed ) |
c9e981f6 | 295 | { |
6c5bdffd GMF |
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 ) ); | |
c9e981f6 | 310 | } |
c9e981f6 GMF |
311 | } |
312 | ||
aab6eaa1 GMF |
313 | return true; |
314 | } | |
315 | ||
316 | /** | |
317 | * @return which options must abort the application. Like the --version. | |
aab6eaa1 GMF |
318 | */ |
319 | bool ConfigurationOptions::halt_on_generic_options( const variables_map &vm ) const | |
320 | { | |
6c5bdffd GMF |
321 | VersionOption v; |
322 | ||
aab6eaa1 | 323 | bool is_help = ( vm.count( HelpCmdStr ) > 0 ); |
6c5bdffd | 324 | bool is_version = ( vm.count( v.get_command_string() ) > 0 ); |
aab6eaa1 GMF |
325 | bool terminate_app = is_help || is_version; |
326 | ||
327 | return terminate_app; | |
328 | } |