コード例 #1
0
ファイル: shairport.c プロジェクト: HugoChanD/shairport-sync
static void sig_shutdown(int foo, siginfo_t *bar, void *baz) {
  debug(1, "shutdown requested...");
  shairport_shutdown();
//  daemon_log(LOG_NOTICE, "exit...");
  daemon_retval_send(255);
  daemon_pid_file_remove();
  exit(0);
}
コード例 #2
0
void
cleanup()
{
#ifdef HAVE_LIBDAEMON
  daemon_retval_send(-1);
  daemon_retval_done();
  daemon_pid_file_remove();
#else
  throw Exception("Daemonizing support is not available.\n"
		  "(libdaemon[-devel] was not available at compile time)\n");
#endif
}
コード例 #3
0
ファイル: Main.cpp プロジェクト: aayushjr/ibrdtn
int main(int argc, char *argv[])
{
	// create a configuration
	dtn::daemon::Configuration &conf = dtn::daemon::Configuration::getInstance();

	// load parameter into the configuration
	conf.params(argc, argv);

#ifdef HAVE_LIBDAEMON
	if (conf.getDaemon().daemonize())
	{
		int ret = 0;
		pid_t pid;

#ifdef HAVE_DAEMON_RESET_SIGS
		/* Reset signal handlers */
		if (daemon_reset_sigs(-1) < 0) {
			daemon_log(LOG_ERR, "Failed to reset all signal handlers: %s", strerror(errno));
			return 1;
		}

		/* Unblock signals */
		if (daemon_unblock_sigs(-1) < 0) {
			daemon_log(LOG_ERR, "Failed to unblock all signals: %s", strerror(errno));
			return 1;
		}
#endif

		/* Set identification string for the daemon for both syslog and PID file */
		daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]);

		/* set the pid file path */
		try {
			std::string p = conf.getDaemon().getPidFile().getPath();
			__daemon_pidfile__ = new char[p.length() + 1];
			::strcpy(__daemon_pidfile__, p.c_str());
			daemon_pid_file_proc = __daemon_pid_file_proc__;
		} catch (const dtn::daemon::Configuration::ParameterNotSetException&) { };

		/* Check if we are called with -k parameter */
		if (conf.getDaemon().kill_daemon())
		{
			int ret;

			/* Kill daemon with SIGTERM */

			/* Check if the new function daemon_pid_file_kill_wait() is available, if it is, use it. */
			if ((ret = daemon_pid_file_kill_wait(SIGTERM, 5)) < 0)
				daemon_log(LOG_WARNING, "Failed to kill daemon: %s", strerror(errno));

			return ret < 0 ? 1 : 0;
		}

		/* Check that the daemon is not rung twice a the same time */
		if ((pid = daemon_pid_file_is_running()) >= 0) {
			daemon_log(LOG_ERR, "Daemon already running on PID file %u", pid);
			return 1;
		}

		/* Prepare for return value passing from the initialization procedure of the daemon process */
		if (daemon_retval_init() < 0) {
			daemon_log(LOG_ERR, "Failed to create pipe.");
			return 1;
		}

		/* Do the fork */
		if ((pid = daemon_fork()) < 0) {

			/* Exit on error */
			daemon_retval_done();
			return 1;

		} else if (pid) { /* The parent */
			int ret;

			/* Wait for 20 seconds for the return value passed from the daemon process */
			if ((ret = daemon_retval_wait(20)) < 0) {
				daemon_log(LOG_ERR, "Could not recieve return value from daemon process: %s", strerror(errno));
				return 255;
			}

			//daemon_log(ret != 0 ? LOG_ERR : LOG_INFO, "Daemon returned %i as return value.", ret);
			return ret;

		} else { /* The daemon */
			/* Close FDs */
			if (daemon_close_all(-1) < 0) {
				daemon_log(LOG_ERR, "Failed to close all file descriptors: %s", strerror(errno));

				/* Send the error condition to the parent process */
				daemon_retval_send(1);
				goto finish;
			}

			/* Create the PID file */
			if (daemon_pid_file_create() < 0) {
				daemon_log(LOG_ERR, "Could not create PID file (%s).", strerror(errno));
				daemon_retval_send(2);
				goto finish;
			}

			/* Initialize signal handling */
			if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, SIGUSR1, SIGUSR2, 0) < 0) {
				daemon_log(LOG_ERR, "Could not register signal handlers (%s).", strerror(errno));
				daemon_retval_send(3);
				goto finish;
			}

			ret = __daemon_run();

	finish:
			/* Do a cleanup */
			daemon_log(LOG_INFO, "Exiting...");
			daemon_retval_send(255);
			daemon_signal_done();
			daemon_pid_file_remove();
		}

		return ret;
	} else {
#endif
		// run the daemon
		return __daemon_run();
#ifdef HAVE_LIBDAEMON
	}
#endif
}
コード例 #4
0
ファイル: Main.cpp プロジェクト: aayushjr/ibrdtn
int __daemon_run()
{
	// catch process signals
	signal(SIGINT, sighandler);
	signal(SIGTERM, sighandler);
	signal(SIGHUP, sighandler);
	signal(SIGQUIT, sighandler);
	signal(SIGUSR1, sighandler);
	signal(SIGUSR2, sighandler);

	sigset_t blockset;
	sigemptyset(&blockset);
	sigaddset(&blockset, SIGPIPE);
	::sigprocmask(SIG_BLOCK, &blockset, NULL);

	dtn::daemon::Configuration &conf = dtn::daemon::Configuration::getInstance();

	// set default logging tag
	ibrcommon::Logger::setDefaultTag("DTNEngine");

	// enable ring-buffer
	ibrcommon::Logger::enableBuffer(200);

	// enable timestamps in logging if requested
	if (conf.getLogger().display_timestamps())
	{
		logopts = (~(ibrcommon::Logger::LOG_DATETIME) & logopts) | ibrcommon::Logger::LOG_TIMESTAMP;
	}

	// init syslog
	ibrcommon::Logger::enableAsync(); // enable asynchronous logging feature (thread-safe)
	ibrcommon::Logger::enableSyslog("ibrdtn-daemon", LOG_PID, LOG_DAEMON, logsys);

	if (!conf.getDebug().quiet())
	{
		if (conf.getLogger().verbose()) {
			// add logging to the cout
			ibrcommon::Logger::addStream(std::cout, logstd | ibrcommon::Logger::LOGGER_NOTICE, logopts);
		} else {
			// add logging to the cout
			ibrcommon::Logger::addStream(std::cout, logstd, logopts);
		}

		// add logging to the cerr
		ibrcommon::Logger::addStream(std::cerr, logerr, logopts);
	}

	// activate debugging
	if (conf.getDebug().enabled() && !conf.getDebug().quiet())
	{
		// init logger
		ibrcommon::Logger::setVerbosity(conf.getDebug().level());

		ibrcommon::Logger::addStream(std::cout, ibrcommon::Logger::LOGGER_DEBUG, logopts);

		_debug = true;
	}

	// load the configuration file
	conf.load();

	try {
		const ibrcommon::File &lf = conf.getLogger().getLogfile();
		ibrcommon::Logger::setLogfile(lf, ibrcommon::Logger::LOGGER_ALL ^ ibrcommon::Logger::LOGGER_DEBUG, logopts);
	} catch (const dtn::daemon::Configuration::ParameterNotSetException&) { };

	// initialize the daemon up to runlevel "Routing Extensions"
	_dtnd.init(dtn::daemon::RUNLEVEL_ROUTING_EXTENSIONS);

#ifdef HAVE_LIBDAEMON
	if (conf.getDaemon().daemonize())
	{
		/* Send OK to parent process */
		daemon_retval_send(0);
		daemon_log(LOG_INFO, "Sucessfully started");
	}
#endif

	ibrcommon::MutexLock l(_shutdown_cond);
	while (!_shutdown) _shutdown_cond.wait();

	_dtnd.init(dtn::daemon::RUNLEVEL_ZERO);

	// stop the asynchronous logger
	ibrcommon::Logger::stop();

	return 0;
}
コード例 #5
0
ファイル: main.c プロジェクト: Dessperado/avahi
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;
}
コード例 #6
0
ファイル: main.c プロジェクト: Dessperado/avahi
static int run_server(DaemonConfig *c) {
    int r = -1;
    int error;
    const AvahiPoll *poll_api = NULL;
    AvahiWatch *sig_watch = NULL;
    int retval_is_sent = 0;
#ifdef HAVE_INOTIFY
    AvahiWatch *inotify_watch = NULL;
#endif
#ifdef HAVE_KQUEUE
    int i;
    AvahiWatch *kqueue_watch = NULL;
#endif

    assert(c);

    ignore_signal(SIGPIPE);

    if (!(nss_support = avahi_nss_support()))
        avahi_log_warn("WARNING: No NSS support for mDNS detected, consider installing nss-mdns!");

    if (!(simple_poll_api = avahi_simple_poll_new())) {
        avahi_log_error("Failed to create main loop object.");
        goto finish;
    }

    poll_api = avahi_simple_poll_get(simple_poll_api);

    if (daemon_signal_init(SIGINT, SIGHUP, SIGTERM, SIGUSR1, 0) < 0) {
        avahi_log_error("Could not register signal handlers (%s).", strerror(errno));
        goto finish;
    }

    if (!(sig_watch = poll_api->watch_new(poll_api, daemon_signal_fd(), AVAHI_WATCH_IN, signal_callback, simple_poll_api))) {
        avahi_log_error( "Failed to create signal watcher");
        goto finish;
    }

    if (simple_protocol_setup(poll_api) < 0)
        goto finish;

#ifdef HAVE_DBUS
    if (c->enable_dbus) {
        if (dbus_protocol_setup(poll_api,
                                config.disable_user_service_publishing,
                                config.n_clients_max,
                                config.n_objects_per_client_max,
                                config.n_entries_per_entry_group_max,
                                !c->fail_on_missing_dbus
#ifdef ENABLE_CHROOT
                                && !config.use_chroot
#endif
            ) < 0) {

            avahi_log_warn("WARNING: Failed to contact D-Bus daemon.");

            if (c->fail_on_missing_dbus)
                goto finish;
        }
    }
#endif

#ifdef ENABLE_CHROOT

    if (config.drop_root && config.use_chroot) {
        if (chroot(AVAHI_CONFIG_DIR) < 0) {
            avahi_log_error("Failed to chroot(): %s", strerror(errno));
            goto finish;
        }

        avahi_log_info("Successfully called chroot().");
        chdir("/");

        if (avahi_caps_drop_all() < 0) {
            avahi_log_error("Failed to drop capabilities.");
            goto finish;
        }
        avahi_log_info("Successfully dropped remaining capabilities.");
    }

#endif

#ifdef HAVE_INOTIFY
    if ((inotify_fd = inotify_init()) < 0)
        avahi_log_warn( "Failed to initialize inotify: %s", strerror(errno));
    else {
        add_inotify_watches();

        if (!(inotify_watch = poll_api->watch_new(poll_api, inotify_fd, AVAHI_WATCH_IN, inotify_callback, NULL))) {
            avahi_log_error( "Failed to create inotify watcher");
            goto finish;
        }
    }
#endif

#ifdef HAVE_KQUEUE
    if ((kq = kqueue()) < 0)
        avahi_log_warn( "Failed to initialize kqueue: %s", strerror(errno));
    else {
        add_kqueue_watches();

        if (!(kqueue_watch = poll_api->watch_new(poll_api, kq, AVAHI_WATCH_IN, kqueue_callback, NULL))) {
            avahi_log_error( "Failed to create kqueue watcher");
            goto finish;
        }
    }
#endif

    load_resolv_conf();
#ifdef ENABLE_CHROOT
    static_service_load(config.use_chroot);
    static_hosts_load(config.use_chroot);
#else
    static_service_load(0);
    static_hosts_load(0);
#endif

    if (!(avahi_server = avahi_server_new(poll_api, &c->server_config, server_callback, c, &error))) {
        avahi_log_error("Failed to create server: %s", avahi_strerror(error));
        goto finish;
    }

    update_wide_area_servers();
    update_browse_domains();

    if (c->daemonize) {
        daemon_retval_send(0);
        retval_is_sent = 1;
    }

    for (;;) {
        if ((r = avahi_simple_poll_iterate(simple_poll_api, -1)) < 0) {

            /* We handle signals through an FD, so let's continue */
            if (errno == EINTR)
                continue;

            avahi_log_error("poll(): %s", strerror(errno));
            goto finish;
        } else if (r > 0)
            /* Quit */
            break;
    }

    r = 0;

finish:

    static_service_remove_from_server();
    static_service_free_all();

    static_hosts_remove_from_server();
    static_hosts_free_all();

    remove_dns_server_entry_groups();

    simple_protocol_shutdown();

#ifdef HAVE_DBUS
    if (c->enable_dbus)
        dbus_protocol_shutdown();
#endif

    if (avahi_server) {
        avahi_server_free(avahi_server);
        avahi_server = NULL;
    }

    daemon_signal_done();

    if (sig_watch)
        poll_api->watch_free(sig_watch);

#ifdef HAVE_INOTIFY
    if (inotify_watch)
        poll_api->watch_free(inotify_watch);
    if (inotify_fd >= 0)
        close(inotify_fd);
#endif

#ifdef HAVE_KQUEUE
    if (kqueue_watch)
        poll_api->watch_free(kqueue_watch);
    if (kq >= 0)
        close(kq);
    for (i = 0; i < num_kfds; i++) {
        if (kfds[i] >= 0)
            close(kfds[i]);
    }
#endif

    if (simple_poll_api) {
        avahi_simple_poll_free(simple_poll_api);
        simple_poll_api = NULL;
    }

    if (!retval_is_sent && c->daemonize)
        daemon_retval_send(1);

    return r;
}
コード例 #7
0
int main(int argc, char *argv[])
{
	pid_t pid;
	/* Reset signal handlers */
	if (daemon_reset_sigs(-1) < 0) {
		daemon_log(LOG_ERR, "Failed to reset all signal handlers: %s",
			strerror(errno));
		return 1;
	}
	/* Unblock signals */
	if (daemon_unblock_sigs(-1) < 0) {
		daemon_log(LOG_ERR, "Failed to unblock all signals: %s",
			strerror(errno));
	}
	/* Set indetification string for the daemon for both syslog and PID file */
	daemon_log_ident = daemon_ident_from_argv0(argv[0]);
	daemon_pid_file_ident = daemon_log_ident;
	//(LOG_ERR, "The log ident is %s\n",daemon_log_ident);
	daemon_pid_file_proc = get_pid_file_proc;
	sprintf (image_pid_file, "/var/run/%s.pid", daemon_pid_file_ident);
	/* Check if we are called with -k parameter */
	if (argc >= 2 && !strcmp(argv[1], "-k")) {
		int ret;
		/* Kill daemon with SIGTERM */
		/* Check if the new function daemon_pid_file_kill_wait() is available,
			if it is, use it. */
		if ((ret = daemon_pid_file_kill_wait(SIGTERM, 5)) < 0)
			daemon_log(LOG_WARNING, "Failed to kill daemon: %s",
				strerror(errno));
		return ret < 0 ? 1 : 0;
	}
	/* Check that the daemon is not rung twice a the same time */
	if ((pid = daemon_pid_file_is_running()) >= 0) {
		daemon_log(LOG_ERR, "Daemon already running on PID file %u", pid);
		return 1;
	}
	/* Prepare for return value passing from the initialization procedure
		of the daemon process */
	if (daemon_retval_init() < 0) {
		daemon_log(LOG_ERR, "Failed to create pipe.");
		return 1;
	}
	/* Do the fork */
	if ((pid = daemon_fork()) < 0) {
		/* Exit on error */
		daemon_retval_done();
		return 1;
	} else if (pid) {  /* The parent */
		int ret;
		/* Wait for 20 seconds for the return value passed from the daemon
			process */
		if ((ret = daemon_retval_wait(20)) < 0) {
			daemon_log(LOG_ERR, "Count not receive return value from daemon"
				"process: %s", strerror(errno));
		}
		//daemon_log(ret != 0 ? LOG_ERR : LOG_INFO,
		//	"Daemon returned %i as return value.", ret);
		return ret;
	} else {  /* The daemon */
		int fd, quit = 0;
		fd_set fds;
		pthread_t sock_thread;
		pthread_t nl_thread;
		/* Close FDs */
		if (daemon_close_all(-1) < 0) {
			daemon_log(LOG_ERR, "Failed to close all file descriptors: %s",
				strerror(errno));
			/* Send the error condition to the parent process */
			daemon_retval_send(1);
			goto finish;
		}
		/* Create the PID file */
		if (daemon_pid_file_create() < 0) {
			daemon_log(LOG_ERR, "Could not create PID file (%s).",
				strerror(errno));
			daemon_retval_send(2);
			goto finish;
		}
		/* Initialize signal handling */
		if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, 0) < 0) {
			daemon_log(LOG_ERR, "Could not register signal handlers (%s).",
				strerror(errno));
			daemon_retval_send(3);
			goto finish;
		}
		/* Init task */
		init_image_config(argc, argv);
		init_netlink();
		/* Send OK to parent process */
		daemon_retval_send(0);
		daemon_log(LOG_INFO, "Sucessfully started");
		/* Main task*/
		pthread_create(&nl_thread, NULL, (void *)netlink_loop, (void *)NULL);
		#if 0
		pthread_create(&sock_thread, NULL, (void *)socket_loop, (void *)NULL);
		#endif
		pthread_create(&sock_thread, NULL, (void *)mq_loop, (void *)NULL);
		/* Prepare for select() on the signal fd */
		FD_ZERO(&fds);
		fd = daemon_signal_fd();
		FD_SET(fd, &fds);
		while (!quit) {
			fd_set fds2 = fds;
			/* Wait for an incoming signal */
			if (select(FD_SETSIZE, &fds2, 0, 0, 0) < 0) {
				/* If we've been interrupted by an incoming signal, continue */
				if (errno == EINTR)
					continue;
				daemon_log(LOG_ERR, "select(): %s", strerror(errno));
				break;
			}
			/* Check if a signal has been recieved */
			if (FD_ISSET(fd, &fds2)) {
				int sig;
				/* Get signal */
				if ((sig = daemon_signal_next()) <= 0) {
					daemon_log(LOG_ERR, "daemon_signal_next() failed: %s",
						strerror(errno));
					break;
				}
				/* Dispatch signal */
				switch (sig) {
					case SIGINT:
					case SIGQUIT:
					case SIGTERM:
						daemon_log(LOG_WARNING, "Got SIGINT, SIGQUIT or"
							"SIGTERM.");
						if (nl_image_config.nl_connected == 1) {
							nl_image_config.nl_connected = 0;
							if (nl_send_image_session_cmd(
								IMAGE_SESSION_CMD_DISCONNECT) < 0) {
								printf("Failed to remove connection with"
									"kernel!\n");
							}
						}
						quit = 1;
						break;
					case SIGHUP:
						daemon_log(LOG_INFO, "Got a HUP");
						daemon_exec("/", NULL, "/bin/ls", "ls", (char*) NULL);
						break;
				}
			}
		}
		/* Do a cleanup */
finish:
		delete_pid_file(IMAGE_SERVER_PROC);
		daemon_log(LOG_INFO, "Exiting...");
		daemon_retval_send(255);
		daemon_signal_done();
		daemon_pid_file_remove();
		return 0;
	}
}
コード例 #8
0
/** Punto de entrada de la aplicacion de navegacion.
 * @return Estado de la aplicacion al terminar.
 */
int main(int argc, char *argv[]) {
	pid_t pid;

	/* Reset signal handlers */
	if (daemon_reset_sigs(-1) < 0) {
		daemon_log(LOG_ERR, "Failed to reset all signal handlers: %s",
				strerror(errno));
		return 1;
	}

	/* Unblock signals */
	if (daemon_unblock_sigs(-1) < 0) {
		daemon_log(LOG_ERR, "Failed to unblock all signals: %s",
				strerror(errno));
		return 1;
	}

	/* Set indetification string for the daemon for both syslog and PID file */
	daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]);

	/* Check if we are called with -k parameter */
	if (argc >= 2 && !strcmp(argv[1], "-k")) {
		int ret;

		/* Kill daemon with SIGTERM */

		/* Check if the new function daemon_pid_file_kill_wait() is available, if it is, use it. */
		if ((ret = daemon_pid_file_kill_wait(SIGTERM, 5)) < 0)
			daemon_log(LOG_WARNING, "Failed to kill daemon: %s",
					strerror(errno));

		return ret < 0 ? 1 : 0;
	}

	/* Check that the daemon is not rung twice a the same time */
	if ((pid = daemon_pid_file_is_running()) >= 0) {
		daemon_log(LOG_ERR, "Daemon already running on PID file %u", pid);
		return 1;
	}

	/* Prepare for return value passing from the initialization procedure of the daemon process */
	if (daemon_retval_init() < 0) {
		daemon_log(LOG_ERR, "Failed to create pipe.");
		return 1;
	}

	/* Do the fork */
	if ((pid = daemon_fork()) < 0) {

		/* Exit on error */
		daemon_retval_done();
		return 1;

	} else if (pid) { /* The parent */
		int ret;

		/* Wait for 20 seconds for the return value passed from the daemon process */
		if ((ret = daemon_retval_wait(20)) < 0) {
			daemon_log(LOG_ERR,
					"Could not recieve return value from daemon process: %s",
					strerror(errno));
			return 255;
		}

		daemon_log(ret != 0 ? LOG_ERR : LOG_INFO,
				"Daemon returned %i as return value.", ret);
		return ret;

	} else { /* The daemon */
		int fd, quit = 0;
		fd_set fds;

		char * config_file;

		config_t cfg;
		config_setting_t *setting;

		/* Base de Datos de Tiempo Real */
		struct rtdb rtdb;

		/* Controlador de estado de la MTi-G */
		struct mti_g mti_g;

		struct time_tracker tracker;

		struct sharksoft sharksoft;

		/* Close FDs */
		if (daemon_close_all(-1) < 0) {
			daemon_log(LOG_ERR, "Failed to close all file descriptors: %s",
					strerror(errno));

			/* Send the error condition to the parent process */
			daemon_retval_send(1);
			goto finish;
		}

		/* Create the PID file */
		if (daemon_pid_file_create() < 0) {
			daemon_log(LOG_ERR, "Could not create PID file (%s).",
					strerror(errno));
			daemon_retval_send(2);
			goto finish;
		}

		/* Initialize signal handling */
		if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, 0) < 0) {
			daemon_log(LOG_ERR, "Could not register signal handlers (%s).",
					strerror(errno));
			daemon_retval_send(3);
			goto finish;
		}

		/*... do some further init work here */

		daemon_log(LOG_INFO, "Starting");

		/* cargar la configuración de la aplicación */
		config_init(&cfg);

		config_file = malloc(strlen(CONFIG_PATH) + strlen(CONFIG_FILE) + 1);
		assert(config_file != NULL);
		strcpy(config_file, CONFIG_PATH);
		strcpy(config_file + strlen(CONFIG_PATH), CONFIG_FILE);


		/* Read the file. If there is an error, report it and exit. */
		if (!config_read_file(&cfg, CONFIG_FILE)) {
			daemon_log(LOG_ERR, "%s:%d - %s\n", config_error_file(&cfg),
					config_error_line(&cfg), config_error_text(&cfg));
			daemon_retval_send(4);
			goto finish;
		}

		daemon_log(LOG_INFO, "Config file readed");

		/* Inicializar el controlador de estado de la MTi-G, enlazando
		 * la RTDB como area de almacenamiento */
		setting = config_lookup(&cfg, "mti_g");
		mti_g_init(&mti_g, setting, &(rtdb.imu), &(rtdb.gps));

		daemon_log(LOG_INFO, "MTi-G state controller inited");

		setting = config_lookup(&cfg, "time_tracker");
		time_tracker_init(&tracker, setting);

		daemon_log(LOG_INFO, "Time Tracker service inited");

		setting = config_lookup(&cfg, "sharksoft");
		sharksoft_init(&sharksoft, setting, &(rtdb.imu), &(rtdb.gps));

		daemon_log(LOG_INFO, "Sharksoft data provider service inited");

		/* Send OK to parent process */
		daemon_retval_send(0);

		daemon_log(LOG_INFO, "Sucessfully started");

		/* Prepare for select() on the signals */
		FD_ZERO(&fds);
		fd = daemon_signal_fd();
		FD_SET(fd, &fds);

		FD_SET(mti_g.fd, &fds);
		FD_SET(sharksoft.fd, &fds);

		while (!quit) {
			fd_set fds2 = fds;

			/* Wait for an incoming signal */
			if (select(FD_SETSIZE, &fds2, 0, 0, 0) < 0) {

				/* If we've been interrupted by an incoming signal, continue */
				if (errno == EINTR)
					continue;

				daemon_log(LOG_ERR, "select(): %s", strerror(errno));
				break;
			}

			/* Check if a signal has been recieved */
			if (FD_ISSET(fd, &fds2)) {
				int sig;

				/* Get signal */
				if ((sig = daemon_signal_next()) <= 0) {
					daemon_log(LOG_ERR, "daemon_signal_next() failed: %s",
							strerror(errno));
					break;
				}

				/* Dispatch signal */
				switch (sig) {

				case SIGINT:
				case SIGQUIT:
				case SIGTERM:
					daemon_log(LOG_WARNING, "Got SIGINT, SIGQUIT or SIGTERM.");
					quit = 1;
					break;

				case SIGHUP:
					daemon_log(LOG_INFO, "Got a HUP");
					daemon_exec("/", NULL, "/bin/ls", "ls", (char*) NULL);
					break;
				}
			}

			/* Procesar señales desde la MTi-G */
			if (FD_ISSET(mti_g.fd, &fds2)) {
				mti_g_handle_request(&mti_g);

				//sharksoft_handle_getdata(&sharksoft);

				//time_tracker_handle(&tracker);
			}

			/* Procesar señales desde el HMI Sharksoft */
			if (FD_ISSET(sharksoft.fd, &fds2)) {
				//time_tracker_handle(&tracker);
				sharksoft_handle_request(&sharksoft);

			}
		}

		time_tracker_dispose(&tracker);

		config_destroy(&cfg);

		/* Do a cleanup */
		finish: daemon_log(LOG_INFO, "Exiting...");
		daemon_retval_send(255);
		daemon_signal_done();
		daemon_pid_file_remove();

		return 0;
	}
}
コード例 #9
0
int main(int argc, char *argv[])
{
    fd_set rfds;
    struct timeval tv;
    int retval;
    pid_t pid;
    char *cpSerialDevice = NULL;

    {
        static struct option long_options[] =
        {
            /* Required arguments */
            {"serial",                  required_argument,  NULL, 's'},

            /* Program options */
            {"help",                    no_argument,        NULL, 'h'},
            {"foreground",              no_argument,        NULL, 'f'},
            {"verbosity",               required_argument,  NULL, 'v'},
            {"baud",                    required_argument,  NULL, 'B'},
            {"interface",               required_argument,  NULL, 'I'},
            {"reset",                   no_argument,        NULL, 'R'},
            {"confignotify",            required_argument,  NULL, 'C'},
            {"activityled",             required_argument,  NULL, 'A'},

            /* Module options */
            {"frontend",                required_argument,  NULL, 'F'},
            {"diversity",               no_argument,        NULL, 'D'},
            
            /* 6LoWPAN network options */
            {"mode",                    required_argument,  NULL, 'm'},
            {"region",                  required_argument,  NULL, 'r'},
            {"channel",                 required_argument,  NULL, 'c'},
            {"pan",                     required_argument,  NULL, 'p'},
            {"network",                 required_argument,  NULL, 'j'},
            {"profile",                 required_argument,  NULL, 'P'},
            {"prefix",                  required_argument,  NULL, '6'},

            /* Security options */
            {"key",                     required_argument,  NULL, 'k'},
            {"authscheme",              required_argument,  NULL, 'a'},
            
            /* Radius with PAP options */
            {"radiusip",                required_argument,  NULL, 'i'},
            
            { NULL, 0, NULL, 0}
        };
        signed char opt;
        int option_index;

        while ((opt = getopt_long(argc, argv, "s:hfv:B:I:RC:A:F:Dm:r:c:p:j:P:6:k:a:i:", long_options, &option_index)) != -1) 
        {
            switch (opt) 
            {
                case 'h':
                    print_usage_exit(argv);
                    break;
                case 'f':
                    daemonize = 0;
                    break;
                case 'v':
                    verbosity = atoi(optarg);
                    break;
                case 'B':
                {
                    char *pcEnd;
                    errno = 0;
                    u32BaudRate = strtoul(optarg, &pcEnd, 0);
                    if (errno)
                    {
                        printf("Baud rate '%s' cannot be converted to 32 bit integer (%s)\n", optarg, strerror(errno));
                        print_usage_exit(argv);
                    }
                    if (*pcEnd != '\0')
                    {
                        printf("Baud rate '%s' contains invalid characters\n", optarg);
                        print_usage_exit(argv);
                    }
                    break;
                }
                case 's':
                    cpSerialDevice = optarg;
                    break;
                    
                case 'C':
                {
                    struct stat sStat;
                    
                    /* Check if the given program exists and is executable */
                    if (stat(optarg, &sStat) == 0)
                    {
                        /* File stat'd ok */
                        pcConfigProgram = optarg;
                        vprConfigChanged = ConfigChangedCallback;
                    }
                    else
                    {
                        printf("Config stat notification program '%s' (%s)\n", optarg, strerror(errno));
                        print_usage_exit(argv);
                    }
                    break;
                }
                
                case 'A':
                {
                    char *pcEnd;
                    uint32_t u32ActivityLED;
                    errno = 0;
                    u32ActivityLED = strtoul(optarg, &pcEnd, 0);
                    if (errno)
                    {
                        printf("Activity LED '%s' cannot be converted to 32 bit integer (%s)\n", optarg, strerror(errno));
                        print_usage_exit(argv);
                    }
                    if (*pcEnd != '\0')
                    {
                        printf("Activity LED '%s' contains invalid characters\n", optarg);
                        print_usage_exit(argv);
                    }
                    eActivityLED = u32ActivityLED;
                    break;
                }
                
                case 'F':
                    if (strcmp(optarg, "SP") == 0)
                    {
                        eRadioFrontEnd = E_FRONTEND_STANDARD_POWER;
                    }
                    else if (strcmp(optarg, "HP") == 0)
                    {
                        eRadioFrontEnd = E_FRONTEND_HIGH_POWER;
                    }
                    else if (strcmp(optarg, "ETSI") == 0)
                    {
                        eRadioFrontEnd = E_FRONTEND_ETSI;
                    }
                    else
                    {
                        printf("Unknown mode '%s' specified. Supported modes are 'coordinator', 'router', 'commissioning'\n", optarg);
                        print_usage_exit(argv);
                    }
                    break;
                    
                case 'D':
                    iAntennaDiversity = 1;
                    break;
                    
                case 'm':
                    if (strcmp(optarg, "coordinator") == 0)
                    {
                        eModuleMode = E_MODE_COORDINATOR;
                    }
                    else if (strcmp(optarg, "router") == 0)
                    {
                        eModuleMode = E_MODE_ROUTER;
                    }
                    else if (strcmp(optarg, "commissioning") == 0)
                    {
                        eModuleMode = E_MODE_COMMISSIONING;
                    }
                    else
                    {
                        printf("Unknown mode '%s' specified. Supported modes are 'coordinator', 'router', 'commissioning'\n", optarg);
                        print_usage_exit(argv);
                    }
                    break;
                    
                case 'r':
                {
                    char *pcEnd;
                    uint32_t u32Region;
                    errno = 0;
                    u32Region = strtoul(optarg, &pcEnd, 0);
                    if (errno)
                    {
                        printf("Region '%s' cannot be converted to 32 bit integer (%s)\n", optarg, strerror(errno));
                        print_usage_exit(argv);
                    }
                    if (*pcEnd != '\0')
                    {
                        printf("Region '%s' contains invalid characters\n", optarg);
                        print_usage_exit(argv);
                    }
                    if (u32Region > E_REGION_MAX)
                    {
                        printf("Invalid region '%s' specified\n", optarg);
                        print_usage_exit(argv);
                    }
                    eRegion = (uint8_t)u32Region;
                    break;
                }
                case 'c':
                {
                    char *pcEnd;
                    uint32_t u32Channel;
                    errno = 0;
                    u32Channel = strtoul(optarg, &pcEnd, 0);
                    if (errno)
                    {
                        printf("Channel '%s' cannot be converted to 32 bit integer (%s)\n", optarg, strerror(errno));
                        print_usage_exit(argv);
                    }
                    if (*pcEnd != '\0')
                    {
                        printf("Channel '%s' contains invalid characters\n", optarg);
                        print_usage_exit(argv);
                    }
                    if ( !((u32Channel == E_CHANNEL_AUTOMATIC) ||
                          ((u32Channel >= E_CHANNEL_MINIMUM) && 
                           (u32Channel <= E_CHANNEL_MAXIMUM))))
                    {
                        printf("Invalid Channel '%s' specified\n", optarg);
                        print_usage_exit(argv);
                    }
                    eChannel = (uint8_t)u32Channel;
                    break;
                }
                case 'p':
                {
                    char *pcEnd;
                    uint32_t u32PanID;
                    errno = 0;
                    u32PanID = strtoul(optarg, &pcEnd, 0);
                    if (errno)
                    {
                        printf("PAN ID '%s' cannot be converted to 32 bit integer (%s)\n", optarg, strerror(errno));
                        print_usage_exit(argv);
                    }
                    if (*pcEnd != '\0')
                    {
                        printf("PAN ID '%s' contains invalid characters\n", optarg);
                        print_usage_exit(argv);
                    }
                    if (u32PanID > 0xFFFF)
                    {
                        printf("Invalid PAN ID '%s' specified\n", optarg);
                        print_usage_exit(argv);
                    }
                    u16PanID = (uint16_t)u32PanID;
                    break;
                }
                case 'j':
                {
                    char *pcEnd;
                    uint32_t u32JenNetID;
                    errno = 0;
                    u32JenNetID = strtoul(optarg, &pcEnd, 0);
                    if (errno)
                    {
                        printf("JenNet ID '%s' cannot be converted to 32 bit integer (%s)\n", optarg, strerror(errno));
                        print_usage_exit(argv);
                    }
                    if (*pcEnd != '\0')
                    {
                        printf("JenNet ID '%s' contains invalid characters\n", optarg);
                        print_usage_exit(argv);
                    }
                    u32UserData = u32JenNetID;
                    break;
                }
                case 'P':
                {
                    char *pcEnd;
                    uint32_t u32JenNetProfile;
                    errno = 0;
                    u32JenNetProfile = strtoul(optarg, &pcEnd, 0);
                    if (errno)
                    {
                        printf("JenNet Profile '%s' cannot be converted to 32 bit integer (%s)\n", optarg, strerror(errno));
                        print_usage_exit(argv);
                    }
                    if (*pcEnd != '\0')
                    {
                        printf("JenNet Profile '%s' contains invalid characters\n", optarg);
                        print_usage_exit(argv);
                    }
                    if (u32JenNetProfile > 0xFF)
                    {
                        printf("Invalid JenNet Profile '%s' specified\n", optarg);
                        print_usage_exit(argv);
                    }
                    u8JenNetProfile = (uint8_t)u32JenNetProfile;
                    break;
                }
                case '6':
                {
                    int result;
                    struct in6_addr address;
                    
                    result = inet_pton(AF_INET6, optarg, &address);
                    if (result <= 0)
                    {
                        if (result == 0)
                        {
                            printf("Unknown host: %s\n", optarg);
                        }
                        else if (result < 0)
                        {
                            perror("inet_pton failed");
                        }
                        exit(EXIT_FAILURE);
                    }
                    else
                    {
                        u64NetworkPrefix =  ((uint64_t)address.s6_addr[0] << 56) | 
                                            ((uint64_t)address.s6_addr[1] << 48) | 
                                            ((uint64_t)address.s6_addr[2] << 40) | 
                                            ((uint64_t)address.s6_addr[3] << 32) |
                                            ((uint64_t)address.s6_addr[4] << 24) | 
                                            ((uint64_t)address.s6_addr[5] << 16) | 
                                            ((uint64_t)address.s6_addr[6] <<  8) | 
                                            ((uint64_t)address.s6_addr[7] <<  0);
                    }
                    break;
                }
                case  'I':
                    cpTunDevice = optarg;
                    break;
                    
                case  'R':
                    iResetCoordinator = 1;
                    break;
                    
                case 'k':
                {
                    int result;
                    
                    /* The network key is specified like an IPv6 address, in 8 groups of 16-bit hexadecimal values separated by colons (:) */
                    result = inet_pton(AF_INET6, optarg, &sSecurityKey);
                    if (result <= 0)
                    {
                        if (result == 0)
                        {
                            printf("Could not parse network key: %s\n", optarg);
                        }
                        else if (result < 0)
                        {
                            perror("inet_pton failed");
                        }
                        exit(EXIT_FAILURE);
                    }
                    iSecureNetwork = 1;
                    break;
                }
                
                case 'a':
                {
                    char *pcEnd;
                    uint32_t u32AuthScheme;
                    errno = 0;
                    u32AuthScheme = strtoul(optarg, &pcEnd, 0);
                    if (errno)
                    {
                        printf("Authorisation scheme '%s' cannot be converted to 32 bit integer (%s)\n", optarg, strerror(errno));
                        print_usage_exit(argv);
                    }
                    if (*pcEnd != '\0')
                    {
                        printf("Authorisation scheme '%s' contains invalid characters\n", optarg);
                        print_usage_exit(argv);
                    }

                    switch(u32AuthScheme)
                    {
                        case 0:
                            printf("Warning - no authorisation scheme selected\n");
                            eAuthScheme = u32AuthScheme;
                            break;
                            
                        case (1):
                            eAuthScheme = u32AuthScheme;
                            break;
                            
                        default:
                            printf("Unknown authorisation scheme selected (%d)\n", u32AuthScheme);
                            print_usage_exit(argv);
                            break;
                    }
                    break;
                }
                
                case 'i':
                {
                    switch(eAuthScheme)
                    {
                        case (E_AUTH_SCHEME_RADIUS_PAP):
                        {
                            int result = inet_pton(AF_INET6, optarg, &uAuthSchemeData.sRadiusPAP.sAuthServerIP);
                            if (result <= 0)
                            {
                                if (result == 0)
                                {
                                    printf("Unknown host: %s\n", optarg);
                                }
                                else if (result < 0)
                                {
                                    perror("inet_pton failed");
                                }
                                exit(EXIT_FAILURE);
                            }
                            break;
                        }
                        
                        default:
                            printf("Option '-i' is not appropriate for authorisation scheme %d\n", eAuthScheme);
                            break;
                    }
                    break;
                }
                    
                default: /* '?' */
                    print_usage_exit(argv);
            }
        }
    }
    
    /* Log everything into syslog */
    daemon_log_ident = daemon_ident_from_argv0(argv[0]);
    
    if (!cpSerialDevice)
    {
        print_usage_exit(argv);
    }
    
    if (daemonize)
    {
        /* Prepare for return value passing from the initialization procedure of the daemon process */
        if (daemon_retval_init() < 0) {
            daemon_log(LOG_ERR, "Failed to create pipe.");
            return 1;
        }

        /* Do the fork */
        if ((pid = daemon_fork()) < 0)
        {
            /* Exit on error */
            daemon_log(LOG_ERR, "Failed to fork() daemon process.");
            daemon_retval_done();
            return 1;
        } 
        else if (pid)
        { /* The parent */
            int ret;

            /* Wait for 20 seconds for the return value passed from the daemon process */
            if ((ret = daemon_retval_wait(20)) < 0)
            {
                daemon_log(LOG_ERR, "Could not recieve return value from daemon process: %s", strerror(errno));
                return 255;
            }

            if (ret == 0)
            {
                daemon_log(LOG_INFO, "Daemon process started.");
            }
            else
            {
                daemon_log(LOG_ERR, "Daemon returned %i.", ret);
            }
            return ret;
        } 
        else
        { /* The daemon */
            /* Close FDs */
            if (daemon_close_all(-1) < 0)
            {
                daemon_log(LOG_ERR, "Failed to close all file descriptors: %s", strerror(errno));

                /* Send the error condition to the parent process */
                daemon_retval_send(1);
                goto finish;
            }

            daemon_log_use = DAEMON_LOG_SYSLOG;

            /* Send OK to parent process */
            daemon_retval_send(0);

            daemon_log(LOG_INFO, "Daemon started");
        }
    }
    else
    {
        /* Running foreground - set verbosity */
        if (verbosity > LOG_WARNING)
        {
            daemon_set_verbosity(verbosity);
        }
    }

    FD_ZERO(&rfds);
    /* Wait up to five seconds. */
    tv.tv_sec = 5;
    tv.tv_usec = 0;
    
    if ((serial_open(cpSerialDevice, u32BaudRate) < 0) || (eTunDeviceOpen(cpTunDevice) != E_TUN_OK))
    {
        goto finish;
    }
    
    /* Install signal handlers */
    signal(SIGTERM, vQuitSignalHandler);
    signal(SIGINT, vQuitSignalHandler);
    
    eJennicModuleStart();
    
    while (bRunning)
    {
        int max_fd = 0;
        
        /* Wait up to one second each loop. */
        tv.tv_sec = 1;
        tv.tv_usec = 0;
        
        FD_ZERO(&rfds);
        FD_SET(serial_fd, &rfds);
        if (serial_fd > max_fd)
        {
            max_fd = serial_fd;
        }
        FD_SET(tun_fd, &rfds);
        if (tun_fd > max_fd)
        {
            max_fd = tun_fd;
        }

        /* Wait for data on one either the serial port or the TUN interface. */
        retval = select(max_fd + 1, &rfds, NULL, NULL, &tv);

        if (retval == -1)
        {
            daemon_log(LOG_ERR, "error in select(): %s", strerror(errno));
        }
        else if (retval)
        {
            int i;
            /* Got data on one of the file descriptors */
            for (i = 0; i < max_fd + 1; i++)
            {
                if (FD_ISSET(i, &rfds) && (i == serial_fd))
                {
                    if(bSL_ReadMessage(&sIncomingMsg.u8Type, &sIncomingMsg.u16Length, sizeof(sIncomingMsg.u8Message), sIncomingMsg.u8Message))
                    {
                        if (eJennicModuleProcessMessage(sIncomingMsg.u8Type, sIncomingMsg.u16Length, sIncomingMsg.u8Message) != E_MODULE_OK)
                        {
                            daemon_log(LOG_ERR, "Error communicating with border router module");
                            bRunning = FALSE;
                        }
                    }
                }
                else if (FD_ISSET(i, &rfds) && (i == tun_fd))
                {
                    if (eTunDeviceReadPacket() != E_TUN_OK)
                    {
                        daemon_log(LOG_ERR, "Error handling tun packet");
                    }
                    /* Kick the state machine to prompt the sending of a ping packet if necessary. */
                    if (eJennicModuleStateMachine(1) != E_MODULE_OK)
                    {
                        daemon_log(LOG_ERR, "Error communicating with border router module");
                        bRunning = FALSE;
                    }
                }
                else if (FD_ISSET(i, &rfds))
                {
                    daemon_log(LOG_DEBUG, "Data on unknown file desciptor (%d)", i);
                }
                else
                {
                    /* Should not get here */
                }
            }
        }
        else
        {
            /* Select timeout */
            if (eJennicModuleStateMachine(1) != E_MODULE_OK)
            {
                daemon_log(LOG_ERR, "Error communicating with border router module");
                bRunning = FALSE;
            }
        }
    }
    
    if (iResetCoordinator)
    {
        daemon_log(LOG_INFO, "Resetting Coordinator Module");    
        eJennicModuleReset();
    }
    
finish:
    if (daemonize)
    {
        daemon_log(LOG_INFO, "Daemon process exiting");  
    }
    return 0;
}
コード例 #10
0
/* Takes ownership of startup */
static gboolean
infinoted_main_run(InfinotedStartup* startup,
                   GError** error)
{
  InfinotedRun* run;
  InfinotedSignal* sig;

#ifdef LIBINFINITY_HAVE_LIBDAEMON
  mode_t prev_umask;
  pid_t pid;
  int saved_errno;
#endif

  /* infinoted_run_new() takes ownership of startup */
  run = infinoted_run_new(startup, error);
  if(run == NULL)
  {
    infinoted_startup_free(startup);
    return FALSE;
  }

#ifdef LIBINFINITY_HAVE_LIBDAEMON
  if(startup->options->daemonize)
  {
    prev_umask = umask(0777);

    if(daemon_retval_init() == -1)
    {
      infinoted_run_free(run);
      return FALSE; /* libdaemon already wrote an error message */
    }

    pid = daemon_fork();
    if(pid < 0)
    {
      /* Translators: fork as in "fork into the background" */
      infinoted_util_set_errno_error(error, errno, _("Failed to fork"));
      infinoted_run_free(run);
      daemon_retval_done();
      return FALSE;
    }
    else if(pid > 0)
    {
      infinoted_run_free(run);
      saved_errno = daemon_retval_wait(5);
      if(saved_errno == 0)
      {
        return TRUE;
      }
      if(saved_errno == -1)
      {
        infinoted_util_set_errno_error(error, errno,
          _("Failed to wait for daemonized child's return value"));
        return FALSE;
      }
      else
      {
        /* on -1, the child process would have subtracted one from
         * errno before passing it back to us. */
        if(saved_errno < 0) ++saved_errno;
        infinoted_util_set_errno_error(
          error, saved_errno, _("Failed to create PID file"));
        return FALSE;
      }
    }
    else
    {
      infinoted_util_daemon_set_global_pid_file_proc();
      if(daemon_pid_file_create() != 0)
      {
        infinoted_util_daemon_set_local_pid_file_proc();
        if(daemon_pid_file_create() != 0)
        {
          if(daemon_pid_file_create() != 0)
          {
            saved_errno = errno;
            infinoted_util_set_errno_error(
              error,
              saved_errno,
              _("Failed to create PID file")
            );
            if(saved_errno < 0) --saved_errno;
            daemon_retval_send(saved_errno);

            infinoted_run_free(run);
            return FALSE;
          }
        }
      }

      daemon_retval_send(0);
    }

    /* libdaemon sets the umask to either 0777 (< 0.14) or 0077 (>= 0.14).
     * We don't want either of that, to make sure the directory tree is
     * always readable by us and potentially by others (for example, a
     * webserver providing read access to the documents). Therefore, reset
     * the umask here to what it previously was, so the system administrator
     * can define the umask by setting it before launching infinoted.
     * See also http://gobby.0x539.de/trac/ticket/617.  */
    umask(prev_umask);
  }
#endif

  sig = infinoted_signal_register(run);

  /* Now start the server. It can later be stopped by signals. */
  infinoted_run_start(run);

  infinoted_signal_unregister(sig);

#ifdef LIBINFINITY_HAVE_LIBDAEMON
  /* startup might be invalid at this point in case a config reload happened,
   * so use run->startup instead (which is revalidated by config reload). */
  if(run->startup->options->daemonize)
    daemon_pid_file_remove();
#endif

  infinoted_run_free(run);
  return TRUE;
}
コード例 #11
0
int main(int argc, char *argv[])
{
	pid_t pid;
    const char *pcFD_GPIO   = NULL;
    const char *pcI2Cbus    = NULL;
    uint8_t     u8I2CAddress = 0;
    const char *pcPWR_GPIO  = NULL;
    
    {
        static struct option long_options[] =
        {
            /* Program options */
            {"help",                    no_argument,        NULL, 'h'},
            {"foreground",              no_argument,        NULL, 'f'},
            {"verbosity",               required_argument,  NULL, 'v'},
            
            {"gpio-fd",                 required_argument,  NULL, 0},
            {"i2c-bus",                 required_argument,  NULL, 1},
            {"i2c-address",             required_argument,  NULL, 2},
            {"gpio-pwr",                required_argument,  NULL, 3},

            { NULL, 0, NULL, 0}
        };
        signed char opt;
        int option_index;

        while ((opt = getopt_long(argc, argv, "hfv:", long_options, &option_index)) != -1) 
        {
            switch (opt) 
            {
                case 'h':
                    print_usage_exit(argv);
                    break;
                case 'f':
                    daemonize = 0;
                    break;
                case 'v':
                    verbosity = atoi(optarg);
                    break;
                
                case 0:
                    pcFD_GPIO = optarg;
                    break;
                    
                case 1:
                    pcI2Cbus = optarg;
                    break;
                    
                case 2:
                {
                    char *pcEnd;
                    errno = 0;
                    uint32_t u32I2CAddress = strtoul(optarg, &pcEnd, 0);
                    if (errno)
                    {
                        fprintf(stderr, "I2C Address '%s' cannot be converted to 32 bit integer (%s)\n", optarg, strerror(errno));
                        print_usage_exit(argv);
                    }
                    if (*pcEnd != '\0')
                    {
                        fprintf(stderr, "I2C Address '%s' contains invalid characters\n", optarg);
                        print_usage_exit(argv);
                    }
                    if (u32I2CAddress > 0x7F)
                    {
                        fprintf(stderr, "I2C Address '%s' outside allowable range (0x01 - 0x7F)\n", optarg);
                        print_usage_exit(argv);
                    }
                    u8I2CAddress = u32I2CAddress;
                    break;
                }
                
                case 3:
                    pcPWR_GPIO = optarg;
                    break;
                    
                default: /* '?' */
                    print_usage_exit(argv);
            }
        }
    }
    
    if (!pcFD_GPIO)
    {
        fprintf(stderr, "GPIO for field detect pin must be specified\n");
        print_usage_exit(argv);
    }
    
    if (!pcI2Cbus)
    {
        fprintf(stderr, "I2C bus must be specified\n");
        print_usage_exit(argv);
    }
    
    if (!u8I2CAddress)
    {
        fprintf(stderr, "I2C address must be specified\n");
        print_usage_exit(argv);
    }
    
    /* Log everything into syslog */
    daemon_log_ident = daemon_ident_from_argv0(argv[0]);
    
    if (daemonize)
    {
        /* Prepare for return value passing from the initialization procedure of the daemon process */
        if (daemon_retval_init() < 0) {
            daemon_log(LOG_ERR, "Failed to create pipe.");
            return 1;
        }

        /* Do the fork */
        if ((pid = daemon_fork()) < 0)
        {
            /* Exit on error */
            daemon_log(LOG_ERR, "Failed to fork() daemon process.");
            daemon_retval_done();
            return 1;
        } 
        else if (pid)
        { /* The parent */
            int ret;

            /* Wait for 20 seconds for the return value passed from the daemon process */
            if ((ret = daemon_retval_wait(20)) < 0)
            {
                daemon_log(LOG_ERR, "Could not recieve return value from daemon process: %s", strerror(errno));
                return 255;
            }

            if (ret == 0)
            {
                daemon_log(LOG_INFO, "Daemon process started.");
            }
            else
            {
                daemon_log(LOG_ERR, "Daemon returned %i.", ret);
            }
            return ret;
        } 
        else
        { /* The daemon */
            /* Close FDs */
            if (daemon_close_all(-1) < 0)
            {
                daemon_log(LOG_ERR, "Failed to close all file descriptors: %s", strerror(errno));

                /* Send the error condition to the parent process */
                daemon_retval_send(1);
                goto finish;
            }

            daemon_log_use = DAEMON_LOG_SYSLOG;

            /* Send OK to parent process */
            daemon_retval_send(0);

            daemon_log(LOG_INFO, "Daemon started");
        }
    }
    else
    {
        /* Running foreground - set verbosity */
        if (verbosity > LOG_WARNING)
        {
            daemon_set_verbosity(verbosity);
        }
    }

    /* Install signal handlers */
    signal(SIGTERM, vQuitSignalHandler);
    signal(SIGINT, vQuitSignalHandler);

    if (eNtagSetup(pcPWR_GPIO, pcFD_GPIO, pcI2Cbus, u8I2CAddress) == E_NFC_OK)
    {
        if (eNdefSetup() == E_NFC_OK)
        {
            while (bRunning != 0)
            {
                if (eNtagWait(30000) == E_NFC_READER_PRESENT)
                {
                    /* Tag detected */
                    while ((eNtagPresent() == E_NFC_READER_PRESENT) && bRunning)
                    {
                        sleep(1);
                        
                        teNfcStatus eStatus = eNtagRfUnlocked();
                        
                        switch (eStatus)
                        {
                            case (E_NFC_OK):
                                vHandleTag();
                                break;
                                
                            case (E_NFC_RF_LOCKED):
                                DEBUG_PRINTF("RF Locked\n");
                                break;
                                
                            default:
                                break;
                        }
                        //usleep(100000);
                        //sleep(1);
                    }
                }
                else
                {
                    /* Blank the tag */
                    tsNdefData sData;
                    eNdefInitData(&sData, 0, 0);
                    eNdefWriteData(&sData);
                }
            }
        }
    }
    else
    {
        DEBUG_PRINTF("Failed to init NTAG\n");
    }
    
finish:
    if (daemonize)
    {
        daemon_log(LOG_INFO, "Daemon process exiting");  
    }
    return 0;
}
コード例 #12
0
pid_t
daemonize()
{
#ifdef HAVE_LIBDAEMON
  pid_t pid;
  mode_t old_umask = umask(0);

  // Prepare for return value passing
  daemon_retval_init();

  // Do the fork
  if ((pid = daemon_fork()) < 0) {
    return -1;
        
  } else if (pid) { // the parent
    int ret;

    // Wait for 20 seconds for the return value passed from the daemon process
    if ((ret = daemon_retval_wait(20)) < 0) {
      daemon_log(LOG_ERR, "Could not recieve return value from daemon process.");
      return -1;
    }

    if ( ret != 0 ) {
      daemon_log(LOG_ERR, "*** Daemon startup failed, see syslog for details. ***");
      switch (ret) {
      case 1:
	daemon_log(LOG_ERR, "Daemon failed to close file descriptors");
	break;
      case 2:
	daemon_log(LOG_ERR, "Daemon failed to create PID file");
	break;
      }
      return -1;
    } else {
      return pid;
    }

  } else { // the daemon
#ifdef DAEMON_CLOSE_ALL_AVAILABLE
    if (daemon_close_all(-1) < 0) {
      daemon_log(LOG_ERR, "Failed to close all file descriptors: %s", strerror(errno));
      // Send the error condition to the parent process
      daemon_retval_send(1);
      return -1;
    }
#endif

    // Create the PID file
    if (daemon_pid_file_create() < 0) {
      printf("Could not create PID file (%s).", strerror(errno));
      daemon_log(LOG_ERR, "Could not create PID file (%s).", strerror(errno));

      // Send the error condition to the parent process
      daemon_retval_send(2);
      return -1;
    }

    // Send OK to parent process
    daemon_retval_send(0);

    daemon_log(LOG_INFO, "Sucessfully started");

    umask(old_umask);
    return 0;
  }
#else
  throw Exception("Daemonizing support is not available.\n"
		  "(libdaemon[-devel] was not available at compile time)\n");
#endif
}
コード例 #13
0
ファイル: dtntunnel.cpp プロジェクト: morgenroth/ibrdtn
int main(int argc, char *argv[])
{
	int index;
	int c;

	std::string ptp_dev("tun0");
	std::string app_name("tunnel");
	std::string endpoint("dtn:none");
	unsigned int lifetime = 60;
	bool daemonize = false;
	bool stop_daemon = false;
	std::string pidfile;
	bool throughput = false;

#ifdef HAVE_LIBDAEMON
	while ((c = getopt (argc, argv, "td:s:l:hDkp:")) != -1)
#else
	while ((c = getopt (argc, argv, "td:s:l:h")) != -1)
#endif
	switch (c)
	{
#ifdef HAVE_LIBDAEMON
		case 'D':
			daemonize = true;
			break;

		case 'k':
			daemonize = true;
			stop_daemon = true;
			break;

		case 'p':
			pidfile = optarg;
			break;
#endif
		case 'd':
			ptp_dev = optarg;
			break;

		case 't':
			throughput = true;
			break;

		case 's':
			app_name = optarg;
			break;

		case 'l':
			lifetime = atoi(optarg);
			break;

		default:
			print_help(argv[0]);
			return 1;
	}

	int optindex = 0;
	for (index = optind; index < argc; ++index)
	{
		switch (optindex)
		{
		case 0:
			endpoint = std::string(argv[index]);
			break;
		}

		optindex++;
	}

	// print help if not enough parameters are set
	if (!stop_daemon && (optindex < 1)) { print_help(argv[0]); exit(0); }

	// catch process signals
	ibrcommon::SignalHandler sighandler(term);
	sighandler.handle(SIGINT);
	sighandler.handle(SIGTERM);
	sighandler.handle(SIGQUIT);

	//initialize sighandler after possible exit call
	sighandler.initialize();

	// logging options
	//const unsigned char logopts = ibrcommon::Logger::LOG_DATETIME | ibrcommon::Logger::LOG_LEVEL;
	const unsigned char logopts = 0;

	// error filter
	const unsigned char logerr = ibrcommon::Logger::LOGGER_ERR | ibrcommon::Logger::LOGGER_CRIT;

	// logging filter, everything but debug, err and crit
	const unsigned char logstd = ibrcommon::Logger::LOGGER_ALL ^ (ibrcommon::Logger::LOGGER_DEBUG | logerr);

	// syslog filter, everything but DEBUG and NOTICE
	const unsigned char logsys = ibrcommon::Logger::LOGGER_ALL ^ (ibrcommon::Logger::LOGGER_DEBUG | ibrcommon::Logger::LOGGER_NOTICE);

#ifdef HAVE_LIBDAEMON
	if (daemonize) {
		// enable syslog logging
		ibrcommon::Logger::enableSyslog(argv[0], LOG_PID, LOG_DAEMON, logsys);
	} else
#endif
	{
		// add logging to the cout
		ibrcommon::Logger::addStream(std::cout, logstd, logopts);

		// add logging to the cerr
		ibrcommon::Logger::addStream(std::cerr, logerr, logopts);
	}

#ifdef HAVE_LIBDAEMON
	if (daemonize)
	{
#ifdef HAVE_DAEMON_RESET_SIGS
		/* Reset signal handlers */
		if (daemon_reset_sigs(-1) < 0) {
			IBRCOMMON_LOGGER_TAG("Core", error) << "Failed to reset all signal handlers: " << strerror(errno) << IBRCOMMON_LOGGER_ENDL;
			return 1;
		}

		/* Unblock signals */
		if (daemon_unblock_sigs(-1) < 0) {
			IBRCOMMON_LOGGER_TAG("Core", error) << "Failed to unblock all signals: " << strerror(errno) << IBRCOMMON_LOGGER_ENDL;
			return 1;
		}
#endif
		pid_t pid;

		/* Set identification string for the daemon for both syslog and PID file */
		daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]);

		/* set the pid file path */
		if (pidfile.length() > 0) {
			__daemon_pidfile__ = new char[pidfile.length() + 1];
			::strcpy(__daemon_pidfile__, pidfile.c_str());
			daemon_pid_file_proc = __daemon_pid_file_proc__;
		}

		/* Check if we are called with -k parameter */
		if (stop_daemon)
		{
			int ret;

			/* Kill daemon with SIGTERM */

			/* Check if the new function daemon_pid_file_kill_wait() is available, if it is, use it. */
			if ((ret = daemon_pid_file_kill_wait(SIGTERM, 5)) < 0)
				IBRCOMMON_LOGGER_TAG("Core", warning) << "Failed to kill daemon: " << strerror(errno) << IBRCOMMON_LOGGER_ENDL;

			return ret < 0 ? 1 : 0;
		}

		/* Check that the daemon is not rung twice a the same time */
		if ((pid = daemon_pid_file_is_running()) >= 0) {
			IBRCOMMON_LOGGER_TAG("Core", error) << "Daemon already running on PID file " << pid << IBRCOMMON_LOGGER_ENDL;
			return 1;
		}

		/* Prepare for return value passing from the initialization procedure of the daemon process */
		if (daemon_retval_init() < 0) {
			IBRCOMMON_LOGGER_TAG("Core", error) << "Failed to create pipe." << IBRCOMMON_LOGGER_ENDL;
			return 1;
		}

		/* Do the fork */
		if ((pid = daemon_fork()) < 0) {

			/* Exit on error */
			daemon_retval_done();
			return 1;

		} else if (pid) { /* The parent */
			int ret;

			/* Wait for 20 seconds for the return value passed from the daemon process */
			if ((ret = daemon_retval_wait(20)) < 0) {
				IBRCOMMON_LOGGER_TAG("Core", error) << "Could not recieve return value from daemon process: " << strerror(errno) << IBRCOMMON_LOGGER_ENDL;
				return 255;
			}

			return ret;

		} else { /* The daemon */
			/* Close FDs */
			if (daemon_close_all(-1) < 0) {
				IBRCOMMON_LOGGER_TAG("Core", error) << "Failed to close all file descriptors: " << strerror(errno) << IBRCOMMON_LOGGER_ENDL;

				/* Send the error condition to the parent process */
				daemon_retval_send(1);

				/* Do a cleanup */
				daemon_retval_send(255);
				daemon_signal_done();
				daemon_pid_file_remove();

				return -1;
			}

			/* Create the PID file */
			if (daemon_pid_file_create() < 0) {
				IBRCOMMON_LOGGER_TAG("Core", error) << "Could not create PID file ( " << strerror(errno) << ")." << IBRCOMMON_LOGGER_ENDL;
				daemon_retval_send(2);

				/* Do a cleanup */
				daemon_retval_send(255);
				daemon_signal_done();
				daemon_pid_file_remove();

				return -1;
			}

			/* Send OK to parent process */
			daemon_retval_send(0);
		}
	}
#endif

	IBRCOMMON_LOGGER_TAG("Core", info) << "IBR-DTN IP <-> Bundle Tunnel" << IBRCOMMON_LOGGER_ENDL;

	// create a connection to the dtn daemon
	ibrcommon::vaddress addr("localhost", 4550);
	ibrcommon::socketstream conn(new ibrcommon::tcpsocket(addr));

	try {
		// set-up tun2bundle gateway
		TUN2BundleGateway gateway(app_name, conn, ptp_dev);
		_gateway = &gateway;

		IBRCOMMON_LOGGER_TAG("Core", info) << "Local:  " << app_name << IBRCOMMON_LOGGER_ENDL;
		IBRCOMMON_LOGGER_TAG("Core", info) << "Peer:   " << endpoint << IBRCOMMON_LOGGER_ENDL;
		IBRCOMMON_LOGGER_TAG("Core", info) << "Device: " << gateway.getDeviceName() << IBRCOMMON_LOGGER_ENDL;
		IBRCOMMON_LOGGER_TAG("Core", notice) << IBRCOMMON_LOGGER_ENDL;
		IBRCOMMON_LOGGER_TAG("Core", notice) << "Now you need to set-up the ip tunnel. You can use commands like this:" << IBRCOMMON_LOGGER_ENDL;
		IBRCOMMON_LOGGER_TAG("Core", notice) << "# sudo ip link set " << gateway.getDeviceName() << " up mtu 65535" << IBRCOMMON_LOGGER_ENDL;
		IBRCOMMON_LOGGER_TAG("Core", notice) << "# sudo ip addr add 10.0.0.1/24 dev " << gateway.getDeviceName() << IBRCOMMON_LOGGER_ENDL;
		IBRCOMMON_LOGGER_TAG("Core", notice) << IBRCOMMON_LOGGER_ENDL;

		timer_t timerid;
		struct sigevent sev;

		if (!daemonize && throughput) {
			// enable throughput timer
			signal(SIGRTMIN, timer_display_throughput);

			sev.sigev_notify = SIGEV_SIGNAL;
			sev.sigev_signo = SIGRTMIN;
			sev.sigev_value.sival_ptr = &timerid;

			// create a timer
			timer_create(CLOCK_MONOTONIC, &sev, &timerid);

			// arm the timer
			struct itimerspec its;
			size_t freq_nanosecs = 200000000;
			its.it_value.tv_sec = freq_nanosecs / 1000000000;;
			its.it_value.tv_nsec = freq_nanosecs % 1000000000;
			its.it_interval.tv_sec = its.it_value.tv_sec;
			its.it_interval.tv_nsec = its.it_value.tv_nsec;

			if (timer_settime(timerid, 0, &its, NULL) == -1) {
				IBRCOMMON_LOGGER_TAG("Core", error) << "Timer set failed." << IBRCOMMON_LOGGER_ENDL;
			}
		}

		// destination
		dtn::data::EID eid(endpoint);

		while (m_running)
		{
			gateway.process(eid, lifetime);
		}

		gateway.shutdown();
	} catch (const ibrcommon::Exception &ex) {
		if (m_running) {
			IBRCOMMON_LOGGER_TAG("Core", error) << ex.what() << IBRCOMMON_LOGGER_ENDL;
			return -1;
		}
	}

#ifdef HAVE_LIBDAEMON
	if (daemonize) {
		/* Do a cleanup */
		IBRCOMMON_LOGGER_TAG("Core", info) << "Stopped " << app_name << IBRCOMMON_LOGGER_ENDL;
		daemon_retval_send(255);
		daemon_signal_done();
		daemon_pid_file_remove();
	} else
#endif
	{
		std::cout << std::endl;
	}

	return 0;
}
コード例 #14
0
void work(void) {
    interface_status_t status;
    int fd = -1;
    fd_set fds;
    int sigfd;
    time_t t = 0;
    int send_retval = 1;
    int paused = 0;
    static char log_ident[256];

    snprintf(log_ident, sizeof(log_ident), "ifplugd(%s)", interface);

    daemon_log_ident = log_ident;

    daemon_log(LOG_INFO, "ifplugd "VERSION" initializing%s.", use_ifmonitor ? ", using NETLINK device monitoring" : "");

    if (daemon_pid_file_create() < 0) {
        daemon_log(LOG_ERR, "Could not create PID file %s.", daemon_pid_file_proc());
        goto finish;
    }

    if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, SIGCHLD, SIGUSR1, SIGUSR2, -1) < 0) {
        daemon_log(LOG_ERR, "Could not register signal handler: %s", strerror(errno));
        goto finish;
    }

    switch (api_mode) {
        case API_ETHTOOL: detect_beat_func = interface_detect_beat_ethtool; break;
        case API_MII: detect_beat_func = interface_detect_beat_mii; break;
        case API_PRIVATE: detect_beat_func = interface_detect_beat_priv; break;
        case API_WLAN: detect_beat_func = interface_detect_beat_wlan; break;
        case API_IFF: detect_beat_func = interface_detect_beat_iff; break;
            
        default:
            detect_beat_func = detect_beat_auto; 
            interface_do_message = 0;
            break;
    }

    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        daemon_log(LOG_ERR, "socket(): %s", strerror(errno));
        goto finish;
    }

    if (use_ifmonitor) {
        int b;
        if ((b = is_iface_available(fd, interface)) < 0) {
            daemon_log(LOG_ERR, "Failed to check interface availabilty!");
            goto finish;
        }
        
        disabled = !b;

        if (nlapi_open(RTMGRP_LINK) < 0)
            goto finish;

        if (ifmonitor_init(ifmonitor_cb) < 0)
            goto finish;
    } else
        disabled = 0;

    if (!disabled) {
        if (welcome_iface(fd, interface) < 0)
            goto finish;
    }

    if ((status = detect_beat(fd, interface)) == IFSTATUS_ERR)
        goto finish;
    
    daemon_log(LOG_INFO, "Initialization complete, link beat %sdetected%s.", status == IFSTATUS_UP ? "" : "not ", use_ifmonitor ? (disabled ? ", interface disabled" : ", interface enabled") : "");
    beep(status == IFSTATUS_UP ? 0 : 1);

    if ((!no_startup_script && status == IFSTATUS_UP) || initial_down)
        if (action(status) < 0)
            goto finish;

    if (send_retval && daemonize && wait_on_fork) {
        char c = status == IFSTATUS_UP ? 2 : (status == IFSTATUS_DOWN ? 3 : 1);
        daemon_retval_send(c);
        send_retval = 0;
    }

    FD_ZERO(&fds);
    sigfd = daemon_signal_fd();
    FD_SET(sigfd, &fds);

    if (use_ifmonitor)
        FD_SET(nlapi_fd, &fds);

    for (;;) {
        interface_status_t s;
        fd_set qfds = fds;
        int d;
        struct timeval tv;

        tv.tv_sec = polltime;
        tv.tv_usec = 0;
        
        if (select(FD_SETSIZE, &qfds, NULL, NULL, &tv) < 0) {
            if (errno == EINTR)
                continue;

            daemon_log(LOG_ERR, "select(): %s", strerror(errno));
            goto finish;
        }

        //daemon_log(LOG_INFO, "select()");
        
        d = disabled;
        s = status;
        
        if (use_ifmonitor) {

            if (FD_ISSET(nlapi_fd, &qfds)) {
                if (nlapi_work(0) < 0)
                    goto finish;
            }

            if (d && !disabled) {
                daemon_log(LOG_INFO, "Interface enabled");
                welcome_iface(fd, interface);
                status = IFSTATUS_DOWN;
            }
            
            if (!d && disabled) {
                daemon_log(LOG_INFO, "Interface disabled");
                status = IFSTATUS_DOWN;
            }
        }
            

        if (!paused && !disabled) {
            //daemon_log(LOG_INFO, "detect");
            if ((status = detect_beat(fd, interface)) == IFSTATUS_ERR) {
                if (!use_ifmonitor)
                    goto finish;

                status = IFSTATUS_DOWN;
            }
        }

        if (status != s) {
            daemon_log(LOG_INFO, "Link beat %s.", status == IFSTATUS_DOWN ? "lost" : "detected");
            beep(status == IFSTATUS_UP ? 0 : 1);
            
            if (t)
                t = 0;
            else {
                t = time(NULL);
                
                if (status == IFSTATUS_UP)
                    t += delay_up;
                
                if (status == IFSTATUS_DOWN)
                    t += delay_down;
            }
        }

        if (FD_ISSET(sigfd, &qfds)) {
            int sig;

            if ((sig = daemon_signal_next()) < 0) {
                daemon_log(LOG_ERR, "daemon_signal_next(): %s", strerror(errno));
                goto finish;
            }

            switch (sig) {

                case SIGINT:
                case SIGTERM:
                    goto cleanup;
                    
                case SIGQUIT:
                    goto finish;
                    
                case SIGCHLD:
                    break;

                case SIGHUP:
                    daemon_log(LOG_INFO, "SIGHUP: %s, link detected on %s: %s", paused ? "Suspended" : "Running", interface, status == IFSTATUS_DOWN ? "no" : "yes");

                    if (use_ifmonitor)
                        daemon_log(LOG_INFO, "SIGHUP: Interface %s", disabled ? "disabled" : "enabled");
                    break;
                    
                case SIGUSR1:
                    daemon_log(LOG_INFO, "SIGUSR1: Daemon suspended (#%i)", ++paused);
                    break;

                case SIGUSR2:
                    if (paused > 0) {
                        daemon_log(LOG_INFO, "SIGUSR2: Daemon resumed (#%i)", paused);
                        paused --;
                    }
                    
                    break;
                    
                default:
                    daemon_log(LOG_INFO, "Ignoring unknown signal %s", strsignal(sig));
                    break;
            }
        }

        if (t && t < time(NULL)) {
            t = 0;

            if (action(status) < 0)
                goto finish;
        }
    }

cleanup:
    if (!no_shutdown_script && (status == IFSTATUS_UP || (status == IFSTATUS_DOWN && t))) {
        setenv(IFPLUGD_ENV_PREVIOUS, strstatus(status), 1);
        setenv(IFPLUGD_ENV_CURRENT, strstatus(-1), 1);
        action(IFSTATUS_DOWN);
        beep(1);
    }
    
finish:

    if (fd >= 0)
        close(fd);

    if (use_ifmonitor)
        nlapi_close();
    
    if (send_retval && daemonize && wait_on_fork)
        daemon_retval_send(255);

    daemon_pid_file_remove();
    daemon_signal_done();
    
    daemon_log(LOG_INFO, "Exiting.");
}
コード例 #15
0
ファイル: cron-main.c プロジェクト: alip/mpdcron
int
main(int argc, char **argv)
{
	int pid, ret;
	struct sigaction new_action, old_action;
	GOptionContext *ctx;
	GError *parse_err = NULL;

	daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]);
	daemon_pid_file_proc = conf_pid_file_proc;
	if (conf_init() < 0)
		return EXIT_FAILURE;

	ctx = g_option_context_new("");
	g_option_context_add_main_entries(ctx, options, PACKAGE);
	g_option_context_set_summary(ctx, PACKAGE"-"VERSION GITHEAD" - mpd cron daemon");

	if (!g_option_context_parse(ctx, &argc, &argv, &parse_err)) {
		g_printerr("option parsing failed: %s\n", parse_err->message);
		g_option_context_free(ctx);
		g_error_free(parse_err);
		return EXIT_FAILURE;
	}
	g_option_context_free(ctx);

	if (optv) {
		about();
		cleanup();
		return EXIT_SUCCESS;
	}

#ifdef DAEMON_SET_VERBOSITY_AVAILABLE
	if (conf.no_daemon)
		daemon_set_verbosity(LOG_DEBUG);
#endif /* DAEMON_SET_VERBOSITY_AVAILABLE */

	/* Version to environment variable */
	g_setenv("MPDCRON_PACKAGE", PACKAGE, 1);
	g_setenv("MPDCRON_VERSION", VERSION, 1);
	g_setenv("MPDCRON_GITHEAD", GITHEAD, 1);

	/* Command line options to environment variables */
	if (conf.no_daemon)
		g_unsetenv("MCOPT_DAEMONIZE");
	else
		g_setenv("MCOPT_DAEMONIZE", "1", 1);

	/* Important! Parse configuration file before killing the daemon
	 * because the configuration file has a pidfile and killwait option.
	 */
	cfd = g_key_file_new();
	if (keyfile_load(&cfd) < 0) {
		cleanup();
		return EXIT_FAILURE;
	}

	if (optk) {
		if (daemon_pid_file_kill_wait(SIGINT, conf.killwait) < 0) {
			g_warning("Failed to kill daemon: %s", strerror(errno));
			cleanup();
			return EXIT_FAILURE;
		}
		daemon_pid_file_remove();
		cleanup();
		return EXIT_SUCCESS;
	}

	/* Logging */
	g_log_set_default_handler(log_handler, GINT_TO_POINTER(conf.no_daemon ? 5 : conf.loglevel));

	/* Signal handling */
	new_action.sa_handler = sig_cleanup;
	sigemptyset(&new_action.sa_mask);
	new_action.sa_flags = 0;

#define HANDLE_SIGNAL(sig)					\
	do {							\
		sigaction((sig), NULL, &old_action);		\
		if (old_action.sa_handler != SIG_IGN)		\
			sigaction((sig), &new_action, NULL);	\
	} while (0)

	HANDLE_SIGNAL(SIGABRT);
	HANDLE_SIGNAL(SIGSEGV);
	HANDLE_SIGNAL(SIGINT);
	HANDLE_SIGNAL(SIGTERM);

#undef HANDLE_SIGNAL

	if (conf.no_daemon) {
		/* Create the main loop */
		loop = g_main_loop_new(NULL, FALSE);

#ifdef HAVE_GMODULE
		/* Load modules which may add initial events */
		keyfile_load_modules(&cfd);
#endif /* HAVE_GMODULE */
		g_key_file_free(cfd);
		cfd = NULL;

		/* Add default initial events */
		loop_connect();

		/* Run the main loop */
		g_main_loop_run(loop);
		cleanup();
		return EXIT_SUCCESS;
	}

	/* Daemonize */
	if ((pid = daemon_pid_file_is_running()) > 0) {
		g_critical("Daemon already running on PID %u", pid);
		return EXIT_FAILURE;
	}

	daemon_retval_init();
	pid = daemon_fork();
	if (pid < 0) {
		g_critical("Failed to fork: %s", strerror(errno));
		daemon_retval_done();
		return EXIT_FAILURE;
	}
	else if (pid != 0) { /* Parent */
		cleanup();

		if ((ret = daemon_retval_wait(2)) < 0) {
			g_critical("Could not receive return value from daemon process: %s",
				strerror(errno));
			return 255;
		}

		if (ret != 0)
			g_critical("Daemon returned %i as return value", ret);
		else
			g_critical("Daemon returned %i as return value", ret);
		return ret;
	}
	else { /* Daemon */
		if (daemon_close_all(-1) < 0) {
			g_critical("Failed to close all file descriptors: %s",
					strerror(errno));
			daemon_retval_send(1);
			return EXIT_FAILURE;
		}

		if (daemon_pid_file_create() < 0) {
			g_critical("Failed to create PID file: %s",
					strerror(errno));
			daemon_retval_send(2);
			return EXIT_FAILURE;
		}

		/* Send OK to parent process */
		daemon_retval_send(0);

		/* Create the main loop */
		loop = g_main_loop_new(NULL, FALSE);

#ifdef HAVE_GMODULE
		/* Load modules which may add initial events */
		keyfile_load_modules(&cfd);
#endif /* HAVE_GMODULE */
		g_key_file_free(cfd);
		cfd = NULL;

		/* Add default initial events */
		loop_connect();

		/* Run the main loop */
		g_main_loop_run(loop);
		cleanup();
		return EXIT_SUCCESS;
	}
	return EXIT_SUCCESS;
}
コード例 #16
0
ファイル: main.c プロジェクト: breu/evgopherd
/**
 * Read the config file, determine if we should daemonize or not,
 * and set up libevent dispatches.
 */
int main(int argc, char *argv[]) {
    int cmdline_debug_level = 0;
    int foreground = 0;
    int option;
    pid_t pid;
    int kill=0;
    int ret;

    /* set some sane config defaults */
    memset((void*)&config, 0, sizeof(gopher_conf_t));

    config.port = 70;
    config.base_dir = ".";
    config.socket_backlog = 5;
    config.config_file = DEFAULT_CONFIGFILE;

    while((option = getopt(argc, argv, "d:c:fp:s:k")) != -1) {
        switch(option) {
        case 'd':
            cmdline_debug_level = atoi(optarg);
            if(cmdline_debug_level < 1 || cmdline_debug_level > 5) {
                ERROR("Debug level must be 1-5 (default %d)", DEFAULT_DEBUGLEVEL);
                usage_quit(argv[0]);
            }
            break;
        case 'c':
            config.config_file = optarg;
            break;
        case 'f':
            foreground = 1;
            break;
        case 'p':
            config.port = atoi(optarg);
            break;
        case 's':
            config.base_dir = optarg;
        case 'k':
            kill = 1;
            break;
        default:
            usage_quit(argv[0]);
        }
    }

    debug_level(cmdline_debug_level ? cmdline_debug_level : DEFAULT_DEBUGLEVEL);

    /* kill before config, so we don't have to specify a config file */
    daemon_pid_file_ident = daemon_ident_from_argv0(argv[0]);

    /* kill? */
    if(kill) {
        if((ret = daemon_pid_file_kill_wait(SIGTERM, 5)) < 0) {
           ERROR("Failed to kill daemon: %s", strerror(errno));
        }
        exit(ret < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
    }

    if((pid = daemon_pid_file_is_running()) >= 0) {
        ERROR("Daemon already running as pid %u", pid);
        exit(EXIT_FAILURE);
    }

    /* TODO: read the config file and verify sufficient config */

    debug_level(cmdline_debug_level);

    /* daemonize, or check for background daemon */
    if(!foreground) {
        debug_output(DBG_OUTPUT_SYSLOG, "evgopherd");

        if(daemon_retval_init() < 0) {
            ERROR("Could not set up daemon pipe");
            exit(EXIT_FAILURE);
        }

        if((pid = daemon_fork()) < 0) {
            daemon_retval_done();
            ERROR("Forking error: %s", strerror(errno));
            exit(EXIT_FAILURE);
        } else if (pid) { /* parent */
            if((ret = daemon_retval_wait(5)) < 0) {
                ERROR("Could not receive startup retval from daemon process: %s", strerror(errno));
                exit(EXIT_FAILURE);
            }

            if(ret > 0)
                ERROR("Daemon declined to start.  Error: %d\n", ret);

            exit(ret == 0 ? EXIT_SUCCESS :EXIT_FAILURE);
        }
    }

    if(daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, SIGPIPE, 0) < 0) {
        ERROR("Could not set up signal handlers: %s", strerror(errno));
        goto finish;
    }

    if(!foreground) {
        if(daemon_pid_file_create() < 0) {
            ERROR("Could not create pidfile: %s", strerror(errno));
            if(!foreground)
                daemon_retval_send(2);
            goto finish;
        }

        /* should close handles here */
        daemon_retval_send(0); /* started up to the point that we can rely on syslog */
    }

    WARN("Daemon started");

    /* need to fork off a watchdog process */
    while(!g_quitflag) {
        /* fork and wait */
        pid_t pid = fork();

        if(pid == -1) {
            ERROR("Error forking child process.  Aborting");
            g_quitflag = 1;
        } else if(pid == 0) { /* child */
            do_child_process();
        } else { /* parent */
            int status;
            waitpid(pid, &status, 0);
            if(WIFEXITED(status) && WEXITSTATUS(status)) {
                /* exited with error */
                ERROR("Error initializing child process.  Aborting");
                g_quitflag=1;
            } else if(!WIFEXITED(status)) {
                ERROR("Child process (%d) crashed.  Restarting.", pid);
            } else {
                /* graceful exit... we've obviously terminated */
                g_quitflag = 1;
            }
        }
    }

    WARN("Daemon exiting gracefully");

 finish:
    daemon_signal_done();
    daemon_pid_file_remove();

    return EXIT_SUCCESS;
}