24 #include <baseapp/run.h> 25 #include <baseapp/daemonize.h> 26 #include <baseapp/main_thread.h> 27 #include <baseapp/thread_manager.h> 29 #include <core/threading/thread.h> 31 #include <blackboard/local.h> 32 #include <config/sqlite.h> 33 #include <config/net_handler.h> 34 #include <utils/ipc/shm.h> 35 #include <utils/system/argparser.h> 36 #include <logging/multi.h> 37 #include <logging/console.h> 38 #include <logging/liblogger.h> 39 #include <logging/factory.h> 40 #include <logging/network.h> 41 #include <utils/time/clock.h> 42 #include <netcomm/fawkes/network_manager.h> 43 #include <plugin/manager.h> 44 #include <plugin/net/handler.h> 45 #include <aspect/manager.h> 48 #include <sys/types.h> 65 ArgumentParser * argument_parser = NULL;
66 FawkesMainThread * main_thread = NULL;
67 MultiLogger * logger = NULL;
68 NetworkLogger * network_logger = NULL;
69 BlackBoard * blackboard = NULL;
70 SQLiteConfiguration * config = NULL;
71 PluginManager * plugin_manager = NULL;
72 AspectManager * aspect_manager = NULL;
73 ThreadManager * thread_manager = NULL;
74 FawkesNetworkManager * network_manager = NULL;
75 ConfigNetworkHandler * nethandler_config = NULL;
76 PluginNetworkHandler * nethandler_plugin = NULL;
78 SharedMemoryRegistry * shm_registry;
79 InitOptions * init_options = NULL;
82 FawkesMainThread::Runner * runner = NULL;
85 init(
int argc,
char **argv)
87 return init(InitOptions(argc, argv));
92 init(InitOptions options)
94 init_options =
new InitOptions(options);
98 if ( options.daemonize() ) {
99 fawkes::daemon::init(options.daemon_pid_file(), options.basename());
100 if (options.daemonize_kill()) {
101 fawkes::daemon::kill();
102 }
else if (options.daemonize_status()) {
103 return fawkes::daemon::running() ? 0 : 1;
105 fawkes::daemon::start();
110 const char *user = NULL;
111 const char *group = NULL;
112 if (options.has_username()) {
113 user = options.username();
115 if (options.has_groupname()) {
116 group = options.groupname();
121 if (! (pw = getpwnam(user))) {
122 printf(
"Failed to find user %s, check -u argument.\n", user);
126 r = setreuid(pw->pw_uid, pw->pw_uid);
128 perror(
"Failed to drop privileges (user)");
134 if (! (gr = getgrnam(group))) {
135 printf(
"Failed to find group %s, check -g argument.\n", user);
139 r = setregid(gr->gr_gid, gr->gr_gid);
141 perror(
"Failed to drop privileges (group)");
147 shm_registry =
new SharedMemoryRegistry(
true);
150 if (options.has_loggers()) {
153 }
catch (Exception &e) {
154 e.append(
"Initializing multi logger failed");
158 logger =
new MultiLogger(
new ConsoleLogger());
165 const char *homedir = getenv(
"HOME");
168 if (asprintf(&userdir,
"%s/%s", homedir, USERDIR) != -1) {
169 if (access(userdir, W_OK) != 0) {
170 if (mkdir(userdir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) {
171 logger->
log_warn(
"FawkesMainThread",
"Failed to create .fawkes " 172 "directory %s, trying without", userdir);
180 config =
new SQLiteConfiguration(CONFDIR);
182 config->
load(options.host_config(), options.default_config());
188 if (modtype ==
"changed") {
189 logger->
log_warn(
"FawkesMainThread",
"Default config value CHANGED: %s" 190 "(was: %s now: %s)", i->path(),
191 i->get_oldvalue().c_str(), i->get_as_string().c_str());
192 }
else if (modtype ==
"erased") {
193 logger->
log_warn(
"FawkesMainThread",
"Default config value ERASED: %s",
196 logger->
log_debug(
"FawkesMainThread",
"Default config value ADDED: %s " 197 "(value: %s)", i->path(), i->get_as_string().c_str());
201 }
catch (Exception &e) {
202 logger->
log_warn(
"FawkesMainThread",
"Failed to read modified default " 203 "config values, no dump?");
208 unsigned int net_tcp_port = 1910;
209 std::string net_service_name =
"Fawkes on %h";
210 if (options.has_net_tcp_port()) {
211 net_tcp_port = options.net_tcp_port();
214 net_tcp_port = config->
get_uint(
"/fawkes/mainapp/net/tcp_port");
215 }
catch (Exception &e) {}
218 if (options.has_net_service_name()) {
219 net_service_name = options.net_service_name();
222 net_service_name = config->
get_string(
"/fawkes/mainapp/net/service_name");
223 }
catch (Exception &e) {}
226 if (net_tcp_port > 65535) {
227 logger->
log_warn(
"FawkesMainThread",
"Invalid port '%u', using 1910",
233 std::string bb_magic_token =
"";
234 unsigned int bb_size = 2097152;
236 bb_magic_token = config->
get_string(
"/fawkes/mainapp/blackboard_magic_token");
237 logger->
log_info(
"FawkesMainApp",
"BlackBoard magic token defined. " 238 "Using shared memory BlackBoard.");
239 }
catch (Exception &e) {
243 bb_size = config->
get_uint(
"/fawkes/mainapp/blackboard_size");
244 }
catch (Exception &e) {
245 logger->
log_warn(
"FawkesMainApp",
"BlackBoard size not defined. " 246 "Will use %u, saving to default DB", bb_size);
251 if ( options.bb_cleanup()) {
257 LocalBlackBoard *lbb = NULL;
258 if ( bb_magic_token ==
"") {
259 lbb =
new LocalBlackBoard(bb_size);
261 lbb =
new LocalBlackBoard(bb_size, bb_magic_token.c_str());
265 aspect_manager =
new AspectManager();
266 thread_manager =
new ThreadManager(aspect_manager, aspect_manager);
268 plugin_manager =
new PluginManager(thread_manager, config,
269 "/fawkes/meta_plugins/",
270 options.plugin_module_flags(),
271 options.init_plugin_cache());
272 network_manager =
new FawkesNetworkManager(thread_manager,
274 net_service_name.c_str());
275 nethandler_config =
new ConfigNetworkHandler(config,
276 network_manager->hub());
278 nethandler_plugin =
new PluginNetworkHandler(plugin_manager,
279 network_manager->hub());
280 nethandler_plugin->
start();
282 network_logger =
new NetworkLogger(network_manager->hub(),
288 lbb->start_nethandler(network_manager->hub());
295 options.load_plugin_list(),
296 options.default_plugin());
300 config, logger, clock,
301 network_manager->hub(),
304 network_manager->nnresolver(),
305 network_manager->service_publisher(),
306 network_manager->service_browser(),
318 fawkes::daemon::cleanup();
321 if (nethandler_plugin) {
322 nethandler_plugin->cancel();
323 nethandler_plugin->join();
329 logger->remove_logger(network_logger);
330 delete network_logger;
334 delete argument_parser;
336 delete nethandler_config;
337 delete nethandler_plugin;
338 delete plugin_manager;
339 delete network_manager;
341 delete thread_manager;
342 delete aspect_manager;
346 argument_parser = NULL;
348 nethandler_config = NULL;
349 nethandler_plugin = NULL;
350 plugin_manager = NULL;
351 network_manager = NULL;
353 thread_manager = NULL;
354 aspect_manager = NULL;
366 }
catch (Exception &e) {}
378 print_usage(init_options->
basename());
383 runner =
new FawkesMainThread::Runner(main_thread, defsigs);
387 }
catch (Exception &e) {
388 printf(
"Running Fawkes failed\n");
405 kill(getpid(), SIGINT);
409 print_usage(
const char *progname)
411 printf(
"Fawkes Main Application - Usage Instructions\n" 412 "================================================" 413 "===============================\n" 414 "Usage: %s [options]\n" 415 "where [options] is one or more of:\n" 416 " -h These help instructions\n" 417 " -C Cleanup old BB and shared memory segments\n" 418 " -c db-file Mutable configuration file, created if it " 420 "exist, if it does must contain valid SQLite database\n" 421 " -d sql-file Default configuration SQL dump file.\n" 422 " -q[qqq] Quiet mode, -q omits debug, -qq debug and" 424 "-qqq omit debug, info and warn, -qqqq no output\n" 425 " -l level Set log level directly mutually exclusive" 427 "level is one of debug, info, warn, error, or none\n" 428 " -L loggers Define loggers. By default this setting is" 430 "config (console logger if unset). Format is:\n" 431 " logger:args[;logger2:args2[!...]]\n" 432 " Currently supported:\n" 433 " console, file:file.log, network logger always added\n" 434 " -p plugins List of plugins to load on startup in given order\n" 435 " -P port TCP port to listen on for Fawkes network connections.\n" 436 " --net-service-name=name mDNS service name to use.\n" 437 " -u user Drop privileges and run as given user.\n" 438 " -g group Drop privileges and run as given group.\n" 439 #ifdef HAVE_LIBDAEMON
440 " -D[pid file] Run daemonized in the background, pid file " 442 "default is /var/run/fawkes.pid, must be absolute path.\n" 443 " -D[pid file] -k Kill a daemonized Fawkes running in the" 445 " -D[pid file] -s Check status of daemon.\n" static void finalize()
Delete internal logger.
virtual std::string get_string(const char *path)
Get value from configuration which is of type string.
static MultiLogger * multilogger_instance(const char *as)
Create MultiLogger instance.
static Clock * instance()
Clock initializer.
ThreadCollector * aspect_collector() const
Get a thread collector to be used for an aspect initializer.
static void cleanup(const char *magic_token, bool use_lister=false)
Cleanup orphaned BlackBoard segments.
Fawkes library namespace.
virtual unsigned int get_uint(const char *path)
Get value from configuration which is of type unsigned int.
std::string get_modtype() const
Get modification type.
static void init_main()
Initialize Thread wrapper instance for main thread.
InitOptions & default_signal_handlers(bool enable)
Set default signal handlers.
virtual void load(const char *filename, const char *defaults_filename, const char *tag=NULL)
Load configuration.
virtual void set_loglevel(LogLevel level)
Sets the log level.
static void destroy_main()
Destroy main thread wrapper instance.
virtual void log_warn(const char *component, const char *format,...)
Log warning message.
InitOptions & show_help(bool show_help)
Set to show help.
void add_logger(Logger *logger)
Add a logger.
static void finalize()
Finalize.
virtual void log_info(const char *component, const char *format,...)
Log informational message.
static void init(MultiLogger *multi_logger=NULL)
Initialize logger.
void run()
Run main thread.
void register_default_inifins(BlackBoard *blackboard, ThreadCollector *collector, Configuration *config, Logger *logger, Clock *clock, FawkesNetworkHub *fnethub, MainLoopEmployer *mloop_employer, LoggerEmployer *logger_employer, BlockedTimingExecutor *btexec, NetworkNameResolver *nnresolver, ServicePublisher *service_publisher, ServiceBrowser *service_browser, PluginManager *pmanager)
Register default aspect initializer/finalizer.
virtual void set_default_uint(const char *path, unsigned int uint)
Set new default value in configuration of type unsigned int.
virtual LogLevel loglevel()
Get log level.
Fawkes default main thread.
virtual void log_debug(const char *component, const char *format,...)
Log debug message.
const char * basename() const
Get program basename.
void start(bool wait=true)
Call this method to start the thread.
InitOptions & daemonize(bool daemonize, bool kill=false, bool status=false, const char *pid_file=0)
Set daemonization options.
static void cleanup(const char *name=0)
Cleanup existing shared memory segments.
SQLiteValueIterator * modified_iterator()
Iterator for modified values.