xref: /freebsd/contrib/ntp/ntpd/cmd_args.c (revision 1e413cf93298b5b97441a21d9a50fdcd0ee9945e)
1 /*
2  * cmd_args.c = command-line argument processing
3  */
4 #ifdef HAVE_CONFIG_H
5 # include <config.h>
6 #endif
7 
8 #include "ntpd.h"
9 #include "ntp_stdlib.h"
10 #include "ntp_cmdargs.h"
11 
12 #ifdef SIM
13 #include "ntpsim.h"
14 #endif /* SIM */
15 
16 /*
17  * Definitions of things either imported from or exported to outside
18  */
19 extern char const *progname;
20 int	listen_to_virtual_ips = 1;
21 
22 #ifdef SYS_WINNT
23 extern BOOL NoWinService;
24 #endif
25 
26 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:-:";
27 
28 #ifdef HAVE_NETINFO
29 extern int	check_netinfo;
30 #endif
31 
32 
33 /*
34  * getstartup - search through the options looking for a debugging flag
35  */
36 void
37 getstartup(
38 	int argc,
39 	char *argv[]
40 	)
41 {
42 	int errflg;
43 	extern int priority_done;
44 	int c;
45 
46 #ifdef DEBUG
47 	debug = 0;		/* no debugging by default */
48 #endif
49 
50 	/*
51 	 * This is a big hack.	We don't really want to read command line
52 	 * configuration until everything else is initialized, since
53 	 * the ability to configure the system may depend on storage
54 	 * and the like having been initialized.  Except that we also
55 	 * don't want to initialize anything until after detaching from
56 	 * the terminal, but we won't know to do that until we've
57 	 * parsed the command line.  Do that now, crudely, and do it
58 	 * again later.  Our ntp_getopt() is explicitly reusable, by the
59 	 * way.  Your own mileage may vary.
60 	 *
61 	 * This hack is even called twice (to allow complete logging to file)
62 	 */
63 	errflg = 0;
64 	progname = argv[0];
65 
66 	/*
67 	 * Decode argument list
68 	 */
69 	while ((c = ntp_getopt(argc, argv, ntp_options)) != EOF)
70 	    switch (c) {
71 #ifdef DEBUG
72 		case 'd':
73 		    ++debug;
74 		    break;
75 		case 'D':
76 		    debug = (int)atol(ntp_optarg);
77 		    printf("Debug1: %s -> %x = %d\n", ntp_optarg, debug, debug);
78 		    break;
79 #else
80 		case 'd':
81 		case 'D':
82 		    msyslog(LOG_ERR, "ntpd not compiled with -DDEBUG option - no DEBUG support");
83 		    fprintf(stderr, "ntpd not compiled with -DDEBUG option - no DEBUG support\n");
84 		    ++errflg;
85 		    break;
86 #endif
87 		case 'L':
88 		    listen_to_virtual_ips = 0;
89 		    break;
90 		case 'l':
91 			{
92 				FILE *new_file;
93 
94 				if(strcmp(ntp_optarg, "stderr") == 0)
95 					new_file = stderr;
96 				else if(strcmp(ntp_optarg, "stdout") == 0)
97 					new_file = stdout;
98 				else
99 					new_file = fopen(ntp_optarg, "a");
100 				if (new_file != NULL) {
101 					NLOG(NLOG_SYSINFO)
102 						msyslog(LOG_NOTICE, "logging to file %s", ntp_optarg);
103 					if (syslog_file != NULL &&
104 						fileno(syslog_file) != fileno(new_file))
105 						(void)fclose(syslog_file);
106 
107 					syslog_file = new_file;
108 					syslogit = 0;
109 				}
110 				else
111 					msyslog(LOG_ERR,
112 						"Cannot open log file %s",
113 						ntp_optarg);
114 			}
115 			break;
116 
117 		case 'n':
118 		case 'q':
119 		    ++nofork;
120 #ifdef SYS_WINNT
121 		    NoWinService = TRUE;
122 #endif
123 		    break;
124 
125 		case 'N':
126 		    priority_done = 0;
127 		    break;
128 
129 		case '?':
130 		    ++errflg;
131 		    break;
132 
133 	    case '-':
134 	      if ( ! strcmp(ntp_optarg, "version") ) {
135 		printf("%.80s: %.80s\n", progname, Version);
136 		exit(0);
137 	      } else if ( ! strcmp(ntp_optarg, "help") ) {
138 		/* usage(); */
139 		/* exit(0); */
140 		++errflg;
141 	      } else if ( ! strcmp(ntp_optarg, "copyright") ) {
142 		printf("unknown\n");
143 		exit(0);
144 	      } else {
145 		fprintf(stderr, "%.80s: Error unknown argument '--%.80s'\n",
146 			progname,
147 			ntp_optarg);
148 		exit(12);
149 	      }
150 	      break;
151 
152 		default:
153 			break;
154 		}
155 
156 	if (errflg || ntp_optind != argc) {
157 		(void) fprintf(stderr, "usage: %s [ -abdgmnqx ] [ -c config_file ] [ -e e_delay ]\n", progname);
158 		(void) fprintf(stderr, "\t\t[ -f freq_file ] [ -k key_file ] [ -l log_file ]\n");
159 		(void) fprintf(stderr, "\t\t[ -p pid_file ] [ -r broad_delay ] [ -s statdir ]\n");
160 		(void) fprintf(stderr, "\t\t[ -t trust_key ] [ -v sys_var ] [ -V default_sysvar ]\n");
161 #if defined(HAVE_SCHED_SETSCHEDULER)
162 		(void) fprintf(stderr, "\t\t[ -P fixed_process_priority ]\n");
163 #endif
164 #ifdef HAVE_CLOCKCTL
165 		(void) fprintf(stderr, "\t\t[ -u user[:group] ] [ -i chrootdir ]\n");
166 #endif
167 		exit(2);
168 	}
169 	ntp_optind = 0;	/* reset ntp_optind to restart ntp_getopt */
170 
171 #ifdef DEBUG
172 	if (debug) {
173 #ifdef HAVE_SETVBUF
174 		static char buf[BUFSIZ];
175 		setvbuf(stdout, buf, _IOLBF, BUFSIZ);
176 #else
177 		setlinebuf(stdout);
178 #endif
179 	}
180 #endif
181 }
182 
183 /*
184  * getCmdOpts - get command line options
185  */
186 void
187 getCmdOpts(
188 	int argc,
189 	char *argv[]
190 	)
191 {
192 	extern char *config_file;
193 	struct sockaddr_in inaddrntp;
194 	int errflg;
195 	int c;
196 
197 	/*
198 	 * Initialize, initialize
199 	 */
200 	errflg = 0;
201 #ifdef DEBUG
202 	debug = 0;
203 #endif	/* DEBUG */
204 
205 	progname = argv[0];
206 
207 	/*
208 	 * Decode argument list
209 	 */
210 	while ((c = ntp_getopt(argc, argv, ntp_options)) != EOF) {
211 		switch (c) {
212 		    case 'a':
213 			proto_config(PROTO_AUTHENTICATE, 1, 0., NULL);
214 			break;
215 
216 		    case 'A':
217 			proto_config(PROTO_AUTHENTICATE, 0, 0., NULL);
218 			break;
219 
220 		    case 'b':
221 			proto_config(PROTO_BROADCLIENT, 1, 0., NULL);
222 			break;
223 
224 		    case 'c':
225 			config_file = ntp_optarg;
226 #ifdef HAVE_NETINFO
227 			check_netinfo = 0;
228 #endif
229 			break;
230 
231 		    case 'd':
232 #ifdef DEBUG
233 			debug++;
234 #else
235 			errflg++;
236 #endif	/* DEBUG */
237 			break;
238 
239 		    case 'D':
240 #ifdef DEBUG
241 			debug = (int)atol(ntp_optarg);
242 			printf("Debug2: %s -> %x = %d\n", ntp_optarg, debug, debug);
243 #else
244 			errflg++;
245 #endif	/* DEBUG */
246 			break;
247 
248 		    case 'f':
249 			stats_config(STATS_FREQ_FILE, ntp_optarg);
250 			break;
251 
252 		    case 'g':
253 			allow_panic = TRUE;
254 			break;
255 
256 		    case 'i':
257 #ifdef HAVE_CLOCKCTL
258 			if (!ntp_optarg)
259 				errflg++;
260 			else
261 				chrootdir = ntp_optarg;
262 			break;
263 #else
264 			errflg++;
265 #endif
266 		    case 'k':
267 			getauthkeys(ntp_optarg);
268 			break;
269 
270 		    case 'L':   /* already done at pre-scan */
271 		    case 'l':   /* already done at pre-scan */
272 			break;
273 
274 		    case 'm':
275 			inaddrntp.sin_family = AF_INET;
276 			inaddrntp.sin_port = htons(NTP_PORT);
277 			inaddrntp.sin_addr.s_addr = htonl(INADDR_NTP);
278 			proto_config(PROTO_MULTICAST_ADD, 0, 0., (struct sockaddr_storage*)&inaddrntp);
279 			sys_bclient = 1;
280 			break;
281 
282 		    case 'n':	/* already done at pre-scan */
283 			break;
284 
285 		    case 'N':	/* already done at pre-scan */
286 			break;
287 
288 		    case 'p':
289 			stats_config(STATS_PID_FILE, ntp_optarg);
290 			break;
291 
292 		    case 'P':
293 #if defined(HAVE_SCHED_SETSCHEDULER)
294 			config_priority = (int)atol(ntp_optarg);
295 			config_priority_override = 1;
296 #else
297 			errflg++;
298 #endif
299 			break;
300 
301 		    case 'q':
302 			mode_ntpdate = TRUE;
303 			break;
304 
305 		    case 'r':
306 			do {
307 				double tmp;
308 
309 				if (sscanf(ntp_optarg, "%lf", &tmp) != 1) {
310 					msyslog(LOG_ERR,
311 						"command line broadcast delay value %s undecodable",
312 						ntp_optarg);
313 				} else {
314 					proto_config(PROTO_BROADDELAY, 0, tmp, NULL);
315 				}
316 			} while (0);
317 			break;
318 
319 		    case 'u':
320 #ifdef HAVE_CLOCKCTL
321 			user = malloc(strlen(ntp_optarg) + 1);
322 			if ((user == NULL) || (ntp_optarg == NULL))
323 				errflg++;
324 			(void)strncpy(user, ntp_optarg, strlen(ntp_optarg) + 1);
325 			group = rindex(user, ':');
326 			if (group)
327 				*group++ = '\0'; /* get rid of the ':' */
328 #else
329 			errflg++;
330 #endif
331 			break;
332 		    case 's':
333 			stats_config(STATS_STATSDIR, ntp_optarg);
334 			break;
335 
336 		    case 't':
337 			do {
338 				u_long tkey;
339 
340 				tkey = (int)atol(ntp_optarg);
341 				if (tkey <= 0 || tkey > NTP_MAXKEY) {
342 					msyslog(LOG_ERR,
343 					    "command line trusted key %s is invalid",
344 					    ntp_optarg);
345 				} else {
346 					authtrust(tkey, 1);
347 				}
348 			} while (0);
349 			break;
350 
351 		    case 'v':
352 		    case 'V':
353 			set_sys_var(ntp_optarg, strlen(ntp_optarg)+1,
354 			    (u_short) (RW | ((c == 'V') ? DEF : 0)));
355 			break;
356 
357 		    case 'x':
358 			clock_max = 600;
359 			break;
360 #ifdef SIM
361 		case 'B':
362 			sscanf(ntp_optarg, "%lf", &ntp_node.bdly);
363                         break;
364 
365 		case 'C':
366 			sscanf(ntp_optarg, "%lf", &ntp_node.snse);
367                         break;
368 
369 		case 'H':
370 			sscanf(ntp_optarg, "%lf", &ntp_node.slew);
371                         break;
372 
373 		case 'O':
374 			sscanf(ntp_optarg, "%lf", &ntp_node.clk_time);
375                         break;
376 
377 		case 'S':
378 			sscanf(ntp_optarg, "%lf", &ntp_node.sim_time);
379                         break;
380 
381 		case 'T':
382 			sscanf(ntp_optarg, "%lf", &ntp_node.ferr);
383                         break;
384 
385 		case 'W':
386 			sscanf(ntp_optarg, "%lf", &ntp_node.fnse);
387                         break;
388 
389 		case 'Y':
390 			sscanf(ntp_optarg, "%lf", &ntp_node.ndly);
391                         break;
392 
393 		case 'Z':
394 			sscanf(ntp_optarg, "%lf", &ntp_node.pdly);
395                         break;
396 
397 #endif /* SIM */
398 		    default:
399 			errflg++;
400 			break;
401 		}
402 	}
403 
404 	if (errflg || ntp_optind != argc) {
405 		(void) fprintf(stderr, "usage: %s [ -abdgmnx ] [ -c config_file ] [ -e e_delay ]\n", progname);
406 		(void) fprintf(stderr, "\t\t[ -f freq_file ] [ -k key_file ] [ -l log_file ]\n");
407 		(void) fprintf(stderr, "\t\t[ -p pid_file ] [ -r broad_delay ] [ -s statdir ]\n");
408 		(void) fprintf(stderr, "\t\t[ -t trust_key ] [ -v sys_var ] [ -V default_sysvar ]\n");
409 #if defined(HAVE_SCHED_SETSCHEDULER)
410 		(void) fprintf(stderr, "\t\t[ -P fixed_process_priority ]\n");
411 #endif
412 #ifdef HAVE_CLOCKCTL
413 		(void) fprintf(stderr, "\t\t[ -u user[:group] ] [ -i chrootdir ]\n");
414 #endif
415 		exit(2);
416 	}
417 	return;
418 }
419