419 lines
8.7 KiB
C
419 lines
8.7 KiB
C
/*
|
|
* cmd_args.c = command-line argument processing
|
|
*/
|
|
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
#include "ntpd.h"
|
|
#include "ntp_stdlib.h"
|
|
#include "ntp_cmdargs.h"
|
|
|
|
#ifdef SIM
|
|
#include "ntpsim.h"
|
|
#endif /* SIM */
|
|
|
|
/*
|
|
* Definitions of things either imported from or exported to outside
|
|
*/
|
|
extern char const *progname;
|
|
int listen_to_virtual_ips = 1;
|
|
|
|
#ifdef SYS_WINNT
|
|
extern BOOL NoWinService;
|
|
#endif
|
|
|
|
static const char *ntp_options = "aAbB:c:C:dD:f:gi:k:l:LmnNO:p:P:qr:s:S:t:T:W:u:v:V:xY:Z:-:";
|
|
|
|
#ifdef HAVE_NETINFO
|
|
extern int check_netinfo;
|
|
#endif
|
|
|
|
|
|
/*
|
|
* getstartup - search through the options looking for a debugging flag
|
|
*/
|
|
void
|
|
getstartup(
|
|
int argc,
|
|
char *argv[]
|
|
)
|
|
{
|
|
int errflg;
|
|
extern int priority_done;
|
|
int c;
|
|
|
|
#ifdef DEBUG
|
|
debug = 0; /* no debugging by default */
|
|
#endif
|
|
|
|
/*
|
|
* This is a big hack. We don't really want to read command line
|
|
* configuration until everything else is initialized, since
|
|
* the ability to configure the system may depend on storage
|
|
* and the like having been initialized. Except that we also
|
|
* don't want to initialize anything until after detaching from
|
|
* the terminal, but we won't know to do that until we've
|
|
* parsed the command line. Do that now, crudely, and do it
|
|
* again later. Our ntp_getopt() is explicitly reusable, by the
|
|
* way. Your own mileage may vary.
|
|
*
|
|
* This hack is even called twice (to allow complete logging to file)
|
|
*/
|
|
errflg = 0;
|
|
progname = argv[0];
|
|
|
|
/*
|
|
* Decode argument list
|
|
*/
|
|
while ((c = ntp_getopt(argc, argv, ntp_options)) != EOF)
|
|
switch (c) {
|
|
#ifdef DEBUG
|
|
case 'd':
|
|
++debug;
|
|
break;
|
|
case 'D':
|
|
debug = (int)atol(ntp_optarg);
|
|
printf("Debug1: %s -> %x = %d\n", ntp_optarg, debug, debug);
|
|
break;
|
|
#else
|
|
case 'd':
|
|
case 'D':
|
|
msyslog(LOG_ERR, "ntpd not compiled with -DDEBUG option - no DEBUG support");
|
|
fprintf(stderr, "ntpd not compiled with -DDEBUG option - no DEBUG support\n");
|
|
++errflg;
|
|
break;
|
|
#endif
|
|
case 'L':
|
|
listen_to_virtual_ips = 0;
|
|
break;
|
|
case 'l':
|
|
{
|
|
FILE *new_file;
|
|
|
|
if(strcmp(ntp_optarg, "stderr") == 0)
|
|
new_file = stderr;
|
|
else if(strcmp(ntp_optarg, "stdout") == 0)
|
|
new_file = stdout;
|
|
else
|
|
new_file = fopen(ntp_optarg, "a");
|
|
if (new_file != NULL) {
|
|
NLOG(NLOG_SYSINFO)
|
|
msyslog(LOG_NOTICE, "logging to file %s", ntp_optarg);
|
|
if (syslog_file != NULL &&
|
|
fileno(syslog_file) != fileno(new_file))
|
|
(void)fclose(syslog_file);
|
|
|
|
syslog_file = new_file;
|
|
syslogit = 0;
|
|
}
|
|
else
|
|
msyslog(LOG_ERR,
|
|
"Cannot open log file %s",
|
|
ntp_optarg);
|
|
}
|
|
break;
|
|
|
|
case 'n':
|
|
case 'q':
|
|
++nofork;
|
|
#ifdef SYS_WINNT
|
|
NoWinService = TRUE;
|
|
#endif
|
|
break;
|
|
|
|
case 'N':
|
|
priority_done = 0;
|
|
break;
|
|
|
|
case '?':
|
|
++errflg;
|
|
break;
|
|
|
|
case '-':
|
|
if ( ! strcmp(ntp_optarg, "version") ) {
|
|
printf("%.80s: %.80s\n", progname, Version);
|
|
exit(0);
|
|
} else if ( ! strcmp(ntp_optarg, "help") ) {
|
|
/* usage(); */
|
|
/* exit(0); */
|
|
++errflg;
|
|
} else if ( ! strcmp(ntp_optarg, "copyright") ) {
|
|
printf("unknown\n");
|
|
exit(0);
|
|
} else {
|
|
fprintf(stderr, "%.80s: Error unknown argument '--%.80s'\n",
|
|
progname,
|
|
ntp_optarg);
|
|
exit(12);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (errflg || ntp_optind != argc) {
|
|
(void) fprintf(stderr, "usage: %s [ -abdgmnqx ] [ -c config_file ] [ -e e_delay ]\n", progname);
|
|
(void) fprintf(stderr, "\t\t[ -f freq_file ] [ -k key_file ] [ -l log_file ]\n");
|
|
(void) fprintf(stderr, "\t\t[ -p pid_file ] [ -r broad_delay ] [ -s statdir ]\n");
|
|
(void) fprintf(stderr, "\t\t[ -t trust_key ] [ -v sys_var ] [ -V default_sysvar ]\n");
|
|
#if defined(HAVE_SCHED_SETSCHEDULER)
|
|
(void) fprintf(stderr, "\t\t[ -P fixed_process_priority ]\n");
|
|
#endif
|
|
#ifdef HAVE_CLOCKCTL
|
|
(void) fprintf(stderr, "\t\t[ -u user[:group] ] [ -i chrootdir ]\n");
|
|
#endif
|
|
exit(2);
|
|
}
|
|
ntp_optind = 0; /* reset ntp_optind to restart ntp_getopt */
|
|
|
|
#ifdef DEBUG
|
|
if (debug) {
|
|
#ifdef HAVE_SETVBUF
|
|
static char buf[BUFSIZ];
|
|
setvbuf(stdout, buf, _IOLBF, BUFSIZ);
|
|
#else
|
|
setlinebuf(stdout);
|
|
#endif
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* getCmdOpts - get command line options
|
|
*/
|
|
void
|
|
getCmdOpts(
|
|
int argc,
|
|
char *argv[]
|
|
)
|
|
{
|
|
extern char *config_file;
|
|
struct sockaddr_in inaddrntp;
|
|
int errflg;
|
|
int c;
|
|
|
|
/*
|
|
* Initialize, initialize
|
|
*/
|
|
errflg = 0;
|
|
#ifdef DEBUG
|
|
debug = 0;
|
|
#endif /* DEBUG */
|
|
|
|
progname = argv[0];
|
|
|
|
/*
|
|
* Decode argument list
|
|
*/
|
|
while ((c = ntp_getopt(argc, argv, ntp_options)) != EOF) {
|
|
switch (c) {
|
|
case 'a':
|
|
proto_config(PROTO_AUTHENTICATE, 1, 0., NULL);
|
|
break;
|
|
|
|
case 'A':
|
|
proto_config(PROTO_AUTHENTICATE, 0, 0., NULL);
|
|
break;
|
|
|
|
case 'b':
|
|
proto_config(PROTO_BROADCLIENT, 1, 0., NULL);
|
|
break;
|
|
|
|
case 'c':
|
|
config_file = ntp_optarg;
|
|
#ifdef HAVE_NETINFO
|
|
check_netinfo = 0;
|
|
#endif
|
|
break;
|
|
|
|
case 'd':
|
|
#ifdef DEBUG
|
|
debug++;
|
|
#else
|
|
errflg++;
|
|
#endif /* DEBUG */
|
|
break;
|
|
|
|
case 'D':
|
|
#ifdef DEBUG
|
|
debug = (int)atol(ntp_optarg);
|
|
printf("Debug2: %s -> %x = %d\n", ntp_optarg, debug, debug);
|
|
#else
|
|
errflg++;
|
|
#endif /* DEBUG */
|
|
break;
|
|
|
|
case 'f':
|
|
stats_config(STATS_FREQ_FILE, ntp_optarg);
|
|
break;
|
|
|
|
case 'g':
|
|
allow_panic = TRUE;
|
|
break;
|
|
|
|
case 'i':
|
|
#ifdef HAVE_CLOCKCTL
|
|
if (!ntp_optarg)
|
|
errflg++;
|
|
else
|
|
chrootdir = ntp_optarg;
|
|
break;
|
|
#else
|
|
errflg++;
|
|
#endif
|
|
case 'k':
|
|
getauthkeys(ntp_optarg);
|
|
break;
|
|
|
|
case 'L': /* already done at pre-scan */
|
|
case 'l': /* already done at pre-scan */
|
|
break;
|
|
|
|
case 'm':
|
|
inaddrntp.sin_family = AF_INET;
|
|
inaddrntp.sin_port = htons(NTP_PORT);
|
|
inaddrntp.sin_addr.s_addr = htonl(INADDR_NTP);
|
|
proto_config(PROTO_MULTICAST_ADD, 0, 0., (struct sockaddr_storage*)&inaddrntp);
|
|
sys_bclient = 1;
|
|
break;
|
|
|
|
case 'n': /* already done at pre-scan */
|
|
break;
|
|
|
|
case 'N': /* already done at pre-scan */
|
|
break;
|
|
|
|
case 'p':
|
|
stats_config(STATS_PID_FILE, ntp_optarg);
|
|
break;
|
|
|
|
case 'P':
|
|
#if defined(HAVE_SCHED_SETSCHEDULER)
|
|
config_priority = (int)atol(ntp_optarg);
|
|
config_priority_override = 1;
|
|
#else
|
|
errflg++;
|
|
#endif
|
|
break;
|
|
|
|
case 'q':
|
|
mode_ntpdate = TRUE;
|
|
break;
|
|
|
|
case 'r':
|
|
do {
|
|
double tmp;
|
|
|
|
if (sscanf(ntp_optarg, "%lf", &tmp) != 1) {
|
|
msyslog(LOG_ERR,
|
|
"command line broadcast delay value %s undecodable",
|
|
ntp_optarg);
|
|
} else {
|
|
proto_config(PROTO_BROADDELAY, 0, tmp, NULL);
|
|
}
|
|
} while (0);
|
|
break;
|
|
|
|
case 'u':
|
|
#ifdef HAVE_CLOCKCTL
|
|
user = malloc(strlen(ntp_optarg) + 1);
|
|
if ((user == NULL) || (ntp_optarg == NULL))
|
|
errflg++;
|
|
(void)strncpy(user, ntp_optarg, strlen(ntp_optarg) + 1);
|
|
group = rindex(user, ':');
|
|
if (group)
|
|
*group++ = '\0'; /* get rid of the ':' */
|
|
#else
|
|
errflg++;
|
|
#endif
|
|
break;
|
|
case 's':
|
|
stats_config(STATS_STATSDIR, ntp_optarg);
|
|
break;
|
|
|
|
case 't':
|
|
do {
|
|
u_long tkey;
|
|
|
|
tkey = (int)atol(ntp_optarg);
|
|
if (tkey <= 0 || tkey > NTP_MAXKEY) {
|
|
msyslog(LOG_ERR,
|
|
"command line trusted key %s is invalid",
|
|
ntp_optarg);
|
|
} else {
|
|
authtrust(tkey, 1);
|
|
}
|
|
} while (0);
|
|
break;
|
|
|
|
case 'v':
|
|
case 'V':
|
|
set_sys_var(ntp_optarg, strlen(ntp_optarg)+1,
|
|
(u_short) (RW | ((c == 'V') ? DEF : 0)));
|
|
break;
|
|
|
|
case 'x':
|
|
clock_max = 600;
|
|
break;
|
|
#ifdef SIM
|
|
case 'B':
|
|
sscanf(ntp_optarg, "%lf", &ntp_node.bdly);
|
|
break;
|
|
|
|
case 'C':
|
|
sscanf(ntp_optarg, "%lf", &ntp_node.snse);
|
|
break;
|
|
|
|
case 'H':
|
|
sscanf(ntp_optarg, "%lf", &ntp_node.slew);
|
|
break;
|
|
|
|
case 'O':
|
|
sscanf(ntp_optarg, "%lf", &ntp_node.clk_time);
|
|
break;
|
|
|
|
case 'S':
|
|
sscanf(ntp_optarg, "%lf", &ntp_node.sim_time);
|
|
break;
|
|
|
|
case 'T':
|
|
sscanf(ntp_optarg, "%lf", &ntp_node.ferr);
|
|
break;
|
|
|
|
case 'W':
|
|
sscanf(ntp_optarg, "%lf", &ntp_node.fnse);
|
|
break;
|
|
|
|
case 'Y':
|
|
sscanf(ntp_optarg, "%lf", &ntp_node.ndly);
|
|
break;
|
|
|
|
case 'Z':
|
|
sscanf(ntp_optarg, "%lf", &ntp_node.pdly);
|
|
break;
|
|
|
|
#endif /* SIM */
|
|
default:
|
|
errflg++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (errflg || ntp_optind != argc) {
|
|
(void) fprintf(stderr, "usage: %s [ -abdgmnx ] [ -c config_file ] [ -e e_delay ]\n", progname);
|
|
(void) fprintf(stderr, "\t\t[ -f freq_file ] [ -k key_file ] [ -l log_file ]\n");
|
|
(void) fprintf(stderr, "\t\t[ -p pid_file ] [ -r broad_delay ] [ -s statdir ]\n");
|
|
(void) fprintf(stderr, "\t\t[ -t trust_key ] [ -v sys_var ] [ -V default_sysvar ]\n");
|
|
#if defined(HAVE_SCHED_SETSCHEDULER)
|
|
(void) fprintf(stderr, "\t\t[ -P fixed_process_priority ]\n");
|
|
#endif
|
|
#ifdef HAVE_CLOCKCTL
|
|
(void) fprintf(stderr, "\t\t[ -u user[:group] ] [ -i chrootdir ]\n");
|
|
#endif
|
|
exit(2);
|
|
}
|
|
return;
|
|
}
|