1 /* Copyright (C) 1996, 1997, 2000 N.M. Maclaren 2 Copyright (C) 1996, 1997, 2000 The University of Cambridge 3 4 This is a complete SNTP implementation, which was easier to write than to port 5 xntp to a new version of Unix with any hope of maintaining it thereafter. It 6 supports the full SNTP (RFC 2030) client- and server-side challenge-response 7 and broadcast protocols. It should achieve nearly optimal accuracy with very 8 few transactions, provided only that a client has access to a trusted server 9 and that communications are not INVARIABLY slow. As this is the environment in 10 which 90-99% of all NTP systems are run .... 11 12 The specification of this program is: 13 14 msntp [ --help | -h | -? ] [ -v | -V | -W ] 15 [ -B [ period ] | -S | -q [ -f savefile ] | 16 [ { -r | -a } [ -P prompt ] [ -l lockfile ] ] 17 [ -c count ] [ -e minerr ][ -E maxerr ] 18 [ -d delay | -x [ separation ] [ -f savefile ] ] 19 [ -4 | -6 ] [ address(es) ] ] 20 21 --help, -h and -? all print the syntax of the command. 22 23 -v indicates that diagnostic messages should be written to standard error, 24 and -V requests more output for investigating apparently inconsistent 25 timestamps. -W requests very verbose debugging output, and will interfere with 26 the timing when writing to the terminal (because of line buffered output from 27 C); it is useful only when debugging the source. Note that the times produced 28 by -V and -W are the corrections needed, and not the error in the local clock. 29 30 -B indicates that it should behave as a server, broadcasting time packets 31 at intervals of 'period' minutes. Acceptable values of 'period' are from 1 to 32 1440 (a day) and the default is 60. Naturally, this will work only if the 33 user has enough privilege. 34 35 -S indicates that it should behave as a server, responding to time requests 36 from clients. Naturally, this will work only if the user has enough privilege. 37 38 -q indicates that it will query a savefile that is being maintained by 39 it being run in daemon mode. 40 41 The default is that it should behave as a client, and the following options 42 are then relevant: 43 44 -r indicates that the system clock should be reset by 'settimeofday'. 45 Naturally, this will work only if the user has enough privilege. 46 47 -a indicates that the system clock should be reset by 'adjtime'. 48 Naturally, this will work only if the user has enough privilege. 49 50 -x indicates that the program should run as a daemon (i.e. forever), and 51 allow for clock drift. 52 53 -4 or -6 force dns resolving to ipv4 or ipv6 addresses. 54 55 The default is to write the current date and time to the standard output in 56 a format like '1996 Oct 15 20:17:25.123 + 4.567 +/- 0.089 secs', indicating the 57 estimated true (local) time and the error in the local clock. In daemon mode, 58 it will add drift information in a format like ' + 1.3 +/- 0.1 ppm', and 59 display this at roughly 'separation' intervals. 60 61 'minerr' is the maximum ignorable variation between the clocks. Acceptable 62 values are from 0.001 to 1, and the default is 0.1 if 'address' is specified 63 and 0.5 otherwise. 64 65 'maxerr' is the maximum value of various delays that are deemed acceptable. 66 Acceptable values are from 1 to 60, and the default is 5. It should sometimes 67 be increased if there are problems with the network, NTP server or system 68 clock, but take care. 69 70 'prompt' is the maximum clock change that will be made automatically. 71 Acceptable values are from 1 to 3600, and the default is 30. If the program is 72 being run interactively, larger values will cause a prompt. The value may also 73 be 'no', and the change will be made without prompting. 74 75 'count' is the maximum number of NTP packets to require. Acceptable values 76 are from 1 to 25 if 'address' is specified and '-x' is not, and from 5 to 25 77 otherwise; the default is 5. If the maximum isn't enough, you need a better 78 consistency algorithm than this program uses. Don't increase it. 79 80 'delay' is a rough limit on the total running time in seconds. Acceptable 81 values are from 1 to 3600, and the default is 15 if 'address' is specified and 82 300 otherwise. 83 84 'separation' is the time to wait between calls to the server in minutes if 85 'address' is specified, and the minimum time between broadcast packets if not. 86 Acceptable values are from 1 to 1440 (a day), and the default is 300. 87 88 'lockfile' may be used in an update mode to ensure that there is only 89 one copy of msntp running at once. The default is installation-dependent, 90 but will usually be /etc/msntp.pid. 91 92 'savefile' may be used in daemon mode to store a record of previous 93 packets, which may speed up recalculating the drift after msntp has to be 94 restarted (e.g. because of network or server outages). The default is 95 installation-dependent, but will usually be /etc/msntp.state. Note that 96 there is no locking of this file, and using it twice may cause chaos. 97 98 'address' is the DNS name or IP number of a host to poll; if no name is 99 given, the program waits for broadcasts. Note that a single component numeric 100 address is not allowed. 101 102 For sanity, it is also required that 'minerr' < 'maxerr' < 'delay' (if 103 listening for broadcasts, 'delay/count' and, in daemon mode, 'separation') and, 104 for sordid Unixish reasons, that 2*'count' < 'delay'. The last could be fixed, 105 but isn't worth it. Note that none of the above values are closely linked to 106 the limits described in the NTP protocol (RFC 1305). Do not increase the 107 compiled-in bounds excessively, or the code will fail. 108 109 The algorithm used to decide whether to accept a correction is whether it would 110 seem to improve matters. Unlike the 'xntp' suite, little attempt is made to 111 handle really knotted scenarios, and diagnostics are written to standard error. 112 In non-daemon client mode, it is intended to be run as a command or in a 'cron' 113 job. Unlike 'ntpdate', its default mode is simply to display the clock error. 114 115 It assumes that floating-point arithmetic is tolerably efficient, which is true 116 for even the cheapest personal computer nowadays. If, however, you want to 117 port this to a toaster, you may have problems! 118 119 In its terminating modes, its return code is EXIT_SUCCESS if the operation was 120 completed successfully and EXIT_FAILURE otherwise. 121 122 In server or daemon mode, it runs for ever and stops with a return code 123 EXIT_FAILURE only after a severe error. Commonly, two server processes will be 124 run, one with each of the -B and -S options. In daemon mode, it will fail if 125 the server is inaccessible for a long time or seriously sick, and will need 126 manual restarting. 127 128 129 WARNING: this program has reached its 'hack count' and needs restructuring, 130 badly. Perhaps the worst code is in run_daemon(). You are advised not to 131 fiddle unless you really have to. */ 132 133 134 135 #include "header.h" 136 137 #include <limits.h> 138 #include <float.h> 139 #include <math.h> 140 141 #define MAIN 142 #include "kludges.h" 143 #undef MAIN 144 145 146 147 /* NTP definitions. Note that these assume 8-bit bytes - sigh. There is 148 little point in parameterising everything, as it is neither feasible nor 149 useful. It would be very useful if more fields could be defined as 150 unspecified. The NTP packet-handling routines contain a lot of extra 151 assumptions. */ 152 153 #define JAN_1970 2208988800.0 /* 1970 - 1900 in seconds */ 154 #define NTP_SCALE 4294967296.0 /* 2^32, of course! */ 155 156 #define NTP_PACKET_MIN 48 /* Without authentication */ 157 #define NTP_PACKET_MAX 68 /* With authentication (ignored) */ 158 #define NTP_DISP_FIELD 8 /* Offset of dispersion field */ 159 #define NTP_REFERENCE 16 /* Offset of reference timestamp */ 160 #define NTP_ORIGINATE 24 /* Offset of originate timestamp */ 161 #define NTP_RECEIVE 32 /* Offset of receive timestamp */ 162 #define NTP_TRANSMIT 40 /* Offset of transmit timestamp */ 163 164 #define NTP_LI_FUDGE 0 /* The current 'status' */ 165 #define NTP_VERSION 3 /* The current version */ 166 #define NTP_VERSION_MAX 4 /* The maximum valid version */ 167 #define NTP_STRATUM 15 /* The current stratum as a server */ 168 #define NTP_STRATUM_MAX 15 /* The maximum valid stratum */ 169 #define NTP_POLLING 8 /* The current 'polling interval' */ 170 #define NTP_PRECISION 0 /* The current 'precision' - 1 sec. */ 171 172 #define NTP_ACTIVE 1 /* NTP symmetric active request */ 173 #define NTP_PASSIVE 2 /* NTP symmetric passive response */ 174 #define NTP_CLIENT 3 /* NTP client request */ 175 #define NTP_SERVER 4 /* NTP server response */ 176 #define NTP_BROADCAST 5 /* NTP server broadcast */ 177 178 #define NTP_INSANITY 3600.0 /* Errors beyond this are hopeless */ 179 #define RESET_MIN 15 /* Minimum period between resets */ 180 #define ABSCISSA 3.0 /* Scale factor for standard errors */ 181 182 183 184 /* Local definitions and global variables (mostly options). These are all of 185 the quantities that control the main actions of the program. The first three 186 are the only ones that are exported to other modules. */ 187 188 const char *argv0 = NULL; /* For diagnostics only - not NULL */ 189 int verbose = 0, /* Default = 0, -v = 1, -V = 2, -W = 3 */ 190 operation = 0; /* Defined in header.h - see action */ 191 const char *lockname = NULL; /* The name of the lock file */ 192 193 #define COUNT_MAX 25 /* Do NOT increase this! */ 194 #define WEEBLE_FACTOR 1.2 /* See run_server() and run_daemon() */ 195 #define ETHERNET_MAX 5 /* See run_daemon() and run_client() */ 196 197 #define action_display 1 /* Just display the result */ 198 #define action_reset 2 /* Reset using 'settimeofday' */ 199 #define action_adjust 3 /* Reset using 'adjtime' */ 200 #define action_broadcast 4 /* Behave as a server, broadcasting */ 201 #define action_server 5 /* Behave as a server for clients */ 202 #define action_query 6 /* Query a daemon savefile */ 203 204 #define save_read_only 1 /* Read the saved state only */ 205 #define save_read_check 2 /* Read and check it */ 206 #define save_write 3 /* Write the saved state */ 207 #define save_clear 4 /* Clear the saved state */ 208 209 static const char version[] = VERSION; /* For reverse engineering :-) */ 210 static int action = 0, /* Defined above - see operation */ 211 period = 0, /* -B value in seconds (broadcast) */ 212 count = 0, /* -c value in seconds */ 213 delay = 0, /* -d or -x value in seconds */ 214 attempts = 0, /* Packets transmitted up to 2*count */ 215 waiting = 0, /* -d/-c except for in daemon mode */ 216 locked = 0; /* set_lock(1) has been called */ 217 static double outgoing[2*COUNT_MAX], /* Transmission timestamps */ 218 minerr = 0.0, /* -e value in seconds */ 219 maxerr = 0.0, /* -E value in seconds */ 220 prompt = 0.0, /* -p value in seconds */ 221 dispersion = 0.0; /* The source dispersion in seconds */ 222 static FILE *savefile = NULL; /* Holds the data to restart from */ 223 224 225 226 /* The unpacked NTP data structure, with all the fields even remotely relevant 227 to SNTP. */ 228 229 typedef struct NTP_DATA { 230 unsigned char status, version, mode, stratum, polling, precision; 231 double dispersion, reference, originate, receive, transmit, current; 232 } ntp_data; 233 234 235 236 /* The following structure is used to keep a record of packets in daemon mode; 237 it contains only the information that is actually used for the drift and error 238 calculations. */ 239 240 typedef struct { 241 double dispersion, weight, when, offset, error; 242 } data_record; 243 244 245 246 void fatal (int syserr, const char *message, const char *insert) { 247 248 /* Issue a diagnostic and stop. Be a little paranoid about recursion. */ 249 250 int k = errno; 251 static int called = 0; 252 253 if (message != NULL) { 254 fprintf(stderr,"%s: ",argv0); 255 fprintf(stderr,message,insert); 256 fprintf(stderr,"\n"); 257 } 258 errno = k; 259 if (syserr) perror(argv0); 260 if (! called) { 261 called = 1; 262 if (savefile != NULL && fclose(savefile)) 263 fatal(1,"unable to close the daemon save file",NULL); 264 if (locked) set_lock(0); 265 } 266 exit(EXIT_FAILURE); 267 } 268 269 270 271 void syntax (int halt) { 272 273 /* The standard, unfriendly Unix error message. Some errors are diagnosed more 274 helpfully. This is called before any files or sockets are opened. */ 275 276 fprintf(stderr,"Syntax: %s [ --help | -h | -? ] [ -v | -V | -W ] \n",argv0); 277 fprintf(stderr," [ -B period | -S | -q [ -f savefile ] |\n"); 278 fprintf(stderr," [ { -r | -a } [ -P prompt ] [ -l lockfile ] ]\n"); 279 fprintf(stderr," [ -c count ] [ -e minerr ] [ -E maxerr ]\n"); 280 fprintf(stderr," [ -d delay | -x [ separation ] "); 281 fprintf(stderr,"[ -f savefile ] ]\n"); 282 fprintf(stderr," [ -4 | -6 ] [ address(es) ] ]\n"); 283 if (halt) exit(EXIT_FAILURE); 284 } 285 286 287 288 void display_data (ntp_data *data) { 289 290 /* This formats the essential NTP data, as a debugging aid. */ 291 292 fprintf(stderr,"sta=%d ver=%d mod=%d str=%d pol=%d dis=%.6f ref=%.6f\n", 293 data->status,data->version,data->mode,data->stratum,data->polling, 294 data->dispersion,data->reference); 295 fprintf(stderr,"ori=%.6f rec=%.6f\n",data->originate,data->receive); 296 fprintf(stderr,"tra=%.6f cur=%.6f\n",data->transmit,data->current); 297 } 298 299 300 301 void display_packet (unsigned char *packet, int length) { 302 303 /* This formats a possible packet very roughly, as a debugging aid. */ 304 305 int i; 306 307 if (length < NTP_PACKET_MIN || length > NTP_PACKET_MAX) return; 308 for (i = 0; i < length; ++i) { 309 if (i != 0 && i%32 == 0) 310 fprintf(stderr,"\n"); 311 else if (i != 0 && i%4 == 0) 312 fprintf(stderr," "); 313 fprintf(stderr,"%.2x",packet[i]); 314 } 315 fprintf(stderr,"\n"); 316 } 317 318 319 320 void pack_ntp (unsigned char *packet, int length, ntp_data *data) { 321 322 /* Pack the essential data into an NTP packet, bypassing struct layout and 323 endian problems. Note that it ignores fields irrelevant to SNTP. */ 324 325 int i, k; 326 double d; 327 328 memset(packet,0,(size_t)length); 329 packet[0] = (data->status<<6)|(data->version<<3)|data->mode; 330 packet[1] = data->stratum; 331 packet[2] = data->polling; 332 packet[3] = data->precision; 333 d = data->originate/NTP_SCALE; 334 for (i = 0; i < 8; ++i) { 335 if ((k = (int)(d *= 256.0)) >= 256) k = 255; 336 packet[NTP_ORIGINATE+i] = k; 337 d -= k; 338 } 339 d = data->receive/NTP_SCALE; 340 for (i = 0; i < 8; ++i) { 341 if ((k = (int)(d *= 256.0)) >= 256) k = 255; 342 packet[NTP_RECEIVE+i] = k; 343 d -= k; 344 } 345 d = data->transmit/NTP_SCALE; 346 for (i = 0; i < 8; ++i) { 347 if ((k = (int)(d *= 256.0)) >= 256) k = 255; 348 packet[NTP_TRANSMIT+i] = k; 349 d -= k; 350 } 351 } 352 353 354 355 void unpack_ntp (ntp_data *data, unsigned char *packet, int length) { 356 357 /* Unpack the essential data from an NTP packet, bypassing struct layout and 358 endian problems. Note that it ignores fields irrelevant to SNTP. */ 359 360 int i; 361 double d; 362 363 data->current = current_time(JAN_1970); /* Best to come first */ 364 data->status = (packet[0] >> 6); 365 data->version = (packet[0] >> 3)&0x07; 366 data->mode = packet[0]&0x07; 367 data->stratum = packet[1]; 368 data->polling = packet[2]; 369 data->precision = packet[3]; 370 d = 0.0; 371 for (i = 0; i < 4; ++i) d = 256.0*d+packet[NTP_DISP_FIELD+i]; 372 data->dispersion = d/65536.0; 373 d = 0.0; 374 for (i = 0; i < 8; ++i) d = 256.0*d+packet[NTP_REFERENCE+i]; 375 data->reference = d/NTP_SCALE; 376 d = 0.0; 377 for (i = 0; i < 8; ++i) d = 256.0*d+packet[NTP_ORIGINATE+i]; 378 data->originate = d/NTP_SCALE; 379 d = 0.0; 380 for (i = 0; i < 8; ++i) d = 256.0*d+packet[NTP_RECEIVE+i]; 381 data->receive = d/NTP_SCALE; 382 d = 0.0; 383 for (i = 0; i < 8; ++i) d = 256.0*d+packet[NTP_TRANSMIT+i]; 384 data->transmit = d/NTP_SCALE; 385 } 386 387 388 389 void make_packet (ntp_data *data, int mode) { 390 391 /* Create an outgoing NTP packet, either from scratch or starting from a 392 request from a client. Note that it implements the NTP specification, even 393 when this is clearly misguided, except possibly for the setting of LI. It 394 would be easy enough to add a sanity flag, but I am not in the business of 395 designing an alternative protocol (however much better it might be). */ 396 397 data->status = NTP_LI_FUDGE<<6; 398 data->stratum = NTP_STRATUM; 399 data->reference = data->dispersion = 0.0; 400 if (mode == NTP_SERVER) { 401 data->mode = (data->mode == NTP_CLIENT ? NTP_SERVER : NTP_PASSIVE); 402 data->originate = data->transmit; 403 data->receive = data->current; 404 } else { 405 data->version = NTP_VERSION; 406 data->mode = mode; 407 data->polling = NTP_POLLING; 408 data->precision = NTP_PRECISION; 409 data->receive = data->originate = 0.0; 410 } 411 data->current = data->transmit = current_time(JAN_1970); 412 } 413 414 415 416 int read_packet (int which, ntp_data *data, double *off, double *err) { 417 418 /* Check the packet and work out the offset and optionally the error. Note 419 that this contains more checking than xntp does. This returns 0 for success, 1 420 for failure and 2 for an ignored broadcast packet (a kludge for servers). Note 421 that it must not change its arguments if it fails. */ 422 423 unsigned char receive[NTP_PACKET_MAX+1]; 424 double delay1, delay2, x, y; 425 int response = 0, failed, length, i, k; 426 427 /* Read the packet and deal with diagnostics. */ 428 429 if ((length = read_socket(which,receive,NTP_PACKET_MAX+1,waiting)) <= 0) 430 return 1; 431 if (length < NTP_PACKET_MIN || length > NTP_PACKET_MAX) { 432 if (verbose) 433 fprintf(stderr,"%s: bad length %d for NTP packet on socket %d\n", 434 argv0,length,which); 435 return 1; 436 } 437 if (verbose > 2) { 438 fprintf(stderr,"Incoming packet on socket %d:\n",which); 439 display_packet(receive,length); 440 } 441 unpack_ntp(data,receive,length); 442 if (verbose > 2) display_data(data); 443 444 /* Start by checking that the packet looks reasonable. Be a little paranoid, 445 but allow for version 1 semantics and sick clients. */ 446 447 if (operation == op_server) { 448 if (data->mode == NTP_BROADCAST) return 2; 449 failed = (data->mode != NTP_CLIENT && data->mode != NTP_ACTIVE); 450 } else if (operation == op_listen) 451 failed = (data->mode != NTP_BROADCAST); 452 else { 453 failed = (data->mode != NTP_SERVER && data->mode != NTP_PASSIVE); 454 response = 1; 455 } 456 if (failed || data->status != 0 || data->version < 1 || 457 data->version > NTP_VERSION_MAX || 458 data->stratum > NTP_STRATUM_MAX) { 459 if (verbose) 460 fprintf(stderr, 461 "%s: totally spurious NTP packet rejected on socket %d\n", 462 argv0,which); 463 return 1; 464 } 465 466 /* Note that the conventions are very poorly defined in the NTP protocol, so we 467 have to guess. Any full NTP server perpetrating completely unsynchronised 468 packets is an abomination, anyway, so reject it. */ 469 470 delay1 = data->transmit-data->receive; 471 delay2 = data->current-data->originate; 472 failed = ((data->stratum != 0 && data->stratum != NTP_STRATUM_MAX && 473 data->reference == 0.0) || 474 (operation != op_server && data->transmit == 0.0)); 475 if (response && 476 (data->originate == 0.0 || data->receive == 0.0 || 477 (data->reference != 0.0 && data->receive < data->reference) || 478 delay1 < 0.0 || delay1 > NTP_INSANITY || delay2 < 0.0 || 479 data->dispersion > NTP_INSANITY)) 480 failed = 1; 481 if (failed) { 482 if (verbose) 483 fprintf(stderr, 484 "%s: incomprehensible NTP packet rejected on socket %d\n", 485 argv0,which); 486 return 1; 487 } 488 489 /* If it is a response, check that it corresponds to one of our requests and 490 has got here in a reasonable length of time. */ 491 492 if (response) { 493 k = 0; 494 for (i = 0; i < attempts; ++i) 495 if (data->originate == outgoing[i]) { 496 outgoing[i] = 0.0; 497 ++k; 498 } 499 if (k != 1 || delay2 > NTP_INSANITY) { 500 if (verbose) 501 fprintf(stderr, 502 "%s: bad response from NTP server rejected on socket %d\n", 503 argv0,which); 504 return 1; 505 } 506 } 507 508 /* Now return the time information. If it is a server response, it contains 509 enough information that we can be almost certain that we have not been fooled 510 too badly. Heaven help us with broadcasts - make a wild kludge here, and see 511 elsewhere for other kludges. */ 512 513 if (dispersion < data->dispersion) dispersion = data->dispersion; 514 if (operation == op_listen || operation == op_server) { 515 *off = data->transmit-data->current; 516 *err = NTP_INSANITY; 517 } else { 518 x = data->receive-data->originate; 519 y = (data->transmit == 0.0 ? 0.0 : data->transmit-data->current); 520 *off = 0.5*(x+y); 521 *err = x-y; 522 x = data->current-data->originate; 523 if (0.5*x > *err) *err = 0.5*x; 524 } 525 return 0; 526 } 527 528 529 530 void format_time (char *text, int length, double offset, double error, 531 double drift, double drifterr) { 532 533 /* Format the current time into a string, with the extra information as 534 requested. Note that the rest of the program uses the correction needed, which 535 is what is printed for diagnostics, but this formats the error in the local 536 system for display to users. So the results from this are the negation of 537 those printed by the verbose options. */ 538 539 int milli, len; 540 time_t now; 541 struct tm *gmt; 542 static const char *months[] = { 543 "Jan", "Feb", "Mar", "Apr", "May", "Jun", 544 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 545 }; 546 547 /* Work out and format the current local time. Note that some semi-ANSI 548 systems do not set the return value from (s)printf. */ 549 550 now = convert_time(current_time(offset),&milli); 551 errno = 0; 552 if ((gmt = localtime(&now)) == NULL) 553 fatal(1,"unable to work out local time",NULL); 554 len = 24; 555 if (length <= len) fatal(0,"internal error calling format_time",NULL); 556 errno = 0; 557 sprintf(text,"%.4d %s %.2d %.2d:%.2d:%.2d.%.3d", 558 gmt->tm_year+1900,months[gmt->tm_mon],gmt->tm_mday, 559 gmt->tm_hour,gmt->tm_min,gmt->tm_sec,milli); 560 if (strlen(text) != len) 561 fatal(1,"unable to format current local time",NULL); 562 563 /* Append the information about the offset, if requested. */ 564 565 if (error >= 0.0) { 566 if (length < len+30) 567 fatal(0,"internal error calling format_time",NULL); 568 errno = 0; 569 sprintf(&text[len]," %c %.3f +/- %.3f secs",(offset > 0.0 ? '-' : '+'), 570 (offset > 0.0 ? offset : -offset),dispersion+error); 571 if (strlen(&text[len]) < 22) 572 fatal(1,"unable to format clock correction",NULL); 573 } 574 575 /* Append the information about the drift, if requested. */ 576 577 if (drifterr >= 0.0) { 578 len = strlen(text); 579 if (length < len+25) 580 fatal(0,"internal error calling format_time",NULL); 581 errno = 0; 582 sprintf(&text[len]," %c %.1f +/- %.1f ppm", 583 (drift > 0.0 ? '-' : '+'),1.0e6*fabs(drift), 584 1.0e6*drifterr); 585 if (strlen(&text[len]) < 17) 586 fatal(1,"unable to format clock correction",NULL); 587 } 588 589 /* It would be better to check for field overflow, but it is a lot of code to 590 trap extremely implausible scenarios. This will usually stop chaos from 591 spreading. */ 592 593 if (strlen(text) >= length) 594 fatal(0,"internal error calling format_time",NULL); 595 } 596 597 598 599 double reset_clock (double offset, double error, int daemon) { 600 601 /* Reset the clock, if appropriate, and return the correction actually used. 602 This contains most of the checking for whether changes are worthwhile, except 603 in daemon mode. */ 604 605 double absoff = (offset < 0 ? -offset : offset); 606 char text[50]; 607 608 /* If the correction is large, ask for confirmation before proceeding. */ 609 610 if (absoff > prompt) { 611 if (! daemon && ftty(stdin) && ftty(stdout)) { 612 printf("The time correction is %.3f +/- %.3f+%.3f seconds\n", 613 offset,dispersion,error); 614 printf("Do you want to correct the time anyway? "); 615 fflush(stdout); 616 if (toupper(getchar()) != 'Y') { 617 printf("OK - quitting\n"); 618 fatal(0,NULL,NULL); 619 } 620 } else { 621 sprintf(text,"%.3f +/- %.3f+%.3f",offset,dispersion,error); 622 fatal(0,"time correction too large: %s seconds",text); 623 } 624 } 625 626 /* See if the correction is reasonably reliable and worth making. */ 627 628 if (absoff < (daemon ? 0.5 : 1.0)*minerr) { 629 if (daemon ? verbose > 1 : verbose) 630 fprintf(stderr,"%s: correction %.3f +/- %.3f+%.3f secs - ignored\n", 631 argv0,offset,dispersion,error); 632 return 0.0; 633 } else if (absoff < 2.0*error) { 634 if (daemon ? verbose > 1 : verbose) 635 fprintf(stderr, 636 "%s: correction %.3f +/- %.3f+%.3f secs - suppressed\n", 637 argv0,offset,dispersion,error); 638 return 0.0; 639 } 640 641 /* Make the correction. Provide some protection against the previous 642 correction not having completed, but it will rarely help much. */ 643 644 adjust_time(offset,(action == action_reset ? 1 : 0), 645 (daemon ? 2.0*minerr : 0.0)); 646 if (daemon ? verbose > 1 : verbose) { 647 format_time(text,50,0.0,-1.0,0.0,-1.0); 648 fprintf(stderr, 649 "%s: time changed by %.3f secs to %s +/- %.3f+%.3f\n", 650 argv0,offset,text,dispersion,error); 651 } 652 return offset; 653 } 654 655 656 657 void run_server (void) { 658 659 /* Set up a socket, and either broadcast at intervals or wait for requests. 660 It is quite tricky to get this to fail, and it will usually indicate that the 661 local system is sick. */ 662 663 unsigned char transmit[NTP_PACKET_MIN]; 664 ntp_data data; 665 double started = current_time(JAN_1970), successes = 0.0, failures = 0.0, 666 broadcasts = 0.0, weeble = 1.0, x, y; 667 int i, j; 668 669 open_socket(0,NULL,delay); 670 while (1) { 671 672 /* In server mode, provide some tracing of normal running (but not too much, 673 except when debugging!) */ 674 675 if (operation == op_server) { 676 x = current_time(JAN_1970)-started; 677 if (verbose && x/3600.0+successes+failures >= weeble) { 678 weeble *= WEEBLE_FACTOR; 679 x -= 3600.0*(i = (int)(x/3600.0)); 680 x -= 60.0*(j = (int)(x/60.0)); 681 if (i > 0) 682 fprintf(stderr,"%s: after %d hours %d mins ",argv0,i,j); 683 else if (j > 0) 684 fprintf(stderr,"%s: after %d mins %.0f secs ",argv0,j,x); 685 else 686 fprintf(stderr,"%s: after %.1f secs ",argv0,x); 687 fprintf(stderr,"%.0f acc. %.0f rej. %.0f b'cast\n", 688 successes,failures,broadcasts); 689 } 690 691 /* Respond to incoming requests or plaster broadcasts over the net. Note that 692 we could skip almost all of the decoding, but it provides a healthy amount of 693 error detection. We could print some information on incoming packets, but the 694 code is not structured to do this very helpfully. */ 695 696 i = read_packet(0,&data,&x,&y); 697 if (i == 2) { 698 ++broadcasts; 699 continue; 700 } else if (i != 0) { 701 ++failures; 702 continue; 703 } else { 704 ++successes; 705 make_packet(&data,NTP_SERVER); 706 } 707 } else { 708 do_nothing(period); 709 make_packet(&data,NTP_BROADCAST); 710 } 711 if (verbose > 2) { 712 fprintf(stderr,"Outgoing packet:\n"); 713 display_data(&data); 714 } 715 pack_ntp(transmit,NTP_PACKET_MIN,&data); 716 if (verbose > 2) display_packet(transmit,NTP_PACKET_MIN); 717 write_socket(0,transmit,NTP_PACKET_MIN); 718 } 719 } 720 721 722 723 double estimate_stats (int *a_total, int *a_index, data_record *record, 724 double correction, double *a_disp, double *a_when, double *a_offset, 725 double *a_error, double *a_drift, double *a_drifterr, int *a_wait, 726 int update) { 727 728 /* This updates the running statistics and returns the best estimate of what to 729 do now. It returns the timestamp relevant to the correction. If broadcasts 730 are rare and the drift is large, it will fail - you should then use a better 731 synchronisation method. It will also fail if something goes severely wrong 732 (e.g. if the local clock is reset by another process or the transmission errors 733 are beyond reason). 734 735 There is a kludge for synchronisation loss during down time. If it detects 736 this, it will update only the history data and return zero; this is then 737 handled specially in run_daemon(). While it could correct the offset, this 738 might not always be the right thing to do. */ 739 740 double weight, disp, when, offset, error, drift, drifterr, 741 now, e, w, x, y, z; 742 int total = *a_total, index = *a_index, wait = *a_wait, i; 743 char text[50]; 744 745 /* Correct the previous data and store a new entry in the circular buffer. */ 746 747 for (i = 0; i < total; ++i) { 748 record[i].when += correction; 749 record[i].offset -= correction; 750 } 751 if (update) { 752 record[index].dispersion = *a_disp; 753 record[index].when = *a_when; 754 record[index].offset = *a_offset; 755 if (verbose > 1) 756 fprintf(stderr,"%s: corr=%.3f when=%.3f disp=%.3f off=%.3f", 757 argv0,correction,*a_when,*a_disp,*a_offset); /* See below */ 758 if (operation == op_listen) { 759 if (verbose > 1) fprintf(stderr,"\n"); 760 record[index].error = minerr; 761 record[index].weight = 1.0; 762 } else { 763 if (verbose > 1) fprintf(stderr," err=%.3f\n",*a_error); 764 record[index].error = x = *a_error; 765 record[index].weight = 1.0/(x > minerr ? x*x : minerr*minerr); 766 } 767 if (++index >= count) index = 0; 768 *a_index = index; 769 if (++total > count) total = count; 770 *a_total = total; 771 if (verbose > 2) 772 fprintf(stderr,"corr=%.6f tot=%d ind=%d\n",correction,total,index); 773 } 774 775 /* If there is insufficient data yet, use the latest estimates and return 776 forthwith. Note that this will not work for broadcasts, but they will be 777 disabled in run_daemon(). */ 778 779 if ((operation == op_listen && total < count && update) || total < 3) { 780 *a_drift = 0.0; 781 *a_drifterr = -1.0; 782 *a_wait = delay; 783 return *a_when; 784 } 785 786 /* Work out the average time, offset, error etc. Note that the dispersion is 787 not subject to the central limit theorem. Unfortunately, the variation in the 788 source's dispersion is our only indication of how consistent its clock is. */ 789 790 disp = weight = when = offset = y = 0.0; 791 for (i = 0; i < total; ++i) { 792 weight += w = record[i].weight; 793 when += w*record[i].when; 794 offset += w*record[i].offset; 795 y += w*record[i].dispersion; 796 if (disp < record[i].dispersion) 797 disp = record[i].dispersion; 798 } 799 when /= weight; 800 offset /= weight; 801 y /= weight; 802 if (verbose > 2) 803 fprintf(stderr,"disp=%.6f wgt=%.3f when=%.6f off=%.6f\n", 804 disp,weight,when,offset); 805 806 /* If there is enough data, estimate the drift and errors by regression. Note 807 that it is essential to calculate the mean square error, not the mean error. */ 808 809 error = drift = x = z = 0.0; 810 for (i = 0; i < total; ++i) { 811 w = record[i].weight/weight; 812 x += w*(record[i].when-when)*(record[i].when-when); 813 drift += w*(record[i].when-when)*(record[i].offset-offset); 814 z += w*(record[i].offset-offset)*(record[i].offset-offset); 815 error += w*record[i].error*record[i].error+ 816 2.0*w*(record[i].dispersion-y)*(record[i].dispersion-y); 817 } 818 if (verbose > 2) 819 fprintf(stderr,"X2=%.3f XY=%.6f Y2=%.9f E2=%.9f ",x,drift,z,error); 820 821 /* When calculating the errors, add some paranoia mainly to check for coding 822 errors and complete lunacy, attempting to retry if at all possible. Because 823 glitches at this point are so common, log a reset even in non-verbose mode. 824 There will be more thorough checks later. Note that we cannot usefully check 825 the error for broadcasts. */ 826 827 z -= drift*drift/x; 828 if (verbose > 2) fprintf(stderr,"S2=%.9f\n",z); 829 if (! update) { 830 if (z > 1.0e6) 831 fatal(0,"stored data too unreliable for time estimation",NULL); 832 } else if (operation == op_client) { 833 e = error+disp*disp+minerr*minerr; 834 if (z > e) { 835 if (verbose || z >= maxerr*maxerr) 836 fprintf(stderr, 837 "%s: excessively high error %.3f > %.3f > %.3f\n", 838 argv0,sqrt(z),sqrt(e),sqrt(error)); 839 if (total <= 1) 840 return 0.0; 841 else if (z < maxerr*maxerr) { 842 sprintf(text,"resetting on error %.3g > %.3g", 843 sqrt(z),sqrt(e)); 844 log_message(text); 845 return 0.0; 846 } else 847 fatal(0,"incompatible (i.e. erroneous) timestamps",NULL); 848 } else if (z > error && verbose) 849 fprintf(stderr, 850 "%s: anomalously high error %.3f > %.3f, but < %.3f\n", 851 argv0,sqrt(z),sqrt(error),sqrt(e)); 852 } else { 853 if (z > maxerr*maxerr) 854 fatal(0,"broadcasts too unreliable for time estimation",NULL); 855 } 856 drift /= x; 857 drifterr = ABSCISSA*sqrt(z/(x*total)); 858 error = (operation == op_listen ? minerr : 0.0)+ABSCISSA*sqrt(z/total); 859 if (verbose > 2) 860 fprintf(stderr,"err=%.6f drift=%.6f+/-%.6f\n",error,drift,drifterr); 861 if (error+drifterr*delay > NTP_INSANITY) 862 fatal(0,"unable to get a reasonable drift estimate",NULL); 863 864 /* Estimate the optimal short-loop period, checking it carefully. Remember to 865 check that this whole process is likely to be accurate enough and that the 866 delay function may be inaccurate. */ 867 868 wait = delay; 869 x = (drift < 0.0 ? -drift : drift); 870 if (x*delay < 0.5*minerr) { 871 if (verbose > 2) fprintf(stderr,"Drift too small to correct\n"); 872 } else if (x < 2.0*drifterr) { 873 if (verbose > 2) 874 fprintf(stderr,"Drift correction suppressed\n"); 875 } else { 876 if ((z = drifterr*delay) < 0.5*minerr) z = 0.5*minerr; 877 wait = (x < z/delay ? delay : (int)(z/x+0.5)); 878 wait = (int)(delay/(int)(delay/(double)wait+0.999)+0.999); 879 if (wait > delay) 880 fatal(0,"internal error in drift calculation",NULL); 881 if (update && (drift*wait > maxerr || wait < RESET_MIN)) { 882 sprintf(text,"%.6f+/-%.6f",drift,drifterr); 883 fatal(0,"drift correction too large: %s",text); 884 } 885 } 886 if (wait < *a_wait/2) wait = *a_wait/2; 887 if (wait > *a_wait*2) wait = *a_wait*2; 888 889 /* Now work out what the correction should be, as distinct from what it should 890 have been, remembering that older times are less certain. */ 891 892 now = current_time(JAN_1970); 893 x = now-when; 894 offset += x*drift; 895 error += x*drifterr; 896 for (i = 0; i < total; ++i) { 897 x = now-record[i].when; 898 z = record[i].error+x*drifterr; 899 if (z < error) { 900 when = record[i].when; 901 offset = record[i].offset+x*drift; 902 error = z; 903 } 904 } 905 if (verbose > 2) 906 fprintf(stderr,"now=%.6f when=%.6f off=%.6f err=%.6f wait=%d\n", 907 now,when,offset,error,wait); 908 909 /* Finally, return the result. */ 910 911 *a_disp = disp; 912 *a_when = when; 913 *a_offset = offset; 914 *a_error = error; 915 *a_drift = drift; 916 *a_drifterr = drifterr; 917 *a_wait = wait; 918 return now; 919 } 920 921 922 923 double correct_drift (double *a_when, double *a_offset, double drift) { 924 925 /* Correct for the drift since the last time it was done, provided that a long 926 enough time has elapsed. And do remember to kludge up the time and 927 discrepancy, when appropriate. */ 928 929 double d, x; 930 931 d = current_time(JAN_1970)-*a_when; 932 *a_when += d; 933 x = *a_offset+d*drift; 934 if (verbose > 2) 935 fprintf(stderr,"Correction %.6f @ %.6f off=%.6f ",x,*a_when,*a_offset); 936 if (d >= waiting && (x < 0.0 ? -x : x) >= 0.5*minerr) { 937 if (verbose > 2) fprintf(stderr,"performed\n"); 938 adjust_time(x,(action == action_reset ? 1 : 0),0.5*minerr); 939 *a_offset = 0.0; 940 return x; 941 } else { 942 if (verbose > 2) fprintf(stderr,"ignored\n"); 943 *a_offset = x; 944 return 0.0; 945 } 946 } 947 948 949 950 void handle_saving (int operation, int *total, int *index, int *cycle, 951 data_record *record, double *previous, double *when, double *correction) { 952 953 /* This handles the saving and restoring of the state to a file. While it is 954 subject to spoofing, this is not a major security problem. But, out of general 955 paranoia, check everything in sight when restoring. Note that this function 956 has no external effect if something goes wrong. */ 957 958 struct { 959 data_record record[COUNT_MAX]; 960 double previous, when, correction; 961 int operation, delay, count, total, index, cycle, waiting; 962 } buffer; 963 double x, y; 964 int i, j; 965 966 if (savefile == NULL) return; 967 968 /* Read the restart file and print its data in diagnostic mode. Note that some 969 care is necessary to avoid introducing a security exposure - but we trust the 970 C library not to trash the stack on bad numbers! */ 971 972 if (operation == save_read_only || operation == save_read_check) { 973 if (fread(&buffer,sizeof(buffer),1,savefile) != 1 || ferror(savefile)) { 974 if (ferror(savefile)) 975 fatal(1,"unable to read record from daemon save file",NULL); 976 else if (verbose) 977 fprintf(stderr,"%s: bad daemon restart information\n",argv0); 978 return; 979 } 980 if (verbose > 2) { 981 fprintf(stderr,"Reading prev=%.6f when=%.6f corr=%.6f\n", 982 buffer.previous,buffer.when,buffer.correction); 983 fprintf(stderr,"op=%d dly=%d cnt=%d tot=%d ind=%d cyc=%d wait=%d\n", 984 buffer.operation,buffer.delay,buffer.count,buffer.total, 985 buffer.index,buffer.cycle,buffer.waiting); 986 if (buffer.total < COUNT_MAX) 987 for (i = 0; i < buffer.total; ++i) 988 fprintf(stderr, 989 "disp=%.6f wgt=%.3f when=%.6f off=%.6f err=%.6f\n", 990 buffer.record[i].dispersion,buffer.record[i].weight, 991 buffer.record[i].when,buffer.record[i].offset, 992 buffer.record[i].error); 993 } 994 995 996 /* Start checking the data for sanity. */ 997 998 if (buffer.operation == 0 && buffer.delay == 0 && buffer.count == 0) { 999 if (operation < 0) 1000 fatal(0,"the daemon save file has been cleared",NULL); 1001 if (verbose) 1002 fprintf(stderr,"%s: restarting from a cleared file\n",argv0); 1003 return; 1004 } 1005 if (operation == save_read_check) { 1006 if (buffer.operation != operation || buffer.delay != delay || 1007 buffer.count != count) { 1008 if (verbose) 1009 fprintf(stderr,"%s: different parameters for restart\n", 1010 argv0); 1011 return; 1012 } 1013 if (buffer.total < 1 || buffer.total > count || buffer.index < 0 || 1014 buffer.index >= count || buffer.cycle < 0 || 1015 buffer.cycle >= count || buffer.correction < -maxerr || 1016 buffer.correction > maxerr || buffer.waiting < RESET_MIN || 1017 buffer.waiting > delay || buffer.previous > buffer.when || 1018 buffer.previous < buffer.when-count*delay || 1019 buffer.when >= *when) { 1020 if (verbose) 1021 fprintf(stderr,"%s: corrupted restart information\n",argv0); 1022 return; 1023 } 1024 1025 /* Checking the record is even more tedious. */ 1026 1027 x = *when; 1028 y = 0.0; 1029 for (i = 0; i < buffer.total; ++i) { 1030 if (buffer.record[i].dispersion < 0.0 || 1031 buffer.record[i].dispersion > maxerr || 1032 buffer.record[i].weight <= 0.0 || 1033 buffer.record[i].weight > 1.001/(minerr*minerr) || 1034 buffer.record[i].offset < -count*maxerr || 1035 buffer.record[i].offset > count*maxerr || 1036 buffer.record[i].error < 0.0 || 1037 buffer.record[i].error > maxerr) { 1038 if (verbose) 1039 fprintf(stderr,"%s: corrupted restart record\n",argv0); 1040 return; 1041 } 1042 if (buffer.record[i].when < x) x = buffer.record[i].when; 1043 if (buffer.record[i].when > y) y = buffer.record[i].when; 1044 } 1045 1046 /* Check for consistency and, finally, whether this is too old. */ 1047 1048 if (y > buffer.when || y-x < (buffer.total-1)*delay || 1049 y-x > (buffer.total-1)*count*delay) { 1050 if (verbose) 1051 fprintf(stderr,"%s: corrupted restart times\n",argv0); 1052 return; 1053 } 1054 if (buffer.when < *when-count*delay) { 1055 if (verbose) 1056 fprintf(stderr,"%s: restart information too old\n",argv0); 1057 return; 1058 } 1059 } 1060 1061 /* If we get here, just copy the data back. */ 1062 1063 memcpy(record,buffer.record,sizeof(buffer.record)); 1064 *previous = buffer.previous; 1065 *when = buffer.when; 1066 *correction = buffer.correction; 1067 *total = buffer.total; 1068 *index = buffer.index; 1069 *cycle = buffer.cycle; 1070 waiting = buffer.waiting; 1071 memset(&buffer,0,sizeof(buffer)); 1072 1073 /* Print out the data if requested. */ 1074 1075 if (verbose > 1) { 1076 fprintf(stderr,"%s: prev=%.3f when=%.3f corr=%.3f\n", 1077 argv0,*previous,*when,*correction); 1078 for (i = 0; i < *total; ++i) { 1079 if ((j = i+*index-*total) < 0) j += *total; 1080 fprintf(stderr,"%s: when=%.3f disp=%.3f off=%.3f", 1081 argv0,record[j].when,record[j].dispersion,record[j].offset); 1082 if (operation == op_client) 1083 fprintf(stderr," err=%.3f\n",record[j].error); 1084 else 1085 fprintf(stderr,"\n"); 1086 } 1087 } 1088 1089 /* All errors on output are fatal. */ 1090 1091 } else if (operation == save_write) { 1092 memcpy(buffer.record,record,sizeof(buffer.record)); 1093 buffer.previous = *previous; 1094 buffer.when = *when; 1095 buffer.correction = *correction; 1096 buffer.operation = operation; 1097 buffer.delay = delay; 1098 buffer.count = count; 1099 buffer.total = *total; 1100 buffer.index = *index; 1101 buffer.cycle = *cycle; 1102 buffer.waiting = waiting; 1103 if (fseek(savefile,0l,SEEK_SET) != 0 || 1104 fwrite(&buffer,sizeof(buffer),1,savefile) != 1 || 1105 fflush(savefile) != 0 || ferror(savefile)) 1106 fatal(1,"unable to write record to daemon save file",NULL); 1107 if (verbose > 2) { 1108 fprintf(stderr,"Writing prev=%.6f when=%.6f corr=%.6f\n", 1109 *previous,*when,*correction); 1110 fprintf(stderr,"op=%d dly=%d cnt=%d tot=%d ind=%d cyc=%d wait=%d\n", 1111 operation,delay,count,*total,*index,*cycle,waiting); 1112 if (*total < COUNT_MAX) 1113 for (i = 0; i < *total; ++i) 1114 fprintf(stderr, 1115 "disp=%.6f wgt=%.3f when=%.6f off=%.6f err=%.6f\n", 1116 record[i].dispersion,record[i].weight, 1117 record[i].when,record[i].offset,record[i].error); 1118 } 1119 1120 /* Clearing the save file is similar. */ 1121 1122 } else if (operation == save_clear) { 1123 if (fseek(savefile,0l,SEEK_SET) != 0 || 1124 fwrite(&buffer,sizeof(buffer),1,savefile) != 1 || 1125 fflush(savefile) != 0 || ferror(savefile)) 1126 fatal(1,"unable to clear daemon save file",NULL); 1127 } else 1128 fatal(0,"internal error in handle_saving",NULL); 1129 } 1130 1131 1132 1133 void query_savefile (void) { 1134 1135 /* This queries a daemon save file. */ 1136 1137 double previous, when, correction = 0.0, offset = 0.0, error = -1.0, 1138 drift = 0.0, drifterr = -1.0; 1139 data_record record[COUNT_MAX]; 1140 int total = 0, index = 0, cycle = 0; 1141 char text[100]; 1142 1143 /* This is a few lines stripped out of run_daemon() and slightly hacked. */ 1144 1145 previous = when = current_time(JAN_1970); 1146 if (verbose > 2) { 1147 format_time(text,50,0.0,-1.0,0.0,-1.0); 1148 fprintf(stderr,"Started=%.6f %s\n",when,text); 1149 } 1150 handle_saving(save_read_only,&total,&index,&cycle,record,&previous,&when, 1151 &correction); 1152 estimate_stats(&total,&index,record,correction,&dispersion, 1153 &when,&offset,&error,&drift,&drifterr,&waiting,0); 1154 format_time(text,100,offset,error,drift,drifterr); 1155 printf("%s\n",text); 1156 if (fclose(savefile)) fatal(1,"unable to close daemon save file",NULL); 1157 if (verbose > 2) fprintf(stderr,"Stopped normally\n"); 1158 exit(EXIT_SUCCESS); 1159 } 1160 1161 1162 1163 void run_daemon (char *hostnames[], int nhosts, int initial) { 1164 1165 /* This does not adjust the time between calls to the server, but it does 1166 adjust the time between clock resets. This function will survive short periods 1167 of server inaccessibility or network glitches, but not long ones, and will then 1168 need restarting manually. 1169 1170 It is far too complex for a single function, but could really only be 1171 simplified by making most of its variables global or by a similarly horrible 1172 trick. Oh, for nested scopes as in Algol 68! */ 1173 1174 double history[COUNT_MAX], started, previous, when, correction = 0.0, 1175 weeble = 1.0, accepts = 0.0, rejects = 0.0, flushes = 0.0, 1176 replicates = 0.0, skips = 0.0, offset = 0.0, error = -1.0, 1177 drift = 0.0, drifterr = -1.0, maxoff = 0.0, x; 1178 data_record record[COUNT_MAX]; 1179 int total = 0, index = 0, item = 0, rej_level = 0, rep_level = 0, 1180 cycle = 0, retry = 1, i, j, k; 1181 unsigned char transmit[NTP_PACKET_MIN]; 1182 ntp_data data; 1183 char text[100]; 1184 1185 /* After initialising, restore from a previous run if possible. Note that 1186 only a few of the variables are actually needed to control the operation and 1187 the rest are mainly for diagnostics. */ 1188 1189 started = previous = when = current_time(JAN_1970); 1190 if (verbose > 2) { 1191 format_time(text,50,0.0,-1.0,0.0,-1.0); 1192 fprintf(stderr,"Started=%.6f %s\n",when,text); 1193 } 1194 if (initial) { 1195 handle_saving(save_read_check,&total,&index,&cycle,record, 1196 &previous,&when,&correction); 1197 cycle = (nhosts > 0 ? cycle%nhosts : 0); 1198 if (total > 0 && started-previous < delay) { 1199 if (verbose > 2) fprintf(stderr,"Last packet too recent\n"); 1200 retry = 0; 1201 } 1202 if (verbose > 2) 1203 fprintf(stderr,"prev=%.6f when=%.6f retry=%d\n", 1204 previous,when,retry); 1205 for (i = 0; i < nhosts; ++i) open_socket(i,hostnames[i],delay); 1206 if (action != action_display) { 1207 set_lock(1); 1208 locked = 1; 1209 } 1210 } 1211 dispersion = 0.0; 1212 attempts = 0; 1213 for (i = 0; i < count; ++i) history[i] = 0.0; 1214 while (1) { 1215 1216 /* Print out a reasonable amount of diagnostics, rather like a server. Note 1217 that it may take a little time, but shouldn't affect the estimates much. Then 1218 check that we aren't in a failing loop. */ 1219 1220 if (verbose > 2) fprintf(stderr,"item=%d rej=%d\n",item,rej_level); 1221 x = current_time(JAN_1970)-started; 1222 if (verbose && 1223 x/3600.0+accepts+rejects+flushes+replicates+skips >= weeble) { 1224 weeble *= WEEBLE_FACTOR; 1225 x -= 3600.0*(i = (int)(x/3600.0)); 1226 x -= 60.0*(j = (int)(x/60.0)); 1227 if (i > 0) 1228 fprintf(stderr,"%s: after %d hours %d mins ",argv0,i,j); 1229 else if (j > 0) 1230 fprintf(stderr,"%s: after %d mins %.0f secs ",argv0,j,x); 1231 else 1232 fprintf(stderr,"%s: after %.1f secs ",argv0,x); 1233 fprintf(stderr,"acc. %.0f rej. %.0f flush %.0f", 1234 accepts,rejects,flushes); 1235 if (operation == op_listen) 1236 fprintf(stderr," rep. %.0f skip %.0f",replicates,skips); 1237 fprintf(stderr," max.off. %.3f corr. %.3f\n",maxoff,correction); 1238 format_time(text,100,offset,error,drift,drifterr); 1239 fprintf(stderr,"%s: %s\n",argv0,text); 1240 maxoff = 0.0; 1241 } 1242 if (current_time(JAN_1970)-previous > count*delay) { 1243 if (verbose) 1244 fprintf(stderr,"%s: no packets in too long a period\n",argv0); 1245 return; 1246 } 1247 1248 /* Listen for the next broadcast packet. This allows up to ETHERNET_MAX 1249 replications per packet, for systems with multiple addresses for receiving 1250 broadcasts; the only reason for a limit is to protect against broken NTP 1251 servers always returning the same time. */ 1252 1253 if (operation == op_listen) { 1254 flushes += flush_socket(0); 1255 if (read_packet(0,&data,&offset,&error)) { 1256 ++rejects; 1257 if (++rej_level > count) 1258 fatal(0,"too many bad or lost packets",NULL); 1259 if (action != action_display && drifterr >= 0.0) { 1260 correction += correct_drift(&when,&offset,drift); 1261 handle_saving(save_write,&total,&index,&cycle,record, 1262 &previous,&when,&correction); 1263 } 1264 continue; 1265 } 1266 if ((rej_level -= (count < 5 ? count : 5)) < 0) rej_level = 0; 1267 x = data.transmit; 1268 for (i = 0; i < count; ++i) 1269 if (x == history[i]) { 1270 ++replicates; 1271 if (++rep_level > ETHERNET_MAX) 1272 fatal(0,"too many replicated packets",NULL); 1273 goto continue1; 1274 } 1275 rep_level = 0; 1276 history[item] = x; 1277 if (++item >= count) item = 0; 1278 1279 /* Accept a packet only after a long enough period has elapsed. */ 1280 1281 when = data.current; 1282 if (! retry && when < previous+delay) { 1283 if (verbose > 2) fprintf(stderr,"Skipping too recent packet\n"); 1284 ++skips; 1285 continue; 1286 } 1287 retry = 0; 1288 if (verbose > 2) 1289 fprintf(stderr,"Offset=%.6f @ %.6f disp=%.6f\n", 1290 offset,when,dispersion); 1291 1292 /* Handle the client/server model. It keeps a record of transmitted times, 1293 mainly out of paranoia. The waiting time is kludged up to attempt to provide 1294 reasonable resilience against both lost packets and dead servers. But it 1295 won't handle much of either, and will stop after a while, needing manual 1296 restarting. Running it under cron is the best approach. */ 1297 1298 } else { 1299 if (! retry) { 1300 if (verbose > 2) fprintf(stderr,"Sleeping for %d\n",waiting); 1301 do_nothing(waiting); 1302 } 1303 make_packet(&data,NTP_CLIENT); 1304 outgoing[item] = data.transmit; 1305 if (++item >= 2*count) item = 0; 1306 if (attempts < 2*count) ++attempts; 1307 if (verbose > 2) { 1308 fprintf(stderr,"Outgoing packet on socket %d:\n",cycle); 1309 display_data(&data); 1310 } 1311 pack_ntp(transmit,NTP_PACKET_MIN,&data); 1312 if (verbose > 2) display_packet(transmit,NTP_PACKET_MIN); 1313 flushes += flush_socket(cycle); 1314 write_socket(cycle,transmit,NTP_PACKET_MIN); 1315 1316 /* Read the packet and check that it is an appropriate response. Because this 1317 is rather more numerically sensitive than simple resynchronisation, reject all 1318 very inaccurate packets. Be careful if you modify this, because the error 1319 handling is rather nasty to avoid replicating code. */ 1320 1321 k = read_packet(cycle,&data,&offset,&error); 1322 if (++cycle >= nhosts) cycle = 0; 1323 if (! k) 1324 when = (data.originate+data.current)/2.0; 1325 else if (action != action_display && drifterr >= 0.0) { 1326 correction += correct_drift(&when,&offset,drift); 1327 handle_saving(save_write,&total,&index,&cycle,record, 1328 &previous,&when,&correction); 1329 } 1330 if (! k && ! retry && when < previous+delay-2) { 1331 if (verbose) 1332 fprintf(stderr,"%s: packets out of order on socket %d\n", 1333 argv0,cycle); 1334 k = 1; 1335 } 1336 if (! k && data.current-data.originate > maxerr) { 1337 if (verbose) 1338 fprintf(stderr, 1339 "%s: very slow response rejected on socket %d\n", 1340 argv0,cycle); 1341 k = 1; 1342 } 1343 1344 /* Count the number of rejected packets and fail if there are too many. */ 1345 1346 if (k) { 1347 ++rejects; 1348 if (++rej_level > count) 1349 fatal(0,"too many bad or lost packets",NULL); 1350 else { 1351 retry = 1; 1352 continue; 1353 } 1354 } else 1355 retry = 0; 1356 if ((rej_level -= (count < 5 ? count : 5)) < 0) rej_level = 0; 1357 if (verbose > 2) 1358 fprintf(stderr,"Offset=%.6f+/-%.6f @ %.6f disp=%.6f\n", 1359 offset,error,when,dispersion); 1360 } 1361 1362 /* Calculate the statistics, and display the results or make the initial 1363 correction. Note that estimate_stats() will return zero if a timestamp 1364 indicates synchronisation loss (usually due to down time or a change of server, 1365 somewhere upstream), and that the recovery operation is unstructured, so great 1366 care should be taken when modifying it. Also, we want to clear the saved state 1367 is the statistics are bad. */ 1368 1369 handle_saving(save_clear,&total,&index,&cycle,record,&previous,&when, 1370 &correction); 1371 ++accepts; 1372 dispersion = data.dispersion; 1373 previous = when = 1374 estimate_stats(&total,&index,record,correction,&dispersion, 1375 &when,&offset,&error,&drift,&drifterr,&waiting,1); 1376 if (verbose > 2) { 1377 fprintf(stderr,"tot=%d ind=%d dis=%.3f when=%.3f off=%.3f ", 1378 total,index,dispersion,when,offset); 1379 fprintf(stderr,"err=%.3f wait=%d\n",error,waiting); 1380 } 1381 if (when == 0.0) return; 1382 x = (maxoff < 0.0 ? -maxoff : maxoff); 1383 if ((offset < 0.0 ? -offset : offset) > x) maxoff = offset; 1384 correction = 0.0; 1385 if (operation == op_client || accepts >= count) { 1386 if (action == action_display) { 1387 format_time(text,100,offset,error,drift,drifterr); 1388 printf("%s\n",text); 1389 } else { 1390 x = reset_clock(offset,error,1); 1391 correction += x; 1392 offset -= x; 1393 } 1394 } else 1395 waiting = delay; 1396 handle_saving(save_write,&total,&index,&cycle,record,&previous,&when, 1397 &correction); 1398 1399 /* Now correct the clock for a while, before getting another packet and 1400 updating the statistics. */ 1401 1402 while (when < previous+delay-waiting) { 1403 do_nothing(waiting); 1404 if (action == action_display) 1405 when += waiting; 1406 else { 1407 correction += correct_drift(&when,&offset,drift); 1408 handle_saving(save_write,&total,&index,&cycle,record, 1409 &previous,&when,&correction); 1410 } 1411 } 1412 continue1: ; 1413 } 1414 } 1415 1416 1417 1418 void run_client (char *hostnames[], int nhosts) { 1419 1420 /* Get enough responses to do something with; or not, as the case may be. Note 1421 that it allows for half of the packets to be bad, so may make up to twice as 1422 many attempts as specified by the -c value. The deadline checking is merely 1423 paranoia, to protect against broken signal handling - it cannot easily be 1424 triggered if the signal handling works. */ 1425 1426 double history[COUNT_MAX], guesses[COUNT_MAX], offset, error, deadline, 1427 a, b, x, y; 1428 int accepts = 0, rejects = 0, flushes = 0, replicates = 0, cycle = 0, k; 1429 unsigned char transmit[NTP_PACKET_MIN]; 1430 ntp_data data; 1431 char text[100]; 1432 1433 if (verbose > 2) { 1434 format_time(text,50,0.0,-1.0,0.0,-1.0); 1435 fprintf(stderr,"Started=%.6f %s\n",current_time(JAN_1970),text); 1436 } 1437 for (k = 0; k < nhosts; ++k) open_socket(k,hostnames[k],delay); 1438 if (action != action_display) { 1439 set_lock(1); 1440 locked = 1; 1441 } 1442 attempts = 0; 1443 deadline = current_time(JAN_1970)+delay; 1444 1445 /* Listen to broadcast packets and select the best (i.e. earliest). This will 1446 be sensitive to a bad NTP broadcaster, but I believe such things are very rare 1447 in practice. In any case, if you have one, it is probably the only one on your 1448 subnet, so you are knackered! This allows up to ETHERNET_MAX replications per 1449 packet, for systems with multiple addresses for receiving broadcasts; the only 1450 reason for a limit is to protect against broken NTP servers always returning 1451 the same time. */ 1452 1453 if (operation == op_listen) { 1454 while (accepts < count) { 1455 if (current_time(JAN_1970) > deadline) 1456 fatal(0,"not enough valid broadcasts received in time",NULL); 1457 flushes += flush_socket(0); 1458 if (read_packet(0,&data,&x,&y)) { 1459 if (++rejects > count) 1460 fatal(0,"too many bad or lost packets",NULL); 1461 else 1462 continue; 1463 } else { 1464 a = data.transmit; 1465 for (k = 0; k < accepts; ++k) 1466 if (a == history[k]) { 1467 if (++replicates > ETHERNET_MAX*count) 1468 fatal(0,"too many replicated packets",NULL); 1469 goto continue1; 1470 } 1471 history[accepts] = a; 1472 guesses[accepts++] = x; 1473 } 1474 if (verbose > 2) 1475 fprintf(stderr,"Offset=%.6f disp=%.6f\n",x,dispersion); 1476 else if (verbose > 1) 1477 fprintf(stderr,"%s: offset=%.3f disp=%.3f\n", 1478 argv0,x,dispersion); 1479 1480 /* Note that bubblesort IS a good method for this amount of data. */ 1481 1482 for (k = accepts-2; k >= 0; --k) 1483 if (guesses[k] < guesses[k+1]) 1484 break; 1485 else { 1486 x = guesses[k]; 1487 guesses[k] = guesses[k+1]; 1488 guesses[k+1] = x; 1489 } 1490 continue1: ; 1491 } 1492 offset = guesses[0]; 1493 error = minerr+guesses[count <= 5 ? count-1 : 5]-offset; 1494 if (verbose > 2) 1495 fprintf(stderr,"accepts=%d rejects=%d flushes=%d replicates=%d\n", 1496 accepts,rejects,flushes,replicates); 1497 1498 /* Handle the client/server model. It keeps a record of transmitted times, 1499 mainly out of paranoia. */ 1500 1501 } else { 1502 offset = 0.0; 1503 error = NTP_INSANITY; 1504 while (accepts < count && attempts < 2*count) { 1505 if (current_time(JAN_1970) > deadline) 1506 fatal(0,"not enough valid responses received in time",NULL); 1507 make_packet(&data,NTP_CLIENT); 1508 outgoing[attempts++] = data.transmit; 1509 if (verbose > 2) { 1510 fprintf(stderr,"Outgoing packet on socket %d:\n",cycle); 1511 display_data(&data); 1512 } 1513 pack_ntp(transmit,NTP_PACKET_MIN,&data); 1514 if (verbose > 2) display_packet(transmit,NTP_PACKET_MIN); 1515 flushes += flush_socket(cycle); 1516 write_socket(cycle,transmit,NTP_PACKET_MIN); 1517 if (read_packet(cycle,&data,&x,&y)) { 1518 if (++rejects > count) 1519 fatal(0,"too many bad or lost packets",NULL); 1520 else 1521 continue; 1522 } else 1523 ++accepts; 1524 if (++cycle >= nhosts) cycle = 0; 1525 1526 /* Work out the most accurate time, and check that it isn't more accurate than 1527 the results warrant. */ 1528 1529 if (verbose > 2) 1530 fprintf(stderr,"Offset=%.6f+/-%.6f disp=%.6f\n",x,y,dispersion); 1531 else if (verbose > 1) 1532 fprintf(stderr,"%s: offset=%.3f+/-%.3f disp=%.3f\n", 1533 argv0,x,y,dispersion); 1534 if ((a = x-offset) < 0.0) a = -a; 1535 if (accepts <= 1) a = 0.0; 1536 b = error+y; 1537 if (y < error) { 1538 offset = x; 1539 error = y; 1540 } 1541 if (verbose > 2) 1542 fprintf(stderr,"best=%.6f+/-%.6f\n",offset,error); 1543 if (a > b) { 1544 sprintf(text,"%d",cycle); 1545 fatal(0,"inconsistent times got from NTP server on socket %s", 1546 text); 1547 } 1548 if (error <= minerr) break; 1549 } 1550 if (verbose > 2) 1551 fprintf(stderr,"accepts=%d rejects=%d flushes=%d\n", 1552 accepts,rejects,flushes); 1553 } 1554 1555 /* Tidy up the socket, issues diagnostics and perform the action. */ 1556 1557 for (k = 0; k < nhosts; ++k) close_socket(k); 1558 if (accepts == 0) fatal(0,"no acceptable packets received",NULL); 1559 if (error > NTP_INSANITY) 1560 fatal(0,"unable to get a reasonable time estimate",NULL); 1561 if (verbose > 2) 1562 fprintf(stderr,"Correction: %.6f +/- %.6f disp=%.6f\n", 1563 offset,error,dispersion); 1564 if (action == action_display) { 1565 format_time(text,75,offset,error,0.0,-1.0); 1566 printf("%s\n",text); 1567 } else 1568 (void)reset_clock(offset,error,0); 1569 if (locked) set_lock(0); 1570 if (verbose > 2) fprintf(stderr,"Stopped normally\n"); 1571 exit(EXIT_SUCCESS); 1572 } 1573 1574 1575 1576 int main (int argc, char *argv[]) { 1577 1578 /* This is the entry point and all that. It decodes the arguments and calls 1579 one of the specialised routines to do the work. */ 1580 1581 char *hostnames[MAX_SOCKETS], *savename = NULL; 1582 int daemon = 0, nhosts = 0, help = 0, args = argc-1, k; 1583 char c; 1584 1585 if (argv[0] == NULL || argv[0][0] == '\0') 1586 argv0 = "msntp"; 1587 else if ((argv0 = strrchr(argv[0],'/')) != NULL) 1588 ++argv0; 1589 else 1590 argv0 = argv[0]; 1591 setvbuf(stdout,NULL,_IOLBF,BUFSIZ); 1592 setvbuf(stderr,NULL,_IOLBF,BUFSIZ); 1593 if (INT_MAX < 2147483647) fatal(0,"msntp requires >= 32-bit ints",NULL); 1594 if (DBL_EPSILON > 1.0e-13) 1595 fatal(0,"msntp requires doubles with eps <= 1.0e-13",NULL); 1596 for (k = 0; k < MAX_SOCKETS; ++k) hostnames[k] = NULL; 1597 1598 /* Decode the arguments. */ 1599 1600 while (argc > 1) { 1601 k = 1; 1602 if (strcmp(argv[1],"-4") == 0) 1603 preferred_family(PREF_FAM_INET); 1604 else if (strcmp(argv[1],"-6") == 0) 1605 preferred_family(PREF_FAM_INET6); 1606 else if (strcmp(argv[1],"-B") == 0 && action == 0) { 1607 action = action_broadcast; 1608 if (argc > 2) { 1609 if (sscanf(argv[2],"%d%c",&period,&c) != 1) syntax(1); 1610 if (period < 1 || period > 1440) 1611 fatal(0,"%s option value out of range","-B"); 1612 period *= 60; 1613 k = 2; 1614 } else 1615 period = 60*60; 1616 } else if (strcmp(argv[1],"-S") == 0 && action == 0) 1617 action = action_server; 1618 else if (strcmp(argv[1],"-q") == 0 && action == 0) 1619 action = action_query; 1620 else if (strcmp(argv[1],"-r") == 0 && action == 0) 1621 action = action_reset; 1622 else if (strcmp(argv[1],"-a") == 0 && action == 0) 1623 action = action_adjust; 1624 else if (strcmp(argv[1],"-l") == 0 && lockname == NULL && argc > 2) { 1625 lockname = argv[2]; 1626 k = 2; 1627 } else if ((strcmp(argv[1],"-x") == 0) && 1628 daemon == 0) { 1629 if (argc > 2 && sscanf(argv[2],"%d%c",&daemon,&c) == 1) { 1630 if (daemon < 1 || daemon > 1440) 1631 fatal(0,"%s option value out of range",argv[1]); 1632 k = 2; 1633 } else 1634 daemon = 300; 1635 } else if (strcmp(argv[1],"-f") == 0 && savename == NULL && argc > 2) { 1636 savename = argv[2]; 1637 k = 2; 1638 } else if ((strcmp(argv[1],"--help") == 0 || 1639 strcmp(argv[1],"-h") == 0 || strcmp(argv[1],"-?") == 0) && 1640 help == 0) 1641 help = 1; 1642 else if (strcmp(argv[1],"-v") == 0 && verbose == 0) 1643 verbose = 1; 1644 else if (strcmp(argv[1],"-V") == 0 && verbose == 0) 1645 verbose = 2; 1646 else if (strcmp(argv[1],"-W") == 0 && verbose == 0) 1647 verbose = 3; 1648 else if (strcmp(argv[1],"-e") == 0 && minerr == 0.0 && argc > 2) { 1649 if (sscanf(argv[2],"%lf%c",&minerr,&c) != 1) syntax(1); 1650 if (minerr <= 0.000999999 || minerr > 1.0) 1651 fatal(0,"%s option value out of range","-e"); 1652 k = 2; 1653 } else if (strcmp(argv[1],"-E") == 0 && maxerr == 0.0 && argc > 2) { 1654 if (sscanf(argv[2],"%lf%c",&maxerr,&c) != 1) syntax(1); 1655 if (maxerr < 1.0 || maxerr > 60.0) 1656 fatal(0,"%s option value out of range","-E"); 1657 k = 2; 1658 } else if (strcmp(argv[1],"-P") == 0 && prompt == 0.0 && argc > 2) { 1659 if (strcmp(argv[2],"no") == 0) 1660 prompt = (double)INT_MAX; 1661 else { 1662 if (sscanf(argv[2],"%lf%c",&prompt,&c) != 1) syntax(1); 1663 if (prompt < 1.0 || prompt > 3600.0) 1664 fatal(0,"%s option value out of range","-p"); 1665 } 1666 k = 2; 1667 } else if (strcmp(argv[1],"-d") == 0 && delay == 0 && argc > 2) { 1668 if (sscanf(argv[2],"%d%c",&delay,&c) != 1) syntax(1); 1669 if (delay < 1 || delay > 3600) 1670 fatal(0,"%s option value out of range","-d"); 1671 k = 2; 1672 } else if (strcmp(argv[1],"-c") == 0 && count == 0 && argc > 2) { 1673 if (sscanf(argv[2],"%d%c",&count,&c) != 1) syntax(1); 1674 if (count < 1 || count > COUNT_MAX) 1675 fatal(0,"%s option value out of range","-c"); 1676 k = 2; 1677 } else 1678 break; 1679 argc -= k; 1680 argv += k; 1681 } 1682 1683 /* Check the arguments for consistency and set the defaults. */ 1684 1685 if (action == action_broadcast || action == action_server) { 1686 operation = (action == action_server ? op_server : op_broadcast); 1687 if (argc != 1 || minerr != 0.0 || maxerr != 0.0 || count != 0 || 1688 delay != 0 || daemon != 0 || prompt != 0.0 || 1689 lockname != NULL || savename != NULL) 1690 syntax(1); 1691 } else if (action == action_query) { 1692 if (argc != 1 || minerr != 0.0 || maxerr != 0.0 || count != 0 || 1693 delay != 0 || daemon != 0 || prompt != 0.0 || lockname != NULL) 1694 syntax(1); 1695 } else { 1696 if (argc < 1 || argc > MAX_SOCKETS || (daemon != 0 && delay != 0)) 1697 syntax(1); 1698 if ((prompt || lockname != NULL) && 1699 action != action_reset && action != action_adjust) 1700 syntax(1); 1701 if (count > 0 && count < argc-1) 1702 fatal(0,"-c value less than number of addresses",NULL); 1703 if (argc > 1) { 1704 operation = op_client; 1705 for (k = 1; k < argc; ++k) { 1706 if (argv[k][0] == '\0' || argv[k][0] == '-') 1707 fatal(0,"invalid Internet address '%s'",argv[k]); 1708 hostnames[k-1] = argv[k]; 1709 } 1710 nhosts = argc-1; 1711 } else { 1712 operation = op_listen; 1713 nhosts = 0; 1714 } 1715 if (action == 0) action = action_display; 1716 if (minerr <= 0.0) minerr = (operation == op_listen ? 0.5 : 0.1); 1717 if (maxerr <= 0.0) maxerr = 5.0; 1718 if (count == 0) count = (argc-1 < 5 ? 5 : argc-1); 1719 if ((argc == 1 || (daemon != 0 && action != action_query)) && count < 5) 1720 fatal(0,"at least 5 packets needed in this mode",NULL); 1721 if ((action == action_reset || action == action_adjust) && 1722 lockname == NULL) 1723 lockname = LOCKNAME; 1724 1725 /* The '-x' option changes the implications of many other settings, though this 1726 is not usually apparent to the caller. Most of the time delays are to ensure 1727 that stuck states terminate, and do not affect the result. */ 1728 1729 if (daemon != 0) { 1730 if (minerr >= maxerr || maxerr >= daemon) 1731 fatal(0,"values not in order -e < -E < -x",NULL); 1732 waiting = delay = daemon *= 60; 1733 } else { 1734 if (savename != NULL) 1735 fatal(0,"-f can be specified only with -x",NULL); 1736 if (delay == 0) 1737 delay = (operation == op_listen ? 300 : 1738 (2*count >= 15 ? 2*count+1 :15)); 1739 if (operation == op_listen) { 1740 if (minerr >= maxerr || maxerr >= delay/count) 1741 fatal(0,"values not in order -e < -E < -d/-c",NULL); 1742 } else { 1743 if (minerr >= maxerr || maxerr >= delay) 1744 fatal(0,"values not in order -e < -E < -d",NULL); 1745 } 1746 if (2*count >= delay) fatal(0,"-c must be less than half -d",NULL); 1747 waiting = delay/count; 1748 } 1749 if (prompt == 0.0) prompt = 30.0; 1750 } 1751 if ((daemon || action == action_query) && savename == NULL) 1752 savename = SAVENAME; 1753 1754 /* Diagnose where we are, if requested, and separate out the classes of 1755 operation. The calls do not return. */ 1756 1757 if (help) syntax(args == 1); 1758 if (verbose) { 1759 fprintf(stderr,"%s options: a=%d p=%d v=%d e=%.3f E=%.3f P=%.3f\n", 1760 argv0,action,period,verbose,minerr,maxerr,prompt); 1761 fprintf(stderr," d=%d c=%d %c=%d op=%d l=%s f=%s", 1762 delay,count,'x',daemon,operation, 1763 (lockname == NULL ? "" : lockname), 1764 (savename == NULL ? "" : savename)); 1765 for (k = 0; k < MAX_SOCKETS; ++k) 1766 if (hostnames[k] != NULL) fprintf(stderr," %s",hostnames[k]); 1767 fprintf(stderr,"\n"); 1768 } 1769 if (nhosts == 0) nhosts = 1; /* Kludge for broadcasts */ 1770 if (operation == op_server || operation == op_broadcast) 1771 run_server(); 1772 else if (action == action_query) { 1773 if (savename == NULL || savename[0] == '\0') 1774 fatal(0,"no daemon save file specified",NULL); 1775 else if ((savefile = fopen(savename,"rb")) == NULL) 1776 fatal(0,"unable to open the daemon save file",NULL); 1777 query_savefile(); 1778 } else if (daemon != 0) { 1779 if (savename != NULL && savename[0] != '\0' && 1780 (savefile = fopen(savename,"rb+")) == NULL && 1781 (savefile = fopen(savename,"wb+")) == NULL) 1782 fatal(0,"unable to open the daemon save file",NULL); 1783 run_daemon(hostnames,nhosts,1); 1784 while (1) run_daemon(hostnames,nhosts,0); 1785 } else 1786 run_client(hostnames,nhosts); 1787 fatal(0,"internal error at end of main",NULL); 1788 return EXIT_FAILURE; 1789 } 1790