Mon Dec 14 00:42:21 2009 UTC ()
fix debug printf format
fix bogus ctype cast


(christos)
diff -r1.1.1.1 -r1.2 src/external/bsd/ntp/dist/ntpd/refclock_acts.c

cvs diff -r1.1.1.1 -r1.2 src/external/bsd/ntp/dist/ntpd/refclock_acts.c (switch to unified diff)

--- src/external/bsd/ntp/dist/ntpd/refclock_acts.c 2009/12/13 16:55:43 1.1.1.1
+++ src/external/bsd/ntp/dist/ntpd/refclock_acts.c 2009/12/14 00:42:21 1.2
@@ -1,938 +1,938 @@ @@ -1,938 +1,938 @@
1/* $NetBSD: refclock_acts.c,v 1.1.1.1 2009/12/13 16:55:43 kardel Exp $ */ 1/* $NetBSD: refclock_acts.c,v 1.2 2009/12/14 00:42:21 christos Exp $ */
2 2
3/* 3/*
4 * refclock_acts - clock driver for the NIST/USNO/PTB/NPL Computer Time 4 * refclock_acts - clock driver for the NIST/USNO/PTB/NPL Computer Time
5 * Services 5 * Services
6 */ 6 */
7#ifdef HAVE_CONFIG_H 7#ifdef HAVE_CONFIG_H
8#include <config.h> 8#include <config.h>
9#endif 9#endif
10 10
11#if defined(REFCLOCK) && (defined(CLOCK_ACTS) || defined(CLOCK_PTBACTS)) 11#if defined(REFCLOCK) && (defined(CLOCK_ACTS) || defined(CLOCK_PTBACTS))
12 12
13#include "ntpd.h" 13#include "ntpd.h"
14#include "ntp_io.h" 14#include "ntp_io.h"
15#include "ntp_unixtime.h" 15#include "ntp_unixtime.h"
16#include "ntp_refclock.h" 16#include "ntp_refclock.h"
17#include "ntp_stdlib.h" 17#include "ntp_stdlib.h"
18#include "ntp_control.h" 18#include "ntp_control.h"
19 19
20#include <stdio.h> 20#include <stdio.h>
21#include <ctype.h> 21#include <ctype.h>
22#ifdef HAVE_SYS_IOCTL_H 22#ifdef HAVE_SYS_IOCTL_H
23# include <sys/ioctl.h> 23# include <sys/ioctl.h>
24#endif /* HAVE_SYS_IOCTL_H */ 24#endif /* HAVE_SYS_IOCTL_H */
25 25
26/* 26/*
27 * This driver supports the US (NIST, USNO) and European (PTB, NPL, 27 * This driver supports the US (NIST, USNO) and European (PTB, NPL,
28 * etc.) modem time services, as well as Spectracom GPS and WWVB 28 * etc.) modem time services, as well as Spectracom GPS and WWVB
29 * receivers connected via a modem. The driver periodically dials a 29 * receivers connected via a modem. The driver periodically dials a
30 * number from a telephone list, receives the timecode data and 30 * number from a telephone list, receives the timecode data and
31 * calculates the local clock correction. It is designed primarily for 31 * calculates the local clock correction. It is designed primarily for
32 * use as backup when neither a radio clock nor connectivity to Internet 32 * use as backup when neither a radio clock nor connectivity to Internet
33 * time servers is available. 33 * time servers is available.
34 * 34 *
35 * This driver requires a modem with a Hayes-compatible command set and 35 * This driver requires a modem with a Hayes-compatible command set and
36 * control over the modem data terminal ready (DTR) control line. The 36 * control over the modem data terminal ready (DTR) control line. The
37 * modem setup string is hard-coded in the driver and may require 37 * modem setup string is hard-coded in the driver and may require
38 * changes for nonstandard modems or special circumstances. For reasons 38 * changes for nonstandard modems or special circumstances. For reasons
39 * unrelated to this driver, the data set ready (DSR) control line 39 * unrelated to this driver, the data set ready (DSR) control line
40 * should not be set when this driver is first started. 40 * should not be set when this driver is first started.
41 * 41 *
42 * The calling program is initiated by setting fudge flag1, either 42 * The calling program is initiated by setting fudge flag1, either
43 * manually or automatically. When flag1 is set, the calling program 43 * manually or automatically. When flag1 is set, the calling program
44 * dials the first number in the phone command of the configuration 44 * dials the first number in the phone command of the configuration
45 * file. If that call fails, the calling program dials the second number 45 * file. If that call fails, the calling program dials the second number
46 * and so on. The number is specified by the Hayes ATDT prefix followed 46 * and so on. The number is specified by the Hayes ATDT prefix followed
47 * by the number itself, including the prefix and long-distance digits 47 * by the number itself, including the prefix and long-distance digits
48 * and delay code, if necessary. The flag1 is reset and the calling 48 * and delay code, if necessary. The flag1 is reset and the calling
49 * program terminated if (a) a valid clock update has been determined, 49 * program terminated if (a) a valid clock update has been determined,
50 * (b) no more numbers remain in the list, (c) a device fault or timeout 50 * (b) no more numbers remain in the list, (c) a device fault or timeout
51 * occurs or (d) fudge flag1 is reset manually. 51 * occurs or (d) fudge flag1 is reset manually.
52 * 52 *
53 * The driver is transparent to each of the modem time services and 53 * The driver is transparent to each of the modem time services and
54 * Spectracom radios. It selects the parsing algorithm depending on the 54 * Spectracom radios. It selects the parsing algorithm depending on the
55 * message length. There is some hazard should the message be corrupted. 55 * message length. There is some hazard should the message be corrupted.
56 * However, the data format is checked carefully and only if all checks 56 * However, the data format is checked carefully and only if all checks
57 * succeed is the message accepted. Corrupted lines are discarded 57 * succeed is the message accepted. Corrupted lines are discarded
58 * without complaint. 58 * without complaint.
59 * 59 *
60 * Fudge controls 60 * Fudge controls
61 * 61 *
62 * flag1 force a call in manual mode 62 * flag1 force a call in manual mode
63 * flag2 enable port locking (not verified) 63 * flag2 enable port locking (not verified)
64 * flag3 no modem; port is directly connected to device 64 * flag3 no modem; port is directly connected to device
65 * flag4 not used 65 * flag4 not used
66 * 66 *
67 * time1 offset adjustment (s) 67 * time1 offset adjustment (s)
68 * 68 *
69 * Ordinarily, the serial port is connected to a modem; however, it can 69 * Ordinarily, the serial port is connected to a modem; however, it can
70 * be connected directly to a device or another computer for testing and 70 * be connected directly to a device or another computer for testing and
71 * calibration. In this case set fudge flag3 and the driver will send a 71 * calibration. In this case set fudge flag3 and the driver will send a
72 * single character 'T' at each poll event. In principle, fudge flag2 72 * single character 'T' at each poll event. In principle, fudge flag2
73 * enables port locking, allowing the modem to be shared when not in use 73 * enables port locking, allowing the modem to be shared when not in use
74 * by this driver. At least on Solaris with the current NTP I/O 74 * by this driver. At least on Solaris with the current NTP I/O
75 * routines, this results only in lots of ugly error messages. 75 * routines, this results only in lots of ugly error messages.
76 */ 76 */
77/* 77/*
78 * National Institute of Science and Technology (NIST) 78 * National Institute of Science and Technology (NIST)
79 * 79 *
80 * Phone: (303) 494-4774 (Boulder, CO); (808) 335-4721 (Hawaii) 80 * Phone: (303) 494-4774 (Boulder, CO); (808) 335-4721 (Hawaii)
81 * 81 *
82 * Data Format 82 * Data Format
83 * 83 *
84 * National Institute of Standards and Technology 84 * National Institute of Standards and Technology
85 * Telephone Time Service, Generator 3B 85 * Telephone Time Service, Generator 3B
86 * Enter question mark "?" for HELP 86 * Enter question mark "?" for HELP
87 * D L D 87 * D L D
88 * MJD YR MO DA H M S ST S UT1 msADV <OTM> 88 * MJD YR MO DA H M S ST S UT1 msADV <OTM>
89 * 47999 90-04-18 21:39:15 50 0 +.1 045.0 UTC(NIST) *<CR><LF> 89 * 47999 90-04-18 21:39:15 50 0 +.1 045.0 UTC(NIST) *<CR><LF>
90 * ... 90 * ...
91 * 91 *
92 * MJD, DST, DUT1 and UTC are not used by this driver. The "*" or "#" is 92 * MJD, DST, DUT1 and UTC are not used by this driver. The "*" or "#" is
93 * the on-time markers echoed by the driver and used by NIST to measure 93 * the on-time markers echoed by the driver and used by NIST to measure
94 * and correct for the propagation delay. 94 * and correct for the propagation delay.
95 * 95 *
96 * US Naval Observatory (USNO) 96 * US Naval Observatory (USNO)
97 * 97 *
98 * Phone: (202) 762-1594 (Washington, DC); (719) 567-6742 (Boulder, CO) 98 * Phone: (202) 762-1594 (Washington, DC); (719) 567-6742 (Boulder, CO)
99 * 99 *
100 * Data Format (two lines, repeating at one-second intervals) 100 * Data Format (two lines, repeating at one-second intervals)
101 * 101 *
102 * jjjjj nnn hhmmss UTC<CR><LF> 102 * jjjjj nnn hhmmss UTC<CR><LF>
103 * *<CR><LF> 103 * *<CR><LF>
104 * 104 *
105 * jjjjj modified Julian day number (not used) 105 * jjjjj modified Julian day number (not used)
106 * nnn day of year 106 * nnn day of year
107 * hhmmss second of day 107 * hhmmss second of day
108 * * on-time marker for previous timecode 108 * * on-time marker for previous timecode
109 * ... 109 * ...
110 * 110 *
111 * USNO does not correct for the propagation delay. A fudge time1 of 111 * USNO does not correct for the propagation delay. A fudge time1 of
112 * about .06 s is advisable. 112 * about .06 s is advisable.
113 * 113 *
114 * European Services (PTB, NPL, etc.) 114 * European Services (PTB, NPL, etc.)
115 * 115 *
116 * PTB: +49 531 512038 (Germany) 116 * PTB: +49 531 512038 (Germany)
117 * NPL: 0906 851 6333 (UK only) 117 * NPL: 0906 851 6333 (UK only)
118 * 118 *
119 * Data format (see the documentation for phone numbers and formats.) 119 * Data format (see the documentation for phone numbers and formats.)
120 * 120 *
121 * 1995-01-23 20:58:51 MEZ 10402303260219950123195849740+40000500<CR><LF> 121 * 1995-01-23 20:58:51 MEZ 10402303260219950123195849740+40000500<CR><LF>
122 * 122 *
123 * Spectracom GPS and WWVB Receivers 123 * Spectracom GPS and WWVB Receivers
124 * 124 *
125 * If a modem is connected to a Spectracom receiver, this driver will 125 * If a modem is connected to a Spectracom receiver, this driver will
126 * call it up and retrieve the time in one of two formats. As this 126 * call it up and retrieve the time in one of two formats. As this
127 * driver does not send anything, the radio will have to either be 127 * driver does not send anything, the radio will have to either be
128 * configured in continuous mode or be polled by another local driver. 128 * configured in continuous mode or be polled by another local driver.
129 */ 129 */
130/* 130/*
131 * Interface definitions 131 * Interface definitions
132 */ 132 */
133#define DEVICE "/dev/acts%d" /* device name and unit */ 133#define DEVICE "/dev/acts%d" /* device name and unit */
134#define SPEED232 B9600 /* uart speed (9600 baud) */ 134#define SPEED232 B9600 /* uart speed (9600 baud) */
135#define PRECISION (-10) /* precision assumed (about 1 ms) */ 135#define PRECISION (-10) /* precision assumed (about 1 ms) */
136#define LOCKFILE "/var/spool/locks/LCK..cua%d" 136#define LOCKFILE "/var/spool/locks/LCK..cua%d"
137#define DESCRIPTION "Automated Computer Time Service" /* WRU */ 137#define DESCRIPTION "Automated Computer Time Service" /* WRU */
138#define REFID "NONE" /* default reference ID */ 138#define REFID "NONE" /* default reference ID */
139#define MSGCNT 20 /* max message count */ 139#define MSGCNT 20 /* max message count */
140#define SMAX 256 /* max clockstats line length */ 140#define SMAX 256 /* max clockstats line length */
141#define MAXPHONE 10 /* max number of phone numbers */ 141#define MAXPHONE 10 /* max number of phone numbers */
142 142
143/* 143/*
144 * Calling program modes 144 * Calling program modes
145 */ 145 */
146#define MODE_AUTO 0 /* automatic mode */ 146#define MODE_AUTO 0 /* automatic mode */
147#define MODE_BACKUP 1 /* backup mode */ 147#define MODE_BACKUP 1 /* backup mode */
148#define MODE_MANUAL 2 /* manual mode */ 148#define MODE_MANUAL 2 /* manual mode */
149 149
150/* 150/*
151 * Service identifiers. 151 * Service identifiers.
152 */ 152 */
153#define REFACTS "NIST" /* NIST reference ID */ 153#define REFACTS "NIST" /* NIST reference ID */
154#define LENACTS 50 /* NIST format */ 154#define LENACTS 50 /* NIST format */
155#define REFUSNO "USNO" /* USNO reference ID */ 155#define REFUSNO "USNO" /* USNO reference ID */
156#define LENUSNO 20 /* USNO */ 156#define LENUSNO 20 /* USNO */
157#define REFPTB "PTB\0" /* PTB/NPL reference ID */ 157#define REFPTB "PTB\0" /* PTB/NPL reference ID */
158#define LENPTB 78 /* PTB/NPL format */ 158#define LENPTB 78 /* PTB/NPL format */
159#define REFWWVB "WWVB" /* WWVB reference ID */ 159#define REFWWVB "WWVB" /* WWVB reference ID */
160#define LENWWVB0 22 /* WWVB format 0 */ 160#define LENWWVB0 22 /* WWVB format 0 */
161#define LENWWVB2 24 /* WWVB format 2 */ 161#define LENWWVB2 24 /* WWVB format 2 */
162#define LF 0x0a /* ASCII LF */ 162#define LF 0x0a /* ASCII LF */
163 163
164/* 164/*
165 * Modem setup strings. These may have to be changed for some modems. 165 * Modem setup strings. These may have to be changed for some modems.
166 * 166 *
167 * AT command prefix 167 * AT command prefix
168 * B1 US answer tone 168 * B1 US answer tone
169 * &C0 disable carrier detect 169 * &C0 disable carrier detect
170 * &D2 hang up and return to command mode on DTR transition 170 * &D2 hang up and return to command mode on DTR transition
171 * E0 modem command echo disabled 171 * E0 modem command echo disabled
172 * l1 set modem speaker volume to low level 172 * l1 set modem speaker volume to low level
173 * M1 speaker enabled until carrier detect 173 * M1 speaker enabled until carrier detect
174 * Q0 return result codes 174 * Q0 return result codes
175 * V1 return result codes as English words 175 * V1 return result codes as English words
176 */ 176 */
177#define MODEM_SETUP "ATB1&C0&D2E0L1M1Q0V1\r" /* modem setup */ 177#define MODEM_SETUP "ATB1&C0&D2E0L1M1Q0V1\r" /* modem setup */
178#define MODEM_HANGUP "ATH\r" /* modem disconnect */ 178#define MODEM_HANGUP "ATH\r" /* modem disconnect */
179 179
180/* 180/*
181 * Timeouts (all in seconds) 181 * Timeouts (all in seconds)
182 */ 182 */
183#define SETUP 3 /* setup timeout */ 183#define SETUP 3 /* setup timeout */
184#define DTR 1 /* DTR timeout */ 184#define DTR 1 /* DTR timeout */
185#define ANSWER 60 /* answer timeout */ 185#define ANSWER 60 /* answer timeout */
186#define CONNECT 20 /* first valid message timeout */ 186#define CONNECT 20 /* first valid message timeout */
187#define TIMECODE 30 /* all valid messages timeout */ 187#define TIMECODE 30 /* all valid messages timeout */
188 188
189/* 189/*
190 * State machine codes 190 * State machine codes
191 */ 191 */
192#define S_IDLE 0 /* wait for poll */ 192#define S_IDLE 0 /* wait for poll */
193#define S_OK 1 /* wait for modem setup */ 193#define S_OK 1 /* wait for modem setup */
194#define S_DTR 2 /* wait for modem DTR */ 194#define S_DTR 2 /* wait for modem DTR */
195#define S_CONNECT 3 /* wait for answer*/ 195#define S_CONNECT 3 /* wait for answer*/
196#define S_FIRST 4 /* wait for first valid message */ 196#define S_FIRST 4 /* wait for first valid message */
197#define S_MSG 5 /* wait for all messages */ 197#define S_MSG 5 /* wait for all messages */
198#define S_CLOSE 6 /* wait after sending disconnect */ 198#define S_CLOSE 6 /* wait after sending disconnect */
199 199
200/* 200/*
201 * Unit control structure 201 * Unit control structure
202 */ 202 */
203struct actsunit { 203struct actsunit {
204 int unit; /* unit number */ 204 int unit; /* unit number */
205 int state; /* the first one was Delaware */ 205 int state; /* the first one was Delaware */
206 int timer; /* timeout counter */ 206 int timer; /* timeout counter */
207 int retry; /* retry index */ 207 int retry; /* retry index */
208 int msgcnt; /* count of messages received */ 208 int msgcnt; /* count of messages received */
209 l_fp tstamp; /* on-time timestamp */ 209 l_fp tstamp; /* on-time timestamp */
210 char *bufptr; /* buffer pointer */ 210 char *bufptr; /* buffer pointer */
211}; 211};
212 212
213/* 213/*
214 * Function prototypes 214 * Function prototypes
215 */ 215 */
216static int acts_start (int, struct peer *); 216static int acts_start (int, struct peer *);
217static void acts_shutdown (int, struct peer *); 217static void acts_shutdown (int, struct peer *);
218static void acts_receive (struct recvbuf *); 218static void acts_receive (struct recvbuf *);
219static void acts_message (struct peer *); 219static void acts_message (struct peer *);
220static void acts_timecode (struct peer *, char *); 220static void acts_timecode (struct peer *, char *);
221static void acts_poll (int, struct peer *); 221static void acts_poll (int, struct peer *);
222static void acts_timeout (struct peer *); 222static void acts_timeout (struct peer *);
223static void acts_disc (struct peer *); 223static void acts_disc (struct peer *);
224static void acts_timer (int, struct peer *); 224static void acts_timer (int, struct peer *);
225 225
226/* 226/*
227 * Transfer vector (conditional structure name) 227 * Transfer vector (conditional structure name)
228 */ 228 */
229struct refclock refclock_acts = { 229struct refclock refclock_acts = {
230 acts_start, /* start up driver */ 230 acts_start, /* start up driver */
231 acts_shutdown, /* shut down driver */ 231 acts_shutdown, /* shut down driver */
232 acts_poll, /* transmit poll message */ 232 acts_poll, /* transmit poll message */
233 noentry, /* not used */ 233 noentry, /* not used */
234 noentry, /* not used */ 234 noentry, /* not used */
235 noentry, /* not used */ 235 noentry, /* not used */
236 acts_timer /* housekeeping timer */ 236 acts_timer /* housekeeping timer */
237}; 237};
238 238
239/* 239/*
240 * Initialize data for processing 240 * Initialize data for processing
241 */ 241 */
242static int 242static int
243acts_start ( 243acts_start (
244 int unit, 244 int unit,
245 struct peer *peer 245 struct peer *peer
246 ) 246 )
247{ 247{
248 struct actsunit *up; 248 struct actsunit *up;
249 struct refclockproc *pp; 249 struct refclockproc *pp;
250 250
251 /* 251 /*
252 * Allocate and initialize unit structure 252 * Allocate and initialize unit structure
253 */ 253 */
254 up = emalloc(sizeof(struct actsunit)); 254 up = emalloc(sizeof(struct actsunit));
255 memset(up, 0, sizeof(struct actsunit)); 255 memset(up, 0, sizeof(struct actsunit));
256 up->unit = unit; 256 up->unit = unit;
257 pp = peer->procptr; 257 pp = peer->procptr;
258 pp->unitptr = (caddr_t)up; 258 pp->unitptr = (caddr_t)up;
259 pp->io.clock_recv = acts_receive; 259 pp->io.clock_recv = acts_receive;
260 pp->io.srcclock = (caddr_t)peer; 260 pp->io.srcclock = (caddr_t)peer;
261 pp->io.datalen = 0; 261 pp->io.datalen = 0;
262 262
263 /* 263 /*
264 * Initialize miscellaneous variables 264 * Initialize miscellaneous variables
265 */ 265 */
266 peer->precision = PRECISION; 266 peer->precision = PRECISION;
267 pp->clockdesc = DESCRIPTION; 267 pp->clockdesc = DESCRIPTION;
268 memcpy((char *)&pp->refid, REFID, 4); 268 memcpy((char *)&pp->refid, REFID, 4);
269 peer->sstclktype = CTL_SST_TS_TELEPHONE; 269 peer->sstclktype = CTL_SST_TS_TELEPHONE;
270 up->bufptr = pp->a_lastcode; 270 up->bufptr = pp->a_lastcode;
271 return (1); 271 return (1);
272} 272}
273 273
274 274
275/* 275/*
276 * acts_shutdown - shut down the clock 276 * acts_shutdown - shut down the clock
277 */ 277 */
278static void 278static void
279acts_shutdown ( 279acts_shutdown (
280 int unit, 280 int unit,
281 struct peer *peer 281 struct peer *peer
282 ) 282 )
283{ 283{
284 struct actsunit *up; 284 struct actsunit *up;
285 struct refclockproc *pp; 285 struct refclockproc *pp;
286 286
287 /* 287 /*
288 * Warning: do this only when a call is not in progress. 288 * Warning: do this only when a call is not in progress.
289 */ 289 */
290 pp = peer->procptr; 290 pp = peer->procptr;
291 up = (struct actsunit *)pp->unitptr; 291 up = (struct actsunit *)pp->unitptr;
292 free(up); 292 free(up);
293} 293}
294 294
295 295
296/* 296/*
297 * acts_receive - receive data from the serial interface 297 * acts_receive - receive data from the serial interface
298 */ 298 */
299static void 299static void
300acts_receive ( 300acts_receive (
301 struct recvbuf *rbufp 301 struct recvbuf *rbufp
302 ) 302 )
303{ 303{
304 struct actsunit *up; 304 struct actsunit *up;
305 struct refclockproc *pp; 305 struct refclockproc *pp;
306 struct peer *peer; 306 struct peer *peer;
307 char tbuf[BMAX]; 307 char tbuf[BMAX];
308 char *tptr; 308 char *tptr;
309 309
310 /* 310 /*
311 * Initialize pointers and read the timecode and timestamp. Note 311 * Initialize pointers and read the timecode and timestamp. Note
312 * we are in raw mode and victim of whatever the terminal 312 * we are in raw mode and victim of whatever the terminal
313 * interface kicks up; so, we have to reassemble messages from 313 * interface kicks up; so, we have to reassemble messages from
314 * arbitrary fragments. Capture the timecode at the beginning of 314 * arbitrary fragments. Capture the timecode at the beginning of
315 * the message and at the '*' and '#' on-time characters. 315 * the message and at the '*' and '#' on-time characters.
316 */ 316 */
317 peer = (struct peer *)rbufp->recv_srcclock; 317 peer = (struct peer *)rbufp->recv_srcclock;
318 pp = peer->procptr; 318 pp = peer->procptr;
319 up = (struct actsunit *)pp->unitptr; 319 up = (struct actsunit *)pp->unitptr;
320 pp->lencode = refclock_gtraw(rbufp, tbuf, BMAX - (up->bufptr - 320 pp->lencode = refclock_gtraw(rbufp, tbuf, BMAX - (up->bufptr -
321 pp->a_lastcode), &pp->lastrec); 321 pp->a_lastcode), &pp->lastrec);
322 for (tptr = tbuf; *tptr != '\0'; tptr++) { 322 for (tptr = tbuf; *tptr != '\0'; tptr++) {
323 if (*tptr == LF) { 323 if (*tptr == LF) {
324 if (up->bufptr == pp->a_lastcode) { 324 if (up->bufptr == pp->a_lastcode) {
325 up->tstamp = pp->lastrec; 325 up->tstamp = pp->lastrec;
326 continue; 326 continue;
327 327
328 } else { 328 } else {
329 *up->bufptr = '\0'; 329 *up->bufptr = '\0';
330 acts_message(peer); 330 acts_message(peer);
331 up->bufptr = pp->a_lastcode; 331 up->bufptr = pp->a_lastcode;
332 } 332 }
333 } else if (!iscntrl(*tptr)) { 333 } else if (!iscntrl((unsigned char)*tptr)) {
334 *up->bufptr++ = *tptr; 334 *up->bufptr++ = *tptr;
335 if (*tptr == '*' || *tptr == '#') { 335 if (*tptr == '*' || *tptr == '#') {
336 up->tstamp = pp->lastrec; 336 up->tstamp = pp->lastrec;
337 write(pp->io.fd, tptr, 1); 337 write(pp->io.fd, tptr, 1);
338 } 338 }
339 } 339 }
340 } 340 }
341} 341}
342 342
343 343
344/* 344/*
345 * acts_message - process message 345 * acts_message - process message
346 */ 346 */
347void 347void
348acts_message( 348acts_message(
349 struct peer *peer 349 struct peer *peer
350 ) 350 )
351{ 351{
352 struct actsunit *up; 352 struct actsunit *up;
353 struct refclockproc *pp; 353 struct refclockproc *pp;
354 int dtr = TIOCM_DTR; 354 int dtr = TIOCM_DTR;
355 char tbuf[SMAX]; 355 char tbuf[SMAX];
356#ifdef DEBUG 356#ifdef DEBUG
357 u_int modem; 357 u_int modem;
358#endif 358#endif
359 359
360 /* 360 /*
361 * What to do depends on the state and the first token in the 361 * What to do depends on the state and the first token in the
362 * message. */ 362 * message. */
363 pp = peer->procptr; 363 pp = peer->procptr;
364 up = (struct actsunit *)pp->unitptr; 364 up = (struct actsunit *)pp->unitptr;
365#ifdef DEBUG 365#ifdef DEBUG
366 ioctl(pp->io.fd, TIOCMGET, (char *)&modem); 366 ioctl(pp->io.fd, TIOCMGET, (char *)&modem);
367 snprintf(tbuf, sizeof(tbuf), "acts: %04x (%d %d) %d %s", modem, 367 snprintf(tbuf, sizeof(tbuf), "acts: %04x (%d %d) %zu %s", modem,
368 up->state, up->timer, strlen(pp->a_lastcode), 368 up->state, up->timer, strlen(pp->a_lastcode),
369 pp->a_lastcode); 369 pp->a_lastcode);
370 if (debug) 370 if (debug)
371 printf("%s\n", tbuf); 371 printf("%s\n", tbuf);
372#endif 372#endif
373 373
374 /* 374 /*
375 * Extract the first token in the line. A NO token sends the 375 * Extract the first token in the line. A NO token sends the
376 * message to the clockstats. 376 * message to the clockstats.
377 */ 377 */
378 strncpy(tbuf, pp->a_lastcode, SMAX); 378 strncpy(tbuf, pp->a_lastcode, SMAX);
379 strtok(tbuf, " "); 379 strtok(tbuf, " ");
380 if (strcmp(tbuf, "NO") == 0) { 380 if (strcmp(tbuf, "NO") == 0) {
381 report_event(PEVNT_CLOCK, peer, pp->a_lastcode); 381 report_event(PEVNT_CLOCK, peer, pp->a_lastcode);
382 return; 382 return;
383 } 383 }
384 switch(up->state) { 384 switch(up->state) {
385 385
386 /* 386 /*
387 * We are waiting for the OK response to the modem setup 387 * We are waiting for the OK response to the modem setup
388 * command. When this happens, raise DTR and dial the number 388 * command. When this happens, raise DTR and dial the number
389 * followed by \r. 389 * followed by \r.
390 */ 390 */
391 case S_OK: 391 case S_OK:
392 if (strcmp(tbuf, "OK") != 0) { 392 if (strcmp(tbuf, "OK") != 0) {
393 msyslog(LOG_ERR, "acts: setup error %s", 393 msyslog(LOG_ERR, "acts: setup error %s",
394 pp->a_lastcode); 394 pp->a_lastcode);
395 acts_disc(peer); 395 acts_disc(peer);
396 return; 396 return;
397 } 397 }
398 ioctl(pp->io.fd, TIOCMBIS, (char *)&dtr); 398 ioctl(pp->io.fd, TIOCMBIS, (char *)&dtr);
399 up->state = S_DTR; 399 up->state = S_DTR;
400 up->timer = DTR; 400 up->timer = DTR;
401 return; 401 return;
402 402
403 /* 403 /*
404 * We are waiting for the call to be answered. All we care about 404 * We are waiting for the call to be answered. All we care about
405 * here is token CONNECT. Send the message to the clockstats. 405 * here is token CONNECT. Send the message to the clockstats.
406 */ 406 */
407 case S_CONNECT: 407 case S_CONNECT:
408 report_event(PEVNT_CLOCK, peer, pp->a_lastcode); 408 report_event(PEVNT_CLOCK, peer, pp->a_lastcode);
409 if (strcmp(tbuf, "CONNECT") != 0) { 409 if (strcmp(tbuf, "CONNECT") != 0) {
410 acts_disc(peer); 410 acts_disc(peer);
411 return; 411 return;
412 } 412 }
413 up->state = S_FIRST; 413 up->state = S_FIRST;
414 up->timer = CONNECT; 414 up->timer = CONNECT;
415 return; 415 return;
416 416
417 /* 417 /*
418 * We are waiting for a timecode. Pass it to the parser. 418 * We are waiting for a timecode. Pass it to the parser.
419 */ 419 */
420 case S_FIRST: 420 case S_FIRST:
421 case S_MSG: 421 case S_MSG:
422 acts_timecode(peer, pp->a_lastcode); 422 acts_timecode(peer, pp->a_lastcode);
423 break; 423 break;
424 } 424 }
425} 425}
426 426
427/* 427/*
428 * acts_timecode - identify the service and parse the timecode message 428 * acts_timecode - identify the service and parse the timecode message
429 */ 429 */
430void 430void
431acts_timecode( 431acts_timecode(
432 struct peer *peer, /* peer structure pointer */ 432 struct peer *peer, /* peer structure pointer */
433 char *str /* timecode string */ 433 char *str /* timecode string */
434 ) 434 )
435{ 435{
436 struct actsunit *up; 436 struct actsunit *up;
437 struct refclockproc *pp; 437 struct refclockproc *pp;
438 int day; /* day of the month */ 438 int day; /* day of the month */
439 int month; /* month of the year */ 439 int month; /* month of the year */
440 u_long mjd; /* Modified Julian Day */ 440 u_long mjd; /* Modified Julian Day */
441 double dut1; /* DUT adjustment */ 441 double dut1; /* DUT adjustment */
442 442
443 u_int dst; /* ACTS daylight/standard time */ 443 u_int dst; /* ACTS daylight/standard time */
444 u_int leap; /* ACTS leap indicator */ 444 u_int leap; /* ACTS leap indicator */
445 double msADV; /* ACTS transmit advance (ms) */ 445 double msADV; /* ACTS transmit advance (ms) */
446 char utc[10]; /* ACTS timescale */ 446 char utc[10]; /* ACTS timescale */
447 char flag; /* ACTS on-time character (* or #) */ 447 char flag; /* ACTS on-time character (* or #) */
448 448
449 char synchar; /* WWVB synchronized indicator */ 449 char synchar; /* WWVB synchronized indicator */
450 char qualchar; /* WWVB quality indicator */ 450 char qualchar; /* WWVB quality indicator */
451 char leapchar; /* WWVB leap indicator */ 451 char leapchar; /* WWVB leap indicator */
452 char dstchar; /* WWVB daylight/savings indicator */ 452 char dstchar; /* WWVB daylight/savings indicator */
453 int tz; /* WWVB timezone */ 453 int tz; /* WWVB timezone */
454 454
455 u_int leapmonth; /* PTB/NPL month of leap */ 455 u_int leapmonth; /* PTB/NPL month of leap */
456 char leapdir; /* PTB/NPL leap direction */ 456 char leapdir; /* PTB/NPL leap direction */
457 457
458 /* 458 /*
459 * The parser selects the modem format based on the message 459 * The parser selects the modem format based on the message
460 * length. Since the data are checked carefully, occasional 460 * length. Since the data are checked carefully, occasional
461 * errors due noise are forgivable. 461 * errors due noise are forgivable.
462 */ 462 */
463 pp = peer->procptr; 463 pp = peer->procptr;
464 up = (struct actsunit *)pp->unitptr; 464 up = (struct actsunit *)pp->unitptr;
465 pp->nsec = 0; 465 pp->nsec = 0;
466 switch(strlen(str)) { 466 switch(strlen(str)) {
467 467
468 /* 468 /*
469 * For USNO format on-time character '*', which is on a line by 469 * For USNO format on-time character '*', which is on a line by
470 * itself. Be sure a timecode has been received. 470 * itself. Be sure a timecode has been received.
471 */ 471 */
472 case 1: 472 case 1:
473 if (*str == '*' && up->msgcnt > 0)  473 if (*str == '*' && up->msgcnt > 0)
474 break; 474 break;
475 475
476 return; 476 return;
477  477
478 /* 478 /*
479 * ACTS format: "jjjjj yy-mm-dd hh:mm:ss ds l uuu aaaaa 479 * ACTS format: "jjjjj yy-mm-dd hh:mm:ss ds l uuu aaaaa
480 * UTC(NIST) *" 480 * UTC(NIST) *"
481 */ 481 */
482 case LENACTS: 482 case LENACTS:
483 if (sscanf(str, 483 if (sscanf(str,
484 "%5ld %2d-%2d-%2d %2d:%2d:%2d %2d %1d %3lf %5lf %9s %c", 484 "%5ld %2d-%2d-%2d %2d:%2d:%2d %2d %1d %3lf %5lf %9s %c",
485 &mjd, &pp->year, &month, &day, &pp->hour, 485 &mjd, &pp->year, &month, &day, &pp->hour,
486 &pp->minute, &pp->second, &dst, &leap, &dut1, 486 &pp->minute, &pp->second, &dst, &leap, &dut1,
487 &msADV, utc, &flag) != 13) { 487 &msADV, utc, &flag) != 13) {
488 refclock_report(peer, CEVNT_BADREPLY); 488 refclock_report(peer, CEVNT_BADREPLY);
489 return; 489 return;
490 } 490 }
491 491
492 /* 492 /*
493 * Wait until ACTS has calculated the roundtrip delay. 493 * Wait until ACTS has calculated the roundtrip delay.
494 * We don't need to do anything, as ACTS adjusts the 494 * We don't need to do anything, as ACTS adjusts the
495 * on-time epoch. 495 * on-time epoch.
496 */ 496 */
497 if (flag != '#') 497 if (flag != '#')
498 return; 498 return;
499 499
500 pp->day = ymd2yd(pp->year, month, day); 500 pp->day = ymd2yd(pp->year, month, day);
501 pp->leap = LEAP_NOWARNING; 501 pp->leap = LEAP_NOWARNING;
502 if (leap == 1) 502 if (leap == 1)
503 pp->leap = LEAP_ADDSECOND; 503 pp->leap = LEAP_ADDSECOND;
504 else if (pp->leap == 2) 504 else if (pp->leap == 2)
505 pp->leap = LEAP_DELSECOND; 505 pp->leap = LEAP_DELSECOND;
506 memcpy(&pp->refid, REFACTS, 4); 506 memcpy(&pp->refid, REFACTS, 4);
507 if (up->msgcnt == 0) 507 if (up->msgcnt == 0)
508 record_clock_stats(&peer->srcadr, str); 508 record_clock_stats(&peer->srcadr, str);
509 up->msgcnt++; 509 up->msgcnt++;
510 break; 510 break;
511 511
512 /* 512 /*
513 * USNO format: "jjjjj nnn hhmmss UTC" 513 * USNO format: "jjjjj nnn hhmmss UTC"
514 */ 514 */
515 case LENUSNO: 515 case LENUSNO:
516 if (sscanf(str, "%5ld %3d %2d%2d%2d %3s", 516 if (sscanf(str, "%5ld %3d %2d%2d%2d %3s",
517 &mjd, &pp->day, &pp->hour, &pp->minute, 517 &mjd, &pp->day, &pp->hour, &pp->minute,
518 &pp->second, utc) != 6) { 518 &pp->second, utc) != 6) {
519 refclock_report(peer, CEVNT_BADREPLY); 519 refclock_report(peer, CEVNT_BADREPLY);
520 return; 520 return;
521 } 521 }
522 522
523 /* 523 /*
524 * Wait for the on-time character, which follows in a 524 * Wait for the on-time character, which follows in a
525 * separate message. There is no provision for leap 525 * separate message. There is no provision for leap
526 * warning. 526 * warning.
527 */ 527 */
528 pp->leap = LEAP_NOWARNING; 528 pp->leap = LEAP_NOWARNING;
529 memcpy(&pp->refid, REFUSNO, 4); 529 memcpy(&pp->refid, REFUSNO, 4);
530 if (up->msgcnt == 0) 530 if (up->msgcnt == 0)
531 record_clock_stats(&peer->srcadr, str); 531 record_clock_stats(&peer->srcadr, str);
532 up->msgcnt++; 532 up->msgcnt++;
533 return; 533 return;
534 534
535 /* 535 /*
536 * PTB/NPL format: "yyyy-mm-dd hh:mm:ss MEZ"  536 * PTB/NPL format: "yyyy-mm-dd hh:mm:ss MEZ"
537 */ 537 */
538 case LENPTB: 538 case LENPTB:
539 if (sscanf(str, 539 if (sscanf(str,
540 "%*4d-%*2d-%*2d %*2d:%*2d:%2d %*5c%*12c%4d%2d%2d%2d%2d%5ld%2lf%c%2d%3lf%*15c%c", 540 "%*4d-%*2d-%*2d %*2d:%*2d:%2d %*5c%*12c%4d%2d%2d%2d%2d%5ld%2lf%c%2d%3lf%*15c%c",
541 &pp->second, &pp->year, &month, &day, &pp->hour, 541 &pp->second, &pp->year, &month, &day, &pp->hour,
542 &pp->minute, &mjd, &dut1, &leapdir, &leapmonth, 542 &pp->minute, &mjd, &dut1, &leapdir, &leapmonth,
543 &msADV, &flag) != 12) { 543 &msADV, &flag) != 12) {
544 refclock_report(peer, CEVNT_BADREPLY); 544 refclock_report(peer, CEVNT_BADREPLY);
545 return; 545 return;
546 } 546 }
547 pp->leap = LEAP_NOWARNING; 547 pp->leap = LEAP_NOWARNING;
548 if (leapmonth == month) { 548 if (leapmonth == month) {
549 if (leapdir == '+') 549 if (leapdir == '+')
550 pp->leap = LEAP_ADDSECOND; 550 pp->leap = LEAP_ADDSECOND;
551 else if (leapdir == '-') 551 else if (leapdir == '-')
552 pp->leap = LEAP_DELSECOND; 552 pp->leap = LEAP_DELSECOND;
553 } 553 }
554 pp->day = ymd2yd(pp->year, month, day); 554 pp->day = ymd2yd(pp->year, month, day);
555 memcpy(&pp->refid, REFPTB, 4); 555 memcpy(&pp->refid, REFPTB, 4);
556 if (up->msgcnt == 0) 556 if (up->msgcnt == 0)
557 record_clock_stats(&peer->srcadr, str); 557 record_clock_stats(&peer->srcadr, str);
558 up->msgcnt++; 558 up->msgcnt++;
559 break; 559 break;
560 560
561 561
562 /* 562 /*
563 * WWVB format 0: "I ddd hh:mm:ss DTZ=nn" 563 * WWVB format 0: "I ddd hh:mm:ss DTZ=nn"
564 */ 564 */
565 case LENWWVB0: 565 case LENWWVB0:
566 if (sscanf(str, "%c %3d %2d:%2d:%2d %cTZ=%2d", 566 if (sscanf(str, "%c %3d %2d:%2d:%2d %cTZ=%2d",
567 &synchar, &pp->day, &pp->hour, &pp->minute, 567 &synchar, &pp->day, &pp->hour, &pp->minute,
568 &pp->second, &dstchar, &tz) != 7) { 568 &pp->second, &dstchar, &tz) != 7) {
569 refclock_report(peer, CEVNT_BADREPLY); 569 refclock_report(peer, CEVNT_BADREPLY);
570 return; 570 return;
571 } 571 }
572 pp->leap = LEAP_NOWARNING; 572 pp->leap = LEAP_NOWARNING;
573 if (synchar != ' ') 573 if (synchar != ' ')
574 pp->leap = LEAP_NOTINSYNC; 574 pp->leap = LEAP_NOTINSYNC;
575 memcpy(&pp->refid, REFWWVB, 4); 575 memcpy(&pp->refid, REFWWVB, 4);
576 if (up->msgcnt == 0) 576 if (up->msgcnt == 0)
577 record_clock_stats(&peer->srcadr, str); 577 record_clock_stats(&peer->srcadr, str);
578 up->msgcnt++; 578 up->msgcnt++;
579 break; 579 break;
580 580
581 /* 581 /*
582 * WWVB format 2: "IQyy ddd hh:mm:ss.mmm LD" 582 * WWVB format 2: "IQyy ddd hh:mm:ss.mmm LD"
583 */ 583 */
584 case LENWWVB2: 584 case LENWWVB2:
585 if (sscanf(str, "%c%c%2d %3d %2d:%2d:%2d.%3ld%c%c%c", 585 if (sscanf(str, "%c%c%2d %3d %2d:%2d:%2d.%3ld%c%c%c",
586 &synchar, &qualchar, &pp->year, &pp->day, 586 &synchar, &qualchar, &pp->year, &pp->day,
587 &pp->hour, &pp->minute, &pp->second, &pp->nsec, 587 &pp->hour, &pp->minute, &pp->second, &pp->nsec,
588 &dstchar, &leapchar, &dstchar) != 11) { 588 &dstchar, &leapchar, &dstchar) != 11) {
589 refclock_report(peer, CEVNT_BADREPLY); 589 refclock_report(peer, CEVNT_BADREPLY);
590 return; 590 return;
591 } 591 }
592 pp->nsec *= 1000000; 592 pp->nsec *= 1000000;
593 pp->leap = LEAP_NOWARNING; 593 pp->leap = LEAP_NOWARNING;
594 if (synchar != ' ') 594 if (synchar != ' ')
595 pp->leap = LEAP_NOTINSYNC; 595 pp->leap = LEAP_NOTINSYNC;
596 else if (leapchar == 'L') 596 else if (leapchar == 'L')
597 pp->leap = LEAP_ADDSECOND; 597 pp->leap = LEAP_ADDSECOND;
598 memcpy(&pp->refid, REFWWVB, 4); 598 memcpy(&pp->refid, REFWWVB, 4);
599 if (up->msgcnt == 0) 599 if (up->msgcnt == 0)
600 record_clock_stats(&peer->srcadr, str); 600 record_clock_stats(&peer->srcadr, str);
601 up->msgcnt++; 601 up->msgcnt++;
602 break; 602 break;
603 603
604 /* 604 /*
605 * None of the above. Just forget about it and wait for the next 605 * None of the above. Just forget about it and wait for the next
606 * message or timeout. 606 * message or timeout.
607 */ 607 */
608 default: 608 default:
609 return; 609 return;
610 } 610 }
611 611
612 /* 612 /*
613 * We have a valid timecode. The fudge time1 value is added to 613 * We have a valid timecode. The fudge time1 value is added to
614 * each sample by the main line routines. Note that in current 614 * each sample by the main line routines. Note that in current
615 * telephone networks the propatation time can be different for 615 * telephone networks the propatation time can be different for
616 * each call and can reach 200 ms for some calls. 616 * each call and can reach 200 ms for some calls.
617 */ 617 */
618 peer->refid = pp->refid; 618 peer->refid = pp->refid;
619 pp->lastrec = up->tstamp; 619 pp->lastrec = up->tstamp;
620 if (!refclock_process(pp)) { 620 if (!refclock_process(pp)) {
621 refclock_report(peer, CEVNT_BADTIME); 621 refclock_report(peer, CEVNT_BADTIME);
622 return; 622 return;
623 } 623 }
624 pp->lastref = pp->lastrec; 624 pp->lastref = pp->lastrec;
625 if (up->state != S_MSG) { 625 if (up->state != S_MSG) {
626 up->state = S_MSG; 626 up->state = S_MSG;
627 up->timer = TIMECODE; 627 up->timer = TIMECODE;
628 } 628 }
629} 629}
630 630
631 631
632/* 632/*
633 * acts_poll - called by the transmit routine 633 * acts_poll - called by the transmit routine
634 */ 634 */
635static void 635static void
636acts_poll ( 636acts_poll (
637 int unit, 637 int unit,
638 struct peer *peer 638 struct peer *peer
639 ) 639 )
640{ 640{
641 struct actsunit *up; 641 struct actsunit *up;
642 struct refclockproc *pp; 642 struct refclockproc *pp;
643 643
644 /* 644 /*
645 * This routine is called at every system poll. All it does is 645 * This routine is called at every system poll. All it does is
646 * set flag1 under certain conditions. The real work is done by 646 * set flag1 under certain conditions. The real work is done by
647 * the timeout routine and state machine. 647 * the timeout routine and state machine.
648 */ 648 */
649 pp = peer->procptr; 649 pp = peer->procptr;
650 up = (struct actsunit *)pp->unitptr; 650 up = (struct actsunit *)pp->unitptr;
651 switch (peer->ttl) { 651 switch (peer->ttl) {
652 652
653 /* 653 /*
654 * In manual mode the calling program is activated by the ntpdc 654 * In manual mode the calling program is activated by the ntpdc
655 * program using the enable flag (fudge flag1), either manually 655 * program using the enable flag (fudge flag1), either manually
656 * or by a cron job. 656 * or by a cron job.
657 */ 657 */
658 case MODE_MANUAL: 658 case MODE_MANUAL:
659 /* fall through */ 659 /* fall through */
660 break; 660 break;
661 661
662 /* 662 /*
663 * In automatic mode the calling program runs continuously at 663 * In automatic mode the calling program runs continuously at
664 * intervals determined by the poll event or specified timeout. 664 * intervals determined by the poll event or specified timeout.
665 */ 665 */
666 case MODE_AUTO: 666 case MODE_AUTO:
667 pp->sloppyclockflag |= CLK_FLAG1; 667 pp->sloppyclockflag |= CLK_FLAG1;
668 break; 668 break;
669 669
670 /* 670 /*
671 * In backup mode the calling program runs continuously as long 671 * In backup mode the calling program runs continuously as long
672 * as either no peers are available or this peer is selected. 672 * as either no peers are available or this peer is selected.
673 */ 673 */
674 case MODE_BACKUP: 674 case MODE_BACKUP:
675 if (sys_peer == NULL || sys_peer == peer) 675 if (sys_peer == NULL || sys_peer == peer)
676 pp->sloppyclockflag |= CLK_FLAG1; 676 pp->sloppyclockflag |= CLK_FLAG1;
677 break; 677 break;
678 } 678 }
679} 679}
680 680
681 681
682/* 682/*
683 * acts_timer - called at one-second intervals 683 * acts_timer - called at one-second intervals
684 */ 684 */
685static void 685static void
686acts_timer( 686acts_timer(
687 int unit, 687 int unit,
688 struct peer *peer 688 struct peer *peer
689 ) 689 )
690{ 690{
691 struct actsunit *up; 691 struct actsunit *up;
692 struct refclockproc *pp; 692 struct refclockproc *pp;
693 693
694 /* 694 /*
695 * This routine implments a timeout which runs for a programmed 695 * This routine implments a timeout which runs for a programmed
696 * interval. The counter is initialized by the state machine and 696 * interval. The counter is initialized by the state machine and
697 * counts down to zero. Upon reaching zero, the state machine is 697 * counts down to zero. Upon reaching zero, the state machine is
698 * called. If flag1 is set while in S_IDLE state, force a 698 * called. If flag1 is set while in S_IDLE state, force a
699 * timeout. 699 * timeout.
700 */ 700 */
701 pp = peer->procptr; 701 pp = peer->procptr;
702 up = (struct actsunit *)pp->unitptr; 702 up = (struct actsunit *)pp->unitptr;
703 if (pp->sloppyclockflag & CLK_FLAG1 && up->state == S_IDLE) { 703 if (pp->sloppyclockflag & CLK_FLAG1 && up->state == S_IDLE) {
704 acts_timeout(peer); 704 acts_timeout(peer);
705 return; 705 return;
706 } 706 }
707 if (up->timer == 0) 707 if (up->timer == 0)
708 return; 708 return;
709 709
710 up->timer--; 710 up->timer--;
711 if (up->timer == 0) 711 if (up->timer == 0)
712 acts_timeout(peer); 712 acts_timeout(peer);
713} 713}
714 714
715 715
716/* 716/*
717 * acts_timeout - called on timeout 717 * acts_timeout - called on timeout
718 */ 718 */
719static void 719static void
720acts_timeout( 720acts_timeout(
721 struct peer *peer 721 struct peer *peer
722 ) 722 )
723{ 723{
724 struct actsunit *up; 724 struct actsunit *up;
725 struct refclockproc *pp; 725 struct refclockproc *pp;
726 int fd; 726 int fd;
727 char device[20]; 727 char device[20];
728 char lockfile[128], pidbuf[8]; 728 char lockfile[128], pidbuf[8];
729 char tbuf[SMAX]; 729 char tbuf[SMAX];
730 730
731 /* 731 /*
732 * The state machine is driven by messages from the modem, when 732 * The state machine is driven by messages from the modem, when
733 * first stated and at timeout. 733 * first stated and at timeout.
734 */ 734 */
735 pp = peer->procptr; 735 pp = peer->procptr;
736 up = (struct actsunit *)pp->unitptr; 736 up = (struct actsunit *)pp->unitptr;
737 pp->sloppyclockflag &= ~CLK_FLAG1; 737 pp->sloppyclockflag &= ~CLK_FLAG1;
738 if (sys_phone[up->retry] == NULL && !(pp->sloppyclockflag & 738 if (sys_phone[up->retry] == NULL && !(pp->sloppyclockflag &
739 CLK_FLAG3)) { 739 CLK_FLAG3)) {
740 msyslog(LOG_ERR, "acts: no phones"); 740 msyslog(LOG_ERR, "acts: no phones");
741 return; 741 return;
742 } 742 }
743 switch(up->state) { 743 switch(up->state) {
744 744
745 /* 745 /*
746 * System poll event. Lock the modem port and open the device. 746 * System poll event. Lock the modem port and open the device.
747 */ 747 */
748 case S_IDLE: 748 case S_IDLE:
749 749
750 /* 750 /*
751 * Lock the modem port. If busy, retry later. Note: if 751 * Lock the modem port. If busy, retry later. Note: if
752 * something fails between here and the close, the lock 752 * something fails between here and the close, the lock
753 * file may not be removed. 753 * file may not be removed.
754 */ 754 */
755 if (pp->sloppyclockflag & CLK_FLAG2) { 755 if (pp->sloppyclockflag & CLK_FLAG2) {
756 snprintf(lockfile, sizeof(lockfile), LOCKFILE, 756 snprintf(lockfile, sizeof(lockfile), LOCKFILE,
757 up->unit); 757 up->unit);
758 fd = open(lockfile, O_WRONLY | O_CREAT | O_EXCL, 758 fd = open(lockfile, O_WRONLY | O_CREAT | O_EXCL,
759 0644); 759 0644);
760 if (fd < 0) { 760 if (fd < 0) {
761 msyslog(LOG_ERR, "acts: port busy"); 761 msyslog(LOG_ERR, "acts: port busy");
762 return; 762 return;
763 } 763 }
764 snprintf(pidbuf, sizeof(pidbuf), "%d\n", 764 snprintf(pidbuf, sizeof(pidbuf), "%d\n",
765 (u_int)getpid()); 765 (u_int)getpid());
766 write(fd, pidbuf, strlen(pidbuf)); 766 write(fd, pidbuf, strlen(pidbuf));
767 close(fd); 767 close(fd);
768 } 768 }
769 769
770 /* 770 /*
771 * Open the device in raw mode and link the I/O. 771 * Open the device in raw mode and link the I/O.
772 */ 772 */
773 if (!pp->io.fd) { 773 if (!pp->io.fd) {
774 snprintf(device, sizeof(device), DEVICE, 774 snprintf(device, sizeof(device), DEVICE,
775 up->unit); 775 up->unit);
776 fd = refclock_open(device, SPEED232, 776 fd = refclock_open(device, SPEED232,
777 LDISC_ACTS | LDISC_RAW | LDISC_REMOTE); 777 LDISC_ACTS | LDISC_RAW | LDISC_REMOTE);
778 if (fd == 0) { 778 if (fd == 0) {
779 msyslog(LOG_ERR, 779 msyslog(LOG_ERR,
780 "acts: open fails"); 780 "acts: open fails");
781 return; 781 return;
782 } 782 }
783 pp->io.fd = fd; 783 pp->io.fd = fd;
784 if (!io_addclock(&pp->io)) { 784 if (!io_addclock(&pp->io)) {
785 msyslog(LOG_ERR, 785 msyslog(LOG_ERR,
786 "acts: addclock fails"); 786 "acts: addclock fails");
787 close(fd); 787 close(fd);
788 pp->io.fd = 0; 788 pp->io.fd = 0;
789 return; 789 return;
790 } 790 }
791 } 791 }
792 792
793 /* 793 /*
794 * If the port is directly connected to the device, skip 794 * If the port is directly connected to the device, skip
795 * the modem business and send 'T' for Spectrabum. 795 * the modem business and send 'T' for Spectrabum.
796 */ 796 */
797 if (pp->sloppyclockflag & CLK_FLAG3) { 797 if (pp->sloppyclockflag & CLK_FLAG3) {
798 if (write(pp->io.fd, "T", 1) < 0) { 798 if (write(pp->io.fd, "T", 1) < 0) {
799 msyslog(LOG_ERR, "acts: write %m"); 799 msyslog(LOG_ERR, "acts: write %m");
800 return; 800 return;
801 } 801 }
802 up->state = S_FIRST; 802 up->state = S_FIRST;
803 up->timer = CONNECT; 803 up->timer = CONNECT;
804 return; 804 return;
805 } 805 }
806 806
807 /* 807 /*
808 * Initialize the modem. This works with Hayes commands. 808 * Initialize the modem. This works with Hayes commands.
809 */ 809 */
810#ifdef DEBUG 810#ifdef DEBUG
811 if (debug) 811 if (debug)
812 printf("acts: setup %s\n", MODEM_SETUP); 812 printf("acts: setup %s\n", MODEM_SETUP);
813#endif 813#endif
814 if (write(pp->io.fd, MODEM_SETUP, strlen(MODEM_SETUP)) < 814 if (write(pp->io.fd, MODEM_SETUP, strlen(MODEM_SETUP)) <
815 0) { 815 0) {
816 msyslog(LOG_ERR, "acts: write %m"); 816 msyslog(LOG_ERR, "acts: write %m");
817 return; 817 return;
818 } 818 }
819 up->state = S_OK; 819 up->state = S_OK;
820 up->timer = SETUP; 820 up->timer = SETUP;
821 return; 821 return;
822 822
823 /* 823 /*
824 * In OK state the modem did not respond to setup. 824 * In OK state the modem did not respond to setup.
825 */ 825 */
826 case S_OK: 826 case S_OK:
827 msyslog(LOG_ERR, "acts: no modem"); 827 msyslog(LOG_ERR, "acts: no modem");
828 break; 828 break;
829 829
830 /* 830 /*
831 * In DTR state we are waiting for the modem to settle down 831 * In DTR state we are waiting for the modem to settle down
832 * before hammering it with a dial command. 832 * before hammering it with a dial command.
833 */ 833 */
834 case S_DTR: 834 case S_DTR:
835 snprintf(tbuf, sizeof(tbuf), "DIAL #%d %s", up->retry, 835 snprintf(tbuf, sizeof(tbuf), "DIAL #%d %s", up->retry,
836 sys_phone[up->retry]); 836 sys_phone[up->retry]);
837 report_event(PEVNT_CLOCK, peer, tbuf); 837 report_event(PEVNT_CLOCK, peer, tbuf);
838#ifdef DEBUG 838#ifdef DEBUG
839 if (debug) 839 if (debug)
840 printf("%s\n", tbuf); 840 printf("%s\n", tbuf);
841#endif 841#endif
842 write(pp->io.fd, sys_phone[up->retry], 842 write(pp->io.fd, sys_phone[up->retry],
843 strlen(sys_phone[up->retry])); 843 strlen(sys_phone[up->retry]));
844 write(pp->io.fd, "\r", 1); 844 write(pp->io.fd, "\r", 1);
845 up->state = S_CONNECT; 845 up->state = S_CONNECT;
846 up->timer = ANSWER; 846 up->timer = ANSWER;
847 return; 847 return;
848 848
849 /* 849 /*
850 * In CONNECT state the call did not complete. 850 * In CONNECT state the call did not complete.
851 */ 851 */
852 case S_CONNECT: 852 case S_CONNECT:
853 msyslog(LOG_ERR, "acts: no answer"); 853 msyslog(LOG_ERR, "acts: no answer");
854 break; 854 break;
855 855
856 /* 856 /*
857 * In FIRST state no messages were received. 857 * In FIRST state no messages were received.
858 */ 858 */
859 case S_FIRST: 859 case S_FIRST:
860 msyslog(LOG_ERR, "acts: no messages"); 860 msyslog(LOG_ERR, "acts: no messages");
861 break; 861 break;
862 862
863 /* 863 /*
864 * In CLOSE state hangup is complete. Close the doors and 864 * In CLOSE state hangup is complete. Close the doors and
865 * windows and get some air. 865 * windows and get some air.
866 */ 866 */
867 case S_CLOSE: 867 case S_CLOSE:
868 868
869 /* 869 /*
870 * Close the device and unlock a shared modem. 870 * Close the device and unlock a shared modem.
871 */ 871 */
872 if (pp->io.fd) { 872 if (pp->io.fd) {
873 io_closeclock(&pp->io); 873 io_closeclock(&pp->io);
874 close(pp->io.fd); 874 close(pp->io.fd);
875 if (pp->sloppyclockflag & CLK_FLAG2) { 875 if (pp->sloppyclockflag & CLK_FLAG2) {
876 snprintf(lockfile, sizeof(lockfile), 876 snprintf(lockfile, sizeof(lockfile),
877 LOCKFILE, up->unit); 877 LOCKFILE, up->unit);
878 unlink(lockfile); 878 unlink(lockfile);
879 } 879 }
880 pp->io.fd = 0; 880 pp->io.fd = 0;
881 } 881 }
882 882
883 /* 883 /*
884 * If messages were received, fold the tent and wait for 884 * If messages were received, fold the tent and wait for
885 * the next poll. If no messages and there are more 885 * the next poll. If no messages and there are more
886 * numbers to dial, retry after a short wait. 886 * numbers to dial, retry after a short wait.
887 */ 887 */
888 up->bufptr = pp->a_lastcode; 888 up->bufptr = pp->a_lastcode;
889 up->timer = 0; 889 up->timer = 0;
890 up->state = S_IDLE; 890 up->state = S_IDLE;
891 if ( up->msgcnt == 0) { 891 if ( up->msgcnt == 0) {
892 up->retry++; 892 up->retry++;
893 if (sys_phone[up->retry] == NULL) 893 if (sys_phone[up->retry] == NULL)
894 up->retry = 0; 894 up->retry = 0;
895 else 895 else
896 up->timer = SETUP; 896 up->timer = SETUP;
897 } else { 897 } else {
898 up->retry = 0; 898 up->retry = 0;
899 } 899 }
900 up->msgcnt = 0; 900 up->msgcnt = 0;
901 return; 901 return;
902 } 902 }
903 acts_disc(peer); 903 acts_disc(peer);
904} 904}
905 905
906 906
907/* 907/*
908 * acts_disc - disconnect the call and clean the place up. 908 * acts_disc - disconnect the call and clean the place up.
909 */ 909 */
910static void 910static void
911acts_disc ( 911acts_disc (
912 struct peer *peer 912 struct peer *peer
913 ) 913 )
914{ 914{
915 struct actsunit *up; 915 struct actsunit *up;
916 struct refclockproc *pp; 916 struct refclockproc *pp;
917 int dtr = TIOCM_DTR; 917 int dtr = TIOCM_DTR;
918 918
919 /* 919 /*
920 * We get here if the call terminated successfully or if an 920 * We get here if the call terminated successfully or if an
921 * error occured. If the median filter has something in it, 921 * error occured. If the median filter has something in it,
922 * feed the data to the clock filter. If a modem port, drop DTR 922 * feed the data to the clock filter. If a modem port, drop DTR
923 * to force command mode and send modem hangup. 923 * to force command mode and send modem hangup.
924 */ 924 */
925 pp = peer->procptr; 925 pp = peer->procptr;
926 up = (struct actsunit *)pp->unitptr; 926 up = (struct actsunit *)pp->unitptr;
927 if (up->msgcnt > 0) 927 if (up->msgcnt > 0)
928 refclock_receive(peer); 928 refclock_receive(peer);
929 if (!(pp->sloppyclockflag & CLK_FLAG3)) { 929 if (!(pp->sloppyclockflag & CLK_FLAG3)) {
930 ioctl(pp->io.fd, TIOCMBIC, (char *)&dtr); 930 ioctl(pp->io.fd, TIOCMBIC, (char *)&dtr);
931 write(pp->io.fd, MODEM_HANGUP, strlen(MODEM_HANGUP)); 931 write(pp->io.fd, MODEM_HANGUP, strlen(MODEM_HANGUP));
932 } 932 }
933 up->timer = SETUP; 933 up->timer = SETUP;
934 up->state = S_CLOSE; 934 up->state = S_CLOSE;
935} 935}
936#else 936#else
937int refclock_acts_bs; 937int refclock_acts_bs;
938#endif /* REFCLOCK */ 938#endif /* REFCLOCK */