Beispiel #1
0
/**
 *  Make sure each of the input files is findable.
 *  Also, while we are at it, compute the output file mod time
 *  based on the mod time of the most recent file.
 */
static void
set_modtime(void)
{
    int ct = STACKCT_OPT(INPUT);
    char const ** ppz = STACKLST_OPT(INPUT);
    struct stat stb;

    if ((ct == 1) && (strcmp(*ppz, "-") == 0)) {
        /*
         *  Read the list of input files from stdin.
         */
        loadStdin();
        ct  = STACKCT_OPT( INPUT);
        ppz = STACKLST_OPT(INPUT);
    }

    do  {
        if (stat(*ppz++, &stb) != 0)
            break;

        if (! S_ISREG(stb.st_mode)) {
            errno = EINVAL;
            break;
        }

        if (++(stb.st_mtime) > modtime)
            modtime = stb.st_mtime;
    } while (--ct > 0);

    if (ct > 0)
        fserr_die("stat-ing %s for text file\n", ppz[-1]);
}
Beispiel #2
0
/*
 *  processEmbeddedOptions
 *
 *  This routine processes the text contained within "/\*==--"
 *  and "=\*\/" as a single option.  If that option is the SUBBLOCK
 *  option, it will need to be massaged for use.
 */
LOCAL void
processEmbeddedOptions(char* pzText)
{
    tSCC zStStr[] = "/*=--";
    tSCC zEndSt[] = "=*/";

    for (;;) {
        char* pzStart = strstr(pzText, zStStr);
        char* pzEnd;
        int   sblct = 0;

        if (pzStart == NULL)
            return;

        if (HAVE_OPT(SUBBLOCK))
            sblct = STACKCT_OPT(SUBBLOCK);

        pzEnd = strstr(pzStart, zEndSt);
        if (pzEnd == NULL)
            return;

        pzStart = compressOptionText(pzStart + sizeof(zStStr)-1, pzEnd);

        optionLoadLine(&getdefsOptions, pzStart);

        if (HAVE_OPT(SUBBLOCK) && (sblct != STACKCT_OPT(SUBBLOCK))) {
            tCC** ppz = STACKLST_OPT(SUBBLOCK);
            ppz[ sblct ] = fixupSubblockString(ppz[sblct]);
        }
        pzText = pzEnd + sizeof(zEndSt);
    }
}
Beispiel #3
0
static void
exec_autogen(char ** pzBase)
{
    char const ** paparg;
    char const ** pparg;
    int    argCt = 5;

    /*
     *  IF we don't have template search directories,
     *  THEN allocate the default arg counter of pointers and
     *       set the program name into it.
     *  ELSE insert each one into the arg list.
     */
    if (! HAVE_OPT(AGARG)) {
        paparg = pparg = (char const **)malloc(argCt * sizeof(char*));
        *pparg++ = pzAutogen;

    } else {
        int    ct  = STACKCT_OPT(AGARG);
        char const ** ppz = STACKLST_OPT(AGARG);

        argCt += ct;
        paparg = pparg = (char const **)malloc(argCt * sizeof(char*));
        *pparg++ = pzAutogen;

        do  {
            *pparg++ = *ppz++;
        } while (--ct > 0);
    }

    *pparg++ = *pzBase;
    *pparg++ = "--";
    *pparg++ = "-";
    *pparg++ = NULL;

#ifdef DEBUG
    fputc('\n', stderr);
    pparg = paparg;
    for (;;) {
        fputs(*pparg++, stderr);
        if (*pparg == NULL)
            break;
        fputc(' ', stderr);
    }
    fputc('\n', stderr);
    fputc('\n', stderr);
#endif

    execvp(pzAutogen, (char**)(void*)paparg);
    fserr_die("exec of %s %s %s %s\n", paparg[0], paparg[1], paparg[2],
              paparg[3]);
}
Beispiel #4
0
static FILE*
open_ag_file(char ** pzBase)
{
    switch (WHICH_IDX_AUTOGEN) {
    case INDEX_OPT_OUTPUT:
    {
        static char const zFileFmt[] = " *      %s\n";
        FILE*  fp;

        if (*pzBase != NULL)
            free(*pzBase);

        if (strcmp(OPT_ARG(OUTPUT), "-") == 0)
            return stdout;

        unlink(OPT_ARG(OUTPUT));
        fp = fopen(OPT_ARG(OUTPUT), "w" FOPEN_BINARY_FLAG);
        fprintf(fp, zDne, OPT_ARG(OUTPUT));

        if (HAVE_OPT(INPUT)) {
            int    ct  = STACKCT_OPT(INPUT);
            char const ** ppz = STACKLST_OPT(INPUT);
            do  {
                fprintf(fp, zFileFmt, *ppz++);
            } while (--ct > 0);
        }

        fputs(" */\n", fp);
        return fp;
    }

    case INDEX_OPT_AUTOGEN:
        if (! ENABLED_OPT(AUTOGEN)) {
            if (*pzBase != NULL)
                free(*pzBase);

            return stdout;
        }

        if (  ( OPT_ARG(AUTOGEN) != NULL)
              && (*OPT_ARG(AUTOGEN) != NUL ))
            pzAutogen = OPT_ARG(AUTOGEN);

        break;
    }

    return NULL;
}
Beispiel #5
0
void write_results(void)
{
  int ct  = STACKCT_OPT(OUTPUT);
  char **output = (char **) &STACKLST_OPT(OUTPUT);
  int i;
  xmlDocPtr doc;

  doc = UpwatchXmlDoc("result", NULL);

  g_hash_table_foreach(cache, write_probe, doc);
  xmlSetDocCompressMode(doc, OPT_VALUE_COMPRESS);
  for (i=0; i < ct; i++) {
    spool_result(OPT_ARG(SPOOLDIR), output[i], doc, NULL);
  }
  xmlFreeDoc(doc);
}
Beispiel #6
0
/*
 * This is where you should define all your AutoGen AutoOpts option parsing.
 * Any user specified option should have it's bit turned on in the 'provides'
 * bit mask.
 * Returns: TCPEDIT_ERROR | TCPEDIT_OK | TCPEDIT_WARN
 */
int
dlt_user_parse_opts(tcpeditdlt_t *ctx)
{
    tcpeditdlt_plugin_t *plugin;
    user_config_t *config;
    assert(ctx);

    plugin = tcpedit_dlt_getplugin(ctx, dlt_value);
    config = plugin->config;

    /*
     * --user-dlt will override the output DLT type, otherwise we'll use
     * the DLT of the decoder
     */
    if (HAVE_OPT(USER_DLT)) {
        config->dlt = OPT_VALUE_USER_DLT;
    } else {
        config->dlt = ctx->decoder->dlt;
    }

    /* --user-dlink */
    if (HAVE_OPT(USER_DLINK)) {
        int  ct = STACKCT_OPT(USER_DLINK);
        char **list = STACKLST_OPT(USER_DLINK);
        int first = 1;

        do  {
            char *p = *list++;
            if (first) {
                config->length = read_hexstring(p, config->l2server, USER_L2MAXLEN);
                memcpy(config->l2client, config->l2server, config->length);
            } else {
                if (config->length != read_hexstring(p, config->l2client, USER_L2MAXLEN)) {
                    tcpedit_seterr(ctx->tcpedit, "%s",
                                   "both --dlink's must contain the same number of bytes");
                    return TCPEDIT_ERROR;
                }
            }

            first = 0;
        } while (--ct > 0);
    }

    return TCPEDIT_OK; /* success */
}
Beispiel #7
0
/*
 *  loadStdin
 *
 *  The input file list is from stdin.
 *
 *  We make some simplifying assumptions:
 *  *ALL* input lines are less than 4096 bytes.  If this is not true,
 *  we may strip some white space in the middle of a line and presume
 *  a comment begins in the middle of a line or we only comment out
 *  the first 4096 bytes of a comment line.  So, rather than all these
 *  problems, we just choke on it.
 */
static void
loadStdin(void)
{
    char z[ 4096 ];
    int    ct  = 0;
    tCC**  ppz = STACKLST_OPT(INPUT);

    if (isatty(STDIN_FILENO)) {
        fputs("getdefs error:  no inputs were specified and stdin is a tty\n",
              stderr);
        USAGE(EXIT_FAILURE);
    }

    while (fgets(z, (int)sizeof(z), stdin) != NULL) {
        char* pz = z + strlen(z);

        if (pz[-1] != '\n') {
            tSCC zErr[] =
                "getdefs error: input line not newline terminated\n";
            fputs(zErr, stderr);
            exit(EXIT_FAILURE);
        }

        while ((pz > z) && isspace(pz[-1]))  pz--;
        *pz = '\0';
        pz = z;
        while (isspace(*pz))  pz++;
        if ((*pz == '\0') || (*pz == '#'))  continue;
        if (access(pz, R_OK) != 0)  continue;

        if (ct++ == 0)
            *ppz = strdup(z);  /* replace the "-" */
        else
            SET_OPT_INPUT(strdup(z)); /* if 'strdup' fails, we die later */
    }
}
Beispiel #8
0
/*
 * Main program.  Initialize us, disconnect us from the tty if necessary,
 * and loop waiting for I/O and/or timer expiries.
 */
int
ntpdmain(
	int argc,
	char *argv[]
	)
{
	l_fp now;
	struct recvbuf *rbuf;
#ifdef _AIX			/* HMS: ifdef SIGDANGER? */
	struct sigaction sa;
#endif

	progname = argv[0];
	initializing = 1;		/* mark that we are initializing */
	process_commandline_opts(&argc, &argv);
	init_logging(progname, 1);	/* Open the log file */

	char *error = NULL;
	if (sandbox_init("ntpd", SANDBOX_NAMED, &error) == -1) {
		msyslog(LOG_ERR, "sandbox_init(ntpd, SANDBOX_NAMED) failed: %s", error);
		sandbox_free_error(error);
	}
#ifdef HAVE_UMASK
	{
		mode_t uv;

		uv = umask(0);
		if(uv)
			(void) umask(uv);
		else
			(void) umask(022);
	}
#endif

#if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */
	{
		uid_t uid;

		uid = getuid();
		if (uid && !HAVE_OPT( SAVECONFIGQUIT )) {
			msyslog(LOG_ERR, "ntpd: must be run as root, not uid %ld", (long)uid);
			printf("must be run as root, not uid %ld\n", (long)uid);
			exit(1);
		}
	}
#endif

	/* getstartup(argc, argv); / * startup configuration, may set debug */

#ifdef DEBUG
	debug = DESC(DEBUG_LEVEL).optOccCt;
	DPRINTF(1, ("%s\n", Version));
#endif

	/* honor -l/--logfile option to log to a file */
	setup_logfile();

/*
 * Enable the Multi-Media Timer for Windows?
 */
#ifdef SYS_WINNT
	if (HAVE_OPT( MODIFYMMTIMER ))
		set_mm_timer(MM_TIMER_HIRES);
#endif

	if (HAVE_OPT( NOFORK ) || HAVE_OPT( QUIT )
#ifdef DEBUG
	    || debug
#endif
	    || HAVE_OPT( SAVECONFIGQUIT ))
		nofork = 1;

	if (HAVE_OPT( NOVIRTUALIPS ))
		listen_to_virtual_ips = 0;

	/*
	 * --interface, listen on specified interfaces
	 */
	if (HAVE_OPT( INTERFACE )) {
		int	ifacect = STACKCT_OPT( INTERFACE );
		const char**	ifaces  = STACKLST_OPT( INTERFACE );
		isc_netaddr_t	netaddr;

		while (ifacect-- > 0) {
			add_nic_rule(
				is_ip_address(*ifaces, &netaddr)
					? MATCH_IFADDR
					: MATCH_IFNAME,
				*ifaces, -1, ACTION_LISTEN);
			ifaces++;
		}
	}

	if (HAVE_OPT( NICE ))
		priority_done = 0;

#if defined(HAVE_SCHED_SETSCHEDULER)
	if (HAVE_OPT( PRIORITY )) {
		config_priority = OPT_VALUE_PRIORITY;
		config_priority_override = 1;
		priority_done = 0;
	}
#endif

#ifdef SYS_WINNT
	/*
	 * Start interpolation thread, must occur before first
	 * get_systime()
	 */
	init_winnt_time();
#endif
	/*
	 * Initialize random generator and public key pair
	 */
	get_systime(&now);

	ntp_srandom((int)(now.l_i * now.l_uf));

#if !defined(VMS)
# ifndef NODETACH
	/*
	 * Detach us from the terminal.  May need an #ifndef GIZMO.
	 */
	if (!nofork) {

		/*
		 * Install trap handlers to log errors and assertion
		 * failures.  Default handlers print to stderr which 
		 * doesn't work if detached.
		 */
		isc_assertion_setcallback(assertion_failed);
		isc_error_setfatal(library_fatal_error);
		isc_error_setunexpected(library_unexpected_error);

#  ifndef SYS_WINNT
#   ifdef HAVE_DAEMON
		daemon(0, 0);
#   else /* not HAVE_DAEMON */
		if (fork())	/* HMS: What about a -1? */
			exit(0);

		{
#if !defined(F_CLOSEM)
			u_long s;
			int max_fd;
#endif /* !FCLOSEM */
			if (syslog_file != NULL) {
				fclose(syslog_file);
				syslog_file = NULL;
			}
#if defined(F_CLOSEM)
			/*
			 * From 'Writing Reliable AIX Daemons,' SG24-4946-00,
			 * by Eric Agar (saves us from doing 32767 system
			 * calls)
			 */
			if (fcntl(0, F_CLOSEM, 0) == -1)
			    msyslog(LOG_ERR, "ntpd: failed to close open files(): %m");
#else  /* not F_CLOSEM */

# if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
			max_fd = sysconf(_SC_OPEN_MAX);
# else /* HAVE_SYSCONF && _SC_OPEN_MAX */
			max_fd = getdtablesize();
# endif /* HAVE_SYSCONF && _SC_OPEN_MAX */
			for (s = 0; s < max_fd; s++)
				(void) close((int)s);
#endif /* not F_CLOSEM */
			(void) open("/", 0);
			(void) dup2(0, 1);
			(void) dup2(0, 2);

			init_logging(progname, 0);
			/* we lost our logfile (if any) daemonizing */
			setup_logfile();

#ifdef SYS_DOMAINOS
			{
				uid_$t puid;
				status_$t st;

				proc2_$who_am_i(&puid);
				proc2_$make_server(&puid, &st);
			}
#endif /* SYS_DOMAINOS */
#if defined(HAVE_SETPGID) || defined(HAVE_SETSID)
# ifdef HAVE_SETSID
			if (setsid() == (pid_t)-1)
				msyslog(LOG_ERR, "ntpd: setsid(): %m");
# else
			if (setpgid(0, 0) == -1)
				msyslog(LOG_ERR, "ntpd: setpgid(): %m");
# endif
#else /* HAVE_SETPGID || HAVE_SETSID */
			{
# if defined(TIOCNOTTY)
				int fid;

				fid = open("/dev/tty", 2);
				if (fid >= 0)
				{
					(void) ioctl(fid, (u_long) TIOCNOTTY, (char *) 0);
					(void) close(fid);
				}
# endif /* defined(TIOCNOTTY) */
# ifdef HAVE_SETPGRP_0
				(void) setpgrp();
# else /* HAVE_SETPGRP_0 */
				(void) setpgrp(0, getpid());
# endif /* HAVE_SETPGRP_0 */
			}
#endif /* HAVE_SETPGID || HAVE_SETSID */
#ifdef _AIX
			/* Don't get killed by low-on-memory signal. */
			sa.sa_handler = catch_danger;
			sigemptyset(&sa.sa_mask);
			sa.sa_flags = SA_RESTART;

			(void) sigaction(SIGDANGER, &sa, NULL);
#endif /* _AIX */
		}
#   endif /* not HAVE_DAEMON */
#  endif /* SYS_WINNT */
	}
# endif /* NODETACH */
#endif /* VMS */

#ifdef SCO5_CLOCK
	/*
	 * SCO OpenServer's system clock offers much more precise timekeeping
	 * on the base CPU than the other CPUs (for multiprocessor systems),
	 * so we must lock to the base CPU.
	 */
	{
	    int fd = open("/dev/at1", O_RDONLY);
	    if (fd >= 0) {
		int zero = 0;
		if (ioctl(fd, ACPU_LOCK, &zero) < 0)
		    msyslog(LOG_ERR, "cannot lock to base CPU: %m");
		close( fd );
	    } /* else ...
	       *   If we can't open the device, this probably just isn't
	       *   a multiprocessor system, so we're A-OK.
	       */
	}
#endif

#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && defined(MCL_FUTURE)
# ifdef HAVE_SETRLIMIT
	/*
	 * Set the stack limit to something smaller, so that we don't lock a lot
	 * of unused stack memory.
	 */
	{
	    struct rlimit rl;

	    /* HMS: must make the rlim_cur amount configurable */
	    if (getrlimit(RLIMIT_STACK, &rl) != -1
		&& (rl.rlim_cur = 50 * 4096) < rl.rlim_max)
	    {
		    if (setrlimit(RLIMIT_STACK, &rl) == -1)
		    {
			    msyslog(LOG_ERR,
				"Cannot adjust stack limit for mlockall: %m");
		    }
	    }
#  ifdef RLIMIT_MEMLOCK
	    /*
	     * The default RLIMIT_MEMLOCK is very low on Linux systems.
	     * Unless we increase this limit malloc calls are likely to
	     * fail if we drop root privlege.  To be useful the value
	     * has to be larger than the largest ntpd resident set size.
	     */
	    rl.rlim_cur = rl.rlim_max = 32*1024*1024;
	    if (setrlimit(RLIMIT_MEMLOCK, &rl) == -1) {
		msyslog(LOG_ERR, "Cannot set RLIMIT_MEMLOCK: %m");
	    }
#  endif /* RLIMIT_MEMLOCK */
	}
# endif /* HAVE_SETRLIMIT */
	/*
	 * lock the process into memory
	 */
	if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0)
		msyslog(LOG_ERR, "mlockall(): %m");
#else /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */
# ifdef HAVE_PLOCK
#  ifdef PROCLOCK
#   ifdef _AIX
	/*
	 * set the stack limit for AIX for plock().
	 * see get_aix_stack() for more info.
	 */
	if (ulimit(SET_STACKLIM, (get_aix_stack() - 8*4096)) < 0)
	{
		msyslog(LOG_ERR,"Cannot adjust stack limit for plock on AIX: %m");
	}
#   endif /* _AIX */
	/*
	 * lock the process into memory
	 */
	if (plock(PROCLOCK) < 0)
		msyslog(LOG_ERR, "plock(PROCLOCK): %m");
#  else /* not PROCLOCK */
#   ifdef TXTLOCK
	/*
	 * Lock text into ram
	 */
	if (plock(TXTLOCK) < 0)
		msyslog(LOG_ERR, "plock(TXTLOCK) error: %m");
#   else /* not TXTLOCK */
	msyslog(LOG_ERR, "plock() - don't know what to lock!");
#   endif /* not TXTLOCK */
#  endif /* not PROCLOCK */
# endif /* HAVE_PLOCK */
#endif /* not (HAVE_MLOCKALL && MCL_CURRENT && MCL_FUTURE) */

	/*
	 * Set up signals we pay attention to locally.
	 */
#ifdef SIGDIE1
	(void) signal_no_reset(SIGDIE1, finish);
#endif	/* SIGDIE1 */
#ifdef SIGDIE2
	(void) signal_no_reset(SIGDIE2, finish);
#endif	/* SIGDIE2 */
#ifdef SIGDIE3
	(void) signal_no_reset(SIGDIE3, finish);
#endif	/* SIGDIE3 */
#ifdef SIGDIE4
	(void) signal_no_reset(SIGDIE4, finish);
#endif	/* SIGDIE4 */

#ifdef SIGBUS
	(void) signal_no_reset(SIGBUS, finish);
#endif /* SIGBUS */

#if !defined(SYS_WINNT) && !defined(VMS)
# ifdef DEBUG
	(void) signal_no_reset(MOREDEBUGSIG, moredebug);
	(void) signal_no_reset(LESSDEBUGSIG, lessdebug);
# else
	(void) signal_no_reset(MOREDEBUGSIG, no_debug);
	(void) signal_no_reset(LESSDEBUGSIG, no_debug);
# endif /* DEBUG */
#endif /* !SYS_WINNT && !VMS */

	/*
	 * Set up signals we should never pay attention to.
	 */
#if defined SIGPIPE
	(void) signal_no_reset(SIGPIPE, SIG_IGN);
#endif	/* SIGPIPE */

	/*
	 * Call the init_ routines to initialize the data structures.
	 *
	 * Exactly what command-line options are we expecting here?
	 */
	init_auth();
	init_util();
	init_restrict();
	init_mon();
	init_timer();
	init_lib();
	init_request();
	init_control();
	init_peer();
#ifdef REFCLOCK
	init_refclock();
#endif
	set_process_priority();
	init_proto();		/* Call at high priority */
	init_io();
	init_loopfilter();
	mon_start(MON_ON);	/* monitor on by default now	  */
				/* turn off in config if unwanted */

	/*
	 * Get the configuration.  This is done in a separate module
	 * since this will definitely be different for the gizmo board.
	 */
	getconfig(argc, argv);
	NLOG(NLOG_SYSINFO) /* 'if' clause for syslog */
	msyslog(LOG_NOTICE, "%s", Version);
	report_event(EVNT_SYSRESTART, NULL, NULL);
	loop_config(LOOP_DRIFTCOMP, old_drift);
	initializing = 0;

#ifdef HAVE_DROPROOT
	if( droproot ) {
		/* Drop super-user privileges and chroot now if the OS supports this */

#ifdef HAVE_LINUX_CAPABILITIES
		/* set flag: keep privileges accross setuid() call (we only really need cap_sys_time): */
		if (prctl( PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L ) == -1) {
			msyslog( LOG_ERR, "prctl( PR_SET_KEEPCAPS, 1L ) failed: %m" );
			exit(-1);
		}
#else
		/* we need a user to switch to */
		if (user == NULL) {
			msyslog(LOG_ERR, "Need user name to drop root privileges (see -u flag!)" );
			exit(-1);
		}
#endif /* HAVE_LINUX_CAPABILITIES */

		if (user != NULL) {
			if (isdigit((unsigned char)*user)) {
				sw_uid = (uid_t)strtoul(user, &endp, 0);
				if (*endp != '\0')
					goto getuser;

				if ((pw = getpwuid(sw_uid)) != NULL) {
					user = strdup(pw->pw_name);
					if (NULL == user) {
						msyslog(LOG_ERR, "strdup() failed: %m");
						exit (-1);
					}
					sw_gid = pw->pw_gid;
				} else {
					errno = 0;
					msyslog(LOG_ERR, "Cannot find user ID %s", user);
					exit (-1);
				}

			} else {
getuser:
				errno = 0;
				if ((pw = getpwnam(user)) != NULL) {
					sw_uid = pw->pw_uid;
					sw_gid = pw->pw_gid;
				} else {
					if (errno)
					    msyslog(LOG_ERR, "getpwnam(%s) failed: %m", user);
					else
					    msyslog(LOG_ERR, "Cannot find user `%s'", user);
					exit (-1);
				}
			}
		}
		if (group != NULL) {
			if (isdigit((unsigned char)*group)) {
				sw_gid = (gid_t)strtoul(group, &endp, 0);
				if (*endp != '\0')
					goto getgroup;
			} else {
getgroup:
				if ((gr = getgrnam(group)) != NULL) {
					sw_gid = gr->gr_gid;
				} else {
					errno = 0;
					msyslog(LOG_ERR, "Cannot find group `%s'", group);
					exit (-1);
				}
			}
		}

		if (chrootdir ) {
			/* make sure cwd is inside the jail: */
			if (chdir(chrootdir)) {
				msyslog(LOG_ERR, "Cannot chdir() to `%s': %m", chrootdir);
				exit (-1);
			}
			if (chroot(chrootdir)) {
				msyslog(LOG_ERR, "Cannot chroot() to `%s': %m", chrootdir);
				exit (-1);
			}
			if (chdir("/")) {
				msyslog(LOG_ERR, "Cannot chdir() to`root after chroot(): %m");
				exit (-1);
			}
		}
		if (user && initgroups(user, sw_gid)) {
			msyslog(LOG_ERR, "Cannot initgroups() to user `%s': %m", user);
			exit (-1);
		}
		if (group && setgid(sw_gid)) {
			msyslog(LOG_ERR, "Cannot setgid() to group `%s': %m", group);
			exit (-1);
		}
		if (group && setegid(sw_gid)) {
			msyslog(LOG_ERR, "Cannot setegid() to group `%s': %m", group);
			exit (-1);
		}
		if (user && setuid(sw_uid)) {
			msyslog(LOG_ERR, "Cannot setuid() to user `%s': %m", user);
			exit (-1);
		}
		if (user && seteuid(sw_uid)) {
			msyslog(LOG_ERR, "Cannot seteuid() to user `%s': %m", user);
			exit (-1);
		}

#ifndef HAVE_LINUX_CAPABILITIES
		/*
		 * for now assume that the privilege to bind to privileged ports
		 * is associated with running with uid 0 - should be refined on
		 * ports that allow binding to NTP_PORT with uid != 0
		 */
		disable_dynamic_updates |= (sw_uid != 0);  /* also notifies routing message listener */
#endif

		if (disable_dynamic_updates && interface_interval) {
			interface_interval = 0;
			msyslog(LOG_INFO, "running in unprivileged mode disables dynamic interface tracking");
		}

#ifdef HAVE_LINUX_CAPABILITIES
		do {
			/*
			 *  We may be running under non-root uid now, but we still hold full root privileges!
			 *  We drop all of them, except for the crucial one or two: cap_sys_time and
			 *  cap_net_bind_service if doing dynamic interface tracking.
			 */
			cap_t caps;
			char *captext = (interface_interval)
				? "cap_sys_time,cap_net_bind_service=ipe"
				: "cap_sys_time=ipe";
			if( ! ( caps = cap_from_text( captext ) ) ) {
				msyslog( LOG_ERR, "cap_from_text() failed: %m" );
				exit(-1);
			}
			if( cap_set_proc( caps ) == -1 ) {
				msyslog( LOG_ERR, "cap_set_proc() failed to drop root privileges: %m" );
				exit(-1);
			}
			cap_free( caps );
		} while(0);
#endif /* HAVE_LINUX_CAPABILITIES */

	}    /* if( droproot ) */
#endif /* HAVE_DROPROOT */

	/*
	 * Use select() on all on all input fd's for unlimited
	 * time.  select() will terminate on SIGALARM or on the
	 * reception of input.	Using select() means we can't do
	 * robust signal handling and we get a potential race
	 * between checking for alarms and doing the select().
	 * Mostly harmless, I think.
	 */
	/* On VMS, I suspect that select() can't be interrupted
	 * by a "signal" either, so I take the easy way out and
	 * have select() time out after one second.
	 * System clock updates really aren't time-critical,
	 * and - lacking a hardware reference clock - I have
	 * yet to learn about anything else that is.
	 */
#if defined(HAVE_IO_COMPLETION_PORT)

	for (;;) {
		GetReceivedBuffers();
#else /* normal I/O */

	BLOCK_IO_AND_ALARM();
	was_alarmed = 0;
	for (;;)
	{
# if !defined(HAVE_SIGNALED_IO)
		extern fd_set activefds;
		extern int maxactivefd;

		fd_set rdfdes;
		int nfound;
# endif

		if (alarm_flag)		/* alarmed? */
		{
			was_alarmed = 1;
			alarm_flag = 0;
		}

		if (!was_alarmed && has_full_recv_buffer() == ISC_FALSE)
		{
			/*
			 * Nothing to do.  Wait for something.
			 */
# ifndef HAVE_SIGNALED_IO
			rdfdes = activefds;
#  if defined(VMS) || defined(SYS_VXWORKS)
			/* make select() wake up after one second */
			{
				struct timeval t1;

				t1.tv_sec = 1; t1.tv_usec = 0;
				nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0,
						(fd_set *)0, &t1);
			}
#  else
			nfound = select(maxactivefd+1, &rdfdes, (fd_set *)0,
					(fd_set *)0, (struct timeval *)0);
#  endif /* VMS */
			if (nfound > 0)
			{
				l_fp ts;

				get_systime(&ts);

				(void)input_handler(&ts);
			}
			else if (nfound == -1 && errno != EINTR)
				msyslog(LOG_ERR, "select() error: %m");
#  ifdef DEBUG
			else if (debug > 5)
				msyslog(LOG_DEBUG, "select(): nfound=%d, error: %m", nfound);
#  endif /* DEBUG */
# else /* HAVE_SIGNALED_IO */

			wait_for_signal();
# endif /* HAVE_SIGNALED_IO */
			if (alarm_flag)		/* alarmed? */
			{
				was_alarmed = 1;
				alarm_flag = 0;
			}
		}

		if (was_alarmed)
		{
			UNBLOCK_IO_AND_ALARM();
			/*
			 * Out here, signals are unblocked.  Call timer routine
			 * to process expiry.
			 */
			timer();
			was_alarmed = 0;
			BLOCK_IO_AND_ALARM();
		}

#endif /* ! HAVE_IO_COMPLETION_PORT */

#ifdef DEBUG_TIMING
		{
			l_fp pts;
			l_fp tsa, tsb;
			int bufcount = 0;

			get_systime(&pts);
			tsa = pts;
#endif
			rbuf = get_full_recv_buffer();
			while (rbuf != NULL)
			{
				if (alarm_flag)
				{
					was_alarmed = 1;
					alarm_flag = 0;
				}
				UNBLOCK_IO_AND_ALARM();

				if (was_alarmed)
				{	/* avoid timer starvation during lengthy I/O handling */
					timer();
					was_alarmed = 0;
				}

				/*
				 * Call the data procedure to handle each received
				 * packet.
				 */
				if (rbuf->receiver != NULL)	/* This should always be true */
				{
#ifdef DEBUG_TIMING
					l_fp dts = pts;

					L_SUB(&dts, &rbuf->recv_time);
					DPRINTF(2, ("processing timestamp delta %s (with prec. fuzz)\n", lfptoa(&dts, 9)));
					collect_timing(rbuf, "buffer processing delay", 1, &dts);
					bufcount++;
#endif
					(rbuf->receiver)(rbuf);
				} else {
					msyslog(LOG_ERR, "receive buffer corruption - receiver found to be NULL - ABORTING");
					abort();
				}

				BLOCK_IO_AND_ALARM();
				freerecvbuf(rbuf);
				rbuf = get_full_recv_buffer();
			}
#ifdef DEBUG_TIMING
			get_systime(&tsb);
			L_SUB(&tsb, &tsa);
			if (bufcount) {
				collect_timing(NULL, "processing", bufcount, &tsb);
				DPRINTF(2, ("processing time for %d buffers %s\n", bufcount, lfptoa(&tsb, 9)));
			}
		}
#endif

		/*
		 * Go around again
		 */

#ifdef HAVE_DNSREGISTRATION
		if (mdnsreg && (current_time - mdnsreg ) > 60 && mdnstries && sys_leap != LEAP_NOTINSYNC) {
			mdnsreg = current_time;
			msyslog(LOG_INFO, "Attemping to register mDNS");
			if ( DNSServiceRegister (&mdns, 0, 0, NULL, "_ntp._udp", NULL, NULL, 
			    htons(NTP_PORT), 0, NULL, NULL, NULL) != kDNSServiceErr_NoError ) {
				if (!--mdnstries) {
					msyslog(LOG_ERR, "Unable to register mDNS, giving up.");
				} else {	
					msyslog(LOG_INFO, "Unable to register mDNS, will try later.");
				}
			} else {
				msyslog(LOG_INFO, "mDNS service registered.");
				mdnsreg = 0;
			}
		}
#endif /* HAVE_DNSREGISTRATION */

	}
	UNBLOCK_IO_AND_ALARM();
	return 1;
}


#ifdef SIGDIE2
/*
 * finish - exit gracefully
 */
static RETSIGTYPE
finish(
	int sig
	)
{
	msyslog(LOG_NOTICE, "ntpd exiting on signal %d", sig);
#ifdef HAVE_DNSREGISTRATION
	if (mdns != NULL)
		DNSServiceRefDeallocate(mdns);
#endif
	switch (sig) {
# ifdef SIGBUS
	case SIGBUS:
		printf("\nfinish(SIGBUS)\n");
		exit(0);
# endif
	case 0:			/* Should never happen... */
		return;

	default:
		exit(0);
	}
}
Beispiel #9
0
/**
 * returns 0 for sucess w/o errors
 * returns 1 for sucess w/ warnings
 * returns -1 for error
 */
int 
tcpedit_post_args(tcpedit_t **tcpedit_ex) {
    tcpedit_t *tcpedit;
    int rcode = 0;
    long ttl;
    assert(tcpedit_ex);
    tcpedit = *tcpedit_ex;
    assert(tcpedit);


    /* --pnat */
    if (HAVE_OPT(PNAT)) {
        int ct = STACKCT_OPT(PNAT);
        char **list = STACKLST_OPT(PNAT);
        int first = 1;

        tcpedit->rewrite_ip ++;

        do {
            char *p = *list++;
            if (first) {
                if (! parse_cidr_map(&tcpedit->cidrmap1, p)) {
                    tcpedit_seterr(tcpedit, 
                            "Unable to parse first --pnat=%s", p);
                    return -1;
                }
            } else {
                if (! parse_cidr_map(&tcpedit->cidrmap2, p)) {
                    tcpedit_seterr(tcpedit, 
                            "Unable to parse second --pnat=%s", p);
                    return -1;
                }
            }
            
            first = 0;
        } while (--ct > 0);
    }
    
    /* --srcipmap */
    if (HAVE_OPT(SRCIPMAP)) {
        tcpedit->rewrite_ip ++;
        if (! parse_cidr_map(&tcpedit->srcipmap, OPT_ARG(SRCIPMAP))) {
            tcpedit_seterr(tcpedit, 
                "Unable to parse --srcipmap=%s", OPT_ARG(SRCIPMAP));
            return -1;
        }
    }

    /* --dstipmap */
    if (HAVE_OPT(DSTIPMAP)) {
        tcpedit->rewrite_ip ++;
        if (! parse_cidr_map(&tcpedit->dstipmap, OPT_ARG(DSTIPMAP))) {
            tcpedit_seterr(tcpedit, 
                "Unable to parse --dstipmap=%s", OPT_ARG(DSTIPMAP));
            return -1;
        }
    }

    /*
     * If we have one and only one -N, then use the same map data
     * for both interfaces/files
     */
    if ((tcpedit->cidrmap1 != NULL) && (tcpedit->cidrmap2 == NULL))
        tcpedit->cidrmap2 = tcpedit->cidrmap1;

    /* --fixcsum */
    if (HAVE_OPT(FIXCSUM)) {
        tcpedit->fixcsum = TCPEDIT_FIXCSUM_ON;
    } else if (HAVE_OPT(NOFIXCSUM)) {
        tcpedit->fixcsum = TCPEDIT_FIXCSUM_DISABLE;
    }

    /* --efcs */
    if (HAVE_OPT(EFCS)) 
        tcpedit->efcs = 1;

    /* --ttl */
    if (HAVE_OPT(TTL)) {
        if (strchr(OPT_ARG(TTL), '+')) {
            tcpedit->ttl_mode = TCPEDIT_TTL_ADD;            
        } else if (strchr(OPT_ARG(TTL), '-')) {
            tcpedit->ttl_mode = TCPEDIT_TTL_SUB;            
        } else {
            tcpedit->ttl_mode = TCPEDIT_TTL_SET;            
        }

        ttl = strtol(OPT_ARG(TTL), (char **)NULL, 10);
        if (ttl < 0)
            ttl *= -1; /* convert to positive value */
            
        if (ttl > 255)
            errx(-1, "Invalid --ttl value (must be 0-255): %ld", ttl);

        tcpedit->ttl_value = (u_int8_t)ttl;
    }
    
    /* --tos */
    if (HAVE_OPT(TOS))
        tcpedit->tos = OPT_VALUE_TOS;

    /* --flowlabel */
    if (HAVE_OPT(FLOWLABEL))
        tcpedit->flowlabel = OPT_VALUE_FLOWLABEL;

    /* --mtu */
    if (HAVE_OPT(MTU))
        tcpedit->mtu = OPT_VALUE_MTU;
        
    /* --mtu-trunc */
    if (HAVE_OPT(MTU_TRUNC))
        tcpedit->mtu_truncate = 1;
        
    /* --skipbroadcast */
    if (HAVE_OPT(SKIPBROADCAST))
        tcpedit->skip_broadcast = 1;

    /* --fixlen */
    if (HAVE_OPT(FIXLEN)) {
        if (strcmp(OPT_ARG(FIXLEN), "pad") == 0) {
            tcpedit->fixlen = TCPEDIT_FIXLEN_PAD;
        } else if (strcmp(OPT_ARG(FIXLEN), "trunc") == 0) {
            tcpedit->fixlen = TCPEDIT_FIXLEN_TRUNC;
        } else if (strcmp(OPT_ARG(FIXLEN), "del") == 0) {
            tcpedit->fixlen = TCPEDIT_FIXLEN_DEL;
        } else {
            tcpedit_seterr(tcpedit, "Invalid --fixlen=%s", OPT_ARG(FIXLEN));
            return -1;
        }
    }

    /* TCP/UDP port rewriting */
    if (HAVE_OPT(PORTMAP)) {
        int ct = STACKCT_OPT(PORTMAP);
        char **list = STACKLST_OPT(PORTMAP);
        int first = 1;
        tcpedit_portmap_t *portmap_head, *portmap;

        do {
            char *p = *list++;
            if (first) {
                if (! parse_portmap(&tcpedit->portmap, p)) {
                    tcpedit_seterr(tcpedit, "Unable to parse --portmap=%s", p);
                    return -1;
                }
            } else {
                if (! parse_portmap(&portmap, p)) {
                    tcpedit_seterr(tcpedit, "Unable to parse --portmap=%s", p);
                    return -1;
                }

                /* append to end of tcpedit->portmap linked list */
                portmap_head = tcpedit->portmap;
                while (portmap_head->next != NULL)
                    portmap_head = portmap_head->next;
                portmap_head->next = portmap;

            }
            first = 0;
        } while (--ct > 0);
    }

    /*
     * IP address rewriting processing.  Call srandom() then add up
     * 5 calls to random() as our mixer for randomizing.  This should
     * work better since most people aren't going to write out values
     * close to 32bit integers.
     */
    if (HAVE_OPT(SEED)) {
        tcpedit->rewrite_ip = TCPEDIT_REWRITE_IP_ON;
        srandom(OPT_VALUE_SEED);
        tcpedit->seed = random() + random() + random() + random() + random();
    }

    if (HAVE_OPT(ENDPOINTS)) {
        tcpedit->rewrite_ip = TCPEDIT_REWRITE_IP_ON;
        if (! parse_endpoints(&tcpedit->cidrmap1, &tcpedit->cidrmap2,
                    OPT_ARG(ENDPOINTS))) {
            tcpedit_seterr(tcpedit, 
                    "Unable to parse --endpoints=%s", OPT_ARG(ENDPOINTS));
            return -1;
        }
    }

    /* 
     * figure out the max packet len
    if (tcpedit->l2.enabled) {
        // custom l2 header
        dbg(1, "Using custom L2 header to calculate max frame size\n");
        tcpedit->maxpacket = tcpedit->mtu + tcpedit->l2.len;
    }
    else if (tcpedit->l2.dlt == DLT_EN10MB || tcpedit->l2.dlt == DLT_VLAN) {
        // ethernet 
        dbg(1, "Using Ethernet to calculate max frame size\n");
        tcpedit->maxpacket = tcpedit->mtu + TCPR_ETH_H;
    } else {
         // uh, wtf is this now?  we'll just assume ethernet and hope things work
        tcpedit->maxpacket = tcpedit->mtu + TCPR_ETH_H;
        tcpedit_seterr(tcpedit, 
            "Unsupported DLT type: %s.  We'll just treat it as ethernet.\n"
            "You may need to increase the MTU (-t <size>) if you get errors\n",
            pcap_datalink_val_to_name(tcpedit->l2.dlt));
        rcode = 1;
    }
     */

    return rcode;
}
Beispiel #10
0
/**
 *  Starting with the current directory, search the directory
 *  list trying to find the base template file name.
 */
LOCAL tSuccess
findFile(char const * pzFName,
         char * pzFullName,
         char const * const * papSuffixList,
         char const * pzReferrer)
{
    char * pzRoot;
    char * pzSfx;
    void * deallocAddr = NULL;

    tSuccess res = SUCCESS;

    /*
     *  Expand leading environment variables.
     *  We will not mess with embedded ones.
     */
    if (*pzFName == '$') {
        if (! optionMakePath(pzFullName, (int)AG_PATH_MAX, pzFName,
                             autogenOptions.pzProgPath))
            return FAILURE;

        AGDUPSTR(pzFName, pzFullName, "find file name");
        deallocAddr = (void*)pzFName;

        /*
         *  pzFName now points to the name the file system can use.
         *  It must _not_ point to pzFullName because we will likely
         *  rewrite that value using this pointer!
         */
    }

    /*
     *  Not a complete file name.  If there is not already
     *  a suffix for the file name, then append ".tpl".
     *  Check for immediate access once again.
     */
    pzRoot = strrchr(pzFName, '/');
    pzSfx  = (pzRoot != NULL)
             ? strchr(++pzRoot, '.')
             : strchr(pzFName,  '.');

    /*
     *  The referrer is useful only if it includes a directory name.
     */
    if (pzReferrer != NULL) {
        char * pz = strrchr(pzReferrer, '/');
        if (pz == NULL)
            pzReferrer = NULL;
        else {
            AGDUPSTR(pzReferrer, pzReferrer, "pzReferrer");
            pz = strrchr(pzReferrer, '/');
            *pz = NUL;
        }
    }

    /*
     *  IF the file name does not contain a directory separator,
     *  then we will use the TEMPL_DIR search list to keep hunting.
     */
    {
        static char const curdir[]  = ".";
        static char const zDirFmt[] = "%s/%s";

        /*
         *  Search each directory in our directory search list
         *  for the file.  We always force one copy of this option.
         */
        int  ct = STACKCT_OPT(TEMPL_DIRS);
        char const ** ppzDir = STACKLST_OPT(TEMPL_DIRS) + ct - 1;
        char const *  pzDir  = curdir;

        if (*pzFName == '/')
            ct = 0;

        do  {
            char * pzEnd;
            void * coerce;

            /*
             *  IF one of our template paths starts with '$', then expand it.
             */
            if (*pzDir == '$') {
                if (! optionMakePath(pzFullName, (int)AG_PATH_MAX, pzDir,
                                     autogenOptions.pzProgPath)) {
                    coerce = (void *)pzDir;
                    strcpy(coerce, curdir);

                } else {
                    AGDUPSTR(pzDir, pzFullName, "find directory name");
                    coerce = (void *)ppzDir[1];
                    free(coerce);
                    ppzDir[1] = pzDir; /* save the computed name for later */
                }
            }

            if ((*pzFName == '/') || (pzDir == curdir)) {
                size_t nln = strlen(pzFName);
                if (nln >= AG_PATH_MAX - MAX_SUFFIX_LEN)
                    break;

                memcpy(pzFullName, pzFName, nln);
                pzEnd  = pzFullName + nln;
                *pzEnd = NUL;
            }
            else {
                pzEnd = pzFullName
                    + snprintf(pzFullName, AG_PATH_MAX - MAX_SUFFIX_LEN,
                               zDirFmt, pzDir, pzFName);
            }

            if (read_okay(pzFullName))
                goto findFileReturn;

            /*
             *  IF the file does not already have a suffix,
             *  THEN try the ones that are okay for this file.
             */
            if ((pzSfx == NULL) && (papSuffixList != NULL)) {
                char const * const * papSL = papSuffixList;
                *(pzEnd++) = '.';

                do  {
                    strcpy(pzEnd, *(papSL++)); /* must fit */
                    if (read_okay(pzFullName))
                        goto findFileReturn;

                } while (*papSL != NULL);
            }

            if (*pzFName == '/')
                break;

            /*
             *  IF there is a referrer, use it before the rest of the
             *  TEMPL_DIRS We detect first time through by *both* pzDir value
             *  and ct value.  "ct" will have this same value next time
             *  through and occasionally "pzDir" will be set to "curdir", but
             *  never again when ct is STACKCT_OPT(TEMPL_DIRS)
             */
            if (  (pzReferrer != NULL)
               && (pzDir == curdir)
               && (ct == STACKCT_OPT(TEMPL_DIRS))) {

                pzDir = pzReferrer;
                ct++;

            } else {
                pzDir = *(ppzDir--);
            }
        } while (--ct >= 0);
    }

    res = FAILURE;

 findFileReturn:
    AGFREE(deallocAddr);
    AGFREE(pzReferrer);
    return res;
}
Beispiel #11
0
int
ntpdmain(
	int argc,
	char *argv[]
	)
{
	l_fp		now;
	struct recvbuf *rbuf;
	const char *	logfilename;
# ifdef HAVE_UMASK
	mode_t		uv;
# endif
# if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */
	uid_t		uid;
# endif
# if defined(HAVE_WORKING_FORK)
	long		wait_sync = 0;
	int		pipe_fds[2];
	int		rc;
	int		exit_code;
#  ifdef _AIX
	struct sigaction sa;
#  endif
#  if !defined(HAVE_SETSID) && !defined (HAVE_SETPGID) && defined(TIOCNOTTY)
	int		fid;
#  endif
# endif	/* HAVE_WORKING_FORK*/
# ifdef SCO5_CLOCK
	int		fd;
	int		zero;
# endif

# ifdef NEED_PTHREAD_WARMUP
	my_pthread_warmup();
# endif
	
# ifdef HAVE_UMASK
	uv = umask(0);
	if (uv)
		umask(uv);
	else
		umask(022);
# endif
	saved_argc = argc;
	saved_argv = argv;
	progname = argv[0];
	initializing = TRUE;		/* mark that we are initializing */
	parse_cmdline_opts(&argc, &argv);
# ifdef DEBUG
	debug = OPT_VALUE_SET_DEBUG_LEVEL;
#  ifdef HAVE_SETLINEBUF
	setlinebuf(stdout);
#  endif
# endif

	if (HAVE_OPT(NOFORK) || HAVE_OPT(QUIT)
# ifdef DEBUG
	    || debug
# endif
	    || HAVE_OPT(SAVECONFIGQUIT))
		nofork = TRUE;

	init_logging(progname, NLOG_SYNCMASK, TRUE);
	/* honor -l/--logfile option to log to a file */
	if (HAVE_OPT(LOGFILE)) {
		logfilename = OPT_ARG(LOGFILE);
		syslogit = FALSE;
		change_logfile(logfilename, FALSE);
	} else {
		logfilename = NULL;
		if (nofork)
			msyslog_term = TRUE;
		if (HAVE_OPT(SAVECONFIGQUIT))
			syslogit = FALSE;
	}
	msyslog(LOG_NOTICE, "%s: Starting", Version);

	{
		int i;
		char buf[1024];	/* Secret knowledge of msyslog buf length */
		char *cp = buf;

		/* Note that every arg has an initial space character */
		snprintf(cp, sizeof(buf), "Command line:");
		cp += strlen(cp);

		for (i = 0; i < saved_argc ; ++i) {
			snprintf(cp, sizeof(buf) - (cp - buf),
				" %s", saved_argv[i]);
			cp += strlen(cp);
		}
		msyslog(LOG_INFO, "%s", buf);
	}

	/*
	 * Install trap handlers to log errors and assertion failures.
	 * Default handlers print to stderr which doesn't work if detached.
	 */
	isc_assertion_setcallback(assertion_failed);
	isc_error_setfatal(library_fatal_error);
	isc_error_setunexpected(library_unexpected_error);

	/* MPE lacks the concept of root */
# if defined(HAVE_GETUID) && !defined(MPE)
	uid = getuid();
	if (uid && !HAVE_OPT( SAVECONFIGQUIT )) {
		msyslog_term = TRUE;
		msyslog(LOG_ERR,
			"must be run as root, not uid %ld", (long)uid);
		exit(1);
	}
# endif

/*
 * Enable the Multi-Media Timer for Windows?
 */
# ifdef SYS_WINNT
	if (HAVE_OPT( MODIFYMMTIMER ))
		set_mm_timer(MM_TIMER_HIRES);
# endif

#ifdef HAVE_DNSREGISTRATION
/*
 * Enable mDNS registrations?
 */
	if (HAVE_OPT( MDNS )) {
		mdnsreg = TRUE;
	}
#endif  /* HAVE_DNSREGISTRATION */

	if (HAVE_OPT( NOVIRTUALIPS ))
		listen_to_virtual_ips = 0;

	/*
	 * --interface, listen on specified interfaces
	 */
	if (HAVE_OPT( INTERFACE )) {
		int		ifacect = STACKCT_OPT( INTERFACE );
		const char**	ifaces  = STACKLST_OPT( INTERFACE );
		sockaddr_u	addr;

		while (ifacect-- > 0) {
			add_nic_rule(
				is_ip_address(*ifaces, AF_UNSPEC, &addr)
					? MATCH_IFADDR
					: MATCH_IFNAME,
				*ifaces, -1, ACTION_LISTEN);
			ifaces++;
		}
	}

	if (HAVE_OPT( NICE ))
		priority_done = 0;

# ifdef HAVE_SCHED_SETSCHEDULER
	if (HAVE_OPT( PRIORITY )) {
		config_priority = OPT_VALUE_PRIORITY;
		config_priority_override = 1;
		priority_done = 0;
	}
# endif

# ifdef HAVE_WORKING_FORK
	/* make sure the FDs are initialised */
	pipe_fds[0] = -1;
	pipe_fds[1] = -1;
	do {					/* 'loop' once */
		if (!HAVE_OPT( WAIT_SYNC ))
			break;
		wait_sync = OPT_VALUE_WAIT_SYNC;
		if (wait_sync <= 0) {
			wait_sync = 0;
			break;
		}
		/* -w requires a fork() even with debug > 0 */
		nofork = FALSE;
		if (pipe(pipe_fds)) {
			exit_code = (errno) ? errno : -1;
			msyslog(LOG_ERR,
				"Pipe creation failed for --wait-sync: %m");
			exit(exit_code);
		}
		waitsync_fd_to_close = pipe_fds[1];
	} while (0);				/* 'loop' once */
# endif	/* HAVE_WORKING_FORK */

	init_lib();
# ifdef SYS_WINNT
	/*
	 * Start interpolation thread, must occur before first
	 * get_systime()
	 */
	init_winnt_time();
# endif
	/*
	 * Initialize random generator and public key pair
	 */
	get_systime(&now);

	ntp_srandom((int)(now.l_i * now.l_uf));

	/*
	 * Detach us from the terminal.  May need an #ifndef GIZMO.
	 */
	if (!nofork) {

# ifdef HAVE_WORKING_FORK
		rc = fork();
		if (-1 == rc) {
			exit_code = (errno) ? errno : -1;
			msyslog(LOG_ERR, "fork: %m");
			exit(exit_code);
		}
		if (rc > 0) {	
			/* parent */
			exit_code = wait_child_sync_if(pipe_fds[0],
						       wait_sync);
			exit(exit_code);
		}
		
		/*
		 * child/daemon 
		 * close all open files excepting waitsync_fd_to_close.
		 * msyslog() unreliable until after init_logging().
		 */
		closelog();
		if (syslog_file != NULL) {
			fclose(syslog_file);
			syslog_file = NULL;
			syslogit = TRUE;
		}
		close_all_except(waitsync_fd_to_close);
		INSIST(0 == open("/dev/null", 0) && 1 == dup2(0, 1) \
			&& 2 == dup2(0, 2));

		init_logging(progname, 0, TRUE);
		/* we lost our logfile (if any) daemonizing */
		setup_logfile(logfilename);

#  ifdef SYS_DOMAINOS
		{
			uid_$t puid;
			status_$t st;

			proc2_$who_am_i(&puid);
			proc2_$make_server(&puid, &st);
		}
#  endif	/* SYS_DOMAINOS */
#  ifdef HAVE_SETSID
		if (setsid() == (pid_t)-1)
			msyslog(LOG_ERR, "setsid(): %m");
#  elif defined(HAVE_SETPGID)
		if (setpgid(0, 0) == -1)
			msyslog(LOG_ERR, "setpgid(): %m");
#  else		/* !HAVE_SETSID && !HAVE_SETPGID follows */
#   ifdef TIOCNOTTY
		fid = open("/dev/tty", 2);
		if (fid >= 0) {
			ioctl(fid, (u_long)TIOCNOTTY, NULL);
			close(fid);
		}
#   endif	/* TIOCNOTTY */
		ntp_setpgrp(0, getpid());
#  endif	/* !HAVE_SETSID && !HAVE_SETPGID */
#  ifdef _AIX
		/* Don't get killed by low-on-memory signal. */
		sa.sa_handler = catch_danger;
		sigemptyset(&sa.sa_mask);
		sa.sa_flags = SA_RESTART;
		sigaction(SIGDANGER, &sa, NULL);
#  endif	/* _AIX */
# endif		/* HAVE_WORKING_FORK */
	}

# ifdef SCO5_CLOCK
	/*
	 * SCO OpenServer's system clock offers much more precise timekeeping
	 * on the base CPU than the other CPUs (for multiprocessor systems),
	 * so we must lock to the base CPU.
	 */
	fd = open("/dev/at1", O_RDONLY);		
	if (fd >= 0) {
		zero = 0;
		if (ioctl(fd, ACPU_LOCK, &zero) < 0)
			msyslog(LOG_ERR, "cannot lock to base CPU: %m");
		close(fd);
	}
# endif

	/* Setup stack size in preparation for locking pages in memory. */
# if defined(HAVE_MLOCKALL)
#  ifdef HAVE_SETRLIMIT
	ntp_rlimit(RLIMIT_STACK, DFLT_RLIMIT_STACK * 4096, 4096, "4k");
#   ifdef RLIMIT_MEMLOCK
	/*
	 * The default RLIMIT_MEMLOCK is very low on Linux systems.
	 * Unless we increase this limit malloc calls are likely to
	 * fail if we drop root privilege.  To be useful the value
	 * has to be larger than the largest ntpd resident set size.
	 */
	ntp_rlimit(RLIMIT_MEMLOCK, DFLT_RLIMIT_MEMLOCK * 1024 * 1024, 1024 * 1024, "MB");
#   endif	/* RLIMIT_MEMLOCK */
#  endif	/* HAVE_SETRLIMIT */
# else	/* !HAVE_MLOCKALL follows */
#  ifdef HAVE_PLOCK
#   ifdef PROCLOCK
#    ifdef _AIX
	/*
	 * set the stack limit for AIX for plock().
	 * see get_aix_stack() for more info.
	 */
	if (ulimit(SET_STACKLIM, (get_aix_stack() - 8 * 4096)) < 0)
		msyslog(LOG_ERR,
			"Cannot adjust stack limit for plock: %m");
#    endif	/* _AIX */
#   endif	/* PROCLOCK */
#  endif	/* HAVE_PLOCK */
# endif	/* !HAVE_MLOCKALL */

	/*
	 * Set up signals we pay attention to locally.
	 */
# ifdef SIGDIE1
	signal_no_reset(SIGDIE1, finish);
	signal_no_reset(SIGDIE2, finish);
	signal_no_reset(SIGDIE3, finish);
	signal_no_reset(SIGDIE4, finish);
# endif
# ifdef SIGBUS
	signal_no_reset(SIGBUS, finish);
# endif

# if !defined(SYS_WINNT) && !defined(VMS)
#  ifdef DEBUG
	(void) signal_no_reset(MOREDEBUGSIG, moredebug);
	(void) signal_no_reset(LESSDEBUGSIG, lessdebug);
#  else
	(void) signal_no_reset(MOREDEBUGSIG, no_debug);
	(void) signal_no_reset(LESSDEBUGSIG, no_debug);
#  endif	/* DEBUG */
# endif	/* !SYS_WINNT && !VMS */

	/*
	 * Set up signals we should never pay attention to.
	 */
# ifdef SIGPIPE
	signal_no_reset(SIGPIPE, SIG_IGN);
# endif

	/*
	 * Call the init_ routines to initialize the data structures.
	 *
	 * Exactly what command-line options are we expecting here?
	 */
	INIT_SSL();
	init_auth();
	init_util();
	init_restrict();
	init_mon();
	init_timer();
	init_request();
	init_control();
	init_peer();
# ifdef REFCLOCK
	init_refclock();
# endif
	set_process_priority();
	init_proto();		/* Call at high priority */
	init_io();
	init_loopfilter();
	mon_start(MON_ON);	/* monitor on by default now	  */
				/* turn off in config if unwanted */

	/*
	 * Get the configuration.  This is done in a separate module
	 * since this will definitely be different for the gizmo board.
	 */
	getconfig(argc, argv);

	if (-1 == cur_memlock) {
# if defined(HAVE_MLOCKALL)
		/*
		 * lock the process into memory
		 */
		if (   !HAVE_OPT(SAVECONFIGQUIT)
#  ifdef RLIMIT_MEMLOCK
		    && -1 != DFLT_RLIMIT_MEMLOCK
#  endif
		    && 0 != mlockall(MCL_CURRENT|MCL_FUTURE))
			msyslog(LOG_ERR, "mlockall(): %m");
# else	/* !HAVE_MLOCKALL follows */
#  ifdef HAVE_PLOCK
#   ifdef PROCLOCK
		/*
		 * lock the process into memory
		 */
		if (!HAVE_OPT(SAVECONFIGQUIT) && 0 != plock(PROCLOCK))
			msyslog(LOG_ERR, "plock(PROCLOCK): %m");
#   else	/* !PROCLOCK follows  */
#    ifdef TXTLOCK
		/*
		 * Lock text into ram
		 */
		if (!HAVE_OPT(SAVECONFIGQUIT) && 0 != plock(TXTLOCK))
			msyslog(LOG_ERR, "plock(TXTLOCK) error: %m");
#    else	/* !TXTLOCK follows */
		msyslog(LOG_ERR, "plock() - don't know what to lock!");
#    endif	/* !TXTLOCK */
#   endif	/* !PROCLOCK */
#  endif	/* HAVE_PLOCK */
# endif	/* !HAVE_MLOCKALL */
	}

	loop_config(LOOP_DRIFTINIT, 0);
	report_event(EVNT_SYSRESTART, NULL, NULL);
	initializing = FALSE;

# ifdef HAVE_DROPROOT
	if (droproot) {
		/* Drop super-user privileges and chroot now if the OS supports this */

#  ifdef HAVE_LINUX_CAPABILITIES
		/* set flag: keep privileges accross setuid() call (we only really need cap_sys_time): */
		if (prctl( PR_SET_KEEPCAPS, 1L, 0L, 0L, 0L ) == -1) {
			msyslog( LOG_ERR, "prctl( PR_SET_KEEPCAPS, 1L ) failed: %m" );
			exit(-1);
		}
#  elif HAVE_SOLARIS_PRIVS
		/* Nothing to do here */
#  else
		/* we need a user to switch to */
		if (user == NULL) {
			msyslog(LOG_ERR, "Need user name to drop root privileges (see -u flag!)" );
			exit(-1);
		}
#  endif	/* HAVE_LINUX_CAPABILITIES || HAVE_SOLARIS_PRIVS */

		if (user != NULL) {
			if (isdigit((unsigned char)*user)) {
				sw_uid = (uid_t)strtoul(user, &endp, 0);
				if (*endp != '\0')
					goto getuser;

				if ((pw = getpwuid(sw_uid)) != NULL) {
					free(user);
					user = estrdup(pw->pw_name);
					sw_gid = pw->pw_gid;
				} else {
					errno = 0;
					msyslog(LOG_ERR, "Cannot find user ID %s", user);
					exit (-1);
				}

			} else {
getuser:
				errno = 0;
				if ((pw = getpwnam(user)) != NULL) {
					sw_uid = pw->pw_uid;
					sw_gid = pw->pw_gid;
				} else {
					if (errno)
						msyslog(LOG_ERR, "getpwnam(%s) failed: %m", user);
					else
						msyslog(LOG_ERR, "Cannot find user `%s'", user);
					exit (-1);
				}
			}
		}
		if (group != NULL) {
			if (isdigit((unsigned char)*group)) {
				sw_gid = (gid_t)strtoul(group, &endp, 0);
				if (*endp != '\0')
					goto getgroup;
			} else {
getgroup:
				if ((gr = getgrnam(group)) != NULL) {
					sw_gid = gr->gr_gid;
				} else {
					errno = 0;
					msyslog(LOG_ERR, "Cannot find group `%s'", group);
					exit (-1);
				}
			}
		}

		if (chrootdir ) {
			/* make sure cwd is inside the jail: */
			if (chdir(chrootdir)) {
				msyslog(LOG_ERR, "Cannot chdir() to `%s': %m", chrootdir);
				exit (-1);
			}
			if (chroot(chrootdir)) {
				msyslog(LOG_ERR, "Cannot chroot() to `%s': %m", chrootdir);
				exit (-1);
			}
			if (chdir("/")) {
				msyslog(LOG_ERR, "Cannot chdir() to`root after chroot(): %m");
				exit (-1);
			}
		}
#  ifdef HAVE_SOLARIS_PRIVS
		if ((lowprivs = priv_str_to_set(LOWPRIVS, ",", NULL)) == NULL) {
			msyslog(LOG_ERR, "priv_str_to_set() failed:%m");
			exit(-1);
		}
		if ((highprivs = priv_allocset()) == NULL) {
			msyslog(LOG_ERR, "priv_allocset() failed:%m");
			exit(-1);
		}
		(void) getppriv(PRIV_PERMITTED, highprivs);
		(void) priv_intersect(highprivs, lowprivs);
		if (setppriv(PRIV_SET, PRIV_PERMITTED, lowprivs) == -1) {
			msyslog(LOG_ERR, "setppriv() failed:%m");
			exit(-1);
		}
#  endif /* HAVE_SOLARIS_PRIVS */
		if (user && initgroups(user, sw_gid)) {
			msyslog(LOG_ERR, "Cannot initgroups() to user `%s': %m", user);
			exit (-1);
		}
		if (group && setgid(sw_gid)) {
			msyslog(LOG_ERR, "Cannot setgid() to group `%s': %m", group);
			exit (-1);
		}
		if (group && setegid(sw_gid)) {
			msyslog(LOG_ERR, "Cannot setegid() to group `%s': %m", group);
			exit (-1);
		}
		if (group) {
			if (0 != setgroups(1, &sw_gid)) {
				msyslog(LOG_ERR, "setgroups(1, %d) failed: %m", sw_gid);
				exit (-1);
			}
		}
		else if (pw)
			if (0 != initgroups(pw->pw_name, pw->pw_gid)) {
				msyslog(LOG_ERR, "initgroups(<%s>, %d) filed: %m", pw->pw_name, pw->pw_gid);
				exit (-1);
			}
		if (user && setuid(sw_uid)) {
			msyslog(LOG_ERR, "Cannot setuid() to user `%s': %m", user);
			exit (-1);
		}
		if (user && seteuid(sw_uid)) {
			msyslog(LOG_ERR, "Cannot seteuid() to user `%s': %m", user);
			exit (-1);
		}

#  if !defined(HAVE_LINUX_CAPABILITIES) && !defined(HAVE_SOLARIS_PRIVS)
		/*
		 * for now assume that the privilege to bind to privileged ports
		 * is associated with running with uid 0 - should be refined on
		 * ports that allow binding to NTP_PORT with uid != 0
		 */
		disable_dynamic_updates |= (sw_uid != 0);  /* also notifies routing message listener */
#  endif /* !HAVE_LINUX_CAPABILITIES && !HAVE_SOLARIS_PRIVS */

		if (disable_dynamic_updates && interface_interval) {
			interface_interval = 0;
			msyslog(LOG_INFO, "running as non-root disables dynamic interface tracking");
		}

#  ifdef HAVE_LINUX_CAPABILITIES
		{
			/*
			 *  We may be running under non-root uid now, but we still hold full root privileges!
			 *  We drop all of them, except for the crucial one or two: cap_sys_time and
			 *  cap_net_bind_service if doing dynamic interface tracking.
			 */
			cap_t caps;
			char *captext;
			
			captext = (0 != interface_interval)
				      ? "cap_sys_time,cap_net_bind_service=pe"
				      : "cap_sys_time=pe";
			caps = cap_from_text(captext);
			if (!caps) {
				msyslog(LOG_ERR,
					"cap_from_text(%s) failed: %m",
					captext);
				exit(-1);
			}
			if (-1 == cap_set_proc(caps)) {
				msyslog(LOG_ERR,
					"cap_set_proc() failed to drop root privs: %m");
				exit(-1);
			}
			cap_free(caps);
		}
#  endif	/* HAVE_LINUX_CAPABILITIES */
#  ifdef HAVE_SOLARIS_PRIVS
		if (priv_delset(lowprivs, "proc_setid") == -1) {
			msyslog(LOG_ERR, "priv_delset() failed:%m");
			exit(-1);
		}
		if (setppriv(PRIV_SET, PRIV_PERMITTED, lowprivs) == -1) {
			msyslog(LOG_ERR, "setppriv() failed:%m");
			exit(-1);
		}
		priv_freeset(lowprivs);
		priv_freeset(highprivs);
#  endif /* HAVE_SOLARIS_PRIVS */
		root_dropped = TRUE;
		fork_deferred_worker();
	}	/* if (droproot) */
# endif	/* HAVE_DROPROOT */

/* libssecomp sandboxing */
#if defined (LIBSECCOMP) && (KERN_SECCOMP)
	scmp_filter_ctx ctx;

	if ((ctx = seccomp_init(SCMP_ACT_KILL)) < 0)
		msyslog(LOG_ERR, "%s: seccomp_init(SCMP_ACT_KILL) failed: %m", __func__);
	else {
		msyslog(LOG_DEBUG, "%s: seccomp_init(SCMP_ACT_KILL) succeeded", __func__);
	}

#ifdef __x86_64__
int scmp_sc[] = {
	SCMP_SYS(adjtimex),
	SCMP_SYS(bind),
	SCMP_SYS(brk),
	SCMP_SYS(chdir),
	SCMP_SYS(clock_gettime),
	SCMP_SYS(clock_settime),
	SCMP_SYS(close),
	SCMP_SYS(connect),
	SCMP_SYS(exit_group),
	SCMP_SYS(fstat),
	SCMP_SYS(fsync),
	SCMP_SYS(futex),
	SCMP_SYS(getitimer),
	SCMP_SYS(getsockname),
	SCMP_SYS(ioctl),
	SCMP_SYS(lseek),
	SCMP_SYS(madvise),
	SCMP_SYS(mmap),
	SCMP_SYS(munmap),
	SCMP_SYS(open),
	SCMP_SYS(poll),
	SCMP_SYS(read),
	SCMP_SYS(recvmsg),
	SCMP_SYS(rename),
	SCMP_SYS(rt_sigaction),
	SCMP_SYS(rt_sigprocmask),
	SCMP_SYS(rt_sigreturn),
	SCMP_SYS(select),
	SCMP_SYS(sendto),
	SCMP_SYS(setitimer),
	SCMP_SYS(setsid),
	SCMP_SYS(socket),
	SCMP_SYS(stat),
	SCMP_SYS(time),
	SCMP_SYS(write),
};
#endif
#ifdef __i386__
int scmp_sc[] = {
	SCMP_SYS(_newselect),
	SCMP_SYS(adjtimex),
	SCMP_SYS(brk),
	SCMP_SYS(chdir),
	SCMP_SYS(clock_gettime),
	SCMP_SYS(clock_settime),
	SCMP_SYS(close),
	SCMP_SYS(exit_group),
	SCMP_SYS(fsync),
	SCMP_SYS(futex),
	SCMP_SYS(getitimer),
	SCMP_SYS(madvise),
	SCMP_SYS(mmap),
	SCMP_SYS(mmap2),
	SCMP_SYS(munmap),
	SCMP_SYS(open),
	SCMP_SYS(poll),
	SCMP_SYS(read),
	SCMP_SYS(rename),
	SCMP_SYS(rt_sigaction),
	SCMP_SYS(rt_sigprocmask),
	SCMP_SYS(select),
	SCMP_SYS(setitimer),
	SCMP_SYS(setsid),
	SCMP_SYS(sigprocmask),
	SCMP_SYS(sigreturn),
	SCMP_SYS(socketcall),
	SCMP_SYS(stat64),
	SCMP_SYS(time),
	SCMP_SYS(write),
};
#endif
	{
		int i;

		for (i = 0; i < COUNTOF(scmp_sc); i++) {
			if (seccomp_rule_add(ctx,
			    SCMP_ACT_ALLOW, scmp_sc[i], 0) < 0) {
				msyslog(LOG_ERR,
				    "%s: seccomp_rule_add() failed: %m",
				    __func__);
			}
		}
	}

	if (seccomp_load(ctx) < 0)
		msyslog(LOG_ERR, "%s: seccomp_load() failed: %m",
		    __func__);	
	else {
		msyslog(LOG_DEBUG, "%s: seccomp_load() succeeded", __func__);
	}
#endif /* LIBSECCOMP and KERN_SECCOMP */

# ifdef HAVE_IO_COMPLETION_PORT

	for (;;) {
		GetReceivedBuffers();
# else /* normal I/O */

	BLOCK_IO_AND_ALARM();
	was_alarmed = FALSE;

	for (;;) {
		if (alarm_flag) {	/* alarmed? */
			was_alarmed = TRUE;
			alarm_flag = FALSE;
		}

		if (!was_alarmed && !has_full_recv_buffer()) {
			/*
			 * Nothing to do.  Wait for something.
			 */
			io_handler();
		}

		if (alarm_flag) {	/* alarmed? */
			was_alarmed = TRUE;
			alarm_flag = FALSE;
		}

		if (was_alarmed) {
			UNBLOCK_IO_AND_ALARM();
			/*
			 * Out here, signals are unblocked.  Call timer routine
			 * to process expiry.
			 */
			timer();
			was_alarmed = FALSE;
			BLOCK_IO_AND_ALARM();
		}

# endif		/* !HAVE_IO_COMPLETION_PORT */

# ifdef DEBUG_TIMING
		{
			l_fp pts;
			l_fp tsa, tsb;
			int bufcount = 0;

			get_systime(&pts);
			tsa = pts;
# endif
			rbuf = get_full_recv_buffer();
			while (rbuf != NULL) {
				if (alarm_flag) {
					was_alarmed = TRUE;
					alarm_flag = FALSE;
				}
				UNBLOCK_IO_AND_ALARM();

				if (was_alarmed) {
					/* avoid timer starvation during lengthy I/O handling */
					timer();
					was_alarmed = FALSE;
				}

				/*
				 * Call the data procedure to handle each received
				 * packet.
				 */
				if (rbuf->receiver != NULL) {
# ifdef DEBUG_TIMING
					l_fp dts = pts;

					L_SUB(&dts, &rbuf->recv_time);
					DPRINTF(2, ("processing timestamp delta %s (with prec. fuzz)\n", lfptoa(&dts, 9)));
					collect_timing(rbuf, "buffer processing delay", 1, &dts);
					bufcount++;
# endif
					(*rbuf->receiver)(rbuf);
				} else {
					msyslog(LOG_ERR, "fatal: receive buffer callback NULL");
					abort();
				}

				BLOCK_IO_AND_ALARM();
				freerecvbuf(rbuf);
				rbuf = get_full_recv_buffer();
			}
# ifdef DEBUG_TIMING
			get_systime(&tsb);
			L_SUB(&tsb, &tsa);
			if (bufcount) {
				collect_timing(NULL, "processing", bufcount, &tsb);
				DPRINTF(2, ("processing time for %d buffers %s\n", bufcount, lfptoa(&tsb, 9)));
			}
		}
# endif

		/*
		 * Go around again
		 */

# ifdef HAVE_DNSREGISTRATION
		if (mdnsreg && (current_time - mdnsreg ) > 60 && mdnstries && sys_leap != LEAP_NOTINSYNC) {
			mdnsreg = current_time;
			msyslog(LOG_INFO, "Attempting to register mDNS");
			if ( DNSServiceRegister (&mdns, 0, 0, NULL, "_ntp._udp", NULL, NULL, 
			    htons(NTP_PORT), 0, NULL, NULL, NULL) != kDNSServiceErr_NoError ) {
				if (!--mdnstries) {
					msyslog(LOG_ERR, "Unable to register mDNS, giving up.");
				} else {	
					msyslog(LOG_INFO, "Unable to register mDNS, will try later.");
				}
			} else {
				msyslog(LOG_INFO, "mDNS service registered.");
				mdnsreg = FALSE;
			}
		}
# endif /* HAVE_DNSREGISTRATION */

	}
	UNBLOCK_IO_AND_ALARM();
	return 1;
}
#endif	/* !SIM */


#if !defined(SIM) && defined(SIGDIE1)
/*
 * finish - exit gracefully
 */
static RETSIGTYPE
finish(
	int sig
	)
{
	const char *sig_desc;

	sig_desc = NULL;
#ifdef HAVE_STRSIGNAL
	sig_desc = strsignal(sig);
#endif
	if (sig_desc == NULL)
		sig_desc = "";
	msyslog(LOG_NOTICE, "%s exiting on signal %d (%s)", progname,
		sig, sig_desc);
	/* See Bug 2513 and Bug 2522 re the unlink of PIDFILE */
# ifdef HAVE_DNSREGISTRATION
	if (mdns != NULL)
		DNSServiceRefDeallocate(mdns);
# endif
	peer_cleanup();
	exit(0);
}
#endif	/* !SIM && SIGDIE1 */


#ifndef SIM
/*
 * wait_child_sync_if - implements parent side of -w/--wait-sync
 */
# ifdef HAVE_WORKING_FORK
static int
wait_child_sync_if(
	int	pipe_read_fd,
	long	wait_sync
	)
{
	int	rc;
	int	exit_code;
	time_t	wait_end_time;
	time_t	cur_time;
	time_t	wait_rem;
	fd_set	readset;
	struct timeval wtimeout;

	if (0 == wait_sync) 
		return 0;

	/* waitsync_fd_to_close used solely by child */
	close(waitsync_fd_to_close);
	wait_end_time = time(NULL) + wait_sync;
	do {
		cur_time = time(NULL);
		wait_rem = (wait_end_time > cur_time)
				? (wait_end_time - cur_time)
				: 0;
		wtimeout.tv_sec = wait_rem;
		wtimeout.tv_usec = 0;
		FD_ZERO(&readset);
		FD_SET(pipe_read_fd, &readset);
		rc = select(pipe_read_fd + 1, &readset, NULL, NULL,
			    &wtimeout);
		if (-1 == rc) {
			if (EINTR == errno)
				continue;
			exit_code = (errno) ? errno : -1;
			msyslog(LOG_ERR,
				"--wait-sync select failed: %m");
			return exit_code;
		}
		if (0 == rc) {
			/*
			 * select() indicated a timeout, but in case
			 * its timeouts are affected by a step of the
			 * system clock, select() again with a zero 
			 * timeout to confirm.
			 */
			FD_ZERO(&readset);
			FD_SET(pipe_read_fd, &readset);
			wtimeout.tv_sec = 0;
			wtimeout.tv_usec = 0;
			rc = select(pipe_read_fd + 1, &readset, NULL,
				    NULL, &wtimeout);
			if (0 == rc)	/* select() timeout */
				break;
			else		/* readable */
				return 0;
		} else			/* readable */
			return 0;
	} while (wait_rem > 0);

	fprintf(stderr, "%s: -w/--wait-sync %ld timed out.\n",
		progname, wait_sync);
	return ETIMEDOUT;
}
Beispiel #12
0
void 
post_args(_U_ int argc, _U_ char *argv[])
{
    char ebuf[SENDPACKET_ERRBUF_SIZE];
    struct tcpr_ether_addr *eth_buff;
    char *intname;
    sendpacket_t *sp;
#ifdef ENABLE_PCAP_FINDALLDEVS
    interface_list_t *intlist = get_interface_list();
#else
    interface_list_t *intlist = NULL;
#endif
    
#ifdef DEBUG
    if (HAVE_OPT(DBUG))
        debug = OPT_VALUE_DBUG;
#else
    if (HAVE_OPT(DBUG))
        warn("not configured with --enable-debug.  Debugging disabled.");
#endif
    

#ifdef ENABLE_VERBOSE
    if (HAVE_OPT(VERBOSE))
        options.verbose = 1;
    
    if (HAVE_OPT(DECODE))
        options.tcpdump->args = safe_strdup(OPT_ARG(DECODE));
    
#endif

    if (HAVE_OPT(UNIDIR))
        options.unidir = 1;

    if (HAVE_OPT(LIMIT))
        options.limit_send = OPT_VALUE_LIMIT; /* default is -1 */


    if ((intname = get_interface(intlist, OPT_ARG(INTF1))) == NULL)
        errx(-1, "Invalid interface name/alias: %s", OPT_ARG(INTF1));
    
    options.intf1 = safe_strdup(intname);

    if (HAVE_OPT(INTF2)) {
        if ((intname = get_interface(intlist, OPT_ARG(INTF2))) == NULL)
            errx(-1, "Invalid interface name/alias: %s", OPT_ARG(INTF2));
    
        options.intf2 = safe_strdup(intname);
    }
    

    if (HAVE_OPT(MAC)) {
        int ct = STACKCT_OPT(MAC);
        char **list = STACKLST_OPT(MAC);
        int first = 1;
        do {
            char *p = *list++;
            if (first)
                mac2hex(p, (u_char *)options.intf1_mac, ETHER_ADDR_LEN);
            else
                mac2hex(p, (u_char *)options.intf2_mac, ETHER_ADDR_LEN);
            first = 0;
        } while (--ct > 0);
    }

    /* 
     * Figure out MAC addresses of sending interface(s)
     * if user doesn't specify MAC address on CLI, query for it 
     */
    if (memcmp(options.intf1_mac, "\00\00\00\00\00\00", ETHER_ADDR_LEN) == 0) {
        if ((sp = sendpacket_open(NULL, options.intf1, ebuf, TCPR_DIR_C2S)) == NULL)
            errx(-1, "Unable to open interface %s: %s", options.intf1, ebuf);

        if ((eth_buff = sendpacket_get_hwaddr(sp)) == NULL) {
            warnx("Unable to get MAC address: %s", sendpacket_geterr(sp));
            err(-1, "Please consult the man page for using the -M option.");
        }
        sendpacket_close(sp);
        memcpy(options.intf1_mac, eth_buff, ETHER_ADDR_LEN);
    }

    if (memcmp(options.intf2_mac, "\00\00\00\00\00\00", ETHER_ADDR_LEN) == 0) {
        if ((sp = sendpacket_open(NULL, options.intf2, ebuf, TCPR_DIR_S2C)) == NULL)
            errx(-1, "Unable to open interface %s: %s", options.intf2, ebuf);

        if ((eth_buff = sendpacket_get_hwaddr(sp)) == NULL) {
            warnx("Unable to get MAC address: %s", sendpacket_geterr(sp));
            err(-1, "Please consult the man page for using the -M option.");
        }
        sendpacket_close(sp);
        memcpy(options.intf2_mac, eth_buff, ETHER_ADDR_LEN);        
    }

    /* 
     * Open interfaces for sending & receiving 
     */
    if ((options.pcap1 = pcap_open_live(options.intf1, options.snaplen, 
                                          options.promisc, options.to_ms, ebuf)) == NULL)
        errx(-1, "Unable to open interface %s: %s", options.intf1, ebuf);


    if (strcmp(options.intf1, options.intf2) == 0)
        errx(-1, "Whoa tiger!  You don't want to use %s twice!", options.intf1);


    /* we always have to open the other pcap handle to send, but we may not listen */
    if ((options.pcap2 = pcap_open_live(options.intf2, options.snaplen,
                                          options.promisc, options.to_ms, ebuf)) == NULL)
        errx(-1, "Unable to open interface %s: %s", options.intf2, ebuf);
    
    /* poll should be -1 to wait indefinitely */
    options.poll_timeout = -1;
}
Beispiel #13
0
/**
 *  Figure out what to use as the base name of the output file.
 *  If an argument is not provided, we use the base name of
 *  the definitions file.
 */
static void
open_output(tOutSpec * spec)
{
    static char const write_mode[] = "w" FOPEN_BINARY_FLAG "+";

    char const * out_file = NULL;

    if (strcmp(spec->zSuffix, OPEN_OUTPUT_NULL) == 0) {
        static int const flags = FPF_NOUNLINK | FPF_NOCHMOD | FPF_TEMPFILE;
    null_open:
        open_output_file(DEV_NULL, DEV_NULL_LEN, write_mode, flags);
        return;
    }

    /*
     *  IF we are to skip the current suffix,
     *  we will redirect the output to /dev/null and
     *  perform all the work.  There may be side effects.
     */
    if (HAVE_OPT(SKIP_SUFFIX)) {
        int     ct  = STACKCT_OPT(SKIP_SUFFIX);
        const char ** ppz = STACKLST_OPT(SKIP_SUFFIX);

        while (--ct >= 0) {
            if (strcmp(spec->zSuffix, *ppz++) == 0)
                goto null_open;
        }
    }

    /*
     *  Remove any suffixes in the last file name
     */
    {
        char const * def_file = OPT_ARG(BASE_NAME);
        char   z[AG_PATH_MAX];
        const char * pst = strrchr(def_file, '/');
        char * end;

        pst = (pst == NULL) ? def_file : (pst + 1);

        /*
         *  We allow users to specify a suffix with '-' and '_', but when
         *  stripping a suffix from the "base name", we do not recognize 'em.
         */
        end = strchr(pst, '.');
        if (end != NULL) {
            size_t len = (unsigned)(end - pst);
            if (len >= sizeof(z))
                AG_ABEND("--base-name name is too long");

            memcpy(z, pst, len);
            z[ end - pst ] = NUL;
            pst = z;
        }

        /*
         *  Now formulate the output file name in the buffer
         *  provided as the input argument.
         */
        out_file = aprf(spec->pzFileFmt, pst, spec->zSuffix);
        if (out_file == NULL)
            AG_ABEND(aprf(OPEN_OUTPUT_BAD_FMT, spec->pzFileFmt, pst,
                          spec->zSuffix));
    }

    open_output_file(out_file, strlen(out_file), write_mode, 0);
    free((void *)out_file);
}
Beispiel #14
0
int init(void)
{

  int ct = 0;
  char **input;
  char **host, **port, **user, **pwd, **thr;
  int i = 0;
#ifndef USE_ST
  struct sigaction new_action;

  new_action.sa_handler = sigalarm_handler;
  sigemptyset (&new_action.sa_mask);
  new_action.sa_flags = 0;
  sigaction (SIGALRM, &new_action, NULL);
#endif

  hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, queue_free);

  if (!HAVE_OPT(THREADS)) {
    fprintf(stderr, "missing threads option\n");
    return 0;
  }
  if (!HAVE_OPT(INPUT)) {
    fprintf(stderr, "missing input option\n");
    return 0;
  }

  ct    = STACKCT_OPT( INPUT );
  input = (char **) &STACKLST_OPT(INPUT);
  host  = (char **) &STACKLST_OPT(HOST);
  port  = (char **) &STACKLST_OPT(PORT);
  user  = (char **) &STACKLST_OPT(UWUSER);
  pwd   = (char **) &STACKLST_OPT(UWPASSWD);
  thr   = (char **) &STACKLST_OPT(THREADS);

  // read in options for queuing
  for (i=0; input[i] && i < ct && i < 4; i++) {
    struct q_info *q = g_hash_table_lookup(hash, input[i]);
    char buf[256];

    if (q == NULL) {
      q = g_malloc0(sizeof(struct q_info));
      q->name = strdup(input[i]);
      g_hash_table_insert(hash, strdup(input[i]), q);
    }

    if (!host || !host[i]) {
      fprintf(stderr, "missing host option for input %s\n", input[i]);
      return 0;
    } else if (strcmp(host[i], "none") == 0) {
      g_hash_table_remove(hash, host[i]);
      continue;
    }
    if (!port || !port[i]) {
      fprintf(stderr, "missing port option for input queue %s\n", input[i]);
      return 0;
    }
    if (!user || !user[i]) {
      fprintf(stderr, "missing uwuser option for input queue %s\n", input[i]);
      return 0;
    }
    if (!pwd || !pwd[i]) {
      fprintf(stderr, "missing uwpasswd option for input %s\n", input[i]);
      return 0;
    }
    if (q->host) g_free(q->host);
    if (q->user) g_free(q->user);
    if (q->pwd)  g_free(q->pwd);
    q->host = strdup(host[i]);
    q->port = atoi(port[i]);
    strcpy(buf, user[i]); // preset
    if (!strchr(user[i], '@') && HAVE_OPT(REALM)) {
      sprintf(buf, "%s@%s", user[i], OPT_ARG(REALM));
    }
    q->user = strdup(buf);
    q->pwd = strdup(pwd[i]);
    q->maxthreads = thr[i] ? atoi(thr[i]) : 1;
  }
  if (HAVE_OPT(ONCE)) {
    every = ONE_SHOT;
    daemonize = FALSE;
  } else {
    daemonize = TRUE;
    every = EVERY_5SECS;
  }
  xmlSetGenericErrorFunc(NULL, UpwatchXmlGenericErrorFunc);
  return(1);
}
Beispiel #15
0
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *   MAIN
 */
int
main(int argc, char ** argv)
{
    FILE* outFp;

    optionProcess(&getdefsOptions, argc, argv);
    validateOptions();

    outFp = startAutogen();

    doPreamble(outFp);

    /*
     *  Process each input file
     */
    {
        int    ct  = STACKCT_OPT(INPUT);
        char const ** ppz = STACKLST_OPT(INPUT);

        do  {
            processFile(*ppz++);
        } while (--ct > 0);
    }

    /*
     *  IF we don't have an ordering file, but we do have a "first index",
     *  THEN alphabetize by definition name.
     */
    if ((pzIndexText == NULL) && HAVE_OPT(FIRST_INDEX)) {
        qsort((void*)papzBlocks, blkUseCt, sizeof(char*), compar_defname);
        set_first_idx();
    }

    else if (ENABLED_OPT(ORDERING) && (blkUseCt > 1))
        qsort((void*)papzBlocks, blkUseCt, sizeof(char*), &compar_text);

    printEntries(outFp);
    fclose(outFp);

    /*
     *  IF output is to a file
     *  THEN set the permissions and modification times
     */
    if (  (WHICH_IDX_AUTOGEN == INDEX_OPT_OUTPUT)
       && (outFp != stdout) )  {
        struct utimbuf tbuf;
        tbuf.actime  = time((time_t*)NULL);
        tbuf.modtime = modtime + 1;
        utime(OPT_ARG(OUTPUT), &tbuf);
        chmod(OPT_ARG(OUTPUT), S_IRUSR|S_IRGRP|S_IROTH);
    }

    /*
     *  IF we are keeping a database of indexes
     *     AND we have augmented the contents,
     *  THEN append the new entries to the file.
     */
    if ((pzIndexText != NULL) && (pzEndIndex != pzIndexEOF))
        updateDatabase();

    if (agPid != -1)
        return awaitAutogen();

    return EXIT_SUCCESS;
}
Beispiel #16
0
/*
 *  doPreamble
 */
static void
doPreamble(FILE* outFp)
{
    /*
     *  Emit the "autogen definitions xxx;" line
     */
    fprintf(outFp, zAgDef, OPT_ARG(TEMPLATE));

    if (HAVE_OPT(FILELIST)) {
        static char const zFmt[] = "%-12s = '%s';\n";
        char const * pzName = OPT_ARG(FILELIST);

        if ((pzName == NULL) || (*pzName == NUL))
            pzName = "infile";

        if (HAVE_OPT(INPUT)) {
            int    ct  = STACKCT_OPT(INPUT);
            char const ** ppz = STACKLST_OPT(INPUT);

            do  {
                fprintf(outFp, zFmt, pzName, *ppz++);
            } while (--ct > 0);
        }

        if (HAVE_OPT(COPY)) {
            int    ct  = STACKCT_OPT(COPY);
            char const ** ppz = STACKLST_OPT(COPY);

            do  {
                fprintf(outFp, zFmt, pzName, *ppz++);
            } while (--ct > 0);
        }
        fputc('\n', outFp);
    }

    /*
     *  IF there are COPY files to be included,
     *  THEN emit the '#include' directives
     */
    if (HAVE_OPT(COPY)) {
        int    ct  = STACKCT_OPT(COPY);
        char const ** ppz = STACKLST_OPT(COPY);
        do  {
            fprintf(outFp, "#include %s\n", *ppz++);
        } while (--ct > 0);
        fputc('\n', outFp);
    }

    /*
     *  IF there are global assignments, then emit them
     *  (these do not get sorted, so we write directly now.)
     */
    if (HAVE_OPT(ASSIGN)) {
        int    ct  = STACKCT_OPT(ASSIGN);
        char const ** ppz = STACKLST_OPT(ASSIGN);
        do  {
            fprintf(outFp, "%s;\n", *ppz++);
        } while (--ct > 0);
        fputc('\n', outFp);
    }
}
Beispiel #17
0
/*
 *  buildDefinition
 */
static void
buildDefinition(char * pzDef, char const * pzFile, int line, char * pzOut)
{
    static char const zSrcFile[] = "    %s = '%s';\n";
    static char const zLineNum[] = "    %s = '%d';\n";

    ag_bool    these_are_global_defs;
    tSuccess   preamble;
    int        re_res;
    char*      pzNextDef = NULL;
    regmatch_t match[2];

    if (*pzDef == '*') {
        these_are_global_defs = AG_TRUE;
        strcpy(pzOut, zGlobal);
        pzOut += sizeof(zGlobal)-1;
        pzOut += sprintf(pzOut, zLineId, line, pzFile);

        pzDef = strchr(pzDef, '\n');
        preamble = PROBLEM;

    } else {
        these_are_global_defs = AG_FALSE;
        preamble = buildPreamble(&pzDef, &pzOut, pzFile, line);
        if (FAILED(preamble)) {
            *pzOut = NUL;
            return;
        }
    }

    /*
     *  FOR each attribute for this entry, ...
     */
    for (;;) {
        /*
         *  Find the next attribute regular expression
         */
        re_res = regexec(&attrib_re, pzDef, COUNT(match), match, 0);
        switch (re_res) {
        case 0:
            /*
             *  NUL-terminate the current attribute.
             *  Set the "next" pointer to the start of the next attribute name.
             */
            pzDef[ match[0].rm_so ] = NUL;
            if (pzNextDef != NULL)
                pzOut = emitDefinition(pzNextDef, pzOut);
            pzNextDef = pzDef = pzDef + match[1].rm_so;
            break;

        case REG_NOMATCH:
            /*
             *  No more attributes.
             */
            if (pzNextDef == NULL) {
                *pzOut++ = '\n'; *pzOut++ = '#';
                sprintf(pzOut,  zNoData, pzFile, line);
                fputs(pzOut, stderr);
                pzOut += strlen(pzOut);
                return;
            }

            pzOut = emitDefinition(pzNextDef, pzOut);
            goto eachAttrDone;
            break;

        default:
        {
            char zRER[ MAXNAMELEN ];
            static char const zErr[] = "error %d (%s) finding `%s' in\n%s\n\n";
            regerror(re_res, &attrib_re, zRER, sizeof(zRER));
            *pzOut++ = '\n';
            *pzOut++ = '#';
            sprintf(pzOut, zErr, re_res, zRER, zAttribRe, pzDef);
            fprintf(stderr, "getdefs:  %s", zErr);
            return;
        }
        }
    } eachAttrDone:;

    if (these_are_global_defs) {
        *pzOut = NUL;
        return;
    }

    if (HAVE_OPT(COMMON_ASSIGN)) {
        int    ct  = STACKCT_OPT(COMMON_ASSIGN);
        char const ** ppz = STACKLST_OPT(COMMON_ASSIGN);
        do  {
            pzOut += sprintf(pzOut, "    %s;\n", *ppz++);
        } while (--ct > 0);
    }

    if (HAVE_OPT(SRCFILE))
        pzOut += sprintf(pzOut, zSrcFile, OPT_ARG(SRCFILE), pzFile);

    if (HAVE_OPT(LINENUM))
        pzOut += sprintf(pzOut, zLineNum, OPT_ARG(LINENUM), line);

    /*
     *  IF the preamble had a problem, it is because it could not
     *  emit the final "#endif\n" directive.  Do that now.
     */
    if (HADGLITCH(preamble))
         strcpy(pzOut, "};\n#endif\n");
    else strcpy(pzOut, "};\n");
}
Beispiel #18
0
/**
 *  validateOptions
 *
 *  -  Sanity check the options
 *  -  massage the SUBBLOCK options into something
 *     more easily used during the source text processing.
 *  -  compile the regular expressions
 *  -  make sure we can find all the input files and their mod times
 *  -  Set up our entry ordering database (if specified)
 *  -  Make sure we have valid strings for SRCFILE and LINENUM
 *     (if we are to use these things).
 *  -  Initialize the user name characters array.
 */
LOCAL void
validateOptions(void)
{
    set_define_re();

    /*
     *  Prepare each sub-block entry so we can parse easily later.
     */
    if (HAVE_OPT(SUBBLOCK)) {
        int     ct  = STACKCT_OPT( SUBBLOCK);
        tCC**   ppz = STACKLST_OPT(SUBBLOCK);

        /*
         *  FOR each SUBBLOCK argument,
         *  DO  condense each name list to be a list of names
         *      separated by a single space and NUL terminated.
         */
        do  {
            *ppz = fixupSubblockString(*ppz);
            ppz++;
        } while (--ct > 0);
    }

    if (! HAVE_OPT(INPUT))
        SET_OPT_INPUT("-");

    set_modtime();

    /*
     *  IF the output is to have order AND it is to be based on a file,
     *  THEN load the contents of that file.
     *       IF we cannot load the file,
     *       THEN it must be new or empty.  Allocate several K to start.
     */
    if (  HAVE_OPT(ORDERING)
       && (OPT_ARG(ORDERING) != NULL)) {
        tSCC zIndexPreamble[] =
            "# -*- buffer-read-only: t -*- vi: set ro:\n"
            "#\n# DO NOT EDIT THIS FILE - it is auto-edited by getdefs\n";

        pzIndexText = loadFile(OPT_ARG(ORDERING));
        if (pzIndexText == NULL) {
            pzIndexText = pzEndIndex = pzIndexEOF = malloc((size_t)0x4000);
            indexAlloc = 0x4000;
            pzEndIndex += sprintf(pzEndIndex, "%s", zIndexPreamble);
        } else {
            pzEndIndex  = pzIndexEOF = pzIndexText + strlen(pzIndexText);
            indexAlloc = (pzEndIndex - pzIndexText) + 1;
        }

        /*
         *  We map the name entries to a connonical form.
         *  By default, everything is mapped to lower case already.
         *  This call will map these three characters to '_'.
         */
        strequate("_-^");
    }

    {
        char const * pz = OPT_ARG(SRCFILE);
        if ((pz == NULL) || (*pz == NUL))
            OPT_ARG(SRCFILE) = "srcfile";

        pz = OPT_ARG(LINENUM);
        if ((pz == NULL) || (*pz == NUL))
            OPT_ARG(LINENUM) = "linenum";
    }

    {
        tSCC zAgNameChars[] = "abcdefghijklmnopqrstuvwxyz"
            "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789" "_-^";
        tSCC zUserNameChs[] = ":.$%*!~<>&@";
        tCC* p = zAgNameChars;

        while (*p)
            zUserNameCh[(unsigned)(*p++)] = 3;

        p = zUserNameChs;
        while (*p)
            zUserNameCh[(unsigned)(*p++)] = 1;
    }
}
Beispiel #19
0
int init(void)
{
  struct sockaddr_in from, to;
  const char *msg;
  int i, idx;
  FILE *in;

  if (!HAVE_OPT(OUTPUT)) {
    LOG(LOG_ERR, "missing output option");
    return 0;
  }
  if (OPT_VALUE_SERVERID == 0) {
    fprintf(stderr, "Please set serverid first\n");
    return 0;
  }

  if (HAVE_OPT(ERRLOG)) {
    int ct  = STACKCT_OPT(ERRLOG);
    char **errlog = (char **) &STACKLST_OPT(ERRLOG);
    for (idx=0, i=0; i < ct && idx < 255; i++) {
      char *start, *end;
  
      start = end = errlog[i];
      while (*end && !isspace(*end)) {
        end++;
      }
      if (!*end) {
        LOG(LOG_WARNING, "Illegal format: %s", errlog[i]);
        continue;
      }
      *end++ = 0;
      errlogspec[idx].style = start;

      while (*end && isspace(*end)) {
        end++;
      }
      if (!*end) {
        LOG(LOG_WARNING, "Illegal format: %s", errlog[i]);
        continue;
      }
      start = end;
      while (*end && !isspace(*end)) {
        end++;
      }
      *end = 0;
      errlogspec[idx++].path = start;
    }
#if HAVE_LIBPCRE
    in = fopen(STATFILE, "r");
    if (in) {
      while (!feof(in)) {
        char path[PATH_MAX];
        long long offset;
        int i;

        if (fscanf(in, "%s %Ld", path, &offset) != 2) continue;
        for (i=0; errlogspec[i].path; i++) {
          if (strcmp(errlogspec[i].path, path)) continue;
          errlogspec[i].offset = offset;
          break;
        }
      }
      fclose(in);
    }
#endif
  }

#if USE_XMBMON
  if (OPT_VALUE_HWSTATS) {
    if (OPT_VALUE_TYAN_TIGER_MP) {
      TyanTigerMP_flag = 1;
    }
    if ((i = InitMBInfo(' ')) != 0) {
      LOG(LOG_ERR, "InitMBInfo: %m");
      if (i < 0) {
        LOG(LOG_ERR,"This program needs setuid root");
      }
    }
  } else {
    LOG(LOG_INFO,"Hardware stats will not be generated");
  }
#endif

  // determine ip address for default gateway interface
  setsin(&to, inet_addr("1.1.1.1"));
  msg = findsaddr(&to, &from);
  if (msg) {
    LOG(LOG_INFO, (char *)msg);
    strcpy(ipaddress, OPT_ARG(IPADDRESS));
  } else {
    strcpy(ipaddress, inet_ntoa(from.sin_addr)); 
  }
  LOG(LOG_INFO, "using ipaddress %s", ipaddress);

  daemonize = TRUE;
  every = EVERY_SECOND;
  xmlSetGenericErrorFunc(NULL, UpwatchXmlGenericErrorFunc);
  sleep(2); // ensure we wait until the next minute

  setpriority(PRIO_PROCESS, 0, 5); // we are not very important - be nice to other processes
  return 1;
}
Beispiel #20
0
/*
 * The actual main function.
 */
int
sntp_main (
	int argc,
	char **argv,
	const char *sntpVersion
	)
{
	int			i;
	int			exitcode;
	int			optct;
	struct event_config *	evcfg;

	/* Initialize logging system - sets up progname */
	sntp_init_logging(argv[0]);

	if (!libevent_version_ok())
		exit(EX_SOFTWARE);

	init_lib();
	init_auth();

	optct = ntpOptionProcess(&sntpOptions, argc, argv);
	argc -= optct;
	argv += optct;


	debug = OPT_VALUE_SET_DEBUG_LEVEL;

	TRACE(2, ("init_lib() done, %s%s\n",
		  (ipv4_works)
		      ? "ipv4_works "
		      : "",
		  (ipv6_works)
		      ? "ipv6_works "
		      : ""));
	ntpver = OPT_VALUE_NTPVERSION;
	steplimit = OPT_VALUE_STEPLIMIT / 1e3;
	gap.tv_usec = max(0, OPT_VALUE_GAP * 1000);
	gap.tv_usec = min(gap.tv_usec, 999999);

	if (HAVE_OPT(LOGFILE))
		open_logfile(OPT_ARG(LOGFILE));

	msyslog(LOG_INFO, "%s", sntpVersion);

	if (0 == argc && !HAVE_OPT(BROADCAST) && !HAVE_OPT(CONCURRENT)) {
		printf("%s: Must supply at least one of -b hostname, -c hostname, or hostname.\n",
		       progname);
		exit(EX_USAGE);
	}


	/*
	** Eventually, we probably want:
	** - separate bcst and ucst timeouts (why?)
	** - multiple --timeout values in the commandline
	*/

	response_timeout = OPT_VALUE_TIMEOUT;
	response_tv.tv_sec = response_timeout;
	response_tv.tv_usec = 0;

	/* IPv6 available? */
	if (isc_net_probeipv6() != ISC_R_SUCCESS) {
		ai_fam_pref = AF_INET;
		TRACE(1, ("No ipv6 support available, forcing ipv4\n"));
	} else {
		/* Check for options -4 and -6 */
		if (HAVE_OPT(IPV4))
			ai_fam_pref = AF_INET;
		else if (HAVE_OPT(IPV6))
			ai_fam_pref = AF_INET6;
	}

	/* TODO: Parse config file if declared */

	/*
	** Init the KOD system.
	** For embedded systems with no writable filesystem,
	** -K /dev/null can be used to disable KoD storage.
	*/
	kod_init_kod_db(OPT_ARG(KOD), FALSE);

	// HMS: Should we use arg-defalt for this too?
	if (HAVE_OPT(KEYFILE))
		auth_init(OPT_ARG(KEYFILE), &keys);

	/*
	** Considering employing a variable that prevents functions of doing
	** anything until everything is initialized properly
	**
	** HMS: What exactly does the above mean?
	*/
	event_set_log_callback(&sntp_libevent_log_cb);
	if (debug > 0)
		event_enable_debug_mode();
#ifdef WORK_THREAD
	evthread_use_pthreads();
	/* we use libevent from main thread only, locks should be academic */
	if (debug > 0)
		evthread_enable_lock_debuging();
#endif
	evcfg = event_config_new();
	if (NULL == evcfg) {
		printf("%s: event_config_new() failed!\n", progname);
		return -1;
	}
#ifndef HAVE_SOCKETPAIR
	event_config_require_features(evcfg, EV_FEATURE_FDS);
#endif
	/* all libevent calls are from main thread */
	/* event_config_set_flag(evcfg, EVENT_BASE_FLAG_NOLOCK); */
	base = event_base_new_with_config(evcfg);
	event_config_free(evcfg);
	if (NULL == base) {
		printf("%s: event_base_new() failed!\n", progname);
		return -1;
	}

	/* wire into intres resolver */
	worker_per_query = TRUE;
	addremove_io_fd = &sntp_addremove_fd;

	open_sockets();

	if (HAVE_OPT(BROADCAST)) {
		int		cn = STACKCT_OPT(  BROADCAST );
		const char **	cp = STACKLST_OPT( BROADCAST );

		while (cn-- > 0) {
			handle_lookup(*cp, CTX_BCST);
			cp++;
		}
	}

	if (HAVE_OPT(CONCURRENT)) {
		int		cn = STACKCT_OPT( CONCURRENT );
		const char **	cp = STACKLST_OPT( CONCURRENT );

		while (cn-- > 0) {
			handle_lookup(*cp, CTX_UCST | CTX_CONC);
			cp++;
		}
	}

	for (i = 0; i < argc; ++i)
		handle_lookup(argv[i], CTX_UCST);

	gettimeofday_cached(base, &start_tv);
	event_base_dispatch(base);
	event_base_free(base);

	if (!time_adjusted &&
	    (ENABLED_OPT(STEP) || ENABLED_OPT(SLEW)))
		exitcode = 1;
	else
		exitcode = 0;

	return exitcode;
}
Beispiel #21
0
void add_diskfree_info(xmlNodePtr node)
{
  float fullest = 0.0;
  char info[32768];
  int i, ignore;

  if (st.disk) {
    sg_fs_stats *disk_stat_ptr = st.disk;
    int counter;

    for (counter=0, ignore=0; counter < st.disk_entries; counter++){
      float use;

    if (HAVE_OPT( IGNOREDISKFREE )) {
        int     ct = STACKCT_OPT(  IGNOREDISKFREE );
        char**  pp = (char **) &STACKLST_OPT( IGNOREDISKFREE );

        do  {
            char* p = *pp++;
            if (strcmp(disk_stat_ptr->device_name, p) ==0 ) ignore=1;
        } while (--ct > 0);
    }

     if (ignore == 0 ) {
        use = 100.00 * ((float) disk_stat_ptr->used / (float) (disk_stat_ptr->used + disk_stat_ptr->avail));
        if (use > fullest) fullest = use;
      }
      ignore=0; /* Reset the ignore flag */
      disk_stat_ptr++; /* next partition please */
    }
  }

  if (fullest > OPT_VALUE_DISKFREE_YELLOW) { // if some disk is more then the yellow treshold full give `df` listing

    char cmd[1024];
    char buffer[24];
    FILE *in;

    if (fullest > OPT_VALUE_DISKFREE_YELLOW) sprintf(buffer, "%d", STAT_YELLOW);
    if (fullest > OPT_VALUE_DISKFREE_RED) sprintf(buffer, "%d", STAT_RED);
    xmlSetProp(node, "color", buffer);

    sprintf(cmd, "%s > /tmp/.uw_sysstat.tmp", OPT_ARG(DF_COMMAND));
    LOG(LOG_INFO, cmd);
    uw_setproctitle("running %s", OPT_ARG(DF_COMMAND));
    system(cmd);
    in = fopen("/tmp/.uw_sysstat.tmp", "r");
    if (in) {
      signed char *s = info;
      size_t len;

      for (len=0; len < sizeof(info)-1; len++) {
        int c;
        if ((c = fgetc(in)) != EOF) {
          if (c < 0) c = ' ';
          *s++ = c;
        }
      }
      *s = 0;
      fclose(in);
    } else {
      strcpy(info, strerror(errno));
    }
    unlink("/tmp/.uw_sysstat.tmp");
    xmlNewTextChild(node, NULL, "info", info);
  }

}
Beispiel #22
0
/*
 * main - parse arguments and handle options
 */
int
ntpdcmain(
	int argc,
	char *argv[]
	)
{
	extern int ntp_optind;

	delay_time.l_ui = 0;
	delay_time.l_uf = DEFDELAY;

#ifdef SYS_VXWORKS
	clear_globals();
	taskPrioritySet(taskIdSelf(), 100 );
#endif

	init_lib();	/* sets up ipv4_works, ipv6_works */
	ssl_applink();

	/* Check to see if we have IPv6. Otherwise default to IPv4 */
	if (!ipv6_works)
		ai_fam_default = AF_INET;

	progname = argv[0];

	{
		int optct = ntpOptionProcess(&ntpdcOptions, argc, argv);
		argc -= optct;
		argv += optct;
	}

	if (HAVE_OPT(IPV4))
		ai_fam_templ = AF_INET;
	else if (HAVE_OPT(IPV6))
		ai_fam_templ = AF_INET6;
	else
		ai_fam_templ = ai_fam_default;

	if (HAVE_OPT(COMMAND)) {
		int		cmdct = STACKCT_OPT( COMMAND );
		const char**	cmds  = STACKLST_OPT( COMMAND );

		while (cmdct-- > 0) {
			ADDCMD(*cmds++);
		}
	}

	debug = DESC(DEBUG_LEVEL).optOccCt;

	if (HAVE_OPT(INTERACTIVE)) {
		interactive = 1;
	}

	if (HAVE_OPT(NUMERIC)) {
		showhostnames = 0;
	}

	if (HAVE_OPT(LISTPEERS)) {
		ADDCMD("listpeers");
	}

	if (HAVE_OPT(PEERS)) {
		ADDCMD("peers");
	}

	if (HAVE_OPT(SHOWPEERS)) {
		ADDCMD("dmpeers");
	}

	if (ntp_optind == argc) {
		ADDHOST(DEFHOST);
	} else {
		for (; ntp_optind < argc; ntp_optind++)
		    ADDHOST(argv[ntp_optind]);
	}

	if (numcmds == 0 && interactive == 0
	    && isatty(fileno(stdin)) && isatty(fileno(stderr))) {
		interactive = 1;
	}

#if 0
	ai_fam_templ = ai_fam_default;
	while ((c = ntp_getopt(argc, argv, "46c:dilnps")) != EOF)
	    switch (c) {
		case '4':
		    ai_fam_templ = AF_INET;
		    break;
		case '6':
		    ai_fam_templ = AF_INET6;
		    break;
		case 'c':
		    ADDCMD(ntp_optarg);
		    break;
		case 'd':
		    ++debug;
		    break;
		case 'i':
		    interactive = 1;
		    break;
		case 'l':
		    ADDCMD("listpeers");
		    break;
		case 'n':
		    showhostnames = 0;
		    break;
		case 'p':
		    ADDCMD("peers");
		    break;
		case 's':
		    ADDCMD("dmpeers");
		    break;
		default:
		    errflg++;
		    break;
	    }

	if (errflg) {
		(void) fprintf(stderr,
			       "usage: %s [-46dilnps] [-c cmd] host ...\n",
			       progname);
		exit(2);
	}

	if (ntp_optind == argc) {
		ADDHOST(DEFHOST);
	} else {
		for (; ntp_optind < argc; ntp_optind++)
		    ADDHOST(argv[ntp_optind]);
	}

	if (numcmds == 0 && interactive == 0
	    && isatty(fileno(stdin)) && isatty(fileno(stderr))) {
		interactive = 1;
	}
#endif

#ifndef SYS_WINNT /* Under NT cannot handle SIGINT, WIN32 spawns a handler */
	if (interactive)
	    (void) signal_no_reset(SIGINT, abortcmd);
#endif /* SYS_WINNT */

	/*
	 * Initialize the packet data buffer
	 */
	pktdatasize = INITDATASIZE;
	pktdata = emalloc(INITDATASIZE);

	if (numcmds == 0) {
		(void) openhost(chosts[0]);
		getcmds();
	} else {
		int ihost;
		int icmd;

		for (ihost = 0; ihost < numhosts; ihost++) {
			if (openhost(chosts[ihost]))
			    for (icmd = 0; icmd < numcmds; icmd++) {
				    if (numhosts > 1) 
					printf ("--- %s ---\n",chosts[ihost]);
				    docmd(ccmds[icmd]);
			    }
		}
	}
#ifdef SYS_WINNT
	WSACleanup();
#endif
	return(0);
} /* main end */
Beispiel #23
0
int run(void)
{
  xmlDocPtr doc;
  xmlNodePtr node;
  int ct  = STACKCT_OPT(OUTPUT);
  char **output = (char **) &STACKLST_OPT(OUTPUT);
  GString *log;
  int i;
  int color;
  int highest_color = STAT_GREEN;
  char buf[24];
extern int forever;

  uw_setproctitle("sleeping");
  for (i=0; i < OPT_VALUE_INTERVAL; i++) { // wait some minutes
    sleep(1);
    if (!forever)  {
      return(0);
    }
  }

  uw_setproctitle("getting system statistics");
  get_stats();
  doc = UpwatchXmlDoc("result", NULL);
  xmlSetDocCompressMode(doc, OPT_VALUE_COMPRESS);

  // do the sysstat
  node = (xmlNodePtr) newnode(doc, "sysstat");
  add_loadavg(node);
  add_cpu(node);
  add_paging(node);
  add_blockio(node);
  add_swap(node);
  add_memory(node);
  add_systemp(node);
  add_sysstat_info(node);
  color = xmlGetPropInt(node, "color");
  if (color > highest_color) highest_color = color;
#if USE_XMBMON|| defined (__OpenBSD__)
  if (OPT_VALUE_HWSTATS ) { 
    // do the hwstat
    get_hwstats();
    node = (xmlNodePtr) newnode(doc, "hwstat");
    add_hwstat(node);
    color = xmlGetPropInt(node, "color");
    if (color > highest_color) highest_color = color;
  }
#endif
  if (OPT_VALUE_LOCALCHECKS ) { 
   // do the local checks
    color = do_local((xmlNodePtr) doc);
    if (color > highest_color) highest_color = color;
  }

#if HAVE_LIBPCRE
  // do the errlog
  node = (xmlNodePtr) newnode(doc, "errlog");
  log = check_logs(&color);
  if (color > highest_color) highest_color = color;
  sprintf(buf, "%u", color);
  xmlSetProp(node, "color", buf);
  if (log) {
    if (log->str && strlen(log->str) > 0) {
      xmlNewTextChild(node, NULL, "info", log->str);
    }
    g_string_free(log, TRUE);
  }
#endif

  // do the diskfree
  uw_setproctitle("checking diskspace");
  node = (xmlNodePtr) newnode(doc, "diskfree");
  add_diskfree_info(node);
  color = xmlGetPropInt(node, "color");

  if (color > highest_color) highest_color = color;

  if (HAVE_OPT(HPQUEUE) && (highest_color != prv_highest_color)) {
    // if status changed, it needs to be sent immediately. So drop into
    // the high priority queue. Else just drop in the normal queue where
    // uw_send in batched mode will pick it up later
    spool_result(OPT_ARG(SPOOLDIR), OPT_ARG(HPQUEUE), doc, NULL);
  } else {
    for (i=0; i < ct; i++) {
      spool_result(OPT_ARG(SPOOLDIR), output[i], doc, NULL);
    }
  }
  prv_highest_color = highest_color; // remember for next time
  xmlFreeDoc(doc);
  return 0;
}
Beispiel #24
0
/*
 * getCmdOpts - get command line options
 */
void
getCmdOpts(
	int argc,
	char *argv[]
	)
{
	extern const char *config_file;
	int errflg;
	tOptions *myOptions = &OPTSTRUCT;

	/*
	 * Initialize, initialize
	 */
	errflg = 0;

	switch (WHICH_IDX_IPV4) {
	    case INDEX_OPT_IPV4:
		default_ai_family = AF_INET;
		break;
	    case INDEX_OPT_IPV6:
		default_ai_family = AF_INET6;
		break;
	    default:
		/* ai_fam_templ = ai_fam_default;	*/
		break;
	}

	if (HAVE_OPT( AUTHREQ ))
		proto_config(PROTO_AUTHENTICATE, 1, 0., NULL);

	if (HAVE_OPT( AUTHNOREQ ))
		proto_config(PROTO_AUTHENTICATE, 0, 0., NULL);

	if (HAVE_OPT( BCASTSYNC ))
		proto_config(PROTO_BROADCLIENT, 1, 0., NULL);

	if (HAVE_OPT( CONFIGFILE )) {
		config_file = OPT_ARG( CONFIGFILE );
#ifdef HAVE_NETINFO
		check_netinfo = 0;
#endif
	}

	if (HAVE_OPT( DRIFTFILE ))
		stats_config(STATS_FREQ_FILE, OPT_ARG( DRIFTFILE ));

	if (HAVE_OPT( PANICGATE ))
		allow_panic = TRUE;

	if (HAVE_OPT( JAILDIR )) {
#ifdef HAVE_DROPROOT
			droproot = 1;
			chrootdir = OPT_ARG( JAILDIR );
#else
			fprintf(stderr, 
				"command line -i option (jaildir) is not supported by this binary"
# ifndef SYS_WINNT
				",\n" "can not drop root privileges.  See configure options\n"
				"--enable-clockctl and --enable-linuxcaps.\n");
# else
				".\n");
# endif
			msyslog(LOG_ERR, 
				"command line -i option (jaildir) is not supported by this binary.");
			errflg++;
#endif
	}

	if (HAVE_OPT( KEYFILE ))
		getauthkeys(OPT_ARG( KEYFILE ));

	if (HAVE_OPT( PIDFILE ))
		stats_config(STATS_PID_FILE, OPT_ARG( PIDFILE ));

	if (HAVE_OPT( QUIT ))
		mode_ntpdate = TRUE;

	if (HAVE_OPT( PROPAGATIONDELAY ))
		do {
			double tmp;
			const char *my_ntp_optarg = OPT_ARG( PROPAGATIONDELAY );

			if (sscanf(my_ntp_optarg, "%lf", &tmp) != 1) {
				msyslog(LOG_ERR,
					"command line broadcast delay value %s undecodable",
					my_ntp_optarg);
			} else {
				proto_config(PROTO_BROADDELAY, 0, tmp, NULL);
			}
		} while (0);

	if (HAVE_OPT( STATSDIR ))
		stats_config(STATS_STATSDIR, OPT_ARG( STATSDIR ));

	if (HAVE_OPT( TRUSTEDKEY )) {
		int		ct = STACKCT_OPT(  TRUSTEDKEY );
		const char**	pp = STACKLST_OPT( TRUSTEDKEY );

		do  {
			u_long tkey;
			const char* p = *pp++;

			tkey = (int)atol(p);
			if (tkey == 0 || tkey > NTP_MAXKEY) {
				msyslog(LOG_ERR,
				    "command line trusted key %s is invalid",
				    p);
			} else {
				authtrust(tkey, 1);
			}
		} while (--ct > 0);
	}

	if (HAVE_OPT( USER )) {
#ifdef HAVE_DROPROOT
		char *ntp_optarg = OPT_ARG( USER );

		droproot = 1;
		user = emalloc(strlen(ntp_optarg) + 1);
		(void)strncpy(user, ntp_optarg, strlen(ntp_optarg) + 1);
		group = rindex(user, ':');
		if (group)
			*group++ = '\0'; /* get rid of the ':' */
#else
		fprintf(stderr, 
			"command line -u/--user option is not supported by this binary"
# ifndef SYS_WINNT
			",\n" "can not drop root privileges.  See configure options\n"
			"--enable-clockctl and --enable-linuxcaps.\n");
# else
			".\n");
# endif
		msyslog(LOG_ERR, 
			"command line -u/--user option is not supported by this binary.");
		errflg++;
#endif
	}

	if (HAVE_OPT( VAR )) {
		int		ct = STACKCT_OPT(  VAR );
		const char**	pp = STACKLST_OPT( VAR );

		do  {
			const char* my_ntp_optarg = *pp++;

			set_sys_var(my_ntp_optarg, strlen(my_ntp_optarg)+1,
			    (u_short) (RW));
		} while (--ct > 0);
	}

	if (HAVE_OPT( DVAR )) {
		int		ct = STACKCT_OPT(  DVAR );
		const char**	pp = STACKLST_OPT( DVAR );

		do  {
			const char* my_ntp_optarg = *pp++;

			set_sys_var(my_ntp_optarg, strlen(my_ntp_optarg)+1,
			    (u_short) (RW | DEF));
		} while (--ct > 0);
	}

	if (HAVE_OPT( SLEW ))
		clock_max = 600;

	if (HAVE_OPT( UPDATEINTERVAL )) {
		long val = OPT_VALUE_UPDATEINTERVAL;
			  
		if (val >= 0)
			interface_interval = val;
		else {
			fprintf(stderr, 
				"command line interface update interval %ld must not be negative\n",
				val);
			msyslog(LOG_ERR, 
				"command line interface update interval %ld must not be negative",
				val);
			errflg++;
		}
	}
#ifdef SIM
	if (HAVE_OPT( SIMBROADCASTDELAY ))
		sscanf(OPT_ARG( SIMBROADCASTDELAY ), "%lf", &ntp_node.bdly);

	if (HAVE_OPT( PHASENOISE ))
		sscanf(OPT_ARG( PHASENOISE ), "%lf", &ntp_node.snse);

	if (HAVE_OPT( SIMSLEW ))
		sscanf(OPT_ARG( SIMSLEW ), "%lf", &ntp_node.slew);

	if (HAVE_OPT( SERVERTIME ))
		sscanf(OPT_ARG( SERVERTIME ), "%lf", &ntp_node.clk_time);

	if (HAVE_OPT( ENDSIMTIME ))
		sscanf(OPT_ARG( ENDSIMTIME ), "%lf", &ntp_node.sim_time);

	if (HAVE_OPT( FREQERR ))
		sscanf(OPT_ARG( FREQERR ), "%lf", &ntp_node.ferr);

	if (HAVE_OPT( WALKNOISE ))
		sscanf(OPT_ARG( WALKNOISE ), "%lf", &ntp_node.fnse);

	if (HAVE_OPT( NDELAY ))
		sscanf(OPT_ARG( NDELAY ), "%lf", &ntp_node.ndly);

	if (HAVE_OPT( PDELAY ))
		sscanf(OPT_ARG( PDELAY ), "%lf", &ntp_node.pdly);

#endif /* SIM */

	if (errflg || argc) {
		if (argc)
			fprintf(stderr, "argc after processing is <%d>\n", argc);
		optionUsage(myOptions, 2);
	}
	return;
}
Beispiel #25
0
/*
 *  emitDefinition
 */
LOCAL char*
emitDefinition(char* pzDef, char* pzOut)
{
    char sep_char;
    char zEntryName[ MAXNAMELEN ];

    /*
     *  Indent attribute definitions four spaces
     */
    {
        char*  p = zEntryName;
        *pzOut++ = ' '; *pzOut++ = ' '; *pzOut++ = ' '; *pzOut++ = ' ';

        while (AG_NAME_CHAR(*pzDef))
            *p++ = *pzOut++ = *pzDef++;

        if (p >= zEntryName + sizeof(zEntryName))
            die("names are constrained to %d bytes\n", MAXNAMELEN);

        *p = NUL;
    }

    /*
     *  Strip the prefixes from all the definition lines
     *  (viz., the "^.*\*" text, except that it is a shortest match
     *  instead of longest match).  Skip the ':' before starting.
     */
    compress_def(++pzDef);

    if (HAVE_OPT( SUBBLOCK )) {
        int    ct  = STACKCT_OPT(  SUBBLOCK );
        char const **  ppz = STACKLST_OPT( SUBBLOCK );

        do  {
            char const * pz = *ppz++;
            if (strcmp(pz, zEntryName) == 0)
                return emit_subblock(pz, pzDef, pzOut);
        } while (--ct > 0);
    }

    if (HAVE_OPT( LISTATTR )) {
        int    ct  = STACKCT_OPT(  LISTATTR );
        char const ** ppz = STACKLST_OPT( LISTATTR );

        do  {
            if (strcmp(*ppz++, zEntryName) == 0)
                return list_attrib(pzDef, pzOut);
        } while (--ct > 0);
    }

    if (isspace(*pzDef))
         sep_char = *pzDef++;
    else sep_char = ' ';

    switch (*pzDef) {
    case NUL:
        *pzOut++ = ';'; *pzOut++ = '\n';
        break;

    case '"':
    case '\'':
    case '{':
        /*
         *  Quoted entries or subblocks do their own stringification
         *  sprintf is safe because we are copying strings around
         *  and *always* making the result smaller than the original
         */
        pzOut += sprintf(pzOut, " =%c%s;\n", sep_char, pzDef);
        break;

    default:
        *pzOut++ = ' '; *pzOut++ = '='; *pzOut++ = sep_char;
        *pzOut++ = '\'';

        for (;;) {
            switch (*pzOut++ = *pzDef++) {
            case '\\':
                *pzOut++  = '\\';
                break;

            case '\'':
                pzOut[-1] = '\\';
                *pzOut++  = '\'';
                break;

            case NUL:
                goto unquotedDone;
            }
        } unquotedDone:;
        pzOut[-1] = '\''; *pzOut++ = ';'; *pzOut++ = '\n';
        break;
    }
    return pzOut;
}
Beispiel #26
0
/*
 * getCmdOpts - get command line options
 */
void
getCmdOpts(
	int argc,
	char *argv[]
	)
{
	extern const char *config_file;
	int errflg;
	tOptions *myOptions = &ntpdOptions;

	/*
	 * Initialize, initialize
	 */
	errflg = 0;

	if (HAVE_OPT( IPV4 ))
		default_ai_family = AF_INET;
	else if (HAVE_OPT( IPV6 ))
		default_ai_family = AF_INET6;

	if (HAVE_OPT( AUTHREQ ))
		proto_config(PROTO_AUTHENTICATE, 1, 0., NULL);
	else if (HAVE_OPT( AUTHNOREQ ))
		proto_config(PROTO_AUTHENTICATE, 0, 0., NULL);

	if (HAVE_OPT( BCASTSYNC ))
		proto_config(PROTO_BROADCLIENT, 1, 0., NULL);

	if (HAVE_OPT( CONFIGFILE )) {
		config_file = OPT_ARG( CONFIGFILE );
#ifdef HAVE_NETINFO
		check_netinfo = 0;
#endif
	}

	if (HAVE_OPT( DRIFTFILE ))
		stats_config(STATS_FREQ_FILE, OPT_ARG( DRIFTFILE ));

	if (HAVE_OPT( PANICGATE ))
		allow_panic = TRUE;

#ifdef HAVE_DROPROOT
	if (HAVE_OPT( JAILDIR )) {
		droproot = 1;
		chrootdir = OPT_ARG( JAILDIR );
	}
#endif

	if (HAVE_OPT( KEYFILE ))
		getauthkeys(OPT_ARG( KEYFILE ));

	if (HAVE_OPT( PIDFILE ))
		stats_config(STATS_PID_FILE, OPT_ARG( PIDFILE ));

	if (HAVE_OPT( QUIT ))
		mode_ntpdate = TRUE;

	if (HAVE_OPT( PROPAGATIONDELAY ))
		do {
			double tmp;
			const char *my_ntp_optarg = OPT_ARG( PROPAGATIONDELAY );

			if (sscanf(my_ntp_optarg, "%lf", &tmp) != 1) {
				msyslog(LOG_ERR,
					"command line broadcast delay value %s undecodable",
					my_ntp_optarg);
			} else {
				proto_config(PROTO_BROADDELAY, 0, tmp, NULL);
			}
		} while (0);

	if (HAVE_OPT( STATSDIR ))
		stats_config(STATS_STATSDIR, OPT_ARG( STATSDIR ));

	if (HAVE_OPT( TRUSTEDKEY )) {
		int		ct = STACKCT_OPT(  TRUSTEDKEY );
		const char**	pp = STACKLST_OPT( TRUSTEDKEY );

		do  {
			u_long tkey;
			const char* p = *pp++;

			tkey = (int)atol(p);
			if (tkey == 0 || tkey > NTP_MAXKEY) {
				msyslog(LOG_ERR,
				    "command line trusted key %s is invalid",
				    p);
			} else {
				authtrust(tkey, 1);
			}
		} while (--ct > 0);
	}

#ifdef HAVE_DROPROOT
	if (HAVE_OPT( USER )) {
		droproot = 1;
		user = estrdup(OPT_ARG( USER ));
		group = rindex(user, ':');
		if (group)
			*group++ = '\0'; /* get rid of the ':' */
	}
#endif

	if (HAVE_OPT( VAR )) {
		int		ct = STACKCT_OPT(  VAR );
		const char**	pp = STACKLST_OPT( VAR );

		do  {
			const char* my_ntp_optarg = *pp++;

			set_sys_var(my_ntp_optarg, strlen(my_ntp_optarg)+1,
			    (u_short) (RW));
		} while (--ct > 0);
	}

	if (HAVE_OPT( DVAR )) {
		int		ct = STACKCT_OPT(  DVAR );
		const char**	pp = STACKLST_OPT( DVAR );

		do  {
			const char* my_ntp_optarg = *pp++;

			set_sys_var(my_ntp_optarg, strlen(my_ntp_optarg)+1,
			    (u_short) (RW | DEF));
		} while (--ct > 0);
	}

	if (HAVE_OPT( SLEW )) {
		clock_max = 600;
		kern_enable = 0;
	}
	if (HAVE_OPT( UPDATEINTERVAL )) {
		long val = OPT_VALUE_UPDATEINTERVAL;
			  
		if (val >= 0)
			interface_interval = val;
		else {
			fprintf(stderr, 
				"command line interface update interval %ld must not be negative\n",
				val);
			msyslog(LOG_ERR, 
				"command line interface update interval %ld must not be negative",
				val);
			errflg++;
		}
	}
#ifdef SIM

	/* SK:
	 * The simulator no longer takes any command line arguments. Hence,
	 * all the code that was here has been removed.
	 */

#endif /* SIM */

	if (errflg || argc) {
		if (argc)
			fprintf(stderr, "argc after processing is <%d>\n", argc);
		optionUsage(myOptions, 2);
	}
	return;
}
Beispiel #27
0
/*
 * getCmdOpts - apply most command line options
 *
 * A few options are examined earlier in ntpd.c ntpdmain() and
 * ports/winnt/ntpd/ntservice.c main().
 */
void
getCmdOpts(
	int	argc,
	char **	argv
	)
{
	extern const char *config_file;
	int errflg;

	/*
	 * Initialize, initialize
	 */
	errflg = 0;

	if (ipv4_works && ipv6_works) {
		if (HAVE_OPT( IPV4 ))
			ipv6_works = 0;
		else if (HAVE_OPT( IPV6 ))
			ipv4_works = 0;
	} else if (!ipv4_works && !ipv6_works) {
		msyslog(LOG_ERR, "Neither IPv4 nor IPv6 networking detected, fatal.");
		exit(1);
	} else if (HAVE_OPT( IPV4 ) && !ipv4_works)
		msyslog(LOG_WARNING, "-4/--ipv4 ignored, IPv4 networking not found.");
	else if (HAVE_OPT( IPV6 ) && !ipv6_works)
		msyslog(LOG_WARNING, "-6/--ipv6 ignored, IPv6 networking not found.");

	if (HAVE_OPT( AUTHREQ ))
		proto_config(PROTO_AUTHENTICATE, 1, 0., NULL);
	else if (HAVE_OPT( AUTHNOREQ ))
		proto_config(PROTO_AUTHENTICATE, 0, 0., NULL);

	if (HAVE_OPT( BCASTSYNC ))
		proto_config(PROTO_BROADCLIENT, 1, 0., NULL);

	if (HAVE_OPT( CONFIGFILE )) {
		config_file = OPT_ARG( CONFIGFILE );
#ifdef HAVE_NETINFO
		check_netinfo = 0;
#endif
	}

	if (HAVE_OPT( DRIFTFILE ))
		stats_config(STATS_FREQ_FILE, OPT_ARG( DRIFTFILE ));

	if (HAVE_OPT( PANICGATE ))
		allow_panic = TRUE;

	if (HAVE_OPT( FORCE_STEP_ONCE ))
		force_step_once = TRUE;

#ifdef HAVE_DROPROOT
	if (HAVE_OPT( JAILDIR )) {
		droproot = 1;
		chrootdir = OPT_ARG( JAILDIR );
	}
#endif

	if (HAVE_OPT( KEYFILE ))
		getauthkeys(OPT_ARG( KEYFILE ));

	if (HAVE_OPT( PIDFILE ))
		stats_config(STATS_PID_FILE, OPT_ARG( PIDFILE ));

	if (HAVE_OPT( QUIT ))
		mode_ntpdate = TRUE;

	if (HAVE_OPT( PROPAGATIONDELAY ))
		do {
			double tmp;
			const char *my_ntp_optarg = OPT_ARG( PROPAGATIONDELAY );

			if (sscanf(my_ntp_optarg, "%lf", &tmp) != 1) {
				msyslog(LOG_ERR,
					"command line broadcast delay value %s undecodable",
					my_ntp_optarg);
			} else {
				proto_config(PROTO_BROADDELAY, 0, tmp, NULL);
			}
		} while (0);

	if (HAVE_OPT( STATSDIR ))
		stats_config(STATS_STATSDIR, OPT_ARG( STATSDIR ));

	if (HAVE_OPT( TRUSTEDKEY )) {
		int		ct = STACKCT_OPT(  TRUSTEDKEY );
		const char**	pp = STACKLST_OPT( TRUSTEDKEY );

		do  {
			u_long tkey;
			const char* p = *pp++;

			tkey = (int)atol(p);
			if (tkey == 0 || tkey > NTP_MAXKEY) {
				msyslog(LOG_ERR,
				    "command line trusted key %s is invalid",
				    p);
			} else {
				authtrust(tkey, 1);
			}
		} while (--ct > 0);
	}

#ifdef HAVE_DROPROOT
	if (HAVE_OPT( USER )) {
		droproot = 1;
		user = estrdup(OPT_ARG( USER ));
		group = strrchr(user, ':');
		if (group != NULL) {
			size_t	len;

			*group++ = '\0'; /* get rid of the ':' */
			len = group - user;
			group = estrdup(group);
			user = erealloc(user, len);
		}
	}
#endif

	if (HAVE_OPT( VAR )) {
		int		ct;
		const char **	pp;
		const char *	v_assign;

		ct = STACKCT_OPT(  VAR );
		pp = STACKLST_OPT( VAR );

		do  {
			v_assign = *pp++;
			set_sys_var(v_assign, strlen(v_assign) + 1, RW);
		} while (--ct > 0);
	}

	if (HAVE_OPT( DVAR )) {
		int		ct = STACKCT_OPT(  DVAR );
		const char**	pp = STACKLST_OPT( DVAR );

		do  {
			const char* my_ntp_optarg = *pp++;

			set_sys_var(my_ntp_optarg, strlen(my_ntp_optarg)+1,
			    (u_short) (RW | DEF));
		} while (--ct > 0);
	}

	if (HAVE_OPT( SLEW ))
		loop_config(LOOP_MAX, 600);

	if (HAVE_OPT( UPDATEINTERVAL )) {
		long val = OPT_VALUE_UPDATEINTERVAL;

		if (val >= 0)
			interface_interval = val;
		else {
			fprintf(stderr,
				"command line interface update interval %ld must not be negative\n",
				val);
			msyslog(LOG_ERR,
				"command line interface update interval %ld must not be negative",
				val);
			errflg++;
		}
	}


	/* save list of servers from cmd line for config_peers() use */
	if (argc > 0) {
		cmdline_server_count = argc;
		cmdline_servers = argv;
	}

	/* display usage & exit with any option processing errors */
	if (errflg)
		optionUsage(&ntpdOptions, 2);	/* does not return */
}