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