~ubuntu-branches/debian/squeeze/ntp/squeeze-201010051545

« back to all changes in this revision

Viewing changes to ntpd/refclock_usno.c

  • Committer: Bazaar Package Importer
  • Author(s): Kurt Roeckx
  • Date: 2009-01-05 21:10:03 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20090105211003-mh6zc3um4k1uhsj7
Tags: 1:4.2.4p4+dfsg-8
It did not properly check the return value of EVP_VerifyFinal
which results in an malformed DSA signature being treated as
a good signature rather than as an error.  (CVE-2009-0021)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * refclock_usno - clock driver for the Naval Observatory dialup
3
 
 * Michael Shields <shields@tembel.org> 1995/02/25
4
 
 */
5
 
 
6
 
#ifdef HAVE_CONFIG_H
7
 
#include <config.h>
8
 
#endif
9
 
 
10
 
#if defined(REFCLOCK) && defined(CLOCK_USNO)
11
 
 
12
 
#include "ntpd.h"
13
 
#include "ntp_io.h"
14
 
#include "ntp_unixtime.h"
15
 
#include "ntp_refclock.h"
16
 
#include "ntp_stdlib.h"
17
 
#include "ntp_control.h"
18
 
 
19
 
#include <stdio.h>
20
 
#include <ctype.h>
21
 
#ifdef HAVE_SYS_IOCTL_H
22
 
# include <sys/ioctl.h>
23
 
#endif /* HAVE_SYS_IOCTL_H */
24
 
 
25
 
/*
26
 
 * This driver supports the Naval Observatory dialup at +1 202 653 0351.
27
 
 * It is a hacked-up version of the ACTS driver.
28
 
 *
29
 
 * This driver does not support the `phone' configuration because that
30
 
 * is needlessly global; it would clash with the ACTS driver.
31
 
 *
32
 
 * The Naval Observatory does not support the echo-delay measurement scheme.
33
 
 *
34
 
 * However, this driver *does* support UUCP port locking, allowing the
35
 
 * line to be shared with other processes when not actually dialing
36
 
 * for time.
37
 
 */
38
 
 
39
 
/*
40
 
 * Interface definitions
41
 
 */
42
 
 
43
 
#define DEVICE          "/dev/cua%d" /* device name and unit */
44
 
#define LOCKFILE        "/var/lock/LCK..cua%d"
45
 
/* #define LOCKFILE     "/usr/spool/uucp/LCK..cua%d" */
46
 
 
47
 
#define PHONE           "atdt 202 653 0351"
48
 
/* #define PHONE        "atdt 1 202 653 0351" */
49
 
 
50
 
#define SPEED232        B1200   /* uart speed (1200 cowardly baud) */
51
 
#define PRECISION       (-10)   /* precision assumed (about 1 ms) */
52
 
#define REFID           "USNO"  /* reference ID */
53
 
#define DESCRIPTION     "Naval Observatory dialup"
54
 
 
55
 
#define MODE_AUTO       0       /* automatic mode */
56
 
#define MODE_BACKUP     1       /* backup mode */
57
 
#define MODE_MANUAL     2       /* manual mode */
58
 
 
59
 
#define MSGCNT          10      /* we need this many time messages */
60
 
#define SMAX            80      /* max token string length */
61
 
#define LENCODE         20      /* length of valid timecode string */
62
 
#define USNO_MINPOLL    10      /* log2 min poll interval (1024 s) */
63
 
#define USNO_MAXPOLL    14      /* log2 max poll interval (16384 s) */
64
 
#define MAXOUTAGE       3600    /* max before USNO kicks in (s) */
65
 
 
66
 
/*
67
 
 * Modem control strings. These may have to be changed for some modems.
68
 
 *
69
 
 * AT   command prefix
70
 
 * B1   initiate call negotiation using Bell 212A
71
 
 * &C1  enable carrier detect
72
 
 * &D2  hang up and return to command mode on DTR transition
73
 
 * E0   modem command echo disabled
74
 
 * l1   set modem speaker volume to low level
75
 
 * M1   speaker enabled untill carrier detect
76
 
 * Q0   return result codes
77
 
 * V1   return result codes as English words
78
 
 */
79
 
#define MODEM_SETUP     "ATB1&C1&D2E0L1M1Q0V1" /* modem setup */
80
 
#define MODEM_HANGUP    "ATH"   /* modem disconnect */
81
 
 
82
 
/*
83
 
 * Timeouts
84
 
 */
85
 
#define IDLE            60      /* idle timeout (s) */
86
 
#define WAIT            2       /* wait timeout (s) */
87
 
#define ANSWER          30      /* answer timeout (s) */
88
 
#define CONNECT         10      /* connect timeout (s) */
89
 
#define TIMECODE        (MSGCNT+16)     /* timecode timeout (s) */
90
 
 
91
 
/*
92
 
 * Unit control structure
93
 
 */
94
 
struct usnounit {
95
 
        int     pollcnt;        /* poll message counter */
96
 
 
97
 
        int     state;          /* the first one was Delaware */
98
 
        int     run;            /* call program run switch */
99
 
        int     msgcnt;         /* count of time messages received */
100
 
        long    redial;         /* interval to next automatic call */
101
 
        int     unit;           /* unit number (= port) */
102
 
};
103
 
 
104
 
/*
105
 
 * Function prototypes
106
 
 */
107
 
static  int     usno_start      P((int, struct peer *));
108
 
static  void    usno_shutdown   P((int, struct peer *));
109
 
static  void    usno_poll       P((int, struct peer *));
110
 
static  void    usno_disc       P((struct peer *));
111
 
#if 0
112
 
static  void    usno_timeout    P((struct peer *));
113
 
static  void    usno_receive    P((struct recvbuf *));
114
 
static  int     usno_write      P((struct peer *, const char *));
115
 
#endif /* 0 */
116
 
 
117
 
/*
118
 
 * Transfer vector
119
 
 */
120
 
struct  refclock refclock_usno = {
121
 
        usno_start,             /* start up driver */
122
 
        usno_shutdown,          /* shut down driver */
123
 
        usno_poll,              /* transmit poll message */
124
 
        noentry,                /* not used (usno_control) */
125
 
        noentry,                /* not used (usno_init) */
126
 
        noentry,                /* not used (usno_buginfo) */
127
 
        NOFLAGS                 /* not used */
128
 
};
129
 
 
130
 
 
131
 
/*
132
 
 * usno_start - open the devices and initialize data for processing
133
 
 */
134
 
static int
135
 
usno_start(
136
 
        int unit,
137
 
        struct peer *peer
138
 
        )
139
 
{
140
 
        register struct usnounit *up;
141
 
        struct refclockproc *pp;
142
 
 
143
 
        /*
144
 
         * Initialize miscellaneous variables
145
 
         */
146
 
        pp = peer->procptr;
147
 
        peer->precision = PRECISION;
148
 
        pp->clockdesc = DESCRIPTION;
149
 
        memcpy((char *)&pp->refid, REFID, 4);
150
 
        peer->minpoll = USNO_MINPOLL;
151
 
        peer->maxpoll = USNO_MAXPOLL;
152
 
        peer->sstclktype = CTL_SST_TS_TELEPHONE;
153
 
 
154
 
        /*
155
 
         * Allocate and initialize unit structure
156
 
         */
157
 
        if (!(up = (struct usnounit *)
158
 
              emalloc(sizeof(struct usnounit))))
159
 
            return (0);
160
 
        memset((char *)up, 0, sizeof(struct usnounit));
161
 
        up->unit = unit;
162
 
        pp->unitptr = (caddr_t)up;
163
 
 
164
 
        /*
165
 
         * Set up the driver timeout
166
 
         */
167
 
        peer->nextdate = current_time + WAIT;
168
 
        return (1);
169
 
}
170
 
 
171
 
 
172
 
/*
173
 
 * usno_shutdown - shut down the clock
174
 
 */
175
 
static void
176
 
usno_shutdown(
177
 
        int unit,
178
 
        struct peer *peer
179
 
        )
180
 
{
181
 
        register struct usnounit *up;
182
 
        struct refclockproc *pp;
183
 
 
184
 
#ifdef DEBUG
185
 
        if (debug)
186
 
            printf("usno: clock %s shutting down\n", ntoa(&peer->srcadr));
187
 
#endif
188
 
        pp = peer->procptr;
189
 
        up = (struct usnounit *)pp->unitptr;
190
 
        usno_disc(peer);
191
 
        free(up);
192
 
}
193
 
 
194
 
 
195
 
#if 0
196
 
/*
197
 
 * usno_receive - receive data from the serial interface
198
 
 */
199
 
static void
200
 
usno_receive(
201
 
        struct recvbuf *rbufp
202
 
        )
203
 
{
204
 
        register struct usnounit *up;
205
 
        struct refclockproc *pp;
206
 
        struct peer *peer;
207
 
        char str[SMAX];
208
 
        u_long mjd;             /* Modified Julian Day */
209
 
        static int day, hour, minute, second;
210
 
 
211
 
        /*
212
 
         * Initialize pointers and read the timecode and timestamp. If
213
 
         * the OK modem status code, leave it where folks can find it.
214
 
         */
215
 
        peer = (struct peer *)rbufp->recv_srcclock;
216
 
        pp = peer->procptr;
217
 
        up = (struct usnounit *)pp->unitptr;
218
 
        pp->lencode = refclock_gtlin(rbufp, pp->a_lastcode, BMAX,
219
 
                                     &pp->lastrec);
220
 
        if (pp->lencode == 0) {
221
 
                if (strcmp(pp->a_lastcode, "OK") == 0)
222
 
                    pp->lencode = 2;
223
 
                return;
224
 
        }
225
 
#ifdef DEBUG
226
 
        if (debug)
227
 
            printf("usno: timecode %d %s\n", pp->lencode,
228
 
                   pp->a_lastcode);
229
 
#endif
230
 
 
231
 
        switch (up->state) {
232
 
 
233
 
            case 0:
234
 
 
235
 
                /*
236
 
                 * State 0. We are not expecting anything. Probably
237
 
                 * modem disconnect noise. Go back to sleep.
238
 
                 */
239
 
                return;
240
 
 
241
 
            case 1:
242
 
 
243
 
                /*
244
 
                 * State 1. We are about to dial. Just drop it.
245
 
                 */
246
 
                return;
247
 
 
248
 
            case 2:
249
 
 
250
 
                /*
251
 
                 * State 2. We are waiting for the call to be answered.
252
 
                 * All we care about here is CONNECT as the first token
253
 
                 * in the string. If the modem signals BUSY, ERROR, NO
254
 
                 * ANSWER, NO CARRIER or NO DIALTONE, we immediately
255
 
                 * hang up the phone. If CONNECT doesn't happen after
256
 
                 * ANSWER seconds, hang up the phone. If everything is
257
 
                 * okay, start the connect timeout and slide into state
258
 
                 * 3.
259
 
                 */
260
 
                (void)strncpy(str, strtok(pp->a_lastcode, " "), SMAX);
261
 
                if (strcmp(str, "BUSY") == 0 || strcmp(str, "ERROR") ==
262
 
                    0 || strcmp(str, "NO") == 0) {
263
 
                        NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
264
 
                                msyslog(LOG_NOTICE,
265
 
                                        "clock %s USNO modem status %s",
266
 
                                        ntoa(&peer->srcadr), pp->a_lastcode);
267
 
                        usno_disc(peer);
268
 
                } else if (strcmp(str, "CONNECT") == 0) {
269
 
                        peer->nextdate = current_time + CONNECT;
270
 
                        up->msgcnt = 0;
271
 
                        up->state++;
272
 
                } else {
273
 
                        NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
274
 
                                msyslog(LOG_WARNING,
275
 
                                        "clock %s USNO unknown modem status %s",
276
 
                                        ntoa(&peer->srcadr), pp->a_lastcode);
277
 
                }
278
 
                return;
279
 
 
280
 
            case 3:
281
 
 
282
 
                /*
283
 
                 * State 3. The call has been answered and we are
284
 
                 * waiting for the first message. If this doesn't
285
 
                 * happen within the timecode timeout, hang up the
286
 
                 * phone. We probably got a wrong number or they are
287
 
                 * down.
288
 
                 */
289
 
                peer->nextdate = current_time + TIMECODE;
290
 
                up->state++;
291
 
                return;
292
 
 
293
 
            case 4:
294
 
 
295
 
                /*
296
 
                 * State 4. We are reading a timecode.  It's an actual
297
 
                 * timecode, or it's the `*' OTM.
298
 
                 *
299
 
                 * jjjjj nnn hhmmss UTC
300
 
                 */
301
 
                if (pp->lencode == LENCODE) {
302
 
                        if (sscanf(pp->a_lastcode, "%5ld %3d %2d%2d%2d UTC",
303
 
                                   &mjd, &day, &hour, &minute, &second) != 5) {
304
 
#ifdef DEBUG
305
 
                                if (debug)
306
 
                                    printf("usno: bad timecode format\n");
307
 
#endif
308
 
                                refclock_report(peer, CEVNT_BADREPLY);
309
 
                        } else
310
 
                            up->msgcnt++;
311
 
                        return;
312
 
                } else if (pp->lencode != 1 || !up->msgcnt)
313
 
                    return;
314
 
                /* else, OTM; drop out of switch */
315
 
        }
316
 
 
317
 
        pp->leap = LEAP_NOWARNING;
318
 
        pp->day = day;
319
 
        pp->hour = hour;
320
 
        pp->minute = minute;
321
 
        pp->second = second;
322
 
 
323
 
        /*
324
 
         * Colossal hack here. We process each sample in a trimmed-mean
325
 
         * filter and determine the reference clock offset and
326
 
         * dispersion. The fudge time1 value is added to each sample as
327
 
         * received.
328
 
         */
329
 
        if (!refclock_process(pp)) {
330
 
#ifdef DEBUG
331
 
                if (debug)
332
 
                    printf("usno: time rejected\n");
333
 
#endif
334
 
                refclock_report(peer, CEVNT_BADTIME);
335
 
                return;
336
 
        } else if (up->msgcnt < MSGCNT)
337
 
            return;
338
 
 
339
 
        /*
340
 
         * We have a filtered sample offset ready for peer processing.
341
 
         * We use lastrec as both the reference time and receive time in
342
 
         * order to avoid being cute, like setting the reference time
343
 
         * later than the receive time, which may cause a paranoid
344
 
         * protocol module to chuck out the data. Finaly, we unhook the
345
 
         * timeout, arm for the next call, fold the tent and go home.
346
 
         */
347
 
        pp->lastref = pp->lastrec;
348
 
        refclock_receive(peer);
349
 
        record_clock_stats(&peer->srcadr, pp->a_lastcode);
350
 
        pp->sloppyclockflag &= ~CLK_FLAG1;
351
 
        up->pollcnt = 0;
352
 
        up->state = 0;
353
 
        usno_disc(peer);
354
 
}
355
 
#endif /* 0 */
356
 
 
357
 
 
358
 
/*
359
 
 * usno_poll - called by the transmit routine
360
 
 */
361
 
static void
362
 
usno_poll(
363
 
        int unit,
364
 
        struct peer *peer
365
 
        )
366
 
{
367
 
        register struct usnounit *up;
368
 
        struct refclockproc *pp;
369
 
 
370
 
        /*
371
 
         * If the driver is running, we set the enable flag (fudge
372
 
         * flag1), which causes the driver timeout routine to initiate a
373
 
         * call. If not, the enable flag can be set using
374
 
         * ntpdc. If this is the sustem peer, then follow the system
375
 
         * poll interval.
376
 
         */
377
 
        pp = peer->procptr;
378
 
        up = (struct usnounit *)pp->unitptr;
379
 
        if (up->run) {
380
 
                pp->sloppyclockflag |= CLK_FLAG1;
381
 
                if (peer == sys_peer)
382
 
                    peer->hpoll = sys_poll;
383
 
                else
384
 
                    peer->hpoll = peer->minpoll;
385
 
        }
386
 
}
387
 
 
388
 
 
389
 
#if 0
390
 
/*
391
 
 * usno_timeout - called by the timer interrupt
392
 
 */
393
 
static void
394
 
usno_timeout(
395
 
        struct peer *peer
396
 
        )
397
 
{
398
 
        register struct usnounit *up;
399
 
        struct refclockproc *pp;
400
 
        int fd;
401
 
        char device[20];
402
 
        char lockfile[128], pidbuf[8];
403
 
        int dtr = TIOCM_DTR;
404
 
 
405
 
        /*
406
 
         * If a timeout occurs in other than state 0, the call has
407
 
         * failed. If in state 0, we just see if there is other work to
408
 
         * do.
409
 
         */
410
 
        pp = peer->procptr;
411
 
        up = (struct usnounit *)pp->unitptr;
412
 
        if (up->state) {
413
 
                if (up->state != 1) {
414
 
                        usno_disc(peer);
415
 
                        return;
416
 
                }
417
 
                /*
418
 
                 * Call, and start the answer timeout. We think it
419
 
                 * strange if the OK status has not been received from
420
 
                 * the modem, but plow ahead anyway.
421
 
                 *
422
 
                 * This code is *here* because we had to stick in a brief
423
 
                 * delay to let the modem settle down after raising DTR,
424
 
                 * and for the OK to be received.  State machines are
425
 
                 * contorted.
426
 
                 */
427
 
                if (strcmp(pp->a_lastcode, "OK") != 0)
428
 
                    NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
429
 
                            msyslog(LOG_NOTICE, "clock %s USNO no modem status",
430
 
                                    ntoa(&peer->srcadr));
431
 
                (void)usno_write(peer, PHONE);
432
 
                NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
433
 
                        msyslog(LOG_NOTICE, "clock %s USNO calling %s\n",
434
 
                                ntoa(&peer->srcadr), PHONE);
435
 
                up->state = 2;
436
 
                up->pollcnt++;
437
 
                pp->polls++;
438
 
                peer->nextdate = current_time + ANSWER;
439
 
                return;
440
 
        }
441
 
        switch (peer->ttl) {
442
 
 
443
 
                /*
444
 
                 * In manual mode the calling program is activated
445
 
                 * by the ntpdc program using the enable flag (fudge
446
 
                 * flag1), either manually or by a cron job.
447
 
                 */
448
 
            case MODE_MANUAL:
449
 
                up->run = 0;
450
 
                break;
451
 
 
452
 
                /*
453
 
                 * In automatic mode the calling program runs
454
 
                 * continuously at intervals determined by the sys_poll
455
 
                 * variable.
456
 
                 */
457
 
            case MODE_AUTO:
458
 
                if (!up->run)
459
 
                    pp->sloppyclockflag |= CLK_FLAG1;
460
 
                up->run = 1;
461
 
                break;
462
 
 
463
 
                /*
464
 
                 * In backup mode the calling program is disabled,
465
 
                 * unless no system peer has been selected for MAXOUTAGE
466
 
                 * (3600 s). Once enabled, it runs until some other NTP
467
 
                 * peer shows up.
468
 
                 */
469
 
            case MODE_BACKUP:
470
 
                if (!up->run && sys_peer == 0) {
471
 
                        if (current_time - last_time > MAXOUTAGE) {
472
 
                                up->run = 1;
473
 
                                peer->hpoll = peer->minpoll;
474
 
                                NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
475
 
                                        msyslog(LOG_NOTICE,
476
 
                                                "clock %s USNO backup started ",
477
 
                                                ntoa(&peer->srcadr));
478
 
                        }
479
 
                } else if (up->run && sys_peer->sstclktype != CTL_SST_TS_TELEPHONE) {
480
 
                        peer->hpoll = peer->minpoll;
481
 
                        up->run = 0;
482
 
                        NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
483
 
                                msyslog(LOG_NOTICE,
484
 
                                        "clock %s USNO backup stopped",
485
 
                                        ntoa(&peer->srcadr));
486
 
                }
487
 
                break;
488
 
 
489
 
            default:
490
 
                msyslog(LOG_ERR,
491
 
                        "clock %s USNO invalid mode", ntoa(&peer->srcadr));
492
 
                
493
 
        }
494
 
 
495
 
        /*
496
 
         * The fudge flag1 is used as an enable/disable; if set either
497
 
         * by the code or via ntpdc, the calling program is
498
 
         * started; if reset, the phones stop ringing.
499
 
         */
500
 
        if (!(pp->sloppyclockflag & CLK_FLAG1)) {
501
 
                up->pollcnt = 0;
502
 
                peer->nextdate = current_time + IDLE;
503
 
                return;
504
 
        }
505
 
 
506
 
        /*
507
 
         * Lock the port.
508
 
         */
509
 
        (void)sprintf(lockfile, LOCKFILE, up->unit);
510
 
        fd = open(lockfile, O_WRONLY|O_CREAT|O_EXCL, 0644);
511
 
        if (fd < 0) {
512
 
                msyslog(LOG_ERR, "clock %s USNO port busy",
513
 
                        ntoa(&peer->srcadr));
514
 
                return;
515
 
        }
516
 
        sprintf(pidbuf, "%d\n", (int) getpid());
517
 
        write(fd, pidbuf, strlen(pidbuf));
518
 
        close(fd);
519
 
 
520
 
        /*
521
 
         * Open serial port. Use ACTS line discipline, if available. It
522
 
         * pumps a timestamp into the data stream at every on-time
523
 
         * character '*' found. Note: the port must have modem control
524
 
         * or deep pockets for the phone bill. HP-UX 9.03 users should
525
 
         * have very deep pockets.
526
 
         */
527
 
        (void)sprintf(device, DEVICE, up->unit);
528
 
        if (!(fd = refclock_open(device, SPEED232, LDISC_ACTS))) {
529
 
                unlink(lockfile);
530
 
                return;
531
 
        }
532
 
        if (ioctl(fd, TIOCMBIC, (char *)&dtr) < 0)
533
 
            msyslog(LOG_WARNING, "usno_timeout: clock %s: couldn't clear DTR: %m",
534
 
                    ntoa(&peer->srcadr));
535
 
 
536
 
        pp->io.clock_recv = usno_receive;
537
 
        pp->io.srcclock = (caddr_t)peer;
538
 
        pp->io.datalen = 0;
539
 
        pp->io.fd = fd;
540
 
        if (!io_addclock(&pp->io)) {
541
 
                (void) close(fd);
542
 
                unlink(lockfile);
543
 
                free(up);
544
 
                return;
545
 
        }
546
 
 
547
 
        /*
548
 
         * Initialize modem and kill DTR. We skedaddle if this comes
549
 
         * bum.
550
 
         */
551
 
        if (!usno_write(peer, MODEM_SETUP)) {
552
 
                msyslog(LOG_ERR, "clock %s USNO couldn't write",
553
 
                        ntoa(&peer->srcadr));
554
 
                io_closeclock(&pp->io);
555
 
                unlink(lockfile);
556
 
                free(up);
557
 
                return;
558
 
        }
559
 
 
560
 
        /*
561
 
         * Initiate a call to the Observatory. If we wind up here in
562
 
         * other than state 0, a successful call could not be completed
563
 
         * within minpoll seconds.
564
 
         */
565
 
        if (up->pollcnt) {
566
 
                refclock_report(peer, CEVNT_TIMEOUT);
567
 
                NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
568
 
                        msyslog(LOG_NOTICE,
569
 
                                "clock %s USNO calling program terminated",
570
 
                                ntoa(&peer->srcadr));
571
 
                pp->sloppyclockflag &= ~CLK_FLAG1;
572
 
                up->pollcnt = 0;
573
 
#ifdef DEBUG
574
 
                if (debug)
575
 
                    printf("usno: calling program terminated\n");
576
 
#endif
577
 
                usno_disc(peer);
578
 
                return;
579
 
        }
580
 
 
581
 
        /*
582
 
         * Raise DTR, and let the modem settle.  Then we'll dial.
583
 
         */
584
 
        if (ioctl(pp->io.fd, TIOCMBIS, (char *)&dtr) < -1)
585
 
            msyslog(LOG_INFO, "usno_timeout: clock %s: couldn't set DTR: %m",
586
 
                    ntoa(&peer->srcadr));
587
 
        up->state = 1;
588
 
        peer->nextdate = current_time + WAIT;
589
 
}
590
 
#endif /* 0 */
591
 
 
592
 
 
593
 
/*
594
 
 * usno_disc - disconnect the call and wait for the ruckus to cool
595
 
 */
596
 
static void
597
 
usno_disc(
598
 
        struct peer *peer
599
 
        )
600
 
{
601
 
        register struct usnounit *up;
602
 
        struct refclockproc *pp;
603
 
        int dtr = TIOCM_DTR;
604
 
        char lockfile[128];
605
 
 
606
 
        /*
607
 
         * We should never get here other than in state 0, unless a call
608
 
         * has timed out. We drop DTR, which will reliably get the modem
609
 
         * off the air, even while the modem is hammering away full tilt.
610
 
         */
611
 
        pp = peer->procptr;
612
 
        up = (struct usnounit *)pp->unitptr;
613
 
 
614
 
        if (ioctl(pp->io.fd, TIOCMBIC, (char *)&dtr) < 0)
615
 
            msyslog(LOG_INFO, "usno_disc: clock %s: couldn't clear DTR: %m",
616
 
                    ntoa(&peer->srcadr));
617
 
 
618
 
        if (up->state > 0) {
619
 
                up->state = 0;
620
 
                msyslog(LOG_NOTICE, "clock %s USNO call failed %d",
621
 
                        ntoa(&peer->srcadr), up->state);
622
 
#ifdef DEBUG
623
 
                if (debug)
624
 
                    printf("usno: call failed %d\n", up->state);
625
 
#endif
626
 
        }
627
 
 
628
 
        io_closeclock(&pp->io);
629
 
        sprintf(lockfile, LOCKFILE, up->unit);
630
 
        unlink(lockfile);
631
 
 
632
 
        peer->nextdate = current_time + WAIT;
633
 
}
634
 
 
635
 
 
636
 
#if 0
637
 
/*
638
 
 * usno_write - write a message to the serial port
639
 
 */
640
 
static int
641
 
usno_write(
642
 
        struct peer *peer,
643
 
        const char *str
644
 
        )
645
 
{
646
 
        register struct usnounit *up;
647
 
        struct refclockproc *pp;
648
 
        int len;
649
 
        int code;
650
 
        char cr = '\r';
651
 
 
652
 
        /*
653
 
         * Not much to do here, other than send the message, handle
654
 
         * debug and report faults.
655
 
         */
656
 
        pp = peer->procptr;
657
 
        up = (struct usnounit *)pp->unitptr;
658
 
        len = strlen(str);
659
 
#ifdef DEBUG
660
 
        if (debug)
661
 
            printf("usno: state %d send %d %s\n", up->state, len,
662
 
                   str);
663
 
#endif
664
 
        code = write(pp->io.fd, str, (unsigned)len) == len;
665
 
        code |= write(pp->io.fd, &cr, 1) == 1;
666
 
        if (!code)
667
 
            refclock_report(peer, CEVNT_FAULT);
668
 
        return (code);
669
 
}
670
 
#endif /* 0 */
671
 
 
672
 
#else
673
 
int refclock_usno_bs;
674
 
#endif /* REFCLOCK */