#include #include #include #include #include #include #include #include "main.h" #include "exec.h" #include "modemman.h" #include "msntab.h" #include "cmdline.h" oop_source* event_source = NULL; struct gengetopt_args_info args; const char *appname = NULL, *username = NULL; #define DEFAULT_MSNTABLE "../conf/msntab" static void *oop_exit_cb(oop_source *source, int sig, void *user) { daemon_log(LOG_ERR, "Recieved signal %s", sig == SIGINT ? "SIGINT" : (sig == SIGTERM ? "SIGTERM" : "UNKNWON")); return OOP_HALT; } static void *oop_reload_cb(oop_source *source, int sig, void *user) { daemon_log(LOG_ERR, "Reloading MSN table."); msntab_flush(); if (msntab_load(args.msntab_arg ? args.msntab_arg : DEFAULT_MSNTABLE) < 0) { daemon_log(LOG_ERR, "Ignoring all calls."); msntab_flush(); } return OOP_CONTINUE; } static void *oop_dump_cb(oop_source *source, int sig, void *user) { msntab_dump(); return OOP_CONTINUE; } int main_loop(void) { int r = -1, retval_sent = 0; oop_source_sys *sys = NULL; daemon_log(LOG_INFO, "Starting up."); if (!(sys = oop_sys_new())) { daemon_log(LOG_ERR, "Failed to create system source."); goto finish; } event_source = oop_sys_source(sys); assert(event_source); if (child_process_init() < 0) goto finish; if (msntab_load(args.msntab_arg ? args.msntab_arg : DEFAULT_MSNTABLE) < 0) goto finish; if (modem_manager_init(args.channels_arg) < 0) goto finish; event_source->on_signal(event_source, SIGINT, oop_exit_cb, NULL); event_source->on_signal(event_source, SIGTERM, oop_exit_cb, NULL); event_source->on_signal(event_source, SIGHUP, oop_reload_cb, NULL); event_source->on_signal(event_source, SIGUSR1, oop_dump_cb, NULL); signal(SIGPIPE, SIG_IGN); if (!args.no_daemon_flag) { daemon_retval_send(0); retval_sent = 1; } daemon_log(LOG_INFO, "Start up complete."); if (oop_sys_run(sys) == OOP_ERROR) { daemon_log(LOG_ERR, "oop_sys_new() returned OOP_ERROR"); goto finish; } r = 0; finish: daemon_log(LOG_INFO, "Shutting down."); if (!retval_sent && !args.no_daemon_flag) daemon_retval_send(1); event_source->cancel_signal(event_source, SIGTERM, oop_exit_cb, NULL); event_source->cancel_signal(event_source, SIGINT, oop_exit_cb, NULL); event_source->cancel_signal(event_source, SIGHUP, oop_reload_cb, NULL); event_source->cancel_signal(event_source, SIGUSR1, oop_dump_cb, NULL); msntab_flush(); modem_manager_done(); child_process_done(); if (sys) { event_source = NULL; oop_sys_delete(sys); } daemon_log(LOG_INFO, "Shut down complete."); return r; } int main(int argc, char*argv[]) { pid_t pid; int ret; appname = daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]); cmdline_parser(argc, argv, &args); if (args.no_syslog_flag) daemon_log_use = DAEMON_LOG_STDERR; if (args.kill_flag) { int ret; if ((ret = daemon_pid_file_kill_wait(SIGINT, 5)) < 0) daemon_log(LOG_WARNING, "Failed to kill daemon."); return ret < 0 ? 1 : 0; } if (args.check_flag) { if ((pid = daemon_pid_file_is_running()) >= 0) daemon_log(LOG_INFO, "Daemon running on PID %u.", pid); else daemon_log(LOG_INFO, "Daemon not running."); return 1; } if ((pid = daemon_pid_file_is_running()) >= 0) { daemon_log(LOG_ERR, "Daemon already running on PID %u.", pid); return 1; } if (!args.no_daemon_flag) { daemon_retval_init(); if ((pid = daemon_fork()) < 0) { daemon_retval_done(); return 1; } else if (pid) { int ret; if ((ret = daemon_retval_wait(20)) < 0) { daemon_log(LOG_ERR, "Failed to recieve return value from daemon process."); return 255; } if (ret) daemon_log(LOG_ERR, "Daemon returned %i as return value.", ret); return ret; } } if (daemon_pid_file_create() < 0) { daemon_log(LOG_ERR, "Could not create PID file (%s).", strerror(errno)); if (!args.no_daemon_flag) daemon_retval_send(1); return 1; } ret = main_loop() < 0 ? 1 : 0; daemon_pid_file_remove(); return ret; }