int application::run_application(int argc, char* argv[]) { missio::logging::initialize(); if(parse_command_line(argc, argv)) { #if defined(CHAT_PLATFORM_POSIX) if(daemonize_) { if(detail::posix_daemon_helper::daemonize()) { std::cout << "daemon started, pid = " << ::getpid() << std::endl; std::cout << "check log files for details" << std::endl; return EXIT_SUCCESS; } } #endif // defined(CHAT_PLATFORM_POSIX) try { LOG_COMP_INFO(application, "starting"); save_pid_file(); configure_logging_library(); configure_signal_handler(); server_.configure(config_); server_.start(); LOG_COMP_INFO(application, "started"); run_io_service(); LOG_COMP_INFO(application, "stopped"); } catch(std::exception const& e) { LOG_COMP_FAILURE(application, e); stop(); } LOG_COMP_INFO(application, "terminated"); } missio::logging::shutdown(); return EXIT_SUCCESS; }
/* * Handle options to control the daemon */ void daemon_manager(const char *bin, const char *cmd) { pid_t pid; char *str; str = str_tolower(cmd); if (strcmp(str, "start") == 0) { if (load_pid_file() > 0) { printf("Daemon is already running\n"); exit(EXIT_FAILURE); } pid = create_daemon(bin); /* If the returned pid is < 0, there was a problem with the fork and we exit with a failure */ if (pid < 0) { free(str); exit(EXIT_FAILURE); } /* If the returned pid > 0 it is the pid of the child and we are the parent. Save the pid to the pid file and exit with success */ if (pid > 0) { save_pid_file(pid); free(str); exit(EXIT_SUCCESS); } /* If this point is reached, the fork was successfull and we are the child process. Continue as daemon from here on. */ } else if (strcmp(str, "stop") == 0) { pid = load_pid_file(); if (pid <= 0) { printf("No pid file, cannot stop\n"); exit(EXIT_FAILURE); } /* Send a SIGTERM signal to the daemon */ kill(pid, SIGTERM); remove_pid_file(); exit(EXIT_SUCCESS); } else if (strcmp(str, "restart") == 0 ) { /* Leave empty for now */ } free(str); }
/**@internal * Main execution loop */ static void main_loop(void) { int result; pthread_t tid; s_config *config = config_get_config(); request *r; void **params; /* Set the time when wifidog started */ if (!started_time) { debug(LOG_INFO, "Setting started_time"); started_time = time(NULL); } else if (started_time < MINIMUM_STARTED_TIME) { debug(LOG_WARNING, "Detected possible clock skew - re-setting started_time"); started_time = time(NULL); } /* save the pid file if needed */ if ((!config) && (!config->pidfile)) save_pid_file(config->pidfile); /* If we don't have the Gateway IP address, get it. Can't fail. */ if (!config->gw_address) { debug(LOG_DEBUG, "Finding IP address of %s", config->gw_interface); if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) { debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface); exit(1); } debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_address); } /* If we don't have the Gateway ID, construct it from the internal MAC address. * "Can't fail" so exit() if the impossible happens. */ if (!config->gw_id) { debug(LOG_DEBUG, "Finding MAC address of %s", config->external_interface); if ((config->gw_id = get_iface_mac(config->external_interface)) == NULL) { debug(LOG_ERR, "Could not get MAC address information of %s, exiting...", config->external_interface); exit(1); } debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_id); } /* Initializes the web server */ debug(LOG_NOTICE, "Creating web server on %s:%d", config->gw_address, config->gw_port); if ((webserver = httpdCreate(config->gw_address, config->gw_port)) == NULL) { debug(LOG_ERR, "Could not create web server: %s", strerror(errno)); exit(1); } register_fd_cleanup_on_fork(webserver->serverSock); debug(LOG_DEBUG, "Assigning callbacks to web server"); httpdAddCContent(webserver, "/wifidog", "about", 0, NULL, http_callback_about); httpdAddCContent(webserver, "/wifidog", "status", 0, NULL, http_callback_status); httpdAddCContent(webserver, "/wifidog", "release", 0, NULL, http_callback_release); httpdAddCContent(webserver, "/wifidog", "allow", 0, NULL, http_callback_allow_redirect); httpdSetErrorFunction(webserver, 404, http_callback_404); /* Set the auth server ip address. */ set_auth_svr_lastip(config); /* Reset the firewall (if WiFiDog crashed) */ fw_destroy(); /* Then initialize it */ if (!fw_init()) { debug(LOG_ERR, "FATAL: Failed to initialize firewall"); exit(1); } /* Start control thread */ result = pthread_create(&tid, NULL, (void *)thread_wdctl, (void *)safe_strdup(config->wdctl_sock)); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (wdctl) - exiting"); termination_handler(0); } pthread_detach(tid); debug(LOG_NOTICE, "Waiting for connections"); while (1) { r = httpdGetConnection(webserver, NULL); /* We can't convert this to a switch because there might be * values that are not -1, 0 or 1. */ if (webserver->lastError == -1) { /* Interrupted system call */ if (NULL != r) { httpdEndRequest(r); } } else if (webserver->lastError < -1) { /* * FIXME * An error occurred - should we abort? * reboot the device ? */ debug(LOG_ERR, "FATAL: httpdGetConnection returned unexpected value %d, exiting.", webserver->lastError); termination_handler(0); } else if (r != NULL) { /* * We got a connection * * We should create another thread */ debug(LOG_INFO, "Received connection from %s, spawning worker thread", r->clientAddr); /* The void**'s are a simulation of the normal C * function calling sequence. */ params = safe_malloc(2 * sizeof(void *)); *params = webserver; *(params + 1) = r; result = pthread_create(&tid, NULL, (void *)thread_httpd, (void *)params); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (httpd) - exiting"); termination_handler(0); } pthread_detach(tid); } else { /* webserver->lastError should be 2 */ /* XXX We failed an ACL.... No handling because * we don't set any... */ } //update the auth server ip update_auth_svr_lastip(config); } /* never reached */ }