コード例 #1
0
ファイル: main.c プロジェクト: softytantraa/inadyn
int main(int argc, char *argv[])
{
	int c, rc = 0, restart;
	struct option opt[] = {
		{ "once",              0, 0, '1' },
		{ "continue-on-error", 0, 0, 'c' },
		{ "exec",              1, 0, 'e' },
		{ "config",            1, 0, 'f' },
		{ "iface",             1, 0, 'i' },
		{ "loglevel",          1, 0, 'l' },
		{ "help",              0, 0, 'h' },
		{ "foreground",        0, 0, 'n' },
		{ "pidfile",           1, 0, 100 },
		{ "drop-privs",        1, 0, 'p' },
		{ "syslog",            0, 0, 's' },
		{ "startup-delay",     1, 0, 't' },
		{ "version",           0, 0, 'v' },
		{ NULL,                0, 0, 0   }
	};
	ddns_t *ctx = NULL;

	while ((c = getopt_long(argc, argv, "1ce:f:h?i:l:np:st:v", opt, NULL)) != EOF) {
		switch (c) {
		case '1':	/* --once */
			once = 1;
			break;

		case 'c':	/* --continue-on-error */
			ignore_errors = 1;
			break;

		case 'e':	/* --exec=CMD */
			script_exec = strdup(optarg);
			break;

		case 'f':	/* --config=FILE */
			config = strdup(optarg);
			break;

		case 'i':	/* --iface=IFNAME */
			iface = strdup(optarg);
			break;

		case 'l':	/* --loglevel=LEVEL */
			loglevel = loglvl(optarg);
			if (-1 == loglevel)
				return usage(1);
			break;

		case 'n':	/* --foreground */
			background = 0;
			break;

		case 100:	/* --pidfile=BASENAME */
			pidfile_name = strdup(optarg);
			break;

		case 'p':	/* --drop-privs=USER[:GROUP] */
			parse_privs(optarg);
			break;

		case 's':	/* --syslog */
			use_syslog = 1;
			break;

		case 't':	/* --startup-delay=SEC */
			startup_delay = atoi(optarg);
			break;

		case 'v':
			puts(VERSION);
			return 0;

		case 'h':	/* --help */
		case ':':	/* Missing parameter for option. */
		case '?':	/* Unknown option. */
		default:
			return usage(0);
		}
	}

	if (background) {
		if (daemon(0, 0) < 0) {
			fprintf(stderr, "Failed daemonizing %s: %m\n", __progname);
			return RC_OS_FORK_FAILURE;
		}
		use_syslog = 1;
	}

	if (use_syslog) {
		openlog(NULL, LOG_PID, LOG_USER);
		setlogmask(LOG_UPTO(loglevel));
	}

	if (drop_privs()) {
		logit(LOG_WARNING, "Failed dropping privileges: %s", strerror(errno));
		return RC_OS_CHANGE_PERSONA_FAILURE;
	}

	/* "Hello!" Let user know we've started up OK */
	logit(LOG_NOTICE, "%s", VERSION_STRING);

	if (!config)
		config = strdup(DEFAULT_CONFIG_FILE);

	/* Prepare SSL library, if enabled */
	ssl_init();

	do {
		restart = 0;

		rc = alloc_context(&ctx);
		if (rc != RC_OK)
			break;

		if (os_install_signal_handler(ctx))
			return RC_OS_INSTALL_SIGHANDLER_FAILED;

		cfg = conf_parse_file(config, ctx);
		if (!cfg) {
			free_context(ctx);
			return RC_FILE_IO_MISSING_FILE;
		}

		rc = ddns_main_loop(ctx);
		if (rc == RC_RESTART)
			restart = 1;

		free_context(ctx);
		cfg_free(cfg);
	} while (restart);

	if (use_syslog)
		closelog();
	free(config);
	ssl_exit();

	return rc;
}
コード例 #2
0
ファイル: smcrouted.c プロジェクト: troglobit/smcroute
/**
 * main - Main program
 *
 * Parses command line options and enters either daemon or client mode.
 *
 * In daemon mode, acquires multicast routing sockets, opens IPC socket
 * and goes in receive-execute command loop.
 *
 * In client mode, creates commands from command line and sends them to
 * the daemon.
 */
int main(int argc, char *argv[])
{
	int log_opts = LOG_NDELAY | LOG_PID;
	int c, new_log_level = -1;

	prognm = progname(argv[0]);
	while ((c = getopt(argc, argv, "c:d:e:f:F:hI:l:m:nNp:P:st:v")) != EOF) {
		switch (c) {
		case 'c':	/* cache timeout */
			cache_tmo = atoi(optarg);
			break;

		case 'd':
			startup_delay = atoi(optarg);
			break;

		case 'e':
			script = optarg;
			break;

#ifndef ENABLE_DOTCONF
		case 'F':
		case 'f':
			warnx("Built without .conf file support.");
			break;
#else
		case 'F':
			log_level = LOG_INFO; /* Raise log level for verify */
			conf_vrfy = 1;
			/* fallthrough */
		case 'f':
			conf_file = optarg;
			break;
#endif

		case 'h':	/* help */
			return usage(0);

		case 'I':
			ident = optarg;
			break;

		case 'l':
			new_log_level = loglvl(optarg);
			break;

		case 'm':
#ifndef ENABLE_MRDISC
			warnx("Built without mrdisc support.");
#else
			interval = atoi(optarg);
			if (interval < 4 || interval > 180)
				errx(1, "Invalid mrdisc announcement interval, 4-180.");
#endif
			break;

		case 'n':	/* run daemon in foreground, i.e., do not fork */
			background = 0;
			do_syslog--;
			break;

		case 'N':
#ifndef ENABLE_DOTCONF
			errx(1, "Built without .conf file, no way to enable individual interfaces.");
#else
			do_vifs = 0;
#endif
			break;

		case 'p':
			cap_set_user(optarg, &uid, &gid);
			break;

		case 'P':
			pid_file = optarg;
			break;

		case 's':	/* Force syslog even though in foreground */
			do_syslog++;
			break;

		case 't':
#ifndef __linux__
			errx(1, "Different multicast routing tables only available on Linux.");
#else
			table_id = atoi(optarg);
			if (table_id < 0)
				return usage(1);
#endif
			break;

		case 'v':	/* version */
			fprintf(stderr, "%s\n", version_info);
			return 0;

		default:	/* unknown option */
			return usage(1);
		}
	}

	if (new_log_level != -1)
		log_level = new_log_level;

	compose_paths();

	if (conf_vrfy) {
		smclog(LOG_INFO, "Verifying configuration file %s ...", conf_file);
		c = conf_read(conf_file, do_vifs);
		smclog(LOG_INFO, "Configuration file %s.", c ? "has unrecoverable errors" : "is OK");

		return c;
	}

	if (!background && do_syslog < 1)
		log_opts |= LOG_PERROR;

	openlog(ident, log_opts, LOG_DAEMON);
	setlogmask(LOG_UPTO(log_level));

	return start_server();
}
コード例 #3
0
ファイル: main.c プロジェクト: wgc1212/pimd
int main(int argc, char *argv[])
{
    int foreground = 0, do_syslog = 1;
    fd_set fds;
    int nfds, fd, n = -1, i, ch;
    struct sigaction sa;
    struct option long_options[] = {
	{ "config",        1, 0, 'f' },
	{ "no-fallback",   0, 0, 500 },
	{ "disable-vifs",  0, 0, 'N' },
	{ "foreground",    0, 0, 'n' },
	{ "help",          0, 0, 'h' },
	{ "ident",         1, 0, 'I' },
	{ "loglevel",      1, 0, 'l' },
	{ "pidfile",       1, 0, 'P' },
	{ "syslog",        0, 0, 's' },
	{ "table-id",      1, 0, 't' },
	{ "version",       0, 0, 'v' },
	{ NULL, 0, 0, 0 }
    };

    snprintf(versionstring, sizeof (versionstring), "pimd version %s", PACKAGE_VERSION);

    prognm = ident = progname(argv[0]);
    while ((ch = getopt_long(argc, argv, "d:f:hI:l:nNP:rst:v", long_options, NULL)) != EOF) {
	const char *errstr;

	switch (ch) {
	    case 'd':
		{
		    char *p,*q;
		    size_t i, len;
		    struct debugname *d;

		    debug = 0;
		    p = optarg;
		    q = NULL;
		    while (p) {
			q = strchr(p, ',');
			if (q)
			    *q++ = '\0';
			len = strlen(p);
			for (i = 0, d = debugnames; i < ARRAY_LEN(debugnames); i++, d++) {
			    if (len >= d->nchars && strncmp(d->name, p, len) == 0)
				break;
			}

			if (i == ARRAY_LEN(debugnames))
			    return usage(1);

			debug |= d->level;
			p = q;
		    }
		}
		break;

	    case 'f':
		config_file = optarg;
		break;

	    case 500:
		no_fallback = 1;
		break;

	    case 'h':
		return usage(0);

	    case 'I':	/* --ident=NAME */
		ident = optarg;
		break;

	    case 'l':
		loglevel = loglvl(optarg);
		if (-1 == loglevel)
		    return usage(1);
		break;

	    case 'n':
		do_syslog--;
		foreground = 1;
		break;

	    case 'N':
		do_vifs = 0;
		break;

	    case 'P':	/* --pidfile=NAME */
		pid_file = strdup(optarg);
		break;

	    case 'r':
		retry_forever++;
		break;

	    case 's':
		do_syslog++;
		break;

	    case 't':
		mrt_table_id = strtonum(optarg, 0, 999999999, &errstr);
		if (errstr) {
		    fprintf(stderr, "Table ID %s!\n", errstr);
		    return usage(1);
		}
		break;

	    case 'v':
		printf("%s\n", versionstring);
		return 0;

	    default:
		return usage(1);
	}
    }

    argc -= optind;
    if (argc > 0)
	return usage(1);

    if (geteuid() != 0)
	errx(1, "Need root privileges to start.");

    compose_paths();
    setlinebuf(stderr);

    if (debug != 0) {
	struct debugname *d;
	char c;
	int tmpd = debug;

	fprintf(stderr, "debug level 0x%lx ", debug);
	c = '(';
	for (d = debugnames; d < debugnames + ARRAY_LEN(debugnames); d++) {
	    if ((tmpd & d->level) == d->level) {
		tmpd &= ~d->level;
		fprintf(stderr, "%c%s", c, d->name);
		c = ',';
	    }
	}
	fprintf(stderr, ")\n");
    }

    if (!debug && !foreground) {
	/* Detach from the terminal */
	haveterminal = 0;
	if (fork())
	    exit(0);

	close(STDIN_FILENO);
	close(STDOUT_FILENO);
	close(STDERR_FILENO);

	fd = open("/dev/null", O_RDWR, 0);
	if (fd >= 0) {
	    dup2(fd, STDIN_FILENO);
	    dup2(fd, STDOUT_FILENO);
	    dup2(fd, STDERR_FILENO);
	    close(fd);
	}
#ifdef SYSV
	setpgrp();
#else
#ifdef TIOCNOTTY
	fd = open("/dev/tty", 2);
	if (fd >= 0) {
	    (void)ioctl(fd, TIOCNOTTY, (char *)0);
	    close(fd);
	}
#else
	if (setsid() < 0)
	    perror("setsid");
#endif /* TIOCNOTTY */
#endif /* SYSV */
    } /* End of child process code */

    /*
     * Create directory for runtime files
     */
    if (-1 == mkdir(_PATH_PIMD_RUNDIR, 0755) && errno != EEXIST)
	err(1, "Failed creating %s directory for runtime files", _PATH_PIMD_RUNDIR);

    /*
     * Setup logging
     */
    log_init(haveterminal && do_syslog > 0);
    logit(LOG_NOTICE, 0, "%s starting ...", versionstring);

    do_randomize();

    callout_init();
    init_igmp();
    init_pim();
    init_routesock(); /* Both for Linux netlink and BSD routing socket */
    init_pim_mrt();
    init_timers();
    ipc_init();

    /* Start up the log rate-limiter */
    resetlogging(NULL);

    /* TODO: check the kernel DVMRP/MROUTED/PIM support version */

    init_vifs();
    init_rp_and_bsr();   /* Must be after init_vifs() */
    add_static_rp();	 /* Must be after init_vifs() */
#ifdef RSRR
    rsrr_init();
#endif /* RSRR */

    sa.sa_handler = handle_signals;
    sa.sa_flags = 0;	/* Interrupt system calls */
    sigemptyset(&sa.sa_mask);
    sigaction(SIGALRM, &sa, NULL);
    sigaction(SIGHUP, &sa, NULL);
    sigaction(SIGTERM, &sa, NULL);
    sigaction(SIGINT, &sa, NULL);
    sigaction(SIGUSR1, &sa, NULL);
    sigaction(SIGUSR2, &sa, NULL);

    IF_DEBUG(DEBUG_IF)
	dump_vifs(stderr);
    IF_DEBUG(DEBUG_PIM_MRT)
	dump_pim_mrt(stderr);

    /* schedule first timer interrupt */
    timer_setTimer(TIMER_INTERVAL, timer, NULL);

    if (pidfile(pid_file))
	warn("Cannot create pidfile");

    /*
     * Main receive loop.
     */
    while (1) {
	if (check_signals())
	    break;

	FD_ZERO(&fds);
	for (i = 0, nfds = 0; i < nhandlers; i++) {
	    FD_SET(ihandlers[i].fd, &fds);
	    if (ihandlers[i].fd >= nfds)
		nfds = ihandlers[i].fd + 1;
	}

	n = select(nfds, &fds, NULL, NULL, timeout(n));
	if (n < 0) {
	    if (errno != EINTR) /* SIGALRM is expected */
		logit(LOG_WARNING, errno, "select failed");
	    continue;
	}

	for (i = 0; n > 0 && i < nhandlers; i++) {
	    if (FD_ISSET(ihandlers[i].fd, &fds))
		ihandlers[i].func(ihandlers[i].fd);
	}
    }

    logit(LOG_NOTICE, 0, "%s exiting.", versionstring);
    cleanup();
    exit(0);
}