コード例 #1
0
/* We only use privsep to get in-kernel SADB and SPD snapshots via sysctl */
void
monitor_loop(void)
{
	u_int32_t	 v, vn;
	ssize_t		 r;
	fd_set		 rfds;
	int		 ret;
	struct timeval	*tvp, tv;

	FD_ZERO(&rfds);
	tvp = NULL;
	vn = 0;

	for (;;) {
		ret = 0;
		v = 0;

		if (sigchld) {
			pid_t	pid;
			int	status;
			do {
				pid = waitpid(m_state.pid, &status, WNOHANG);
			} while (pid == -1 && errno == EINTR);

			if (pid == m_state.pid &&
			    (WIFEXITED(status) || WIFSIGNALED(status)))
				break;
		}

		FD_SET(m_state.s, &rfds);
		if (select(m_state.s + 1, &rfds, NULL, NULL, tvp) == -1) {
			if (errno == EINTR || errno == EAGAIN)
				continue;
			log_err(0, "monitor_loop: select() ");
			break;
		}

		/* Wait for next task */
		if (FD_ISSET(m_state.s, &rfds)) {
			if ((r = m_read(m_state.s, &v, sizeof v)) < 1) {
				if (r == -1)
					log_err(0, "monitor_loop: read() ");
				break;
			}
		}

		/* Retry after timeout */
		if (v == 0 && tvp != NULL) {
			v = vn;
			tvp = NULL;
			vn = 0;
		}

		switch (v) {
		case MONITOR_GETSNAP:
			/* Get the data. */
			m_priv_pfkey_snap(m_state.s);
			break;
		case MONITOR_CARPINC:
			carp_demote(CARP_INC, 1);
			break;
		case MONITOR_CARPDEC:
			carp_demote(CARP_DEC, 1);
			break;
		case MONITOR_CONTROL_ACTIVATE:
			ret = m_priv_control_activate();
			break;
		case MONITOR_CONTROL_PASSIVATE:
			ret = m_priv_control_passivate();
			break;
		}

		if (ret == -1) {
			/* Trigger retry after timeout */
			tv.tv_sec = MONITOR_RETRY_TIMEOUT;
			tv.tv_usec = 0;
			tvp = &tv;
			vn = v;
		}
	}

	monitor_carpundemote(NULL);

	if (!sigchld)
		log_msg(0, "monitor_loop: priv process exiting abnormally");
	exit(0);
}
コード例 #2
0
ファイル: sasyncd.c プロジェクト: SylvestreG/bitrig
int
main(int argc, char **argv)
{
	extern char	*__progname;
	char		*cfgfile = 0;
	int		 ch;

	if (geteuid() != 0) {
		/* No point in continuing. */
		fprintf(stderr, "%s: This daemon needs to be run as root.\n",
		    __progname);
		return 1;
	}

	while ((ch = getopt(argc, argv, "c:dv")) != -1) {
		switch (ch) {
		case 'c':
			if (cfgfile)
				usage();
			cfgfile = optarg;
			break;
		case 'd':
			cfgstate.debug++;
			break;
		case 'v':
			cfgstate.verboselevel++;
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (argc > 0)
		usage();

	log_init(__progname);
	timer_init();

	cfgstate.runstate = INIT;
	LIST_INIT(&cfgstate.peerlist);

	cfgstate.listen_port = SASYNCD_DEFAULT_PORT;
	cfgstate.flags |= CTL_DEFAULT;

	if (!cfgfile)
		cfgfile = SASYNCD_CFGFILE;

	if (conf_parse_file(cfgfile) == 0 ) {
		if (!cfgstate.sharedkey) {
			fprintf(stderr, "config: "
			    "no shared key specified, cannot continue");
			exit(1);
		}
	} else {
		exit(1);
	}

	carp_demote(CARP_INC, 0);

	if (carp_init())
		return 1;
	if (pfkey_init(0))
		return 1;
	if (net_init())
		return 1;

	if (!cfgstate.debug)
		if (daemon(1, 0)) {
			perror("daemon()");
			exit(1);
		}

	if (monitor_init()) {
		/* Parent, with privileges. */
		monitor_loop();
		exit(0);
	}

	/* Child, no privileges left. Run main loop. */
	sasyncd_run(getppid());

	/* Shutdown. */
	log_msg(0, "shutting down...");

	net_shutdown();
	pfkey_shutdown();
	return 0;
}