/** * infinoted_util_daemon_pid_file_kill: * @sig: The signal to send to the daemon process. * * This is a thin wrapper for <function>daemon_pid_file_kill()</function> * which uses <function>daemon_pid_file_kill_wait()</function> if available * with a timeout of 5 seconds. * * Returns: 0 if the signal was sent or nonzero otherwise. */ int infinoted_util_daemon_pid_file_kill(int sig) { #ifdef LIBINFINITY_HAVE_LIBDAEMON # ifdef DAEMON_PID_FILE_KILL_WAIT_AVAILABLE return daemon_pid_file_kill_wait(sig, 5); # else return daemon_pid_file_kill(sig); # endif #else return 0; #endif }
int main(int argc, char *argv[]) { int r = 255; int wrote_pid_file = 0; avahi_set_log_function(log_function); init_rand_seed(); avahi_server_config_init(&config.server_config); config.command = DAEMON_RUN; config.daemonize = 0; config.config_file = NULL; #ifdef HAVE_DBUS config.enable_dbus = 1; config.fail_on_missing_dbus = 1; config.n_clients_max = 0; config.n_objects_per_client_max = 0; config.n_entries_per_entry_group_max = 0; #endif config.drop_root = 1; config.set_rlimits = 1; #ifdef ENABLE_CHROOT config.use_chroot = 1; #endif config.modify_proc_title = 1; config.disable_user_service_publishing = 0; config.publish_dns_servers = NULL; config.publish_resolv_conf = 0; config.use_syslog = 0; config.debug = 0; config.rlimit_as_set = 0; config.rlimit_core_set = 0; config.rlimit_data_set = 0; config.rlimit_fsize_set = 0; config.rlimit_nofile_set = 0; config.rlimit_stack_set = 0; #ifdef RLIMIT_NPROC config.rlimit_nproc_set = 0; #endif if ((argv0 = strrchr(argv[0], '/'))) argv0 = avahi_strdup(argv0 + 1); else argv0 = avahi_strdup(argv[0]); daemon_pid_file_ident = (const char *) argv0; daemon_log_ident = (char*) argv0; daemon_pid_file_proc = pid_file_proc; if (parse_command_line(&config, argc, argv) < 0) goto finish; if (config.modify_proc_title) avahi_init_proc_title(argc, argv); #ifdef ENABLE_CHROOT config.use_chroot = config.use_chroot && config.drop_root; #endif if (config.command == DAEMON_HELP) { help(stdout); r = 0; } else if (config.command == DAEMON_VERSION) { printf("%s "PACKAGE_VERSION"\n", argv0); r = 0; } else if (config.command == DAEMON_KILL) { if (daemon_pid_file_kill_wait(SIGTERM, 5) < 0) { avahi_log_warn("Failed to kill daemon: %s", strerror(errno)); goto finish; } r = 0; } else if (config.command == DAEMON_RELOAD) { if (daemon_pid_file_kill(SIGHUP) < 0) { avahi_log_warn("Failed to kill daemon: %s", strerror(errno)); goto finish; } r = 0; } else if (config.command == DAEMON_CHECK) r = (daemon_pid_file_is_running() >= 0) ? 0 : 1; else if (config.command == DAEMON_RUN) { pid_t pid; if (getuid() != 0 && config.drop_root) { avahi_log_error("This program is intended to be run as root."); goto finish; } if ((pid = daemon_pid_file_is_running()) >= 0) { avahi_log_error("Daemon already running on PID %u", pid); goto finish; } if (load_config_file(&config) < 0) goto finish; if (config.daemonize) { daemon_retval_init(); if ((pid = daemon_fork()) < 0) goto finish; else if (pid != 0) { int ret; /** Parent **/ if ((ret = daemon_retval_wait(20)) < 0) { avahi_log_error("Could not receive return value from daemon process."); goto finish; } r = ret; goto finish; } /* Child */ } if (config.use_syslog || config.daemonize) daemon_log_use = DAEMON_LOG_SYSLOG; if (sd_listen_fds(0) <= 0) if (daemon_close_all(-1) < 0) avahi_log_warn("Failed to close all remaining file descriptors: %s", strerror(errno)); daemon_reset_sigs(-1); daemon_unblock_sigs(-1); if (make_runtime_dir() < 0) goto finish; if (config.drop_root) { #ifdef ENABLE_CHROOT if (config.use_chroot) if (avahi_caps_reduce() < 0) goto finish; #endif if (drop_root() < 0) goto finish; #ifdef ENABLE_CHROOT if (config.use_chroot) if (avahi_caps_reduce2() < 0) goto finish; #endif } if (daemon_pid_file_create() < 0) { avahi_log_error("Failed to create PID file: %s", strerror(errno)); if (config.daemonize) daemon_retval_send(1); goto finish; } else wrote_pid_file = 1; if (config.set_rlimits) enforce_rlimits(); chdir("/"); #ifdef ENABLE_CHROOT if (config.drop_root && config.use_chroot) if (avahi_chroot_helper_start(argv0) < 0) { avahi_log_error("failed to start chroot() helper daemon."); goto finish; } #endif avahi_log_info("%s "PACKAGE_VERSION" starting up.", argv0); sd_notifyf(0, "STATUS=%s "PACKAGE_VERSION" starting up.", argv0); avahi_set_proc_title(argv0, "%s: starting up", argv0); if (run_server(&config) == 0) r = 0; avahi_log_info("%s "PACKAGE_VERSION" exiting.", argv0); sd_notifyf(0, "STATUS=%s "PACKAGE_VERSION" exiting.", argv0); } finish: if (config.daemonize) daemon_retval_done(); avahi_server_config_free(&config.server_config); avahi_free(config.config_file); avahi_strfreev(config.publish_dns_servers); avahi_strfreev(resolv_conf_name_servers); avahi_strfreev(resolv_conf_search_domains); if (wrote_pid_file) { #ifdef ENABLE_CHROOT avahi_chroot_helper_unlink(pid_file_proc()); #else daemon_pid_file_remove(); #endif } #ifdef ENABLE_CHROOT avahi_chroot_helper_shutdown(); #endif avahi_free(argv0); return r; }
void parse_args(int argc, char *argv[]) { static struct option long_options[] = { {"no-auto", no_argument, 0, 'a'}, {"no-daemon", no_argument, 0, 'n'}, {"no-syslog", no_argument, 0, 's'}, {"no-beep", no_argument, 0, 'b'}, {"ignore-fail", no_argument, 0, 'f'}, {"ignore-fail-positive", no_argument, 0, 'F'}, {"ignore-retval", no_argument, 0, 'I'}, {"iface", required_argument, 0, 'i'}, {"run", required_argument, 0, 'r'}, {"poll-time", required_argument, 0, 't'}, {"delay-up", required_argument, 0, 'u'}, {"delay-down", required_argument, 0, 'd'}, {"api-mode", required_argument, 0, 'm'}, {"wait-on-fork", no_argument, 0, 'w'}, {"wait-on-kill", no_argument, 0, 'W'}, {"no-startup", no_argument, 0, 'p'}, {"no-shutdown", no_argument, 0, 'q'}, {"help", no_argument, 0, 'h'}, {"kill", no_argument, 0, 'k'}, {"check-running", no_argument, 0, 'c'}, {"version", no_argument, 0, 'v'}, {"extra-arg", required_argument, 0, 'x'}, {"suspend", no_argument, 0, 'S'}, {"resume", no_argument, 0, 'R'}, {"info", no_argument, 0, 'z'}, {"initial-down", no_argument, 0, 'l'}, {"monitor", no_argument, 0, 'M'}, {0, 0, 0, 0} }; int option_index = 0; int help = 0, _kill = 0, _check = 0, _version = 0, _suspend = 0, _resume = 0, _info = 0; for (;;) { int c; if ((c = getopt_long(argc, argv, "asni:r:t:u:d:hkbfFvm:pqwx:cISRzlMW", long_options, &option_index)) < 0) break; switch (c) { case 'a' : interface_auto_up = !interface_auto_up; break; case 's' : use_syslog = !use_syslog; break; case 'n' : daemonize = !daemonize; break; case 'i' : if (interface) free(interface); interface = strdup(optarg); break; case 'r': run = strdup(optarg); break; case 'I': ignore_retval = !ignore_retval; break; case 't': polltime = atoi(optarg); if (polltime < 0) polltime = 0; break; case 'u': delay_up = atoi(optarg); break; case 'd': delay_down = atoi(optarg); break; case 'h': help = 1; break; case 'k': _kill = 1; break; case 'c': _check = 1; break; case 'v': _version = 1; break; case 'b': use_beep = !use_beep; break; case 'f': failure_status = IFSTATUS_DOWN; break; case 'F': failure_status = IFSTATUS_UP; break; case 'm': switch (tolower(optarg[0])) { case 'e': api_mode = API_ETHTOOL; break; case 'm': api_mode = API_MII; break; case 'p': api_mode = API_PRIVATE; break; case 'w': api_mode = API_WLAN; break; case 'a': api_mode = API_AUTO; break; case 'i': api_mode = API_IFF; break; default: daemon_log(LOG_ERR, "Unknown API mode: %s", optarg); exit(2); } break; case 'p': no_startup_script = !no_startup_script; break; case 'q': no_shutdown_script = !no_shutdown_script; break; case 'l': initial_down = !initial_down; break; case 'w': wait_on_fork = !wait_on_fork; break; case 'W': wait_on_kill = !wait_on_kill; break; case 'x': extra_arg = strdup(optarg); break; case 'S': _suspend = 1; break; case 'R': _resume = 1; break; case 'z': _info = 1; break; case 'M': use_ifmonitor = !use_ifmonitor; break; default: daemon_log(LOG_ERR, "Unknown parameter."); exit(1); } } if (!interface) interface = strdup("eth0"); if (!use_syslog) daemon_log_use = DAEMON_LOG_STDERR; if (help) { usage(argv[0]); exit(0); } if (_kill || _resume || _suspend || _info) { int rv; if (_kill && wait_on_kill) rv = daemon_pid_file_kill_wait(SIGINT, 5); else rv = daemon_pid_file_kill(_kill ? SIGINT : (_resume ? SIGUSR2 : (_info ? SIGHUP : SIGUSR1))); if (rv < 0) { daemon_log(LOG_ERR, "Failed to kill daemon. (%s)", strerror(errno)); exit(6); } exit(0); } if (_version) { #ifdef SVN_REVISION printf("ifplugd "VERSION" (SVN: "SVN_REVISION")\n"); #else printf("ifplugd "VERSION"\n"); #endif exit(0); } if (_check) { pid_t pid = daemon_pid_file_is_running(); if (pid == (pid_t) -1 || pid == 0) { printf("ifplugd not running.\n"); exit(255); } else { printf("ifplugd process for device %s running as pid %u.\n", interface, pid); exit(0); } } }