lxcpp: fix cgroup unit tests
[platform/core/security/vasum.git] / server / main.cpp
1 /*
2  *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Jan Olszak <j.olszak@samsung.com>
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License
17  */
18
19
20 /**
21  * @file
22  * @author  Jan Olszak (j.olszak@samsung.com)
23  * @brief   Main file for the Vasum Daemon
24  */
25
26 #include "config.hpp"
27
28 #include "exception.hpp"
29 #include "server.hpp"
30
31 #include "logger/logger.hpp"
32 #include "logger/backend-stderr.hpp"
33 #include "logger/backend-journal.hpp"
34 #include "logger/backend-syslog.hpp"
35 #include "utils/typeinfo.hpp"
36 #include "utils/signal.hpp"
37 #include "utils/daemon.hpp"
38
39 #include <boost/program_options.hpp>
40 #include <iostream>
41
42 using namespace logger;
43 using namespace vasum;
44
45 namespace po = boost::program_options;
46
47
48 namespace {
49
50 const std::string PROGRAM_NAME_AND_VERSION =
51     "Vasum Server " PROGRAM_VERSION;
52
53 const std::string CONFIG_PATH = "/etc/vasum/daemon.conf";
54
55
56 } // namespace
57
58 int main(int argc, char* argv[])
59 {
60     bool runAsRoot = false;
61     try {
62 #ifndef NDEBUG
63         const char *defaultLoggingBackend = "stderr";
64 #else
65         const char *defaultLoggingBackend = "syslog";
66 #endif
67         // 100 - wider terminal, nicer option descriptions
68         po::options_description desc("Allowed options", 100);
69
70         desc.add_options()
71         ("help,h", "print this help")
72         ("root,r", "Don't drop root privileges at startup")
73         ("daemon,d", "Run server as daemon")
74         ("log-level,l", po::value<std::string>()->default_value("DEBUG"), "set log level")
75         ("log-backend,b", po::value<std::string>()->default_value(defaultLoggingBackend),
76                           "set log backend [stderr,syslog,file"
77 #ifdef HAVE_SYSTEMD
78                           ",journal"
79 #endif
80                           "]")
81         ("log-file,f", po::value<std::string>()->default_value("vasum.log"),
82                           "set filename for file logging, optional")
83         ("check,c", "check runtime environment and exit")
84         ("version,v", "show application version")
85         ;
86
87         po::variables_map vm;
88         po::basic_parsed_options< char > parsed =
89             po::command_line_parser(argc, argv).options(desc).allow_unregistered().run();
90
91         std::vector<std::string> unrecognized_options =
92             po::collect_unrecognized(parsed.options, po::include_positional);
93
94         if (!unrecognized_options.empty()) {
95             std::cerr << "Unrecognized options: ";
96
97             for (auto& uo : unrecognized_options) {
98                 std::cerr << ' ' << uo;
99             }
100
101             std::cerr << std::endl << std::endl;
102             std::cerr << desc << std::endl;
103
104             return 1;
105         }
106
107         po::store(parsed, vm);
108         po::notify(vm);
109
110         if (vm.count("help")) {
111             std::cout << desc << std::endl;
112             return 0;
113         } else if (vm.count("version")) {
114             std::cout << PROGRAM_NAME_AND_VERSION << std::endl;
115             return 0;
116         } else if (vm.count("check")) {
117             std::cout << "Checking runtime environment..." << std::endl;
118             return Server::checkEnvironment() ? 0 : 1;
119         }
120
121         bool runAsDaemon = vm.count("daemon") > 0;
122
123         if (runAsDaemon && !utils::daemonize()) {
124             std::cerr << "Failed to daemonize" << std::endl;
125             return 1;
126         }
127
128         Logger::setLogLevel(vm["log-level"].as<std::string>());
129         const std::string logBackend = vm["log-backend"].as<std::string>();
130         if(logBackend.compare("stderr") == 0) {
131             Logger::setLogBackend(new StderrBackend());
132         }
133         else if(logBackend.compare("file") == 0) {
134             const std::string logFilename = vm["log-file"].as<std::string>();
135             if(logFilename.empty()) {
136                 std::cerr << "Error: invalid log file provided for file logging backend" << std::endl;
137                 return 1;
138             }
139             Logger::setLogBackend(new FileBackend(logFilename));
140         }
141 #ifdef HAVE_SYSTEMD
142         else if(logBackend.compare("journal") == 0) {
143             Logger::setLogBackend(new SystemdJournalBackend());
144         }
145 #endif
146         else if(logBackend.compare("syslog") == 0) {
147             Logger::setLogBackend(new SyslogBackend());
148         }
149         else {
150             std::cerr << "Error: unrecognized logging backend option: " << logBackend << std::endl;
151             return 1;
152         }
153
154         runAsRoot = vm.count("root") > 0;
155
156     } catch (std::exception& e) {
157         std::cerr << e.what() << std::endl;
158         return 1;
159     }
160
161     try {
162         // Block all signals
163         // Server will unblock handled signals
164         utils::signalBlockAllExcept({SIGTERM});
165
166         // TODO: SIGTERM used by lxc, get rid of this
167         utils::signalIgnore({SIGTERM});
168
169         LOGI("Starting daemon...");
170         Server server(CONFIG_PATH);
171         server.run(runAsRoot);
172         server.reloadIfRequired(argv);
173         LOGI("Daemon stopped");
174
175     } catch (std::exception& e) {
176         LOGE("Unexpected: " << utils::getTypeName(e) << ": " << e.what());
177         return 1;
178     }
179
180     return 0;
181 }