2 * @brief Config class implementation. This class represents the actual configuration.
6 * @copyright Intra2net AG
13 * Default Constructor. Available command line and config file options with their default values are defined here.
20 // Define valid command line parameters
21 Opt_desc_cmd = new po::options_description("Command line options");
22 Opt_desc_cmd->add_options()
23 ("help,?","Show help.")
24 ("version,v","Show version.")
25 ("protocol,q",po::value<string>(),"Set the service protocol type.")
26 ("host,h",po::value<string>(),"Set the hostname to update.")
27 ("login,l",po::value<string>(),"Set the login.")
28 ("password,p",po::value<string>(),"Set the password.")
31 // Define valid config file main section parameters
32 Opt_desc_conf_main = new po::options_description("Config file main section options");
33 Opt_desc_conf_main->add_options()
34 ("main.daemon_mode",po::value<bool>()->default_value(false),"Run as system daemon.")
35 ("main.logfile",po::value<string>()->default_value("/var/log/bpdyndns.log"),"Where to log.")
36 ("main.loglevel",po::value<int>()->default_value(0),"Loglevel.")
37 ("main.syslog",po::value<bool>()->default_value(false),"Use syslog facility.")
40 // Define valid config file main section parameters
41 Opt_desc_conf_service = new po::options_description("Config file service section options");
42 Opt_desc_conf_service->add_options()
43 ("service.protocol",po::value<string>(),"The service protocol.")
44 ("service.host",po::value<string>(),"The hostname to update.")
45 ("service.login",po::value<string>(),"Login name.")
46 ("service.password",po::value<string>(),"Corresponding password.")
57 delete Opt_desc_conf_main;
58 delete Opt_desc_conf_service;
60 cout << "Config destructor!!!" << endl;
65 * Parses the command line arguments and does the needed actions.
66 * @param argc Command line argument number given to main.
67 * @param argv[] Pointer to command line argument array given to main.
68 * @return 0 if all is fine,
70 const int Config::parse_cmd_line(int argc, char *argv[])
75 po::store(po::parse_command_line(argc, argv, *this->Opt_desc_cmd), vm);
80 else if(vm.count("version"))
83 // Are all needed options set to create a Service Object
84 if(vm.count("protocol") && vm.count("host") && vm.count("login") && vm.count("password"))
86 // Get the cmd parameter values for protocol host login and password
87 string protocol = vm["protocol"].as<string>();
88 string host = vm["host"].as<string>();
89 string login = vm["login"].as<string>();
90 string password = vm["password"].as<string>();
92 //TODO: convert protocol option to lowercase
94 ServicePtr service = create_service(protocol,host,login,password);
95 if ( service != NULL )
97 Services.push_back(service);
102 cout << "Not all needed options set!\n" << endl;
106 catch(po::unknown_option e)
108 cout << "Unknown option set." << endl;
121 * @return A pointer to the created Service object.
123 ServicePtr Config::create_service(const string &protocol,const string &host, const string &login, const string &password)
125 if(protocol == "dhs")
127 ServicePtr service_dhs(new DHS(host,login,password));
130 else if(protocol == "ods")
132 ServicePtr service_ods(new ODS(host,login,password));
137 cout << "Could not find specified protocol: " << protocol << endl;
145 * Loads a service config file, invoked by load_config_from_files.
146 * @param full_filename Filename of the service config file to load.
147 * @return 0 if all is fine, 3 if an unknown option was detected, 4 if the service file could not be opened for reading.
149 const int Config::load_service_config_file(const string& full_filename)
151 cout << "Loading service config file: " << full_filename << endl;
152 ifstream service_config_file(full_filename.c_str(),ifstream::in);
153 if(service_config_file.is_open())
157 po::variables_map vm;
158 po::parsed_options parsed_service_options = po::parse_config_file(service_config_file,*this->Opt_desc_conf_service,true);
159 po::store(parsed_service_options,vm);
162 if(vm.count("service.protocol") && vm.count("service.host") && vm.count("service.login") && vm.count("service.password"))
164 // create the corresponding service
165 string protocol = vm["service.protocol"].as<string>();
166 string host = vm["service.host"].as<string>();
167 string login = vm["service.login"].as<string>();
168 string password = vm["service.password"].as<string>();
170 // TODO: convert protocol to lowercase
171 //protocol = tolower(protocol.c_str());
173 ServicePtr service = create_service(protocol,host,login,password);
174 if ( service != NULL )
176 Services.push_back(service);
180 catch ( po::unknown_option e )
182 // unknown option in config file detected
183 service_config_file.close();
184 cout << "Unknown option in service config file detected!" << endl;
187 service_config_file.close();
191 cout << "Can't open service config file for reading: " << service_config_file << endl;
198 * Loads the main config file, invoked by load_config_from_files
199 * @param full_filename The full filename of the main config file to load
200 * @return 0 if all is fine. 3 if unknown option was detected, 4 if main config file could not be opened for reading
202 const int Config::load_main_config_file(const string& full_filename)
204 // load main config file
205 cout << "Loading main config file: " << full_filename << endl;
206 ifstream main_config_file(full_filename.c_str(),ifstream::in);
207 if(main_config_file.is_open())
211 po::variables_map vm;
212 po::parsed_options parsed_main_options = po::parse_config_file(main_config_file,*this->Opt_desc_conf_main,true);
213 po::store(parsed_main_options,vm);
216 if(vm.count("main.daemon_mode") && vm.count("main.logfile") && vm.count("main.loglevel") && vm.count("main.syslog"))
218 Daemon_mode = vm["main.daemon_mode"].as<bool>();
219 Logfile = vm["main.logfile"].as<string>();
220 Loglevel = vm["main.loglevel"].as<int>();
221 Syslog = vm["main.syslog"].as<bool>();
224 catch ( po::unknown_option e )
226 // unknown option in config file detected
227 main_config_file.close();
228 cout << "Unknown option in main config file detected!" << endl;
231 main_config_file.close();
235 cout << "Can't open main config file for reading: " << main_config_file << endl;
241 // TODO: Seperate into smaller methods
243 * Loads the main and the service config file and does the needed action.
244 * @param config_path The path to the config directory.
245 * @return 0 if all is fine.
247 const int Config::load_config_from_files(const string& config_path)
249 fs::path full_config_path = fs::system_complete(fs::path(config_path));
251 if ( fs::exists(full_config_path) && fs::is_directory(full_config_path) )
253 fs::directory_iterator end_iter;
254 for ( fs::directory_iterator dir_itr(full_config_path) ; dir_itr != end_iter ; ++dir_itr )
256 if( fs::is_regular_file( dir_itr->status() ) )
258 string actual_file = dir_itr->path().filename();
259 boost::regex expr(".*\.conf?");
261 // If it is the main config file do the following
262 if ( actual_file == "bpdyndnsd.conf" )
264 // Load the main config file
265 string full_filename = dir_itr->path().string();
266 int ret_val = load_main_config_file(full_filename);
272 // If it is a service definition file *.conf, parse it and generate the corresponding service
273 else if ( boost::regex_search( actual_file,expr ) )
275 string full_filename = dir_itr->path().string();
276 int ret_val = load_service_config_file(full_filename);
287 cout << "Config path doesn't exist or is not a directory" << endl;
295 * Getter method for Service list member.
296 * @return Pointer to a list of Service's.
298 list<ServicePtr> Config::get_services()
300 return this->Services;
305 * Prints out the usage to the command line.
307 void Config::print_usage()
309 cout << "Usage: bpdyndnsd [Command line options]" << "\n" << endl;
310 cout << *Opt_desc_cmd << endl;
315 * Prints out the programm name and the given version string on stdout.
316 * @param version Version string.
318 void Config::print_version(const string& version)
320 cout << "Bullet proof dynamic dns daemon.\nbpdyndnsd " << version << endl;