main.c revision 132451
1/*  Copyright (C) 1996, 1997, 2000 N.M. Maclaren
2    Copyright (C) 1996, 1997, 2000 The University of Cambridge
3
4This is a complete SNTP implementation, which was easier to write than to port
5xntp to a new version of Unix with any hope of maintaining it thereafter.  It
6supports the full SNTP (RFC 2030) client- and server-side challenge-response
7and broadcast protocols.  It should achieve nearly optimal accuracy with very
8few transactions, provided only that a client has access to a trusted server
9and that communications are not INVARIABLY slow.  As this is the environment in
10which 90-99% of all NTP systems are run ....
11
12The 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,
24and -V requests more output for investigating apparently inconsistent
25timestamps.  -W requests very verbose debugging output, and will interfere with
26the timing when writing to the terminal (because of line buffered output from
27C); it is useful only when debugging the source.  Note that the times produced
28by -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
31at intervals of 'period' minutes.  Acceptable values of 'period' are from 1 to
321440 (a day) and the default is 60.  Naturally, this will work only if the
33user has enough privilege.
34
35    -S indicates that it should behave as a server, responding to time requests
36from 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
39it being run in daemon mode.
40
41     The default is that it should behave as a client, and the following options
42are then relevant:
43
44    -r indicates that the system clock should be reset by 'settimeofday'.
45Naturally, this will work only if the user has enough privilege.
46
47    -a indicates that the system clock should be reset by 'adjtime'.
48Naturally, 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
51allow 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
56a format like '1996 Oct 15 20:17:25.123 + 4.567 +/- 0.089 secs', indicating the
57estimated true (local) time and the error in the local clock.  In daemon mode,
58it will add drift information in a format like ' + 1.3 +/- 0.1 ppm', and
59display this at roughly 'separation' intervals.
60
61    'minerr' is the maximum ignorable variation between the clocks.  Acceptable
62values are from 0.001 to 1, and the default is 0.1 if 'address' is specified
63and 0.5 otherwise.
64
65    'maxerr' is the maximum value of various delays that are deemed acceptable.
66Acceptable values are from 1 to 60, and the default is 5.  It should sometimes
67be increased if there are problems with the network, NTP server or system
68clock, but take care.
69
70    'prompt' is the maximum clock change that will be made automatically.
71Acceptable values are from 1 to 3600, and the default is 30.  If the program is
72being run interactively, larger values will cause a prompt.  The value may also
73be 'no', and the change will be made without prompting.
74
75    'count' is the maximum number of NTP packets to require.  Acceptable values
76are from 1 to 25 if 'address' is specified and '-x' is not, and from 5 to 25
77otherwise; the default is 5.  If the maximum isn't enough, you need a better
78consistency algorithm than this program uses.  Don't increase it.
79
80    'delay' is a rough limit on the total running time in seconds.  Acceptable
81values are from 1 to 3600, and the default is 15 if 'address' is specified and
82300 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.
86Acceptable 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
89one copy of msntp running at once.  The default is installation-dependent,
90but will usually be /etc/msntp.pid.
91
92    'savefile' may be used in daemon mode to store a record of previous
93packets, which may speed up recalculating the drift after msntp has to be
94restarted (e.g. because of network or server outages).  The default is
95installation-dependent, but will usually be /etc/msntp.state.  Note that
96there 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
99given, the program waits for broadcasts.  Note that a single component numeric
100address is not allowed.
101
102For sanity, it is also required that 'minerr' < 'maxerr' < 'delay' (if
103listening for broadcasts, 'delay/count' and, in daemon mode, 'separation') and,
104for sordid Unixish reasons, that 2*'count' < 'delay'.  The last could be fixed,
105but isn't worth it.  Note that none of the above values are closely linked to
106the limits described in the NTP protocol (RFC 1305).  Do not increase the
107compiled-in bounds excessively, or the code will fail.
108
109The algorithm used to decide whether to accept a correction is whether it would
110seem to improve matters.  Unlike the 'xntp' suite, little attempt is made to
111handle really knotted scenarios, and diagnostics are written to standard error.
112In non-daemon client mode, it is intended to be run as a command or in a 'cron'
113job.  Unlike 'ntpdate', its default mode is simply to display the clock error.
114
115It assumes that floating-point arithmetic is tolerably efficient, which is true
116for even the cheapest personal computer nowadays.  If, however, you want to
117port this to a toaster, you may have problems!
118
119In its terminating modes, its return code is EXIT_SUCCESS if the operation was
120completed successfully and EXIT_FAILURE otherwise.
121
122In server or daemon mode, it runs for ever and stops with a return code
123EXIT_FAILURE only after a severe error.  Commonly, two server processes will be
124run, one with each of the -B and -S options.  In daemon mode, it will fail if
125the server is inaccessible for a long time or seriously sick, and will need
126manual restarting.
127
128
129WARNING: this program has reached its 'hack count' and needs restructuring,
130badly.  Perhaps the worst code is in run_daemon().  You are advised not to
131fiddle 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
148little point in parameterising everything, as it is neither feasible nor
149useful.  It would be very useful if more fields could be defined as
150unspecified.  The NTP packet-handling routines contain a lot of extra
151assumptions. */
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
185the quantities that control the main actions of the program.  The first three
186are the only ones that are exported to other modules. */
187
188const char *argv0 = NULL;              /* For diagnostics only - not NULL */
189int verbose = 0,                       /* Default = 0, -v = 1, -V = 2, -W = 3 */
190    operation = 0;                     /* Defined in header.h - see action */
191const 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
209static const char version[] = VERSION; /* For reverse engineering :-) */
210static 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 */
217static 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 */
222static 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
227to SNTP. */
228
229typedef 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;
237it contains only the information that is actually used for the drift and error
238calculations. */
239
240typedef struct {
241    double dispersion, weight, when, offset, error;
242} data_record;
243
244
245
246void 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
271void syntax (int halt) {
272
273/* The standard, unfriendly Unix error message.  Some errors are diagnosed more
274helpfully.  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
288void 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
301void 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
320void pack_ntp (unsigned char *packet, int length, ntp_data *data) {
321
322/* Pack the essential data into an NTP packet, bypassing struct layout and
323endian 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
355void unpack_ntp (ntp_data *data, unsigned char *packet, int length) {
356
357/* Unpack the essential data from an NTP packet, bypassing struct layout and
358endian 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
389void make_packet (ntp_data *data, int mode) {
390
391/* Create an outgoing NTP packet, either from scratch or starting from a
392request from a client.  Note that it implements the NTP specification, even
393when this is clearly misguided, except possibly for the setting of LI.  It
394would be easy enough to add a sanity flag, but I am not in the business of
395designing 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
416int 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
419that this contains more checking than xntp does.  This returns 0 for success, 1
420for failure and 2 for an ignored broadcast packet (a kludge for servers).  Note
421that 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,
445but 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
467have to guess.  Any full NTP server perpetrating completely unsynchronised
468packets 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
490has 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
509enough information that we can be almost certain that we have not been fooled
510too badly.  Heaven help us with broadcasts - make a wild kludge here, and see
511elsewhere 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
530void 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
534requested.  Note that the rest of the program uses the correction needed, which
535is what is printed for diagnostics, but this formats the error in the local
536system for display to users.  So the results from this are the negation of
537those 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
548systems 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
590trap extremely implausible scenarios.  This will usually stop chaos from
591spreading. */
592
593    if (strlen(text) >= length)
594        fatal(0,"internal error calling format_time",NULL);
595}
596
597
598
599double reset_clock (double offset, double error, int daemon) {
600
601/* Reset the clock, if appropriate, and return the correction actually used.
602This contains most of the checking for whether changes are worthwhile, except
603in 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
642correction 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
657void run_server (void) {
658
659/* Set up a socket, and either broadcast at intervals or wait for requests.
660It is quite tricky to get this to fail, and it will usually indicate that the
661local 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,
673except 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
692we could skip almost all of the decoding, but it provides a healthy amount of
693error detection.  We could print some information on incoming packets, but the
694code 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
723double 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
729do now.  It returns the timestamp relevant to the correction.  If broadcasts
730are rare and the drift is large, it will fail - you should then use a better
731synchronisation 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
733are beyond reason).
734
735There is a kludge for synchronisation loss during down time.  If it detects
736this, it will update only the history data and return zero; this is then
737handled specially in run_daemon().  While it could correct the offset, this
738might 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
776forthwith.  Note that this will not work for broadcasts, but they will be
777disabled 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
787not subject to the central limit theorem.  Unfortunately, the variation in the
788source'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
807that 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
822errors and complete lunacy, attempting to retry if at all possible.  Because
823glitches at this point are so common, log a reset even in non-verbose mode.
824There will be more thorough checks later.  Note that we cannot usefully check
825the 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
865check that this whole process is likely to be accurate enough and that the
866delay 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
890have 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
923double 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
926enough time has elapsed.  And do remember to kludge up the time and
927discrepancy, 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
950void 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
954subject to spoofing, this is not a major security problem.  But, out of general
955paranoia, check everything in sight when restoring.  Note that this function
956has 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
969care is necessary to avoid introducing a security exposure - but we trust the
970C 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
1133void 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
1163void run_daemon (char *hostnames[], int nhosts, int initial) {
1164
1165/* This does not adjust the time between calls to the server, but it does
1166adjust the time between clock resets.  This function will survive short periods
1167of server inaccessibility or network glitches, but not long ones, and will then
1168need restarting manually.
1169
1170It is far too complex for a single function, but could really only be
1171simplified by making most of its variables global or by a similarly horrible
1172trick.  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
1186only a few of the variables are actually needed to control the operation and
1187the 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
1217that it may take a little time, but shouldn't affect the estimates much.  Then
1218check 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
1249replications per packet, for systems with multiple addresses for receiving
1250broadcasts; the only reason for a limit is to protect against broken NTP
1251servers 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,
1293mainly out of paranoia.  The waiting time is kludged up to attempt to provide
1294reasonable resilience against both lost packets and dead servers.  But it
1295won't handle much of either, and will stop after a while, needing manual
1296restarting.  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
1317is rather more numerically sensitive than simple resynchronisation, reject all
1318very inaccurate packets.  Be careful if you modify this, because the error
1319handling 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
1363correction.  Note that estimate_stats() will return zero if a timestamp
1364indicates synchronisation loss (usually due to down time or a change of server,
1365somewhere upstream), and that the recovery operation is unstructured, so great
1366care should be taken when modifying it.  Also, we want to clear the saved state
1367is 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
1400updating 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        }
1412continue1: ;
1413    }
1414}
1415
1416
1417
1418void run_client (char *hostnames[], int nhosts) {
1419
1420/* Get enough responses to do something with; or not, as the case may be.  Note
1421that it allows for half of the packets to be bad, so may make up to twice as
1422many attempts as specified by the -c value.  The deadline checking is merely
1423paranoia, to protect against broken signal handling - it cannot easily be
1424triggered 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
1446be sensitive to a bad NTP broadcaster, but I believe such things are very rare
1447in practice.  In any case, if you have one, it is probably the only one on your
1448subnet, so you are knackered!  This allows up to ETHERNET_MAX replications per
1449packet, for systems with multiple addresses for receiving broadcasts; the only
1450reason for a limit is to protect against broken NTP servers always returning
1451the 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                }
1490continue1:  ;
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,
1499mainly 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
1527the 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
1576int main (int argc, char *argv[]) {
1577
1578/* This is the entry point and all that.  It decodes the arguments and calls
1579one 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
1726is not usually apparent to the caller.  Most of the time delays are to ensure
1727that 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
1755operation.  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