Bump version to 0.3.
[profile/ivi/settings-daemon.git] / src / configurator.cpp
1 /**
2  * @file configurator.cpp
3  *
4  * @brief Source file containing implementation of the settingsd
5  *        configuration manager.
6  *
7  * @author Ossama Othman @<ossama.othman@@intel.com@>
8  *
9  * @copyright @par
10  * Copyright 2012, 2013 Intel Corporation All Rights Reserved.
11  * @par
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation;
15  * version 2.1 of the License.
16  * @par
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  * @par
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with this library; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
25  * Boston, MA  02110-1301  USA
26  */
27
28
29 #include "../lib/config.hpp"
30 #include "configurator.hpp"
31
32 #include <unistd.h>
33 #include <fstream>
34 #include <cstdlib>
35
36
37 namespace po = boost::program_options;
38
39 ivi::settings::configurator::configurator(int & argc,
40                                           char * argv[],
41                                           char const * /* logger_name */)
42   : vm_()
43 {
44   parse_config(argc, argv);
45 }
46
47 std::string
48 ivi::settings::configurator::settings_dir() const
49 {
50   return vm_["settings-dir"].as<std::string>();
51 }
52
53 int
54 ivi::settings::configurator::websocket_port() const
55 {
56   return vm_["websocket-port"].as<int>();
57 }
58
59 char const *
60 ivi::settings::configurator::ssl_cert_file() const
61 {
62   return libwebsocket_ssl_filepath("ssl-cert-file");
63 }
64
65 char const *
66 ivi::settings::configurator::ssl_private_key_file() const
67 {
68   return libwebsocket_ssl_filepath("ssl-private-key-file");
69 }
70
71 char const *
72 ivi::settings::configurator::ssl_ca_file() const
73 {
74   return libwebsocket_ssl_filepath("ssl-ca-file");
75 }
76
77 void
78 ivi::settings::configurator::parse_config(int & argc, char * argv[])
79 {
80   /// Options recognized by settingsd.
81   boost::program_options::options_description desc(
82     "Allowed " PACKAGE " options");
83
84   desc.add_options()
85     ("settings-dir",
86      po::value<std::string>()->default_value(IVI_SETTINGS_DEFAULT_SETTINGS_DIR),
87      "settings plugin directory")
88     ("websocket-port",
89      po::value<int>()->default_value(IVI_SETTINGS_DEFAULT_WEBSOCKET_PORT),
90      "settings web socket server TCP/IP port")
91     ("ssl-cert-file",
92      po::value<std::string>(),
93      "SSL server certificate file")
94     ("ssl-private-key-file",
95      po::value<std::string>(),
96      "SSL private key file")
97     ("ssl-ca-file",
98      po::value<std::string>(),
99       "SSL CA certificate file")
100     ("version", "display version information")
101     ("help", "display help message");
102
103   // Option precedence - high to low:
104   //
105   //   1. Command line
106   //   2. User config
107   //   3. System config
108   //
109   // The store() function will only assign a value once, and will
110   // not change it's value subsequently.
111   po::store(po::parse_command_line(argc, argv, desc), vm_);
112
113   /**
114    * @todo Check for config in $XDG_CONFIG_DIRS and $XDG_CONFIG_HOME.
115    */
116   // User config is stored in ~/.config/ivi_settings.
117   std::ifstream user_config_file(std::string(std::getenv("HOME"))
118                                  + "/.config/" PACKAGE);
119   if (user_config_file)
120     po::store(po::parse_config_file(user_config_file, desc), vm_);
121
122   // Configuration file name such as
123   // "/etc/settingsd/settingsd.conf"
124   static char const config_filename[] =
125     IVI_SETTINGS_CONFIG_DIR "/" PACKAGE ".conf";
126
127   std::ifstream system_config_file(config_filename);
128   if (system_config_file)
129     po::store(po::parse_config_file(system_config_file, desc), vm_);
130
131   po::notify(vm_);
132
133   if (vm_.count("version")) {
134     display_version_info();
135     std::exit(EXIT_SUCCESS);
136   } else if (vm_.count("help")) {
137     std::cout << desc << std::endl;
138     std::exit(EXIT_SUCCESS);
139   }
140 }
141
142 void
143 ivi::settings::configurator::display_version_info() const
144 {
145   static char const copyright[] =
146     PACKAGE_STRING "\n"
147     "Copyright (c) 2012, 2013 Intel Corporation.\n"
148     "\n"
149     "This " PACKAGE_NAME " (\"Software\") is furnished under "
150     "license and may only be\n"
151     "used or copied in accordance with the terms of that license.\n"
152     "No license, express or implied, by estoppel or otherwise, to any\n"
153     "intellectual property rights is granted by this document. The\n"
154     "Software is subject to change without notice, and should not be\n"
155     "construed as a commitment by Intel Corporation to market, license,\n"
156     "sell or support any product or technology. Unless otherwise provided\n"
157     "for in the license under which this Software is provided, the\n"
158     "Software is provided AS IS, with no warranties of any kind, express\n"
159     "or implied. Except as expressly permitted by the Software license,\n"
160     "neither Intel Corporation nor its suppliers assumes any\n"
161     "responsibility or liability for any errors or inaccuracies that may\n"
162     "appear herein. Except as expressly permitted by the Software\n"
163     "license, no part of the Software may be reproduced, stored in a\n"
164     "retrieval system, transmitted in any form, or distributed by any\n"
165     "means without the express written consent of Intel Corporation.\n";
166
167   std::cout << copyright << std::endl;
168 }
169
170 void
171 ivi::settings::configurator::configure_logger(
172   char const * /* logger_name */)
173 {
174   // Start with log configuration file, if it exists, and override as
175   // needed with command line specifed options.
176   std::string const log_config_filename =
177     vm_["log-config-file"].as<std::string>();
178
179   if (access(log_config_filename.c_str(), R_OK) == 0) {
180     /**
181      * @bug There is a TOCTOU race here since the config file may
182      *      be yanked out from under us before the
183      *      @c log4plus::PropertyConfigurator pulls the config from
184      *      the file.
185      */
186
187     // Reset configuration before pulling configuration from file.
188     // log4cplus::Logger::getDefaultHierarchy().resetConfiguration();
189
190     // Now pull the configuration from the file.
191     // log4cplus::PropertyConfigurator::doConfigure(log_config_filename);
192   }
193
194   // logger_ = log4cplus::Logger::getInstance(logger_name);
195
196   /// @todo Set the log file.
197
198   // We have a logger.  Now set the log level.
199   set_log_level();
200 }
201
202 void
203 ivi::settings::configurator::set_log_level()
204 {
205 /*
206   log4cplus::LogLevel level;
207
208   std::string const l = vm_["log-level"].as<std::string>();
209
210   if (l == "FATAL")
211     level = log4cplus::FATAL_LOG_LEVEL;
212   else if (l == "ERROR")
213     level = log4cplus::ERROR_LOG_LEVEL;
214   else if (l == "WARN")
215     level = log4cplus::WARN_LOG_LEVEL;
216   else if (l == "INFO")
217     level = log4cplus::INFO_LOG_LEVEL;
218   else if (l == "DEBUG")
219     level = log4cplus::DEBUG_LOG_LEVEL;
220   else if (l == "TRACE")
221     level = log4cplus::TRACE_LOG_LEVEL;
222   else if (l == "ALL")
223     level = log4cplus::ALL_LOG_LEVEL;
224   else if (l == "OFF")
225     level = log4cplus::OFF_LOG_LEVEL;
226   else {
227     LOG4CPLUS_WARN(logger_, "Unknown log option: \"" + l + "\"");
228     return;
229   }
230
231   logger_.setLogLevel(level);
232 */
233 }
234
235 char const *
236 ivi::settings::configurator::libwebsocket_ssl_filepath(
237   std::string const & option) const
238 {
239   using boost::program_options::variable_value;
240
241   variable_value const & value = vm_[option];
242
243   return value.empty() ? nullptr : value.as<std::string>().c_str();
244 }
245
246
247 // Local Variables:
248 // mode:c++
249 // c-basic-offset:2
250 // indent-tabs-mode: nil
251 // End: