xref: /netbsd-src/external/bsd/ntp/dist/ntpd/refclock_parse.c (revision 6a493d6bc668897c91594964a732d38505b70cbb)
1 /*	$NetBSD: refclock_parse.c,v 1.10 2013/12/28 03:20:14 christos Exp $	*/
2 
3 /*
4  * /src/NTP/REPOSITORY/ntp4-dev/ntpd/refclock_parse.c,v 4.81 2009/05/01 10:15:29 kardel RELEASE_20090105_A
5  *
6  * refclock_parse.c,v 4.81 2009/05/01 10:15:29 kardel RELEASE_20090105_A
7  *
8  * generic reference clock driver for several DCF/GPS/MSF/... receivers
9  *
10  * PPS notes:
11  *   On systems that support PPSAPI (RFC2783) PPSAPI is the
12  *   preferred interface.
13  *
14  *   Optionally make use of a STREAMS module for input processing where
15  *   available and configured. This STREAMS module reduces the time
16  *   stamp latency for serial and PPS events.
17  *   Currently the STREAMS module is only available for Suns running
18  *   SunOS 4.x and SunOS5.x.
19  *
20  * Copyright (c) 1995-2009 by Frank Kardel <kardel <AT> ntp.org>
21  * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universit�t Erlangen-N�rnberg, Germany
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the above copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. Neither the name of the author nor the names of its contributors
32  *    may be used to endorse or promote products derived from this software
33  *    without specific prior written permission.
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
36  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
39  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45  * SUCH DAMAGE.
46  *
47  */
48 
49 #ifdef HAVE_CONFIG_H
50 # include "config.h"
51 #endif
52 
53 #include "ntp_types.h"
54 
55 #if defined(REFCLOCK) && defined(CLOCK_PARSE)
56 
57 /*
58  * This driver currently provides the support for
59  *   - Meinberg receiver DCF77 PZF 535 (TCXO version)       (DCF)
60  *   - Meinberg receiver DCF77 PZF 535 (OCXO version)       (DCF)
61  *   - Meinberg receiver DCF77 PZF 509                      (DCF)
62  *   - Meinberg receiver DCF77 AM receivers (e.g. C51)      (DCF)
63  *   - IGEL CLOCK                                           (DCF)
64  *   - ELV DCF7000                                          (DCF)
65  *   - Schmid clock                                         (DCF)
66  *   - Conrad DCF77 receiver module                         (DCF)
67  *   - FAU DCF77 NTP receiver (TimeBrick)                   (DCF)
68  *   - WHARTON 400A Series clock			    (DCF)
69  *
70  *   - Meinberg GPS166/GPS167                               (GPS)
71  *   - Trimble (TSIP and TAIP protocol)                     (GPS)
72  *
73  *   - RCC8000 MSF Receiver                                 (MSF)
74  *   - VARITEXT clock					    (MSF)
75  */
76 
77 /*
78  * Meinberg receivers are usually connected via a
79  * 9600 baud serial line
80  *
81  * The Meinberg GPS receivers also have a special NTP time stamp
82  * format. The firmware release is Uni-Erlangen.
83  *
84  * Meinberg generic receiver setup:
85  *	output time code every second
86  *	Baud rate 9600 7E2S
87  *
88  * Meinberg GPS16x setup:
89  *      output time code every second
90  *      Baudrate 19200 8N1
91  *
92  * This software supports the standard data formats used
93  * in Meinberg receivers.
94  *
95  * Special software versions are only sensible for the
96  * GPS 16x family of receivers.
97  *
98  * Meinberg can be reached via: http://www.meinberg.de/
99  */
100 
101 #include "ntpd.h"
102 #include "ntp_refclock.h"
103 #include "timevalops.h"		/* includes <sys/time.h> */
104 #include "ntp_control.h"
105 #include "ntp_string.h"
106 
107 #include <stdio.h>
108 #include <ctype.h>
109 #ifndef TM_IN_SYS_TIME
110 # include <time.h>
111 #endif
112 
113 #ifdef HAVE_UNISTD_H
114 # include <unistd.h>
115 #endif
116 
117 #if !defined(STREAM) && !defined(HAVE_SYSV_TTYS) && !defined(HAVE_BSD_TTYS) && !defined(HAVE_TERMIOS)
118 # include "Bletch:  Define one of {STREAM,HAVE_SYSV_TTYS,HAVE_TERMIOS}"
119 #endif
120 
121 #ifdef STREAM
122 # include <sys/stream.h>
123 # include <sys/stropts.h>
124 #endif
125 
126 #ifdef HAVE_TERMIOS
127 # include <termios.h>
128 # define TTY_GETATTR(_FD_, _ARG_) tcgetattr((_FD_), (_ARG_))
129 # define TTY_SETATTR(_FD_, _ARG_) tcsetattr((_FD_), TCSANOW, (_ARG_))
130 # undef HAVE_SYSV_TTYS
131 #endif
132 
133 #ifdef HAVE_SYSV_TTYS
134 # define TTY_GETATTR(_FD_, _ARG_) ioctl((_FD_), TCGETA, (_ARG_))
135 # define TTY_SETATTR(_FD_, _ARG_) ioctl((_FD_), TCSETAW, (_ARG_))
136 #endif
137 
138 #ifdef HAVE_BSD_TTYS
139 /* #error CURRENTLY NO BSD TTY SUPPORT */
140 # include "Bletch: BSD TTY not currently supported"
141 #endif
142 
143 #ifdef HAVE_SYS_IOCTL_H
144 # include <sys/ioctl.h>
145 #endif
146 
147 #ifdef HAVE_PPSAPI
148 # include "ppsapi_timepps.h"
149 # include "refclock_atom.h"
150 #endif
151 
152 #ifdef PPS
153 # ifdef HAVE_SYS_PPSCLOCK_H
154 #  include <sys/ppsclock.h>
155 # endif
156 # ifdef HAVE_TIO_SERIAL_STUFF
157 #  include <linux/serial.h>
158 # endif
159 #endif
160 
161 #define BUFFER_SIZE(_BUF, _PTR) ((_BUF) + sizeof(_BUF) - (_PTR))
162 #define BUFFER_SIZES(_BUF, _PTR, _SZ) ((_BUF) + (_SZ) - (_PTR))
163 
164 /*
165  * document type of PPS interfacing - copy of ifdef mechanism in local_input()
166  */
167 #undef PPS_METHOD
168 
169 #ifdef HAVE_PPSAPI
170 #define PPS_METHOD "PPS API"
171 #else
172 #ifdef TIOCDCDTIMESTAMP
173 #define PPS_METHOD "TIOCDCDTIMESTAMP"
174 #else /* TIOCDCDTIMESTAMP */
175 #if defined(HAVE_STRUCT_PPSCLOCKEV) && (defined(HAVE_CIOGETEV) || defined(HAVE_TIOCGPPSEV))
176 #ifdef HAVE_CIOGETEV
177 #define PPS_METHOD "CIOGETEV"
178 #endif
179 #ifdef HAVE_TIOCGPPSEV
180 #define PPS_METHOD "TIOCGPPSEV"
181 #endif
182 #endif
183 #endif /* TIOCDCDTIMESTAMP */
184 #endif /* HAVE_PPSAPI */
185 
186 #include "ntp_io.h"
187 #include "ntp_stdlib.h"
188 
189 #include "parse.h"
190 #include "mbg_gps166.h"
191 #include "trimble.h"
192 #include "binio.h"
193 #include "ascii.h"
194 #include "ieee754io.h"
195 #include "recvbuff.h"
196 
197 static char rcsid[] = "refclock_parse.c,v 4.81 2009/05/01 10:15:29 kardel RELEASE_20090105_A+POWERUPTRUST";
198 
199 /**===========================================================================
200  ** external interface to ntp mechanism
201  **/
202 
203 static	int	parse_start	(int, struct peer *);
204 static	void	parse_shutdown	(int, struct peer *);
205 static	void	parse_poll	(int, struct peer *);
206 static	void	parse_control	(int, const struct refclockstat *, struct refclockstat *, struct peer *);
207 
208 struct	refclock refclock_parse = {
209 	parse_start,
210 	parse_shutdown,
211 	parse_poll,
212 	parse_control,
213 	noentry,
214 	noentry,
215 	NOFLAGS
216 };
217 
218 /*
219  * Definitions
220  */
221 #define	MAXUNITS	4	/* maximum number of "PARSE" units permitted */
222 #define PARSEDEVICE	"/dev/refclock-%d" /* device to open %d is unit number */
223 #define PARSEPPSDEVICE	"/dev/refclockpps-%d" /* optional pps device to open %d is unit number */
224 
225 #undef ABS
226 #define ABS(_X_) (((_X_) < 0) ? -(_X_) : (_X_))
227 
228 #define PARSE_HARDPPS_DISABLE 0
229 #define PARSE_HARDPPS_ENABLE  1
230 
231 /**===========================================================================
232  ** function vector for dynamically binding io handling mechanism
233  **/
234 
235 struct parseunit;		/* to keep inquiring minds happy */
236 
237 typedef struct bind
238 {
239   const char *bd_description;	                                /* name of type of binding */
240   int	(*bd_init)     (struct parseunit *);			/* initialize */
241   void	(*bd_end)      (struct parseunit *);			/* end */
242   int   (*bd_setcs)    (struct parseunit *, parsectl_t *);	/* set character size */
243   int	(*bd_disable)  (struct parseunit *);			/* disable */
244   int	(*bd_enable)   (struct parseunit *);			/* enable */
245   int	(*bd_getfmt)   (struct parseunit *, parsectl_t *);	/* get format */
246   int	(*bd_setfmt)   (struct parseunit *, parsectl_t *);	/* setfmt */
247   int	(*bd_timecode) (struct parseunit *, parsectl_t *);	/* get time code */
248   void	(*bd_receive)  (struct recvbuf *);			/* receive operation */
249   int	(*bd_io_input) (struct recvbuf *);			/* input operation */
250 } bind_t;
251 
252 #define PARSE_END(_X_)			(*(_X_)->binding->bd_end)(_X_)
253 #define PARSE_SETCS(_X_, _CS_)		(*(_X_)->binding->bd_setcs)(_X_, _CS_)
254 #define PARSE_ENABLE(_X_)		(*(_X_)->binding->bd_enable)(_X_)
255 #define PARSE_DISABLE(_X_)		(*(_X_)->binding->bd_disable)(_X_)
256 #define PARSE_GETFMT(_X_, _DCT_)	(*(_X_)->binding->bd_getfmt)(_X_, _DCT_)
257 #define PARSE_SETFMT(_X_, _DCT_)	(*(_X_)->binding->bd_setfmt)(_X_, _DCT_)
258 #define PARSE_GETTIMECODE(_X_, _DCT_)	(*(_X_)->binding->bd_timecode)(_X_, _DCT_)
259 
260 /*
261  * special handling flags
262  */
263 #define PARSE_F_PPSONSECOND	0x00000001 /* PPS pulses are on second */
264 #define PARSE_F_POWERUPTRUST	0x00000100 /* POWERUP state ist trusted for */
265                                            /* trusttime after SYNC was seen */
266 /**===========================================================================
267  ** error message regression handling
268  **
269  ** there are quite a few errors that can occur in rapid succession such as
270  ** noisy input data or no data at all. in order to reduce the amount of
271  ** syslog messages in such case, we are using a backoff algorithm. We limit
272  ** the number of error messages of a certain class to 1 per time unit. if a
273  ** configurable number of messages is displayed that way, we move on to the
274  ** next time unit / count for that class. a count of messages that have been
275  ** suppressed is held and displayed whenever a corresponding message is
276  ** displayed. the time units for a message class will also be displayed.
277  ** whenever an error condition clears we reset the error message state,
278  ** thus we would still generate much output on pathological conditions
279  ** where the system oscillates between OK and NOT OK states. coping
280  ** with that condition is currently considered too complicated.
281  **/
282 
283 #define ERR_ALL	        (unsigned)~0	/* "all" errors */
284 #define ERR_BADDATA	(unsigned)0	/* unusable input data/conversion errors */
285 #define ERR_NODATA	(unsigned)1	/* no input data */
286 #define ERR_BADIO	(unsigned)2	/* read/write/select errors */
287 #define ERR_BADSTATUS	(unsigned)3	/* unsync states */
288 #define ERR_BADEVENT	(unsigned)4	/* non nominal events */
289 #define ERR_INTERNAL	(unsigned)5	/* internal error */
290 #define ERR_CNT		(unsigned)(ERR_INTERNAL+1)
291 
292 #define ERR(_X_)	if (list_err(parse, (_X_)))
293 
294 struct errorregression
295 {
296 	u_long err_count;	/* number of repititions per class */
297 	u_long err_delay;	/* minimum delay between messages */
298 };
299 
300 static struct errorregression
301 err_baddata[] =			/* error messages for bad input data */
302 {
303 	{ 1,       0 },		/* output first message immediately */
304 	{ 5,      60 },		/* output next five messages in 60 second intervals */
305 	{ 3,    3600 },		/* output next 3 messages in hour intervals */
306 	{ 0, 12*3600 }		/* repeat messages only every 12 hours */
307 };
308 
309 static struct errorregression
310 err_nodata[] =			/* error messages for missing input data */
311 {
312 	{ 1,       0 },		/* output first message immediately */
313 	{ 5,      60 },		/* output next five messages in 60 second intervals */
314 	{ 3,    3600 },		/* output next 3 messages in hour intervals */
315 	{ 0, 12*3600 }		/* repeat messages only every 12 hours */
316 };
317 
318 static struct errorregression
319 err_badstatus[] =		/* unsynchronized state messages */
320 {
321 	{ 1,       0 },		/* output first message immediately */
322 	{ 5,      60 },		/* output next five messages in 60 second intervals */
323 	{ 3,    3600 },		/* output next 3 messages in hour intervals */
324 	{ 0, 12*3600 }		/* repeat messages only every 12 hours */
325 };
326 
327 static struct errorregression
328 err_badio[] =			/* io failures (bad reads, selects, ...) */
329 {
330 	{ 1,       0 },		/* output first message immediately */
331 	{ 5,      60 },		/* output next five messages in 60 second intervals */
332 	{ 5,    3600 },		/* output next 3 messages in hour intervals */
333 	{ 0, 12*3600 }		/* repeat messages only every 12 hours */
334 };
335 
336 static struct errorregression
337 err_badevent[] =		/* non nominal events */
338 {
339 	{ 20,      0 },		/* output first message immediately */
340 	{ 6,      60 },		/* output next five messages in 60 second intervals */
341 	{ 5,    3600 },		/* output next 3 messages in hour intervals */
342 	{ 0, 12*3600 }		/* repeat messages only every 12 hours */
343 };
344 
345 static struct errorregression
346 err_internal[] =		/* really bad things - basically coding/OS errors */
347 {
348 	{ 0,       0 },		/* output all messages immediately */
349 };
350 
351 static struct errorregression *
352 err_tbl[] =
353 {
354 	err_baddata,
355 	err_nodata,
356 	err_badio,
357 	err_badstatus,
358 	err_badevent,
359 	err_internal
360 };
361 
362 struct errorinfo
363 {
364 	u_long err_started;	/* begin time (ntp) of error condition */
365 	u_long err_last;	/* last time (ntp) error occurred */
366 	u_long err_cnt;	/* number of error repititions */
367 	u_long err_suppressed;	/* number of suppressed messages */
368 	struct errorregression *err_stage; /* current error stage */
369 };
370 
371 /**===========================================================================
372  ** refclock instance data
373  **/
374 
375 struct parseunit
376 {
377 	/*
378 	 * NTP management
379 	 */
380 	struct peer         *peer;		/* backlink to peer structure - refclock inactive if 0  */
381 	struct refclockproc *generic;		/* backlink to refclockproc structure */
382 
383 	/*
384 	 * PARSE io
385 	 */
386 	bind_t	     *binding;	        /* io handling binding */
387 
388 	/*
389 	 * parse state
390 	 */
391 	parse_t	      parseio;	        /* io handling structure (user level parsing) */
392 
393 	/*
394 	 * type specific parameters
395 	 */
396 	struct parse_clockinfo   *parse_type;	        /* link to clock description */
397 
398 	/*
399 	 * clock state handling/reporting
400 	 */
401 	u_char	      flags;	        /* flags (leap_control) */
402 	u_long	      lastchange;       /* time (ntp) when last state change accured */
403 	u_long	      statetime[CEVNT_MAX+1]; /* accumulated time of clock states */
404 	u_long        pollneeddata; 	/* current_time(!=0) for receive sample expected in PPS mode */
405 	u_short	      lastformat;       /* last format used */
406 	u_long        lastsync;		/* time (ntp) when clock was last seen fully synchronized */
407         u_long        maxunsync;        /* max time in seconds a receiver is trusted after loosing synchronisation */
408         double        ppsphaseadjust;   /* phase adjustment of PPS time stamp */
409         u_long        lastmissed;       /* time (ntp) when poll didn't get data (powerup heuristic) */
410 	u_long        ppsserial;        /* magic cookie for ppsclock serials (avoids stale ppsclock data) */
411 	int	      ppsfd;	        /* fd to ise for PPS io */
412 #ifdef HAVE_PPSAPI
413         int           hardppsstate;     /* current hard pps state */
414 	struct refclock_atom atom;      /* PPSAPI structure */
415 #endif
416 	parsetime_t   timedata;		/* last (parse module) data */
417 	void         *localdata;        /* optional local, receiver-specific data */
418         unsigned long localstate;       /* private local state */
419 	struct errorinfo errors[ERR_CNT];  /* error state table for suppressing excessive error messages */
420 	struct ctl_var *kv;	        /* additional pseudo variables */
421 	u_long        laststatistic;    /* time when staticstics where output */
422 };
423 
424 
425 /**===========================================================================
426  ** Clockinfo section all parameter for specific clock types
427  ** includes NTP parameters, TTY parameters and IO handling parameters
428  **/
429 
430 static	void	poll_dpoll	(struct parseunit *);
431 static	void	poll_poll	(struct peer *);
432 static	int	poll_init	(struct parseunit *);
433 
434 typedef struct poll_info
435 {
436 	u_long      rate;		/* poll rate - once every "rate" seconds - 0 off */
437 	const char *string;		/* string to send for polling */
438 	u_long      count;		/* number of characters in string */
439 } poll_info_t;
440 
441 #define NO_CL_FLAGS	0
442 #define NO_POLL		0
443 #define NO_INIT		0
444 #define NO_END		0
445 #define NO_EVENT	0
446 #define NO_LCLDATA	0
447 #define NO_MESSAGE	0
448 #define NO_PPSDELAY     0
449 
450 #define DCF_ID		"DCF"	/* generic DCF */
451 #define DCF_A_ID	"DCFa"	/* AM demodulation */
452 #define DCF_P_ID	"DCFp"	/* psuedo random phase shift */
453 #define GPS_ID		"GPS"	/* GPS receiver */
454 
455 #define	NOCLOCK_ROOTDELAY	0.0
456 #define	NOCLOCK_BASEDELAY	0.0
457 #define	NOCLOCK_DESCRIPTION	0
458 #define NOCLOCK_MAXUNSYNC       0
459 #define NOCLOCK_CFLAG           0
460 #define NOCLOCK_IFLAG           0
461 #define NOCLOCK_OFLAG           0
462 #define NOCLOCK_LFLAG           0
463 #define NOCLOCK_ID		"TILT"
464 #define NOCLOCK_POLL		NO_POLL
465 #define NOCLOCK_INIT		NO_INIT
466 #define NOCLOCK_END		NO_END
467 #define NOCLOCK_DATA		NO_LCLDATA
468 #define NOCLOCK_FORMAT		""
469 #define NOCLOCK_TYPE		CTL_SST_TS_UNSPEC
470 #define NOCLOCK_SAMPLES		0
471 #define NOCLOCK_KEEP		0
472 
473 #define DCF_TYPE		CTL_SST_TS_LF
474 #define GPS_TYPE		CTL_SST_TS_UHF
475 
476 /*
477  * receiver specific constants
478  */
479 #define MBG_SPEED		(B9600)
480 #define MBG_CFLAG		(CS7|PARENB|CREAD|CLOCAL|HUPCL|CSTOPB)
481 #define MBG_IFLAG		(IGNBRK|IGNPAR|ISTRIP)
482 #define MBG_OFLAG		0
483 #define MBG_LFLAG		0
484 #define MBG_FLAGS               PARSE_F_PPSONSECOND
485 
486 /*
487  * Meinberg DCF77 receivers
488  */
489 #define	DCFUA31_ROOTDELAY	0.0  /* 0 */
490 #define	DCFUA31_BASEDELAY	0.010  /* 10.7421875ms: 10 ms (+/- 3 ms) */
491 #define	DCFUA31_DESCRIPTION	"Meinberg DCF77 C51 or compatible"
492 #define DCFUA31_MAXUNSYNC       60*30       /* only trust clock for 1/2 hour */
493 #define DCFUA31_SPEED		MBG_SPEED
494 #define DCFUA31_CFLAG           MBG_CFLAG
495 #define DCFUA31_IFLAG           MBG_IFLAG
496 #define DCFUA31_OFLAG           MBG_OFLAG
497 #define DCFUA31_LFLAG           MBG_LFLAG
498 #define DCFUA31_SAMPLES		5
499 #define DCFUA31_KEEP		3
500 #define DCFUA31_FORMAT		"Meinberg Standard"
501 
502 /*
503  * Meinberg DCF PZF535/TCXO (FM/PZF) receiver
504  */
505 #define	DCFPZF535_ROOTDELAY	0.0
506 #define	DCFPZF535_BASEDELAY	0.001968  /* 1.968ms +- 104us (oscilloscope) - relative to start (end of STX) */
507 #define	DCFPZF535_DESCRIPTION	"Meinberg DCF PZF 535/509 / TCXO"
508 #define DCFPZF535_MAXUNSYNC     60*60*12           /* only trust clock for 12 hours
509 						    * @ 5e-8df/f we have accumulated
510 						    * at most 2.16 ms (thus we move to
511 						    * NTP synchronisation */
512 #define DCFPZF535_SPEED		MBG_SPEED
513 #define DCFPZF535_CFLAG         MBG_CFLAG
514 #define DCFPZF535_IFLAG         MBG_IFLAG
515 #define DCFPZF535_OFLAG         MBG_OFLAG
516 #define DCFPZF535_LFLAG         MBG_LFLAG
517 #define DCFPZF535_SAMPLES	       5
518 #define DCFPZF535_KEEP		       3
519 #define DCFPZF535_FORMAT	"Meinberg Standard"
520 
521 /*
522  * Meinberg DCF PZF535/OCXO receiver
523  */
524 #define	DCFPZF535OCXO_ROOTDELAY	0.0
525 #define	DCFPZF535OCXO_BASEDELAY	0.001968 /* 1.968ms +- 104us (oscilloscope) - relative to start (end of STX) */
526 #define	DCFPZF535OCXO_DESCRIPTION "Meinberg DCF PZF 535/509 / OCXO"
527 #define DCFPZF535OCXO_MAXUNSYNC     60*60*96       /* only trust clock for 4 days
528 						    * @ 5e-9df/f we have accumulated
529 						    * at most an error of 1.73 ms
530 						    * (thus we move to NTP synchronisation) */
531 #define DCFPZF535OCXO_SPEED	    MBG_SPEED
532 #define DCFPZF535OCXO_CFLAG         MBG_CFLAG
533 #define DCFPZF535OCXO_IFLAG         MBG_IFLAG
534 #define DCFPZF535OCXO_OFLAG         MBG_OFLAG
535 #define DCFPZF535OCXO_LFLAG         MBG_LFLAG
536 #define DCFPZF535OCXO_SAMPLES		   5
537 #define DCFPZF535OCXO_KEEP	           3
538 #define DCFPZF535OCXO_FORMAT	    "Meinberg Standard"
539 
540 /*
541  * Meinberg GPS16X receiver
542  */
543 static	void	gps16x_message	 (struct parseunit *, parsetime_t *);
544 static  int     gps16x_poll_init (struct parseunit *);
545 
546 #define	GPS16X_ROOTDELAY	0.0         /* nothing here */
547 #define	GPS16X_BASEDELAY	0.001968         /* XXX to be fixed ! 1.968ms +- 104us (oscilloscope) - relative to start (end of STX) */
548 #define	GPS16X_DESCRIPTION      "Meinberg GPS16x receiver"
549 #define GPS16X_MAXUNSYNC        60*60*96       /* only trust clock for 4 days
550 						* @ 5e-9df/f we have accumulated
551 						* at most an error of 1.73 ms
552 						* (thus we move to NTP synchronisation) */
553 #define GPS16X_SPEED		B19200
554 #define GPS16X_CFLAG            (CS8|CREAD|CLOCAL|HUPCL)
555 #define GPS16X_IFLAG            (IGNBRK|IGNPAR)
556 #define GPS16X_OFLAG            MBG_OFLAG
557 #define GPS16X_LFLAG            MBG_LFLAG
558 #define GPS16X_POLLRATE	6
559 #define GPS16X_POLLCMD	""
560 #define GPS16X_CMDSIZE	0
561 
562 static poll_info_t gps16x_pollinfo = { GPS16X_POLLRATE, GPS16X_POLLCMD, GPS16X_CMDSIZE };
563 
564 #define GPS16X_INIT		gps16x_poll_init
565 #define GPS16X_POLL	        0
566 #define GPS16X_END		0
567 #define GPS16X_DATA		((void *)(&gps16x_pollinfo))
568 #define GPS16X_MESSAGE		gps16x_message
569 #define GPS16X_ID		GPS_ID
570 #define GPS16X_FORMAT		"Meinberg GPS Extended"
571 #define GPS16X_SAMPLES		5
572 #define GPS16X_KEEP		3
573 
574 /*
575  * ELV DCF7000 Wallclock-Receiver/Switching Clock (Kit)
576  *
577  * This is really not the hottest clock - but before you have nothing ...
578  */
579 #define DCF7000_ROOTDELAY	0.0 /* 0 */
580 #define DCF7000_BASEDELAY	0.405 /* slow blow */
581 #define DCF7000_DESCRIPTION	"ELV DCF7000"
582 #define DCF7000_MAXUNSYNC	(60*5) /* sorry - but it just was not build as a clock */
583 #define DCF7000_SPEED		(B9600)
584 #define DCF7000_CFLAG           (CS8|CREAD|PARENB|PARODD|CLOCAL|HUPCL)
585 #define DCF7000_IFLAG		(IGNBRK)
586 #define DCF7000_OFLAG		0
587 #define DCF7000_LFLAG		0
588 #define DCF7000_SAMPLES		5
589 #define DCF7000_KEEP		3
590 #define DCF7000_FORMAT		"ELV DCF7000"
591 
592 /*
593  * Schmid DCF Receiver Kit
594  *
595  * When the WSDCF clock is operating optimally we want the primary clock
596  * distance to come out at 300 ms.  Thus, peer.distance in the WSDCF peer
597  * structure is set to 290 ms and we compute delays which are at least
598  * 10 ms long.  The following are 290 ms and 10 ms expressed in u_fp format
599  */
600 #define WS_POLLRATE	1	/* every second - watch interdependency with poll routine */
601 #define WS_POLLCMD	"\163"
602 #define WS_CMDSIZE	1
603 
604 static poll_info_t wsdcf_pollinfo = { WS_POLLRATE, WS_POLLCMD, WS_CMDSIZE };
605 
606 #define WSDCF_INIT		poll_init
607 #define WSDCF_POLL		poll_dpoll
608 #define WSDCF_END		0
609 #define WSDCF_DATA		((void *)(&wsdcf_pollinfo))
610 #define	WSDCF_ROOTDELAY		0.0	/* 0 */
611 #define	WSDCF_BASEDELAY	 	0.010	/*  ~  10ms */
612 #define WSDCF_DESCRIPTION	"WS/DCF Receiver"
613 #define WSDCF_FORMAT		"Schmid"
614 #define WSDCF_MAXUNSYNC		(60*60)	/* assume this beast hold at 1 h better than 2 ms XXX-must verify */
615 #define WSDCF_SPEED		(B1200)
616 #define WSDCF_CFLAG		(CS8|CREAD|CLOCAL)
617 #define WSDCF_IFLAG		0
618 #define WSDCF_OFLAG		0
619 #define WSDCF_LFLAG		0
620 #define WSDCF_SAMPLES		5
621 #define WSDCF_KEEP		3
622 
623 /*
624  * RAW DCF77 - input of DCF marks via RS232 - many variants
625  */
626 #define RAWDCF_FLAGS		0
627 #define RAWDCF_ROOTDELAY	0.0 /* 0 */
628 #define RAWDCF_BASEDELAY	0.258
629 #define RAWDCF_FORMAT		"RAW DCF77 Timecode"
630 #define RAWDCF_MAXUNSYNC	(0) /* sorry - its a true receiver - no signal - no time */
631 #define RAWDCF_SPEED		(B50)
632 #ifdef NO_PARENB_IGNPAR /* Was: defined(SYS_IRIX4) || defined(SYS_IRIX5) */
633 /* somehow doesn't grok PARENB & IGNPAR (mj) */
634 # define RAWDCF_CFLAG            (CS8|CREAD|CLOCAL)
635 #else
636 # define RAWDCF_CFLAG            (CS8|CREAD|CLOCAL|PARENB)
637 #endif
638 #ifdef RAWDCF_NO_IGNPAR /* Was: defined(SYS_LINUX) && defined(CLOCK_RAWDCF) */
639 # define RAWDCF_IFLAG		0
640 #else
641 # define RAWDCF_IFLAG		(IGNPAR)
642 #endif
643 #define RAWDCF_OFLAG		0
644 #define RAWDCF_LFLAG		0
645 #define RAWDCF_SAMPLES		20
646 #define RAWDCF_KEEP		12
647 #define RAWDCF_INIT		0
648 
649 /*
650  * RAW DCF variants
651  */
652 /*
653  * Conrad receiver
654  *
655  * simplest (cheapest) DCF clock - e. g. DCF77 receiver by Conrad
656  * (~40DM - roughly $30 ) followed by a level converter for RS232
657  */
658 #define CONRAD_BASEDELAY	0.292 /* Conrad receiver @ 50 Baud on a Sun */
659 #define CONRAD_DESCRIPTION	"RAW DCF77 CODE (Conrad DCF77 receiver module)"
660 
661 /* Gude Analog- und Digitalsystem GmbH 'Expert mouseCLOCK USB v2.0' */
662 #define GUDE_EMC_USB_V20_SPEED            (B4800)
663 #define GUDE_EMC_USB_V20_BASEDELAY        0.425 /* USB serial<->USB converter FTDI232R */
664 #define GUDE_EMC_USB_V20_DESCRIPTION      "RAW DCF77 CODE (Expert mouseCLOCK USB v2.0)"
665 
666 /*
667  * TimeBrick receiver
668  */
669 #define TIMEBRICK_BASEDELAY	0.210 /* TimeBrick @ 50 Baud on a Sun */
670 #define TIMEBRICK_DESCRIPTION	"RAW DCF77 CODE (TimeBrick)"
671 
672 /*
673  * IGEL:clock receiver
674  */
675 #define IGELCLOCK_BASEDELAY	0.258 /* IGEL:clock receiver */
676 #define IGELCLOCK_DESCRIPTION	"RAW DCF77 CODE (IGEL:clock)"
677 #define IGELCLOCK_SPEED		(B1200)
678 #define IGELCLOCK_CFLAG		(CS8|CREAD|HUPCL|CLOCAL)
679 
680 /*
681  * RAWDCF receivers that need to be powered from DTR
682  * (like Expert mouse clock)
683  */
684 static	int	rawdcf_init_1	(struct parseunit *);
685 #define RAWDCFDTRSET_DESCRIPTION	"RAW DCF77 CODE (DTR SET/RTS CLR)"
686 #define RAWDCFDTRSET75_DESCRIPTION	"RAW DCF77 CODE (DTR SET/RTS CLR @ 75 baud)"
687 #define RAWDCFDTRSET_INIT 		rawdcf_init_1
688 
689 /*
690  * RAWDCF receivers that need to be powered from
691  * DTR CLR and RTS SET
692  */
693 static	int	rawdcf_init_2	(struct parseunit *);
694 #define RAWDCFDTRCLRRTSSET_DESCRIPTION	"RAW DCF77 CODE (DTR CLR/RTS SET)"
695 #define RAWDCFDTRCLRRTSSET75_DESCRIPTION "RAW DCF77 CODE (DTR CLR/RTS SET @ 75 baud)"
696 #define RAWDCFDTRCLRRTSSET_INIT	rawdcf_init_2
697 
698 /*
699  * Trimble GPS receivers (TAIP and TSIP protocols)
700  */
701 #ifndef TRIM_POLLRATE
702 #define TRIM_POLLRATE	0	/* only true direct polling */
703 #endif
704 
705 #define TRIM_TAIPPOLLCMD	">SRM;FR_FLAG=F;EC_FLAG=F<>QTM<"
706 #define TRIM_TAIPCMDSIZE	(sizeof(TRIM_TAIPPOLLCMD)-1)
707 
708 static poll_info_t trimbletaip_pollinfo = { TRIM_POLLRATE, TRIM_TAIPPOLLCMD, TRIM_TAIPCMDSIZE };
709 static	int	trimbletaip_init	(struct parseunit *);
710 static	void	trimbletaip_event	(struct parseunit *, int);
711 
712 /* query time & UTC correction data */
713 static char tsipquery[] = { DLE, 0x21, DLE, ETX, DLE, 0x2F, DLE, ETX };
714 
715 static poll_info_t trimbletsip_pollinfo = { TRIM_POLLRATE, tsipquery, sizeof(tsipquery) };
716 static	int	trimbletsip_init	(struct parseunit *);
717 static	void	trimbletsip_end   	(struct parseunit *);
718 static	void	trimbletsip_message	(struct parseunit *, parsetime_t *);
719 static	void	trimbletsip_event	(struct parseunit *, int);
720 
721 #define TRIMBLETSIP_IDLE_TIME	    (300) /* 5 minutes silence at most */
722 #define TRIMBLE_RESET_HOLDOFF       TRIMBLETSIP_IDLE_TIME
723 
724 #define TRIMBLETAIP_SPEED	    (B4800)
725 #define TRIMBLETAIP_CFLAG           (CS8|CREAD|CLOCAL)
726 #define TRIMBLETAIP_IFLAG           (BRKINT|IGNPAR|ISTRIP|ICRNL|IXON)
727 #define TRIMBLETAIP_OFLAG           (OPOST|ONLCR)
728 #define TRIMBLETAIP_LFLAG           (0)
729 
730 #define TRIMBLETSIP_SPEED	    (B9600)
731 #define TRIMBLETSIP_CFLAG           (CS8|CLOCAL|CREAD|PARENB|PARODD)
732 #define TRIMBLETSIP_IFLAG           (IGNBRK)
733 #define TRIMBLETSIP_OFLAG           (0)
734 #define TRIMBLETSIP_LFLAG           (ICANON)
735 
736 #define TRIMBLETSIP_SAMPLES	    5
737 #define TRIMBLETSIP_KEEP	    3
738 #define TRIMBLETAIP_SAMPLES	    5
739 #define TRIMBLETAIP_KEEP	    3
740 
741 #define TRIMBLETAIP_FLAGS	    (PARSE_F_PPSONSECOND)
742 #define TRIMBLETSIP_FLAGS	    (TRIMBLETAIP_FLAGS)
743 
744 #define TRIMBLETAIP_POLL	    poll_dpoll
745 #define TRIMBLETSIP_POLL	    poll_dpoll
746 
747 #define TRIMBLETAIP_INIT	    trimbletaip_init
748 #define TRIMBLETSIP_INIT	    trimbletsip_init
749 
750 #define TRIMBLETAIP_EVENT	    trimbletaip_event
751 
752 #define TRIMBLETSIP_EVENT	    trimbletsip_event
753 #define TRIMBLETSIP_MESSAGE	    trimbletsip_message
754 
755 #define TRIMBLETAIP_END		    0
756 #define TRIMBLETSIP_END		    trimbletsip_end
757 
758 #define TRIMBLETAIP_DATA	    ((void *)(&trimbletaip_pollinfo))
759 #define TRIMBLETSIP_DATA	    ((void *)(&trimbletsip_pollinfo))
760 
761 #define TRIMBLETAIP_ID		    GPS_ID
762 #define TRIMBLETSIP_ID		    GPS_ID
763 
764 #define TRIMBLETAIP_FORMAT	    "Trimble TAIP"
765 #define TRIMBLETSIP_FORMAT	    "Trimble TSIP"
766 
767 #define TRIMBLETAIP_ROOTDELAY        0x0
768 #define TRIMBLETSIP_ROOTDELAY        0x0
769 
770 #define TRIMBLETAIP_BASEDELAY        0.0
771 #define TRIMBLETSIP_BASEDELAY        0.020	/* GPS time message latency */
772 
773 #define TRIMBLETAIP_DESCRIPTION      "Trimble GPS (TAIP) receiver"
774 #define TRIMBLETSIP_DESCRIPTION      "Trimble GPS (TSIP) receiver"
775 
776 #define TRIMBLETAIP_MAXUNSYNC        0
777 #define TRIMBLETSIP_MAXUNSYNC        0
778 
779 #define TRIMBLETAIP_EOL		    '<'
780 
781 /*
782  * RadioCode Clocks RCC 800 receiver
783  */
784 #define RCC_POLLRATE   0       /* only true direct polling */
785 #define RCC_POLLCMD    "\r"
786 #define RCC_CMDSIZE    1
787 
788 static poll_info_t rcc8000_pollinfo = { RCC_POLLRATE, RCC_POLLCMD, RCC_CMDSIZE };
789 #define RCC8000_FLAGS		0
790 #define RCC8000_POLL            poll_dpoll
791 #define RCC8000_INIT            poll_init
792 #define RCC8000_END             0
793 #define RCC8000_DATA            ((void *)(&rcc8000_pollinfo))
794 #define RCC8000_ROOTDELAY       0.0
795 #define RCC8000_BASEDELAY       0.0
796 #define RCC8000_ID              "MSF"
797 #define RCC8000_DESCRIPTION     "RCC 8000 MSF Receiver"
798 #define RCC8000_FORMAT          "Radiocode RCC8000"
799 #define RCC8000_MAXUNSYNC       (60*60) /* should be ok for an hour */
800 #define RCC8000_SPEED		(B2400)
801 #define RCC8000_CFLAG           (CS8|CREAD|CLOCAL)
802 #define RCC8000_IFLAG           (IGNBRK|IGNPAR)
803 #define RCC8000_OFLAG           0
804 #define RCC8000_LFLAG           0
805 #define RCC8000_SAMPLES         5
806 #define RCC8000_KEEP	        3
807 
808 /*
809  * Hopf Radio clock 6021 Format
810  *
811  */
812 #define HOPF6021_ROOTDELAY	0.0
813 #define HOPF6021_BASEDELAY	0.0
814 #define HOPF6021_DESCRIPTION	"HOPF 6021"
815 #define HOPF6021_FORMAT         "hopf Funkuhr 6021"
816 #define HOPF6021_MAXUNSYNC	(60*60)  /* should be ok for an hour */
817 #define HOPF6021_SPEED         (B9600)
818 #define HOPF6021_CFLAG          (CS8|CREAD|CLOCAL)
819 #define HOPF6021_IFLAG		(IGNBRK|ISTRIP)
820 #define HOPF6021_OFLAG		0
821 #define HOPF6021_LFLAG		0
822 #define HOPF6021_FLAGS          0
823 #define HOPF6021_SAMPLES        5
824 #define HOPF6021_KEEP	        3
825 
826 /*
827  * Diem's Computime Radio Clock Receiver
828  */
829 #define COMPUTIME_FLAGS       0
830 #define COMPUTIME_ROOTDELAY   0.0
831 #define COMPUTIME_BASEDELAY   0.0
832 #define COMPUTIME_ID          DCF_ID
833 #define COMPUTIME_DESCRIPTION "Diem's Computime receiver"
834 #define COMPUTIME_FORMAT      "Diem's Computime Radio Clock"
835 #define COMPUTIME_TYPE        DCF_TYPE
836 #define COMPUTIME_MAXUNSYNC   (60*60)       /* only trust clock for 1 hour */
837 #define COMPUTIME_SPEED       (B9600)
838 #define COMPUTIME_CFLAG       (CSTOPB|CS7|CREAD|CLOCAL)
839 #define COMPUTIME_IFLAG       (IGNBRK|IGNPAR|ISTRIP)
840 #define COMPUTIME_OFLAG       0
841 #define COMPUTIME_LFLAG       0
842 #define COMPUTIME_SAMPLES     5
843 #define COMPUTIME_KEEP        3
844 
845 /*
846  * Varitext Radio Clock Receiver
847  */
848 #define VARITEXT_FLAGS       0
849 #define VARITEXT_ROOTDELAY   0.0
850 #define VARITEXT_BASEDELAY   0.0
851 #define VARITEXT_ID          "MSF"
852 #define VARITEXT_DESCRIPTION "Varitext receiver"
853 #define VARITEXT_FORMAT      "Varitext Radio Clock"
854 #define VARITEXT_TYPE        DCF_TYPE
855 #define VARITEXT_MAXUNSYNC   (60*60)       /* only trust clock for 1 hour */
856 #define VARITEXT_SPEED       (B9600)
857 #define VARITEXT_CFLAG       (CS7|CREAD|CLOCAL|PARENB|PARODD)
858 #define VARITEXT_IFLAG       (IGNPAR|IGNBRK|INPCK) /*|ISTRIP)*/
859 #define VARITEXT_OFLAG       0
860 #define VARITEXT_LFLAG       0
861 #define VARITEXT_SAMPLES     32
862 #define VARITEXT_KEEP        20
863 
864 /*
865  * SEL240x Satellite Sychronized Clock
866  */
867 #define SEL240X_POLLRATE	0 /* only true direct polling */
868 #define SEL240X_POLLCMD		"BUB8"
869 #define SEL240X_CMDSIZE		4
870 
871 static poll_info_t sel240x_pollinfo = { SEL240X_POLLRATE,
872 	                                SEL240X_POLLCMD,
873 					SEL240X_CMDSIZE };
874 #define SEL240X_FLAGS		(PARSE_F_PPSONSECOND)
875 #define SEL240X_POLL		poll_dpoll
876 #define SEL240X_INIT		poll_init
877 #define SEL240X_END		0
878 #define SEL240X_DATA            ((void *)(&sel240x_pollinfo))
879 #define SEL240X_ROOTDELAY	0.0
880 #define SEL240X_BASEDELAY	0.0
881 #define SEL240X_ID		GPS_ID
882 #define SEL240X_DESCRIPTION	"SEL240x Satellite Synchronized Clock"
883 #define SEL240X_FORMAT		"SEL B8"
884 #define SEL240X_MAXUNSYNC	60*60*12 /* only trust clock for 12 hours */
885 #define SEL240X_SPEED		(B9600)
886 #define SEL240X_CFLAG		(CS8|CREAD|CLOCAL)
887 #define SEL240X_IFLAG		(IGNBRK|IGNPAR)
888 #define SEL240X_OFLAG		(0)
889 #define SEL240X_LFLAG		(0)
890 #define SEL240X_SAMPLES		5
891 #define SEL240X_KEEP		3
892 
893 static struct parse_clockinfo
894 {
895 	u_long  cl_flags;		/* operation flags (PPS interpretation, trust handling) */
896   void  (*cl_poll)    (struct parseunit *);			/* active poll routine */
897   int   (*cl_init)    (struct parseunit *);			/* active poll init routine */
898   void  (*cl_event)   (struct parseunit *, int);		/* special event handling (e.g. reset clock) */
899   void  (*cl_end)     (struct parseunit *);			/* active poll end routine */
900   void  (*cl_message) (struct parseunit *, parsetime_t *);	/* process a lower layer message */
901 	void   *cl_data;		/* local data area for "poll" mechanism */
902 	double    cl_rootdelay;		/* rootdelay */
903 	double    cl_basedelay;		/* current offset by which the RS232
904 				time code is delayed from the actual time */
905 	const char *cl_id;		/* ID code */
906 	const char *cl_description;		/* device name */
907 	const char *cl_format;		/* fixed format */
908 	u_char  cl_type;		/* clock type (ntp control) */
909 	u_long  cl_maxunsync;		/* time to trust oscillator after losing synch */
910 	u_long  cl_speed;		/* terminal input & output baudrate */
911 	u_long  cl_cflag;             /* terminal control flags */
912 	u_long  cl_iflag;             /* terminal input flags */
913 	u_long  cl_oflag;             /* terminal output flags */
914 	u_long  cl_lflag;             /* terminal local flags */
915 	u_long  cl_samples;	      /* samples for median filter */
916 	u_long  cl_keep;              /* samples for median filter to keep */
917 } parse_clockinfo[] =
918 {
919 	{				/* mode 0 */
920 		MBG_FLAGS,
921 		NO_POLL,
922 		NO_INIT,
923 		NO_EVENT,
924 		NO_END,
925 		NO_MESSAGE,
926 		NO_LCLDATA,
927 		DCFPZF535_ROOTDELAY,
928 		DCFPZF535_BASEDELAY,
929 		DCF_P_ID,
930 		DCFPZF535_DESCRIPTION,
931 		DCFPZF535_FORMAT,
932 		DCF_TYPE,
933 		DCFPZF535_MAXUNSYNC,
934 		DCFPZF535_SPEED,
935 		DCFPZF535_CFLAG,
936 		DCFPZF535_IFLAG,
937 		DCFPZF535_OFLAG,
938 		DCFPZF535_LFLAG,
939 		DCFPZF535_SAMPLES,
940 		DCFPZF535_KEEP
941 	},
942 	{				/* mode 1 */
943 		MBG_FLAGS,
944 		NO_POLL,
945 		NO_INIT,
946 		NO_EVENT,
947 		NO_END,
948 		NO_MESSAGE,
949 		NO_LCLDATA,
950 		DCFPZF535OCXO_ROOTDELAY,
951 		DCFPZF535OCXO_BASEDELAY,
952 		DCF_P_ID,
953 		DCFPZF535OCXO_DESCRIPTION,
954 		DCFPZF535OCXO_FORMAT,
955 		DCF_TYPE,
956 		DCFPZF535OCXO_MAXUNSYNC,
957 		DCFPZF535OCXO_SPEED,
958 		DCFPZF535OCXO_CFLAG,
959 		DCFPZF535OCXO_IFLAG,
960 		DCFPZF535OCXO_OFLAG,
961 		DCFPZF535OCXO_LFLAG,
962 		DCFPZF535OCXO_SAMPLES,
963 		DCFPZF535OCXO_KEEP
964 	},
965 	{				/* mode 2 */
966 		MBG_FLAGS,
967 		NO_POLL,
968 		NO_INIT,
969 		NO_EVENT,
970 		NO_END,
971 		NO_MESSAGE,
972 		NO_LCLDATA,
973 		DCFUA31_ROOTDELAY,
974 		DCFUA31_BASEDELAY,
975 		DCF_A_ID,
976 		DCFUA31_DESCRIPTION,
977 		DCFUA31_FORMAT,
978 		DCF_TYPE,
979 		DCFUA31_MAXUNSYNC,
980 		DCFUA31_SPEED,
981 		DCFUA31_CFLAG,
982 		DCFUA31_IFLAG,
983 		DCFUA31_OFLAG,
984 		DCFUA31_LFLAG,
985 		DCFUA31_SAMPLES,
986 		DCFUA31_KEEP
987 	},
988 	{				/* mode 3 */
989 		MBG_FLAGS,
990 		NO_POLL,
991 		NO_INIT,
992 		NO_EVENT,
993 		NO_END,
994 		NO_MESSAGE,
995 		NO_LCLDATA,
996 		DCF7000_ROOTDELAY,
997 		DCF7000_BASEDELAY,
998 		DCF_A_ID,
999 		DCF7000_DESCRIPTION,
1000 		DCF7000_FORMAT,
1001 		DCF_TYPE,
1002 		DCF7000_MAXUNSYNC,
1003 		DCF7000_SPEED,
1004 		DCF7000_CFLAG,
1005 		DCF7000_IFLAG,
1006 		DCF7000_OFLAG,
1007 		DCF7000_LFLAG,
1008 		DCF7000_SAMPLES,
1009 		DCF7000_KEEP
1010 	},
1011 	{				/* mode 4 */
1012 		NO_CL_FLAGS,
1013 		WSDCF_POLL,
1014 		WSDCF_INIT,
1015 		NO_EVENT,
1016 		WSDCF_END,
1017 		NO_MESSAGE,
1018 		WSDCF_DATA,
1019 		WSDCF_ROOTDELAY,
1020 		WSDCF_BASEDELAY,
1021 		DCF_A_ID,
1022 		WSDCF_DESCRIPTION,
1023 		WSDCF_FORMAT,
1024 		DCF_TYPE,
1025 		WSDCF_MAXUNSYNC,
1026 		WSDCF_SPEED,
1027 		WSDCF_CFLAG,
1028 		WSDCF_IFLAG,
1029 		WSDCF_OFLAG,
1030 		WSDCF_LFLAG,
1031 		WSDCF_SAMPLES,
1032 		WSDCF_KEEP
1033 	},
1034 	{				/* mode 5 */
1035 		RAWDCF_FLAGS,
1036 		NO_POLL,
1037 		RAWDCF_INIT,
1038 		NO_EVENT,
1039 		NO_END,
1040 		NO_MESSAGE,
1041 		NO_LCLDATA,
1042 		RAWDCF_ROOTDELAY,
1043 		CONRAD_BASEDELAY,
1044 		DCF_A_ID,
1045 		CONRAD_DESCRIPTION,
1046 		RAWDCF_FORMAT,
1047 		DCF_TYPE,
1048 		RAWDCF_MAXUNSYNC,
1049 		RAWDCF_SPEED,
1050 		RAWDCF_CFLAG,
1051 		RAWDCF_IFLAG,
1052 		RAWDCF_OFLAG,
1053 		RAWDCF_LFLAG,
1054 		RAWDCF_SAMPLES,
1055 		RAWDCF_KEEP
1056 	},
1057 	{				/* mode 6 */
1058 		RAWDCF_FLAGS,
1059 		NO_POLL,
1060 		RAWDCF_INIT,
1061 		NO_EVENT,
1062 		NO_END,
1063 		NO_MESSAGE,
1064 		NO_LCLDATA,
1065 		RAWDCF_ROOTDELAY,
1066 		TIMEBRICK_BASEDELAY,
1067 		DCF_A_ID,
1068 		TIMEBRICK_DESCRIPTION,
1069 		RAWDCF_FORMAT,
1070 		DCF_TYPE,
1071 		RAWDCF_MAXUNSYNC,
1072 		RAWDCF_SPEED,
1073 		RAWDCF_CFLAG,
1074 		RAWDCF_IFLAG,
1075 		RAWDCF_OFLAG,
1076 		RAWDCF_LFLAG,
1077 		RAWDCF_SAMPLES,
1078 		RAWDCF_KEEP
1079 	},
1080 	{				/* mode 7 */
1081 		MBG_FLAGS,
1082 		GPS16X_POLL,
1083 		GPS16X_INIT,
1084 		NO_EVENT,
1085 		GPS16X_END,
1086 		GPS16X_MESSAGE,
1087 		GPS16X_DATA,
1088 		GPS16X_ROOTDELAY,
1089 		GPS16X_BASEDELAY,
1090 		GPS16X_ID,
1091 		GPS16X_DESCRIPTION,
1092 		GPS16X_FORMAT,
1093 		GPS_TYPE,
1094 		GPS16X_MAXUNSYNC,
1095 		GPS16X_SPEED,
1096 		GPS16X_CFLAG,
1097 		GPS16X_IFLAG,
1098 		GPS16X_OFLAG,
1099 		GPS16X_LFLAG,
1100 		GPS16X_SAMPLES,
1101 		GPS16X_KEEP
1102 	},
1103 	{				/* mode 8 */
1104 		RAWDCF_FLAGS,
1105 		NO_POLL,
1106 		NO_INIT,
1107 		NO_EVENT,
1108 		NO_END,
1109 		NO_MESSAGE,
1110 		NO_LCLDATA,
1111 		RAWDCF_ROOTDELAY,
1112 		IGELCLOCK_BASEDELAY,
1113 		DCF_A_ID,
1114 		IGELCLOCK_DESCRIPTION,
1115 		RAWDCF_FORMAT,
1116 		DCF_TYPE,
1117 		RAWDCF_MAXUNSYNC,
1118 		IGELCLOCK_SPEED,
1119 		IGELCLOCK_CFLAG,
1120 		RAWDCF_IFLAG,
1121 		RAWDCF_OFLAG,
1122 		RAWDCF_LFLAG,
1123 		RAWDCF_SAMPLES,
1124 		RAWDCF_KEEP
1125 	},
1126 	{				/* mode 9 */
1127 		TRIMBLETAIP_FLAGS,
1128 #if TRIM_POLLRATE		/* DHD940515: Allow user config */
1129 		NO_POLL,
1130 #else
1131 		TRIMBLETAIP_POLL,
1132 #endif
1133 		TRIMBLETAIP_INIT,
1134 		TRIMBLETAIP_EVENT,
1135 		TRIMBLETAIP_END,
1136 		NO_MESSAGE,
1137 		TRIMBLETAIP_DATA,
1138 		TRIMBLETAIP_ROOTDELAY,
1139 		TRIMBLETAIP_BASEDELAY,
1140 		TRIMBLETAIP_ID,
1141 		TRIMBLETAIP_DESCRIPTION,
1142 		TRIMBLETAIP_FORMAT,
1143 		GPS_TYPE,
1144 		TRIMBLETAIP_MAXUNSYNC,
1145 		TRIMBLETAIP_SPEED,
1146 		TRIMBLETAIP_CFLAG,
1147 		TRIMBLETAIP_IFLAG,
1148 		TRIMBLETAIP_OFLAG,
1149 		TRIMBLETAIP_LFLAG,
1150 		TRIMBLETAIP_SAMPLES,
1151 		TRIMBLETAIP_KEEP
1152 	},
1153 	{				/* mode 10 */
1154 		TRIMBLETSIP_FLAGS,
1155 #if TRIM_POLLRATE		/* DHD940515: Allow user config */
1156 		NO_POLL,
1157 #else
1158 		TRIMBLETSIP_POLL,
1159 #endif
1160 		TRIMBLETSIP_INIT,
1161 		TRIMBLETSIP_EVENT,
1162 		TRIMBLETSIP_END,
1163 		TRIMBLETSIP_MESSAGE,
1164 		TRIMBLETSIP_DATA,
1165 		TRIMBLETSIP_ROOTDELAY,
1166 		TRIMBLETSIP_BASEDELAY,
1167 		TRIMBLETSIP_ID,
1168 		TRIMBLETSIP_DESCRIPTION,
1169 		TRIMBLETSIP_FORMAT,
1170 		GPS_TYPE,
1171 		TRIMBLETSIP_MAXUNSYNC,
1172 		TRIMBLETSIP_SPEED,
1173 		TRIMBLETSIP_CFLAG,
1174 		TRIMBLETSIP_IFLAG,
1175 		TRIMBLETSIP_OFLAG,
1176 		TRIMBLETSIP_LFLAG,
1177 		TRIMBLETSIP_SAMPLES,
1178 		TRIMBLETSIP_KEEP
1179 	},
1180 	{                             /* mode 11 */
1181 		NO_CL_FLAGS,
1182 		RCC8000_POLL,
1183 		RCC8000_INIT,
1184 		NO_EVENT,
1185 		RCC8000_END,
1186 		NO_MESSAGE,
1187 		RCC8000_DATA,
1188 		RCC8000_ROOTDELAY,
1189 		RCC8000_BASEDELAY,
1190 		RCC8000_ID,
1191 		RCC8000_DESCRIPTION,
1192 		RCC8000_FORMAT,
1193 		DCF_TYPE,
1194 		RCC8000_MAXUNSYNC,
1195 		RCC8000_SPEED,
1196 		RCC8000_CFLAG,
1197 		RCC8000_IFLAG,
1198 		RCC8000_OFLAG,
1199 		RCC8000_LFLAG,
1200 		RCC8000_SAMPLES,
1201 		RCC8000_KEEP
1202 	},
1203 	{                             /* mode 12 */
1204 		HOPF6021_FLAGS,
1205 		NO_POLL,
1206 		NO_INIT,
1207 		NO_EVENT,
1208 		NO_END,
1209 		NO_MESSAGE,
1210 		NO_LCLDATA,
1211 		HOPF6021_ROOTDELAY,
1212 		HOPF6021_BASEDELAY,
1213 		DCF_ID,
1214 		HOPF6021_DESCRIPTION,
1215 		HOPF6021_FORMAT,
1216 		DCF_TYPE,
1217 		HOPF6021_MAXUNSYNC,
1218 		HOPF6021_SPEED,
1219 		HOPF6021_CFLAG,
1220 		HOPF6021_IFLAG,
1221 		HOPF6021_OFLAG,
1222 		HOPF6021_LFLAG,
1223 		HOPF6021_SAMPLES,
1224 		HOPF6021_KEEP
1225 	},
1226 	{                            /* mode 13 */
1227 		COMPUTIME_FLAGS,
1228 		NO_POLL,
1229 		NO_INIT,
1230 		NO_EVENT,
1231 		NO_END,
1232 		NO_MESSAGE,
1233 		NO_LCLDATA,
1234 		COMPUTIME_ROOTDELAY,
1235 		COMPUTIME_BASEDELAY,
1236 		COMPUTIME_ID,
1237 		COMPUTIME_DESCRIPTION,
1238 		COMPUTIME_FORMAT,
1239 		COMPUTIME_TYPE,
1240 		COMPUTIME_MAXUNSYNC,
1241 		COMPUTIME_SPEED,
1242 		COMPUTIME_CFLAG,
1243 		COMPUTIME_IFLAG,
1244 		COMPUTIME_OFLAG,
1245 		COMPUTIME_LFLAG,
1246 		COMPUTIME_SAMPLES,
1247 		COMPUTIME_KEEP
1248 	},
1249 	{				/* mode 14 */
1250 		RAWDCF_FLAGS,
1251 		NO_POLL,
1252 		RAWDCFDTRSET_INIT,
1253 		NO_EVENT,
1254 		NO_END,
1255 		NO_MESSAGE,
1256 		NO_LCLDATA,
1257 		RAWDCF_ROOTDELAY,
1258 		RAWDCF_BASEDELAY,
1259 		DCF_A_ID,
1260 		RAWDCFDTRSET_DESCRIPTION,
1261 		RAWDCF_FORMAT,
1262 		DCF_TYPE,
1263 		RAWDCF_MAXUNSYNC,
1264 		RAWDCF_SPEED,
1265 		RAWDCF_CFLAG,
1266 		RAWDCF_IFLAG,
1267 		RAWDCF_OFLAG,
1268 		RAWDCF_LFLAG,
1269 		RAWDCF_SAMPLES,
1270 		RAWDCF_KEEP
1271 	},
1272 	{				/* mode 15 */
1273 		0,				/* operation flags (io modes) */
1274   		NO_POLL,			/* active poll routine */
1275 		NO_INIT,			/* active poll init routine */
1276   		NO_EVENT,		        /* special event handling (e.g. reset clock) */
1277   		NO_END,				/* active poll end routine */
1278   		NO_MESSAGE,			/* process a lower layer message */
1279 		NO_LCLDATA,			/* local data area for "poll" mechanism */
1280 		0,				/* rootdelay */
1281 		11.0 /* bits */ / 9600,		/* current offset by which the RS232
1282 				           	time code is delayed from the actual time */
1283 		DCF_ID,				/* ID code */
1284 		"WHARTON 400A Series clock",	/* device name */
1285 		"WHARTON 400A Series clock Output Format 1",	/* fixed format */
1286 			/* Must match a format-name in a libparse/clk_xxx.c file */
1287 		DCF_TYPE,			/* clock type (ntp control) */
1288 		(1*60*60),		        /* time to trust oscillator after losing synch */
1289 		B9600,				/* terminal input & output baudrate */
1290 		(CS8|CREAD|PARENB|CLOCAL|HUPCL),/* terminal control flags */
1291 		0,				/* terminal input flags */
1292 		0,				/* terminal output flags */
1293 		0,				/* terminal local flags */
1294 		5,				/* samples for median filter */
1295 		3,				/* samples for median filter to keep */
1296 	},
1297 	{				/* mode 16 - RAWDCF RTS set, DTR clr */
1298 		RAWDCF_FLAGS,
1299 		NO_POLL,
1300 		RAWDCFDTRCLRRTSSET_INIT,
1301 		NO_EVENT,
1302 		NO_END,
1303 		NO_MESSAGE,
1304 		NO_LCLDATA,
1305 		RAWDCF_ROOTDELAY,
1306 		RAWDCF_BASEDELAY,
1307 		DCF_A_ID,
1308 		RAWDCFDTRCLRRTSSET_DESCRIPTION,
1309 		RAWDCF_FORMAT,
1310 		DCF_TYPE,
1311 		RAWDCF_MAXUNSYNC,
1312 		RAWDCF_SPEED,
1313 		RAWDCF_CFLAG,
1314 		RAWDCF_IFLAG,
1315 		RAWDCF_OFLAG,
1316 		RAWDCF_LFLAG,
1317 		RAWDCF_SAMPLES,
1318 		RAWDCF_KEEP
1319 	},
1320         {                            /* mode 17 */
1321                 VARITEXT_FLAGS,
1322                 NO_POLL,
1323                 NO_INIT,
1324                 NO_EVENT,
1325                 NO_END,
1326                 NO_MESSAGE,
1327                 NO_LCLDATA,
1328                 VARITEXT_ROOTDELAY,
1329                 VARITEXT_BASEDELAY,
1330                 VARITEXT_ID,
1331                 VARITEXT_DESCRIPTION,
1332                 VARITEXT_FORMAT,
1333                 VARITEXT_TYPE,
1334                 VARITEXT_MAXUNSYNC,
1335                 VARITEXT_SPEED,
1336                 VARITEXT_CFLAG,
1337                 VARITEXT_IFLAG,
1338                 VARITEXT_OFLAG,
1339                 VARITEXT_LFLAG,
1340                 VARITEXT_SAMPLES,
1341                 VARITEXT_KEEP
1342         },
1343 	{				/* mode 18 */
1344 		MBG_FLAGS,
1345 		NO_POLL,
1346 		NO_INIT,
1347 		NO_EVENT,
1348 		GPS16X_END,
1349 		GPS16X_MESSAGE,
1350 		GPS16X_DATA,
1351 		GPS16X_ROOTDELAY,
1352 		GPS16X_BASEDELAY,
1353 		GPS16X_ID,
1354 		GPS16X_DESCRIPTION,
1355 		GPS16X_FORMAT,
1356 		GPS_TYPE,
1357 		GPS16X_MAXUNSYNC,
1358 		GPS16X_SPEED,
1359 		GPS16X_CFLAG,
1360 		GPS16X_IFLAG,
1361 		GPS16X_OFLAG,
1362 		GPS16X_LFLAG,
1363 		GPS16X_SAMPLES,
1364 		GPS16X_KEEP
1365 	},
1366 	{				/* mode 19 */
1367 		RAWDCF_FLAGS,
1368 		NO_POLL,
1369 		RAWDCF_INIT,
1370 		NO_EVENT,
1371 		NO_END,
1372 		NO_MESSAGE,
1373 		NO_LCLDATA,
1374 		RAWDCF_ROOTDELAY,
1375 		GUDE_EMC_USB_V20_BASEDELAY,
1376 		DCF_A_ID,
1377 		GUDE_EMC_USB_V20_DESCRIPTION,
1378 		RAWDCF_FORMAT,
1379 		DCF_TYPE,
1380 		RAWDCF_MAXUNSYNC,
1381 		GUDE_EMC_USB_V20_SPEED,
1382 		RAWDCF_CFLAG,
1383 		RAWDCF_IFLAG,
1384 		RAWDCF_OFLAG,
1385 		RAWDCF_LFLAG,
1386 		RAWDCF_SAMPLES,
1387 		RAWDCF_KEEP
1388 	},
1389 	{				/* mode 20, like mode 14 but driven by 75 baud */
1390 		RAWDCF_FLAGS,
1391 		NO_POLL,
1392 		RAWDCFDTRSET_INIT,
1393 		NO_EVENT,
1394 		NO_END,
1395 		NO_MESSAGE,
1396 		NO_LCLDATA,
1397 		RAWDCF_ROOTDELAY,
1398 		RAWDCF_BASEDELAY,
1399 		DCF_A_ID,
1400 		RAWDCFDTRSET75_DESCRIPTION,
1401 		RAWDCF_FORMAT,
1402 		DCF_TYPE,
1403 		RAWDCF_MAXUNSYNC,
1404 		B75,
1405 		RAWDCF_CFLAG,
1406 		RAWDCF_IFLAG,
1407 		RAWDCF_OFLAG,
1408 		RAWDCF_LFLAG,
1409 		RAWDCF_SAMPLES,
1410 		RAWDCF_KEEP
1411 	},
1412 	{				/* mode 21, like mode 16 but driven by 75 baud
1413 					 - RAWDCF RTS set, DTR clr */
1414 		RAWDCF_FLAGS,
1415 		NO_POLL,
1416 		RAWDCFDTRCLRRTSSET_INIT,
1417 		NO_EVENT,
1418 		NO_END,
1419 		NO_MESSAGE,
1420 		NO_LCLDATA,
1421 		RAWDCF_ROOTDELAY,
1422 		RAWDCF_BASEDELAY,
1423 		DCF_A_ID,
1424 		RAWDCFDTRCLRRTSSET75_DESCRIPTION,
1425 		RAWDCF_FORMAT,
1426 		DCF_TYPE,
1427 		RAWDCF_MAXUNSYNC,
1428 		B75,
1429 		RAWDCF_CFLAG,
1430 		RAWDCF_IFLAG,
1431 		RAWDCF_OFLAG,
1432 		RAWDCF_LFLAG,
1433 		RAWDCF_SAMPLES,
1434 		RAWDCF_KEEP
1435 	},
1436 	{				/* mode 22 - like 2 with POWERUP trust */
1437 		MBG_FLAGS | PARSE_F_POWERUPTRUST,
1438 		NO_POLL,
1439 		NO_INIT,
1440 		NO_EVENT,
1441 		NO_END,
1442 		NO_MESSAGE,
1443 		NO_LCLDATA,
1444 		DCFUA31_ROOTDELAY,
1445 		DCFUA31_BASEDELAY,
1446 		DCF_A_ID,
1447 		DCFUA31_DESCRIPTION,
1448 		DCFUA31_FORMAT,
1449 		DCF_TYPE,
1450 		DCFUA31_MAXUNSYNC,
1451 		DCFUA31_SPEED,
1452 		DCFUA31_CFLAG,
1453 		DCFUA31_IFLAG,
1454 		DCFUA31_OFLAG,
1455 		DCFUA31_LFLAG,
1456 		DCFUA31_SAMPLES,
1457 		DCFUA31_KEEP
1458 	},
1459 	{				/* mode 23 - like 7 with POWERUP trust */
1460 		MBG_FLAGS | PARSE_F_POWERUPTRUST,
1461 		GPS16X_POLL,
1462 		GPS16X_INIT,
1463 		NO_EVENT,
1464 		GPS16X_END,
1465 		GPS16X_MESSAGE,
1466 		GPS16X_DATA,
1467 		GPS16X_ROOTDELAY,
1468 		GPS16X_BASEDELAY,
1469 		GPS16X_ID,
1470 		GPS16X_DESCRIPTION,
1471 		GPS16X_FORMAT,
1472 		GPS_TYPE,
1473 		GPS16X_MAXUNSYNC,
1474 		GPS16X_SPEED,
1475 		GPS16X_CFLAG,
1476 		GPS16X_IFLAG,
1477 		GPS16X_OFLAG,
1478 		GPS16X_LFLAG,
1479 		GPS16X_SAMPLES,
1480 		GPS16X_KEEP
1481 	},
1482 	{				/* mode 24 */
1483 		SEL240X_FLAGS,
1484 		SEL240X_POLL,
1485 		SEL240X_INIT,
1486 		NO_EVENT,
1487 		SEL240X_END,
1488 		NO_MESSAGE,
1489 		SEL240X_DATA,
1490 		SEL240X_ROOTDELAY,
1491 		SEL240X_BASEDELAY,
1492 		SEL240X_ID,
1493 		SEL240X_DESCRIPTION,
1494 		SEL240X_FORMAT,
1495 		GPS_TYPE,
1496 		SEL240X_MAXUNSYNC,
1497 		SEL240X_SPEED,
1498 		SEL240X_CFLAG,
1499 		SEL240X_IFLAG,
1500 		SEL240X_OFLAG,
1501 		SEL240X_LFLAG,
1502 		SEL240X_SAMPLES,
1503 		SEL240X_KEEP
1504 	},
1505 };
1506 
1507 static int ncltypes = sizeof(parse_clockinfo) / sizeof(struct parse_clockinfo);
1508 
1509 #define CLK_REALTYPE(x) ((int)(((x)->ttl) & 0x7F))
1510 #define CLK_TYPE(x)	((CLK_REALTYPE(x) >= ncltypes) ? ~0 : CLK_REALTYPE(x))
1511 #define CLK_UNIT(x)	((int)REFCLOCKUNIT(&(x)->srcadr))
1512 #define CLK_PPS(x)	(((x)->ttl) & 0x80)
1513 
1514 /*
1515  * Other constant stuff
1516  */
1517 #define	PARSEHSREFID	0x7f7f08ff	/* 127.127.8.255 refid for hi strata */
1518 
1519 #define PARSESTATISTICS   (60*60)	        /* output state statistics every hour */
1520 
1521 static int notice = 0;
1522 
1523 #define PARSE_STATETIME(parse, i) ((parse->generic->currentstatus == i) ? parse->statetime[i] + current_time - parse->lastchange : parse->statetime[i])
1524 
1525 static void parse_event   (struct parseunit *, int);
1526 static void parse_process (struct parseunit *, parsetime_t *);
1527 static void clear_err     (struct parseunit *, u_long);
1528 static int  list_err      (struct parseunit *, u_long);
1529 static char * l_mktime    (u_long);
1530 
1531 /**===========================================================================
1532  ** implementation error message regression module
1533  **/
1534 static void
1535 clear_err(
1536 	struct parseunit *parse,
1537 	u_long            lstate
1538 	)
1539 {
1540 	if (lstate == ERR_ALL)
1541 	{
1542 		size_t i;
1543 
1544 		for (i = 0; i < ERR_CNT; i++)
1545 		{
1546 			parse->errors[i].err_stage   = err_tbl[i];
1547 			parse->errors[i].err_cnt     = 0;
1548 			parse->errors[i].err_last    = 0;
1549 			parse->errors[i].err_started = 0;
1550 			parse->errors[i].err_suppressed = 0;
1551 		}
1552 	}
1553 	else
1554 	{
1555 		parse->errors[lstate].err_stage   = err_tbl[lstate];
1556 		parse->errors[lstate].err_cnt     = 0;
1557 		parse->errors[lstate].err_last    = 0;
1558 		parse->errors[lstate].err_started = 0;
1559 		parse->errors[lstate].err_suppressed = 0;
1560 	}
1561 }
1562 
1563 static int
1564 list_err(
1565 	struct parseunit *parse,
1566 	u_long            lstate
1567 	)
1568 {
1569 	int do_it;
1570 	struct errorinfo *err = &parse->errors[lstate];
1571 
1572 	if (err->err_started == 0)
1573 	{
1574 		err->err_started = current_time;
1575 	}
1576 
1577 	do_it = (current_time - err->err_last) >= err->err_stage->err_delay;
1578 
1579 	if (do_it)
1580 	    err->err_cnt++;
1581 
1582 	if (err->err_stage->err_count &&
1583 	    (err->err_cnt >= err->err_stage->err_count))
1584 	{
1585 		err->err_stage++;
1586 		err->err_cnt = 0;
1587 	}
1588 
1589 	if (!err->err_cnt && do_it)
1590 	    msyslog(LOG_INFO, "PARSE receiver #%d: interval for following error message class is at least %s",
1591 		    CLK_UNIT(parse->peer), l_mktime(err->err_stage->err_delay));
1592 
1593 	if (!do_it)
1594 	    err->err_suppressed++;
1595 	else
1596 	    err->err_last = current_time;
1597 
1598 	if (do_it && err->err_suppressed)
1599 	{
1600 		msyslog(LOG_INFO, "PARSE receiver #%d: %ld message%s suppressed, error condition class persists for %s",
1601 			CLK_UNIT(parse->peer), err->err_suppressed, (err->err_suppressed == 1) ? " was" : "s where",
1602 			l_mktime(current_time - err->err_started));
1603 		err->err_suppressed = 0;
1604 	}
1605 
1606 	return do_it;
1607 }
1608 
1609 /*--------------------------------------------------
1610  * mkreadable - make a printable ascii string (without
1611  * embedded quotes so that the ntpq protocol isn't
1612  * fooled
1613  */
1614 #ifndef isprint
1615 #define isprint(_X_) (((_X_) > 0x1F) && ((_X_) < 0x7F))
1616 #endif
1617 
1618 static char *
1619 mkreadable(
1620 	char  *buffer,
1621 	long  blen,
1622 	const char  *src,
1623 	u_long  srclen,
1624 	int hex
1625 	)
1626 {
1627 	static const char ellipsis[] = "...";
1628 	char *b    = buffer;
1629 	char *endb = NULL;
1630 
1631 	if (blen < 4)
1632 		return NULL;		/* don't bother with mini buffers */
1633 
1634 	endb = buffer + blen - sizeof(ellipsis);
1635 
1636 	blen--;			/* account for '\0' */
1637 
1638 	while (blen && srclen--)
1639 	{
1640 		if (!hex &&             /* no binary only */
1641 		    (*src != '\\') &&   /* no plain \ */
1642 		    (*src != '"') &&    /* no " */
1643 		    isprint((unsigned char)*src))	/* only printables */
1644 		{			/* they are easy... */
1645 			*buffer++ = *src++;
1646 			blen--;
1647 		}
1648 		else
1649 		{
1650 			if (blen < 4)
1651 			{
1652 				while (blen--)
1653 				{
1654 					*buffer++ = '.';
1655 				}
1656 				*buffer = '\0';
1657 				return b;
1658 			}
1659 			else
1660 			{
1661 				if (*src == '\\')
1662 				{
1663 					memcpy(buffer, "\\\\", 2);
1664 					buffer += 2;
1665 					blen   -= 2;
1666 					src++;
1667 				}
1668 				else
1669 				{
1670 					snprintf(buffer, blen, "\\x%02x", *src++);
1671 					blen   -= 4;
1672 					buffer += 4;
1673 				}
1674 			}
1675 		}
1676 		if (srclen && !blen && endb) /* overflow - set last chars to ... */
1677 			memcpy(endb, ellipsis, sizeof(ellipsis));
1678 	}
1679 
1680 	*buffer = '\0';
1681 	return b;
1682 }
1683 
1684 
1685 /*--------------------------------------------------
1686  * mkascii - make a printable ascii string
1687  * assumes (unless defined better) 7-bit ASCII
1688  */
1689 static char *
1690 mkascii(
1691 	char  *buffer,
1692 	long  blen,
1693 	const char  *src,
1694 	u_long  srclen
1695 	)
1696 {
1697 	return mkreadable(buffer, blen, src, srclen, 0);
1698 }
1699 
1700 /**===========================================================================
1701  ** implementation of i/o handling methods
1702  ** (all STREAM, partial STREAM, user level)
1703  **/
1704 
1705 /*
1706  * define possible io handling methods
1707  */
1708 #ifdef STREAM
1709 static int  ppsclock_init   (struct parseunit *);
1710 static int  stream_init     (struct parseunit *);
1711 static void stream_end      (struct parseunit *);
1712 static int  stream_enable   (struct parseunit *);
1713 static int  stream_disable  (struct parseunit *);
1714 static int  stream_setcs    (struct parseunit *, parsectl_t *);
1715 static int  stream_getfmt   (struct parseunit *, parsectl_t *);
1716 static int  stream_setfmt   (struct parseunit *, parsectl_t *);
1717 static int  stream_timecode (struct parseunit *, parsectl_t *);
1718 static void stream_receive  (struct recvbuf *);
1719 #endif
1720 
1721 static int  local_init     (struct parseunit *);
1722 static void local_end      (struct parseunit *);
1723 static int  local_nop      (struct parseunit *);
1724 static int  local_setcs    (struct parseunit *, parsectl_t *);
1725 static int  local_getfmt   (struct parseunit *, parsectl_t *);
1726 static int  local_setfmt   (struct parseunit *, parsectl_t *);
1727 static int  local_timecode (struct parseunit *, parsectl_t *);
1728 static void local_receive  (struct recvbuf *);
1729 static int  local_input    (struct recvbuf *);
1730 
1731 static bind_t io_bindings[] =
1732 {
1733 #ifdef STREAM
1734 	{
1735 		"parse STREAM",
1736 		stream_init,
1737 		stream_end,
1738 		stream_setcs,
1739 		stream_disable,
1740 		stream_enable,
1741 		stream_getfmt,
1742 		stream_setfmt,
1743 		stream_timecode,
1744 		stream_receive,
1745 		0,
1746 	},
1747 	{
1748 		"ppsclock STREAM",
1749 		ppsclock_init,
1750 		local_end,
1751 		local_setcs,
1752 		local_nop,
1753 		local_nop,
1754 		local_getfmt,
1755 		local_setfmt,
1756 		local_timecode,
1757 		local_receive,
1758 		local_input,
1759 	},
1760 #endif
1761 	{
1762 		"normal",
1763 		local_init,
1764 		local_end,
1765 		local_setcs,
1766 		local_nop,
1767 		local_nop,
1768 		local_getfmt,
1769 		local_setfmt,
1770 		local_timecode,
1771 		local_receive,
1772 		local_input,
1773 	},
1774 	{
1775 		(char *)0,
1776 		NULL,
1777 		NULL,
1778 		NULL,
1779 		NULL,
1780 		NULL,
1781 		NULL,
1782 		NULL,
1783 		NULL,
1784 		NULL,
1785 		NULL,
1786 	}
1787 };
1788 
1789 #ifdef STREAM
1790 
1791 /*--------------------------------------------------
1792  * ppsclock STREAM init
1793  */
1794 static int
1795 ppsclock_init(
1796 	struct parseunit *parse
1797 	)
1798 {
1799         static char m1[] = "ppsclocd";
1800 	static char m2[] = "ppsclock";
1801 
1802 	/*
1803 	 * now push the parse streams module
1804 	 * it will ensure exclusive access to the device
1805 	 */
1806 	if (ioctl(parse->ppsfd, I_PUSH, (caddr_t)m1) == -1 &&
1807 	    ioctl(parse->ppsfd, I_PUSH, (caddr_t)m2) == -1)
1808 	{
1809 		if (errno != EINVAL)
1810 		{
1811 			msyslog(LOG_ERR, "PARSE receiver #%d: ppsclock_init: ioctl(fd, I_PUSH, \"ppsclock\"): %m",
1812 				CLK_UNIT(parse->peer));
1813 		}
1814 		return 0;
1815 	}
1816 	if (!local_init(parse))
1817 	{
1818 		(void)ioctl(parse->ppsfd, I_POP, (caddr_t)0);
1819 		return 0;
1820 	}
1821 
1822 	parse->flags |= PARSE_PPSCLOCK;
1823 	return 1;
1824 }
1825 
1826 /*--------------------------------------------------
1827  * parse STREAM init
1828  */
1829 static int
1830 stream_init(
1831 	struct parseunit *parse
1832 	)
1833 {
1834 	static char m1[] = "parse";
1835 	/*
1836 	 * now push the parse streams module
1837 	 * to test whether it is there (neat interface 8-( )
1838 	 */
1839 	if (ioctl(parse->generic->io.fd, I_PUSH, (caddr_t)m1) == -1)
1840 	{
1841 		if (errno != EINVAL) /* accept non-existence */
1842 		{
1843 			msyslog(LOG_ERR, "PARSE receiver #%d: stream_init: ioctl(fd, I_PUSH, \"parse\"): %m", CLK_UNIT(parse->peer));
1844 		}
1845 		return 0;
1846 	}
1847 	else
1848 	{
1849 		while(ioctl(parse->generic->io.fd, I_POP, (caddr_t)0) == 0)
1850 		    /* empty loop */;
1851 
1852 		/*
1853 		 * now push it a second time after we have removed all
1854 		 * module garbage
1855 		 */
1856 		if (ioctl(parse->generic->io.fd, I_PUSH, (caddr_t)m1) == -1)
1857 		{
1858 			msyslog(LOG_ERR, "PARSE receiver #%d: stream_init: ioctl(fd, I_PUSH, \"parse\"): %m", CLK_UNIT(parse->peer));
1859 			return 0;
1860 		}
1861 		else
1862 		{
1863 			return 1;
1864 		}
1865 	}
1866 }
1867 
1868 /*--------------------------------------------------
1869  * parse STREAM end
1870  */
1871 static void
1872 stream_end(
1873 	struct parseunit *parse
1874 	)
1875 {
1876 	while(ioctl(parse->generic->io.fd, I_POP, (caddr_t)0) == 0)
1877 	    /* empty loop */;
1878 }
1879 
1880 /*--------------------------------------------------
1881  * STREAM setcs
1882  */
1883 static int
1884 stream_setcs(
1885 	struct parseunit *parse,
1886 	parsectl_t  *tcl
1887 	)
1888 {
1889 	struct strioctl strioc;
1890 
1891 	strioc.ic_cmd     = PARSEIOC_SETCS;
1892 	strioc.ic_timout  = 0;
1893 	strioc.ic_dp      = (char *)tcl;
1894 	strioc.ic_len     = sizeof (*tcl);
1895 
1896 	if (ioctl(parse->generic->io.fd, I_STR, (caddr_t)&strioc) == -1)
1897 	{
1898 		msyslog(LOG_ERR, "PARSE receiver #%d: stream_setcs: ioctl(fd, I_STR, PARSEIOC_SETCS): %m", CLK_UNIT(parse->peer));
1899 		return 0;
1900 	}
1901 	return 1;
1902 }
1903 
1904 /*--------------------------------------------------
1905  * STREAM enable
1906  */
1907 static int
1908 stream_enable(
1909 	struct parseunit *parse
1910 	)
1911 {
1912 	struct strioctl strioc;
1913 
1914 	strioc.ic_cmd     = PARSEIOC_ENABLE;
1915 	strioc.ic_timout  = 0;
1916 	strioc.ic_dp      = (char *)0;
1917 	strioc.ic_len     = 0;
1918 
1919 	if (ioctl(parse->generic->io.fd, I_STR, (caddr_t)&strioc) == -1)
1920 	{
1921 		msyslog(LOG_ERR, "PARSE receiver #%d: stream_enable: ioctl(fd, I_STR, PARSEIOC_ENABLE): %m", CLK_UNIT(parse->peer));
1922 		return 0;
1923 	}
1924 	parse->generic->io.clock_recv = stream_receive; /* ok - parse input in kernel */
1925 	return 1;
1926 }
1927 
1928 /*--------------------------------------------------
1929  * STREAM disable
1930  */
1931 static int
1932 stream_disable(
1933 	struct parseunit *parse
1934 	)
1935 {
1936 	struct strioctl strioc;
1937 
1938 	strioc.ic_cmd     = PARSEIOC_DISABLE;
1939 	strioc.ic_timout  = 0;
1940 	strioc.ic_dp      = (char *)0;
1941 	strioc.ic_len     = 0;
1942 
1943 	if (ioctl(parse->generic->io.fd, I_STR, (caddr_t)&strioc) == -1)
1944 	{
1945 		msyslog(LOG_ERR, "PARSE receiver #%d: stream_disable: ioctl(fd, I_STR, PARSEIOC_DISABLE): %m", CLK_UNIT(parse->peer));
1946 		return 0;
1947 	}
1948 	parse->generic->io.clock_recv = local_receive; /* ok - parse input in daemon */
1949 	return 1;
1950 }
1951 
1952 /*--------------------------------------------------
1953  * STREAM getfmt
1954  */
1955 static int
1956 stream_getfmt(
1957 	struct parseunit *parse,
1958 	parsectl_t  *tcl
1959 	)
1960 {
1961 	struct strioctl strioc;
1962 
1963 	strioc.ic_cmd     = PARSEIOC_GETFMT;
1964 	strioc.ic_timout  = 0;
1965 	strioc.ic_dp      = (char *)tcl;
1966 	strioc.ic_len     = sizeof (*tcl);
1967 	if (ioctl(parse->generic->io.fd, I_STR, (caddr_t)&strioc) == -1)
1968 	{
1969 		msyslog(LOG_ERR, "PARSE receiver #%d: ioctl(fd, I_STR, PARSEIOC_GETFMT): %m", CLK_UNIT(parse->peer));
1970 		return 0;
1971 	}
1972 	return 1;
1973 }
1974 
1975 /*--------------------------------------------------
1976  * STREAM setfmt
1977  */
1978 static int
1979 stream_setfmt(
1980 	struct parseunit *parse,
1981 	parsectl_t  *tcl
1982 	)
1983 {
1984 	struct strioctl strioc;
1985 
1986 	strioc.ic_cmd     = PARSEIOC_SETFMT;
1987 	strioc.ic_timout  = 0;
1988 	strioc.ic_dp      = (char *)tcl;
1989 	strioc.ic_len     = sizeof (*tcl);
1990 
1991 	if (ioctl(parse->generic->io.fd, I_STR, (caddr_t)&strioc) == -1)
1992 	{
1993 		msyslog(LOG_ERR, "PARSE receiver #%d: stream_setfmt: ioctl(fd, I_STR, PARSEIOC_SETFMT): %m", CLK_UNIT(parse->peer));
1994 		return 0;
1995 	}
1996 	return 1;
1997 }
1998 
1999 
2000 /*--------------------------------------------------
2001  * STREAM timecode
2002  */
2003 static int
2004 stream_timecode(
2005 	struct parseunit *parse,
2006 	parsectl_t  *tcl
2007 	)
2008 {
2009 	struct strioctl strioc;
2010 
2011 	strioc.ic_cmd     = PARSEIOC_TIMECODE;
2012 	strioc.ic_timout  = 0;
2013 	strioc.ic_dp      = (char *)tcl;
2014 	strioc.ic_len     = sizeof (*tcl);
2015 
2016 	if (ioctl(parse->generic->io.fd, I_STR, (caddr_t)&strioc) == -1)
2017 	{
2018 		ERR(ERR_INTERNAL)
2019 			msyslog(LOG_ERR, "PARSE receiver #%d: stream_timecode: ioctl(fd, I_STR, PARSEIOC_TIMECODE): %m", CLK_UNIT(parse->peer));
2020 		return 0;
2021 	}
2022 	clear_err(parse, ERR_INTERNAL);
2023 	return 1;
2024 }
2025 
2026 /*--------------------------------------------------
2027  * STREAM receive
2028  */
2029 static void
2030 stream_receive(
2031 	struct recvbuf *rbufp
2032 	)
2033 {
2034 	struct parseunit * parse;
2035 	parsetime_t parsetime;
2036 
2037 	parse = (struct parseunit *)rbufp->recv_peer->procptr->unitptr;
2038 	if (!parse->peer)
2039 	    return;
2040 
2041 	if (rbufp->recv_length != sizeof(parsetime_t))
2042 	{
2043 		ERR(ERR_BADIO)
2044 			msyslog(LOG_ERR,"PARSE receiver #%d: stream_receive: bad size (got %d expected %d)",
2045 				CLK_UNIT(parse->peer), rbufp->recv_length, (int)sizeof(parsetime_t));
2046 		parse_event(parse, CEVNT_BADREPLY);
2047 		return;
2048 	}
2049 	clear_err(parse, ERR_BADIO);
2050 
2051 	memmove((caddr_t)&parsetime,
2052 		(caddr_t)rbufp->recv_buffer,
2053 		sizeof(parsetime_t));
2054 
2055 #ifdef DEBUG
2056 	if (debug > 3)
2057 	  {
2058 	    printf("PARSE receiver #%d: status %06x, state %08x, time %lx.%08lx, stime %lx.%08lx, ptime %lx.%08lx\n",
2059 		   CLK_UNIT(parse->peer),
2060 		   (unsigned int)parsetime.parse_status,
2061 		   (unsigned int)parsetime.parse_state,
2062 		   (unsigned long)parsetime.parse_time.tv.tv_sec,
2063 		   (unsigned long)parsetime.parse_time.tv.tv_usec,
2064 		   (unsigned long)parsetime.parse_stime.tv.tv_sec,
2065 		   (unsigned long)parsetime.parse_stime.tv.tv_usec,
2066 		   (unsigned long)parsetime.parse_ptime.tv.tv_sec,
2067 		   (unsigned long)parsetime.parse_ptime.tv.tv_usec);
2068 	  }
2069 #endif
2070 
2071 	/*
2072 	 * switch time stamp world - be sure to normalize small usec field
2073 	 * errors.
2074 	 */
2075 
2076 	parsetime.parse_stime.fp = tval_stamp_to_lfp(parsetime.parse_stime.tv);
2077 
2078 	if (PARSE_TIMECODE(parsetime.parse_state))
2079 	{
2080 		parsetime.parse_time.fp = tval_stamp_to_lfp(parsetime.parse_time.tv);
2081 	}
2082 
2083 	if (PARSE_PPS(parsetime.parse_state))
2084 	{
2085 		parsetime.parse_ptime.fp = tval_stamp_to_lfp(parsetime.parse_ptime.tv);
2086 	}
2087 
2088 	parse_process(parse, &parsetime);
2089 }
2090 #endif
2091 
2092 /*--------------------------------------------------
2093  * local init
2094  */
2095 static int
2096 local_init(
2097 	struct parseunit *parse
2098 	)
2099 {
2100 	return parse_ioinit(&parse->parseio);
2101 }
2102 
2103 /*--------------------------------------------------
2104  * local end
2105  */
2106 static void
2107 local_end(
2108 	struct parseunit *parse
2109 	)
2110 {
2111 	parse_ioend(&parse->parseio);
2112 }
2113 
2114 
2115 /*--------------------------------------------------
2116  * local nop
2117  */
2118 static int
2119 local_nop(
2120 	struct parseunit *parse
2121 	)
2122 {
2123 	return 1;
2124 }
2125 
2126 /*--------------------------------------------------
2127  * local setcs
2128  */
2129 static int
2130 local_setcs(
2131 	struct parseunit *parse,
2132 	parsectl_t  *tcl
2133 	)
2134 {
2135 	return parse_setcs(tcl, &parse->parseio);
2136 }
2137 
2138 /*--------------------------------------------------
2139  * local getfmt
2140  */
2141 static int
2142 local_getfmt(
2143 	struct parseunit *parse,
2144 	parsectl_t  *tcl
2145 	)
2146 {
2147 	return parse_getfmt(tcl, &parse->parseio);
2148 }
2149 
2150 /*--------------------------------------------------
2151  * local setfmt
2152  */
2153 static int
2154 local_setfmt(
2155 	struct parseunit *parse,
2156 	parsectl_t  *tcl
2157 	)
2158 {
2159 	return parse_setfmt(tcl, &parse->parseio);
2160 }
2161 
2162 /*--------------------------------------------------
2163  * local timecode
2164  */
2165 static int
2166 local_timecode(
2167 	struct parseunit *parse,
2168 	parsectl_t  *tcl
2169 	)
2170 {
2171 	return parse_timecode(tcl, &parse->parseio);
2172 }
2173 
2174 
2175 /*--------------------------------------------------
2176  * local input
2177  */
2178 static int
2179 local_input(
2180 	struct recvbuf *rbufp
2181 	)
2182 {
2183 	struct parseunit * parse;
2184 
2185 	int count;
2186 	unsigned char *s;
2187 	timestamp_t ts;
2188 
2189 	parse = (struct parseunit *)rbufp->recv_peer->procptr->unitptr;
2190 	if (!parse->peer)
2191 		return 0;
2192 
2193 	/*
2194 	 * eat all characters, parsing then and feeding complete samples
2195 	 */
2196 	count = rbufp->recv_length;
2197 	s = (unsigned char *)rbufp->recv_buffer;
2198 	ts.fp = rbufp->recv_time;
2199 
2200 	while (count--)
2201 	{
2202 		if (parse_ioread(&parse->parseio, (unsigned int)(*s++), &ts))
2203 		{
2204 			struct recvbuf *buf;
2205 
2206 			/*
2207 			 * got something good to eat
2208 			 */
2209 			if (!PARSE_PPS(parse->parseio.parse_dtime.parse_state))
2210 			{
2211 #ifdef HAVE_PPSAPI
2212 				if (parse->flags & PARSE_PPSCLOCK)
2213 				{
2214 					struct timespec pps_timeout;
2215 					pps_info_t      pps_info;
2216 
2217 					pps_timeout.tv_sec  = 0;
2218 					pps_timeout.tv_nsec = 0;
2219 
2220 					if (time_pps_fetch(parse->atom.handle, PPS_TSFMT_TSPEC, &pps_info,
2221 							   &pps_timeout) == 0)
2222 					{
2223 						if (pps_info.assert_sequence + pps_info.clear_sequence != parse->ppsserial)
2224 						{
2225 							double dtemp;
2226 
2227 						        struct timespec pts;
2228 							/*
2229 							 * add PPS time stamp if available via ppsclock module
2230 							 * and not supplied already.
2231 							 */
2232 							if (parse->flags & PARSE_CLEAR)
2233 							  pts = pps_info.clear_timestamp;
2234 							else
2235 							  pts = pps_info.assert_timestamp;
2236 
2237 							parse->parseio.parse_dtime.parse_ptime.fp.l_ui = pts.tv_sec + JAN_1970;
2238 
2239 							dtemp = pts.tv_nsec / 1e9;
2240 							if (dtemp < 0.) {
2241 								dtemp += 1;
2242 								parse->parseio.parse_dtime.parse_ptime.fp.l_ui--;
2243 							}
2244 							if (dtemp > 1.) {
2245 								dtemp -= 1;
2246 								parse->parseio.parse_dtime.parse_ptime.fp.l_ui++;
2247 							}
2248 							parse->parseio.parse_dtime.parse_ptime.fp.l_uf = dtemp * FRAC;
2249 
2250 						        parse->parseio.parse_dtime.parse_state |= PARSEB_PPS|PARSEB_S_PPS;
2251 #ifdef DEBUG
2252 							if (debug > 3)
2253 							{
2254 								printf(
2255 								       "parse: local_receive: fd %d PPSAPI seq %ld - PPS %s\n",
2256 								       rbufp->fd,
2257 								       (long)pps_info.assert_sequence + (long)pps_info.clear_sequence,
2258 								       lfptoa(&parse->parseio.parse_dtime.parse_ptime.fp, 6));
2259 							}
2260 #endif
2261 						}
2262 #ifdef DEBUG
2263 						else
2264 						{
2265 							if (debug > 3)
2266 							{
2267 								printf(
2268 								       "parse: local_receive: fd %d PPSAPI seq assert %ld, seq clear %ld - NO PPS event\n",
2269 								       rbufp->fd,
2270 								       (long)pps_info.assert_sequence, (long)pps_info.clear_sequence);
2271 							}
2272 						}
2273 #endif
2274 						parse->ppsserial = pps_info.assert_sequence + pps_info.clear_sequence;
2275 					}
2276 #ifdef DEBUG
2277 					else
2278 					{
2279 						if (debug > 3)
2280 						{
2281 							printf(
2282 							       "parse: local_receive: fd %d PPSAPI time_pps_fetch errno = %d\n",
2283 							       rbufp->fd,
2284 							       errno);
2285 						}
2286 					}
2287 #endif
2288 				}
2289 #else
2290 #ifdef TIOCDCDTIMESTAMP
2291 				struct timeval dcd_time;
2292 
2293 				if (ioctl(parse->ppsfd, TIOCDCDTIMESTAMP, &dcd_time) != -1)
2294 				{
2295 					l_fp tstmp;
2296 
2297 					TVTOTS(&dcd_time, &tstmp);
2298 					tstmp.l_ui += JAN_1970;
2299 					L_SUB(&ts.fp, &tstmp);
2300 					if (ts.fp.l_ui == 0)
2301 					{
2302 #ifdef DEBUG
2303 						if (debug)
2304 						{
2305 							printf(
2306 							       "parse: local_receive: fd %d DCDTIMESTAMP %s\n",
2307 							       parse->ppsfd,
2308 							       lfptoa(&tstmp, 6));
2309 							printf(" sigio %s\n",
2310 							       lfptoa(&ts.fp, 6));
2311 						}
2312 #endif
2313 						parse->parseio.parse_dtime.parse_ptime.fp = tstmp;
2314 						parse->parseio.parse_dtime.parse_state |= PARSEB_PPS|PARSEB_S_PPS;
2315 					}
2316 				}
2317 #else /* TIOCDCDTIMESTAMP */
2318 #if defined(HAVE_STRUCT_PPSCLOCKEV) && (defined(HAVE_CIOGETEV) || defined(HAVE_TIOCGPPSEV))
2319 				if (parse->flags & PARSE_PPSCLOCK)
2320 				  {
2321 				    l_fp tts;
2322 				    struct ppsclockev ev;
2323 
2324 #ifdef HAVE_CIOGETEV
2325 				    if (ioctl(parse->ppsfd, CIOGETEV, (caddr_t)&ev) == 0)
2326 #endif
2327 #ifdef HAVE_TIOCGPPSEV
2328 				    if (ioctl(parse->ppsfd, TIOCGPPSEV, (caddr_t)&ev) == 0)
2329 #endif
2330 					{
2331 					  if (ev.serial != parse->ppsserial)
2332 					    {
2333 					      /*
2334 					       * add PPS time stamp if available via ppsclock module
2335 					       * and not supplied already.
2336 					       */
2337 					      if (!buftvtots((const char *)&ev.tv, &tts))
2338 						{
2339 						  ERR(ERR_BADDATA)
2340 						    msyslog(LOG_ERR,"parse: local_receive: timestamp conversion error (buftvtots) (ppsclockev.tv)");
2341 						}
2342 					      else
2343 						{
2344 						  parse->parseio.parse_dtime.parse_ptime.fp = tts;
2345 						  parse->parseio.parse_dtime.parse_state |= PARSEB_PPS|PARSEB_S_PPS;
2346 						}
2347 					    }
2348 					  parse->ppsserial = ev.serial;
2349 					}
2350 				  }
2351 #endif
2352 #endif /* TIOCDCDTIMESTAMP */
2353 #endif /* !HAVE_PPSAPI */
2354 			}
2355 			if (count)
2356 			{	/* simulate receive */
2357 				buf = get_free_recv_buffer();
2358 				if (buf != NULL) {
2359 					memmove((caddr_t)buf->recv_buffer,
2360 						(caddr_t)&parse->parseio.parse_dtime,
2361 						sizeof(parsetime_t));
2362 					buf->recv_length  = sizeof(parsetime_t);
2363 					buf->recv_time    = rbufp->recv_time;
2364 #ifndef HAVE_IO_COMPLETION_PORT
2365 					buf->srcadr       = rbufp->srcadr;
2366 #endif
2367 					buf->dstadr       = rbufp->dstadr;
2368 					buf->receiver     = rbufp->receiver;
2369 					buf->fd           = rbufp->fd;
2370 					buf->X_from_where = rbufp->X_from_where;
2371 					parse->generic->io.recvcount++;
2372 					packets_received++;
2373 					add_full_recv_buffer(buf);
2374 #ifdef HAVE_IO_COMPLETION_PORT
2375 					SetEvent(WaitableIoEventHandle);
2376 #endif
2377 				}
2378 				parse_iodone(&parse->parseio);
2379 			}
2380 			else
2381 			{
2382 				memmove((caddr_t)rbufp->recv_buffer,
2383 					(caddr_t)&parse->parseio.parse_dtime,
2384 					sizeof(parsetime_t));
2385 				parse_iodone(&parse->parseio);
2386 				rbufp->recv_length = sizeof(parsetime_t);
2387 				return 1; /* got something & in place return */
2388 			}
2389 		}
2390 	}
2391 	return 0;		/* nothing to pass up */
2392 }
2393 
2394 /*--------------------------------------------------
2395  * local receive
2396  */
2397 static void
2398 local_receive(
2399 	struct recvbuf *rbufp
2400 	)
2401 {
2402 	struct parseunit * parse;
2403 	parsetime_t parsetime;
2404 
2405 	parse = (struct parseunit *)rbufp->recv_peer->procptr->unitptr;
2406 	if (!parse->peer)
2407 	    return;
2408 
2409 	if (rbufp->recv_length != sizeof(parsetime_t))
2410 	{
2411 		ERR(ERR_BADIO)
2412 			msyslog(LOG_ERR,"PARSE receiver #%d: local_receive: bad size (got %d expected %d)",
2413 				CLK_UNIT(parse->peer), rbufp->recv_length, (int)sizeof(parsetime_t));
2414 		parse_event(parse, CEVNT_BADREPLY);
2415 		return;
2416 	}
2417 	clear_err(parse, ERR_BADIO);
2418 
2419 	memmove((caddr_t)&parsetime,
2420 		(caddr_t)rbufp->recv_buffer,
2421 		sizeof(parsetime_t));
2422 
2423 #ifdef DEBUG
2424 	if (debug > 3)
2425 	  {
2426 	    printf("PARSE receiver #%d: status %06x, state %08x, time(fp) %lx.%08lx, stime(fp) %lx.%08lx, ptime(fp) %lx.%08lx\n",
2427 		   CLK_UNIT(parse->peer),
2428 		   (unsigned int)parsetime.parse_status,
2429 		   (unsigned int)parsetime.parse_state,
2430 		   (unsigned long)parsetime.parse_time.fp.l_ui,
2431 		   (unsigned long)parsetime.parse_time.fp.l_uf,
2432 		   (unsigned long)parsetime.parse_stime.fp.l_ui,
2433 		   (unsigned long)parsetime.parse_stime.fp.l_uf,
2434 		   (unsigned long)parsetime.parse_ptime.fp.l_ui,
2435 		   (unsigned long)parsetime.parse_ptime.fp.l_uf);
2436 	  }
2437 #endif
2438 
2439 	parse_process(parse, &parsetime);
2440 }
2441 
2442 /*--------------------------------------------------
2443  * init_iobinding - find and initialize lower layers
2444  */
2445 static bind_t *
2446 init_iobinding(
2447 	struct parseunit *parse
2448 	)
2449 {
2450   bind_t *b = io_bindings;
2451 
2452 	while (b->bd_description != (char *)0)
2453 	{
2454 		if ((*b->bd_init)(parse))
2455 		{
2456 			return b;
2457 		}
2458 		b++;
2459 	}
2460 	return (bind_t *)0;
2461 }
2462 
2463 /**===========================================================================
2464  ** support routines
2465  **/
2466 
2467 static char *
2468 ap(char *buffer, size_t len, char *pos, const char *fmt, ...)
2469 {
2470 	va_list va;
2471 	int l;
2472 	size_t rem = len - (pos - buffer);
2473 
2474 	if (rem == 0)
2475 		return pos;
2476 
2477 	va_start(va, fmt);
2478 	l = vsnprintf(pos, rem, fmt, va);
2479 	va_end(va);
2480 
2481 	if (l != -1) {
2482 		rem--;
2483 		if (rem >= (size_t)l)
2484 			pos += l;
2485 		else
2486 			pos += rem;
2487 	}
2488 
2489 	return pos;
2490 }
2491 
2492 /*--------------------------------------------------
2493  * convert a flag field to a string
2494  */
2495 static char *
2496 parsestate(
2497 	u_long lstate,
2498 	char *buffer,
2499 	int size
2500 	)
2501 {
2502 	static struct bits
2503 	{
2504 		u_long      bit;
2505 		const char *name;
2506 	} flagstrings[] =
2507 	  {
2508 		  { PARSEB_ANNOUNCE,   "DST SWITCH WARNING" },
2509 		  { PARSEB_POWERUP,    "NOT SYNCHRONIZED" },
2510 		  { PARSEB_NOSYNC,     "TIME CODE NOT CONFIRMED" },
2511 		  { PARSEB_DST,        "DST" },
2512 		  { PARSEB_UTC,        "UTC DISPLAY" },
2513 		  { PARSEB_LEAPADD,    "LEAP ADD WARNING" },
2514 		  { PARSEB_LEAPDEL,    "LEAP DELETE WARNING" },
2515 		  { PARSEB_LEAPSECOND, "LEAP SECOND" },
2516 		  { PARSEB_ALTERNATE,  "ALTERNATE ANTENNA" },
2517 		  { PARSEB_TIMECODE,   "TIME CODE" },
2518 		  { PARSEB_PPS,        "PPS" },
2519 		  { PARSEB_POSITION,   "POSITION" },
2520 		  { 0,		       NULL }
2521 	  };
2522 
2523 	static struct sbits
2524 	{
2525 		u_long      bit;
2526 		const char *name;
2527 	} sflagstrings[] =
2528 	  {
2529 		  { PARSEB_S_LEAP,     "LEAP INDICATION" },
2530 		  { PARSEB_S_PPS,      "PPS SIGNAL" },
2531 		  { PARSEB_S_ANTENNA,  "ANTENNA" },
2532 		  { PARSEB_S_POSITION, "POSITION" },
2533 		  { 0,		       NULL }
2534 	  };
2535 	int i;
2536 	char *s, *t;
2537 
2538 	s = t = buffer;
2539 
2540 	i = 0;
2541 	while (flagstrings[i].bit)
2542 	{
2543 		if (flagstrings[i].bit & lstate)
2544 		{
2545 			if (s != t)
2546 <<<<<<< refclock_parse.c
2547 				t = ap(buffer, size, t, "; ");
2548 			t = ap(buffer, size, t, "%s", flagstrings[i].name);
2549 =======
2550 				strlcpy(t, "; ", BUFFER_SIZES(buffer, t, size));
2551 			if (strlcat(t, flagstrings[i].name, BUFFER_SIZES(buffer, t, size)) <
2552 			    BUFFER_SIZES(buffer, t, size))
2553 				t += strlen(t);
2554 >>>>>>> 1.1.1.3
2555 		}
2556 		i++;
2557 	}
2558 
2559 	if (lstate & (PARSEB_S_LEAP|PARSEB_S_ANTENNA|PARSEB_S_PPS|PARSEB_S_POSITION))
2560 	{
2561 <<<<<<< refclock_parse.c
2562 		if (s != t)
2563 			t = ap(buffer, size, t, "; ");
2564 
2565 		t = ap(buffer, size, t, "(");
2566 =======
2567 		if (s != t &&
2568 		    strlcpy(t, "; ", BUFFER_SIZES(buffer, t, size)) <
2569 		    BUFFER_SIZES(buffer, t, size))
2570 			t += strlen(t);
2571 >>>>>>> 1.1.1.3
2572 
2573 <<<<<<< refclock_parse.c
2574 		s = t;
2575 =======
2576 		if (strlcpy(t, "(", BUFFER_SIZES(buffer, t, size)) <
2577 		    BUFFER_SIZES(buffer, t, size))
2578 			s = t = t + strlen(t);
2579 >>>>>>> 1.1.1.3
2580 
2581 		i = 0;
2582 		while (sflagstrings[i].bit)
2583 		{
2584 			if (sflagstrings[i].bit & lstate)
2585 			{
2586 <<<<<<< refclock_parse.c
2587 				if (t != s)
2588 				{
2589 					t = ap(buffer, size, t, "; ");
2590 				}
2591 =======
2592 				if (t != s &&
2593 				    strlcpy(t, "; ", BUFFER_SIZES(buffer, t, size)) <
2594 				    BUFFER_SIZES(buffer, t, size))
2595 					t += 2;
2596 >>>>>>> 1.1.1.3
2597 
2598 <<<<<<< refclock_parse.c
2599 				t = ap(buffer, size, t, "%s",
2600 				    sflagstrings[i].name);
2601 =======
2602 				if (strlcpy(t, sflagstrings[i].name, BUFFER_SIZES(buffer, t, size)) <
2603 				    BUFFER_SIZES(buffer, t, size))
2604 					t += strlen(t);
2605 >>>>>>> 1.1.1.3
2606 			}
2607 			i++;
2608 		}
2609 <<<<<<< refclock_parse.c
2610 		t = ap(buffer, size, t, ")");
2611 =======
2612 		strlcpy(t, ")", BUFFER_SIZES(buffer, t, size));
2613 >>>>>>> 1.1.1.3
2614 	}
2615 	return buffer;
2616 }
2617 
2618 /*--------------------------------------------------
2619  * convert a status flag field to a string
2620  */
2621 static char *
2622 parsestatus(
2623 	u_long lstate,
2624 	char *buffer,
2625 	int size
2626 	)
2627 {
2628 	static struct bits
2629 	{
2630 		u_long      bit;
2631 		const char *name;
2632 	} flagstrings[] =
2633 	  {
2634 		  { CVT_OK,      "CONVERSION SUCCESSFUL" },
2635 		  { CVT_NONE,    "NO CONVERSION" },
2636 		  { CVT_FAIL,    "CONVERSION FAILED" },
2637 		  { CVT_BADFMT,  "ILLEGAL FORMAT" },
2638 		  { CVT_BADDATE, "DATE ILLEGAL" },
2639 		  { CVT_BADTIME, "TIME ILLEGAL" },
2640 		  { CVT_ADDITIONAL, "ADDITIONAL DATA" },
2641 		  { 0,		 NULL }
2642 	  };
2643 	int i;
2644 	char *t;
2645 
2646 	t = buffer;
2647 	*buffer = '\0';
2648 
2649 	i = 0;
2650 	while (flagstrings[i].bit)
2651 	{
2652 		if (flagstrings[i].bit & lstate)
2653 		{
2654 <<<<<<< refclock_parse.c
2655 			if (t == buffer)
2656 				t = ap(buffer, size, t, "; ");
2657 			t = ap(buffer, size, t, "%s", flagstrings[i].name);
2658 =======
2659 			if (buffer[0])
2660 				strlcat(buffer, "; ", size);
2661 			strlcat(buffer, flagstrings[i].name, size);
2662 >>>>>>> 1.1.1.3
2663 		}
2664 		i++;
2665 	}
2666 
2667 	return buffer;
2668 }
2669 
2670 /*--------------------------------------------------
2671  * convert a clock status flag field to a string
2672  */
2673 static const char *
2674 clockstatus(
2675 	u_long lstate
2676 	)
2677 {
2678 	static char buffer[20];
2679 	static struct status
2680 	{
2681 		u_long      value;
2682 		const char *name;
2683 	} flagstrings[] =
2684 	  {
2685 		  { CEVNT_NOMINAL, "NOMINAL" },
2686 		  { CEVNT_TIMEOUT, "NO RESPONSE" },
2687 		  { CEVNT_BADREPLY,"BAD FORMAT" },
2688 		  { CEVNT_FAULT,   "FAULT" },
2689 		  { CEVNT_PROP,    "PROPAGATION DELAY" },
2690 		  { CEVNT_BADDATE, "ILLEGAL DATE" },
2691 		  { CEVNT_BADTIME, "ILLEGAL TIME" },
2692 		  { (unsigned)~0L, NULL }
2693 	  };
2694 	int i;
2695 
2696 	i = 0;
2697 	while (flagstrings[i].value != (u_int)~0)
2698 	{
2699 		if (flagstrings[i].value == lstate)
2700 		{
2701 			return flagstrings[i].name;
2702 		}
2703 		i++;
2704 	}
2705 
2706 	snprintf(buffer, sizeof(buffer), "unknown #%ld", (u_long)lstate);
2707 
2708 	return buffer;
2709 }
2710 
2711 
2712 /*--------------------------------------------------
2713  * l_mktime - make representation of a relative time
2714  */
2715 static char *
2716 l_mktime(
2717 	u_long delta
2718 	)
2719 {
2720 	u_long tmp, m, s;
2721 	static char buffer[40];
2722 	char *t;
2723 
2724 	buffer[0] = '\0';
2725 	t = buffer;
2726 
2727 	if ((tmp = delta / (60*60*24)) != 0)
2728 	{
2729 		t = ap(buffer, sizeof(buffer), t, "%ldd+", (u_long)tmp);
2730 		delta -= tmp * 60*60*24;
2731 	}
2732 
2733 	s = delta % 60;
2734 	delta /= 60;
2735 	m = delta % 60;
2736 	delta /= 60;
2737 
2738 	t = ap(buffer, sizeof(buffer), t, "%02d:%02d:%02d",
2739 	     (int)delta, (int)m, (int)s);
2740 
2741 	return buffer;
2742 }
2743 
2744 
2745 /*--------------------------------------------------
2746  * parse_statistics - list summary of clock states
2747  */
2748 static void
2749 parse_statistics(
2750 	struct parseunit *parse
2751 	)
2752 {
2753 	int i;
2754 
2755 	NLOG(NLOG_CLOCKSTATIST) /* conditional if clause for conditional syslog */
2756 		{
2757 			msyslog(LOG_INFO, "PARSE receiver #%d: running time: %s",
2758 				CLK_UNIT(parse->peer),
2759 				l_mktime(current_time - parse->generic->timestarted));
2760 
2761 			msyslog(LOG_INFO, "PARSE receiver #%d: current status: %s",
2762 				CLK_UNIT(parse->peer),
2763 				clockstatus(parse->generic->currentstatus));
2764 
2765 			for (i = 0; i <= CEVNT_MAX; i++)
2766 			{
2767 				u_long s_time;
2768 				u_long percent, d = current_time - parse->generic->timestarted;
2769 
2770 				percent = s_time = PARSE_STATETIME(parse, i);
2771 
2772 				while (((u_long)(~0) / 10000) < percent)
2773 				{
2774 					percent /= 10;
2775 					d       /= 10;
2776 				}
2777 
2778 				if (d)
2779 				    percent = (percent * 10000) / d;
2780 				else
2781 				    percent = 10000;
2782 
2783 				if (s_time)
2784 				    msyslog(LOG_INFO, "PARSE receiver #%d: state %18s: %13s (%3ld.%02ld%%)",
2785 					    CLK_UNIT(parse->peer),
2786 					    clockstatus((unsigned int)i),
2787 					    l_mktime(s_time),
2788 					    percent / 100, percent % 100);
2789 			}
2790 		}
2791 }
2792 
2793 /*--------------------------------------------------
2794  * cparse_statistics - wrapper for statistics call
2795  */
2796 static void
2797 cparse_statistics(
2798         struct parseunit *parse
2799 	)
2800 {
2801 	if (parse->laststatistic + PARSESTATISTICS < current_time)
2802 		parse_statistics(parse);
2803 	parse->laststatistic = current_time;
2804 }
2805 
2806 /**===========================================================================
2807  ** ntp interface routines
2808  **/
2809 
2810 /*--------------------------------------------------
2811  * parse_shutdown - shut down a PARSE clock
2812  */
2813 static void
2814 parse_shutdown(
2815 	int unit,
2816 	struct peer *peer
2817 	)
2818 {
2819 	struct parseunit *parse = NULL;
2820 
2821 	if (peer && peer->procptr)
2822 		parse = peer->procptr->unitptr;
2823 
2824 	if (!parse)
2825 	{
2826 		/* nothing to clean up */
2827 		return;
2828 	}
2829 
2830 	if (!parse->peer)
2831 	{
2832 		msyslog(LOG_INFO, "PARSE receiver #%d: INTERNAL ERROR - unit already inactive - shutdown ignored", unit);
2833 		return;
2834 	}
2835 
2836 #ifdef HAVE_PPSAPI
2837 	if (parse->flags & PARSE_PPSCLOCK)
2838 	{
2839 		(void)time_pps_destroy(parse->atom.handle);
2840 	}
2841 #endif
2842 	if (parse->generic->io.fd != parse->ppsfd && parse->ppsfd != -1)
2843 		(void)closeserial(parse->ppsfd);  /* close separate PPS source */
2844 
2845 	/*
2846 	 * print statistics a last time and
2847 	 * stop statistics machine
2848 	 */
2849 	parse_statistics(parse);
2850 
2851 	if (parse->parse_type->cl_end)
2852 	{
2853 		parse->parse_type->cl_end(parse);
2854 	}
2855 
2856 	/*
2857 	 * cleanup before leaving this world
2858 	 */
2859 	if (parse->binding)
2860 	    PARSE_END(parse);
2861 
2862 	/*
2863 	 * Tell the I/O module to turn us off.  We're history.
2864 	 */
2865 	io_closeclock(&parse->generic->io);
2866 
2867 	free_varlist(parse->kv);
2868 
2869 	NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
2870 		msyslog(LOG_INFO, "PARSE receiver #%d: reference clock \"%s\" removed",
2871 			CLK_UNIT(parse->peer), parse->parse_type->cl_description);
2872 
2873 	parse->peer = (struct peer *)0; /* unused now */
2874 	peer->procptr->unitptr = (caddr_t)0;
2875 	free(parse);
2876 }
2877 
2878 #ifdef HAVE_PPSAPI
2879 /*----------------------------------------
2880  * set up HARDPPS via PPSAPI
2881  */
2882 static void
2883 parse_hardpps(
2884 	      struct parseunit *parse,
2885 	      int mode
2886 	      )
2887 {
2888         if (parse->hardppsstate == mode)
2889 	        return;
2890 
2891 	if (CLK_PPS(parse->peer) && (parse->flags & PARSE_PPSKERNEL)) {
2892 		int	i = 0;
2893 
2894 		if (mode == PARSE_HARDPPS_ENABLE)
2895 		        {
2896 			        if (parse->flags & PARSE_CLEAR)
2897 				        i = PPS_CAPTURECLEAR;
2898 				else
2899 				        i = PPS_CAPTUREASSERT;
2900 			}
2901 
2902 		if (time_pps_kcbind(parse->atom.handle, PPS_KC_HARDPPS, i,
2903 		    PPS_TSFMT_TSPEC) < 0) {
2904 		        msyslog(LOG_ERR, "PARSE receiver #%d: time_pps_kcbind failed: %m",
2905 				CLK_UNIT(parse->peer));
2906 		} else {
2907 		        NLOG(NLOG_CLOCKINFO)
2908 		                msyslog(LOG_INFO, "PARSE receiver #%d: kernel PPS synchronisation %sabled",
2909 					CLK_UNIT(parse->peer), (mode == PARSE_HARDPPS_ENABLE) ? "en" : "dis");
2910 			/*
2911 			 * tell the rest, that we have a kernel PPS source, iff we ever enable HARDPPS
2912 			 */
2913 			if (mode == PARSE_HARDPPS_ENABLE)
2914 			        pps_enable = 1;
2915 		}
2916 	}
2917 
2918 	parse->hardppsstate = mode;
2919 }
2920 
2921 /*----------------------------------------
2922  * set up PPS via PPSAPI
2923  */
2924 static int
2925 parse_ppsapi(
2926 	     struct parseunit *parse
2927 	)
2928 {
2929 	int cap, mode_ppsoffset;
2930 	const char *cp;
2931 
2932 	parse->flags &= ~PARSE_PPSCLOCK;
2933 
2934 	/*
2935 	 * collect PPSAPI offset capability - should move into generic handling
2936 	 */
2937 	if (time_pps_getcap(parse->atom.handle, &cap) < 0) {
2938 		msyslog(LOG_ERR, "PARSE receiver #%d: parse_ppsapi: time_pps_getcap failed: %m",
2939 			CLK_UNIT(parse->peer));
2940 
2941 		return 0;
2942 	}
2943 
2944 	/*
2945 	 * initialize generic PPSAPI interface
2946 	 *
2947 	 * we leave out CLK_FLAG3 as time_pps_kcbind()
2948 	 * is handled here for now. Ideally this should also
2949 	 * be part of the generic PPSAPI interface
2950 	 */
2951 	if (!refclock_params(parse->flags & (CLK_FLAG1|CLK_FLAG2|CLK_FLAG4), &parse->atom))
2952 		return 0;
2953 
2954 	/* nb. only turn things on, if someone else has turned something
2955 	 *	on before we get here, leave it alone!
2956 	 */
2957 
2958 	if (parse->flags & PARSE_CLEAR) {
2959 		cp = "CLEAR";
2960 		mode_ppsoffset = PPS_OFFSETCLEAR;
2961 	} else {
2962 		cp = "ASSERT";
2963 		mode_ppsoffset = PPS_OFFSETASSERT;
2964 	}
2965 
2966 	msyslog(LOG_INFO, "PARSE receiver #%d: initializing PPS to %s",
2967 		CLK_UNIT(parse->peer), cp);
2968 
2969 	if (!(mode_ppsoffset & cap)) {
2970 	  msyslog(LOG_WARNING, "PARSE receiver #%d: Cannot set PPS_%sCLEAR, this will increase jitter (PPS API capabilities=0x%x)",
2971 		  CLK_UNIT(parse->peer), cp, cap);
2972 		mode_ppsoffset = 0;
2973 	} else {
2974 	        if (mode_ppsoffset == PPS_OFFSETCLEAR)
2975 		        {
2976 			        parse->atom.pps_params.clear_offset.tv_sec = -parse->ppsphaseadjust;
2977 			        parse->atom.pps_params.clear_offset.tv_nsec = -1e9*(parse->ppsphaseadjust - (long)parse->ppsphaseadjust);
2978 			}
2979 
2980 		if (mode_ppsoffset == PPS_OFFSETASSERT)
2981 	                {
2982 		                parse->atom.pps_params.assert_offset.tv_sec = -parse->ppsphaseadjust;
2983 				parse->atom.pps_params.assert_offset.tv_nsec = -1e9*(parse->ppsphaseadjust - (long)parse->ppsphaseadjust);
2984 			}
2985 	}
2986 
2987 	parse->atom.pps_params.mode |= mode_ppsoffset;
2988 
2989 	if (time_pps_setparams(parse->atom.handle, &parse->atom.pps_params) < 0) {
2990 	  msyslog(LOG_ERR, "PARSE receiver #%d: FAILED set PPS parameters: %m",
2991 		  CLK_UNIT(parse->peer));
2992 		return 0;
2993 	}
2994 
2995 	parse->flags |= PARSE_PPSCLOCK;
2996 	return 1;
2997 }
2998 #else
2999 #define parse_hardpps(_PARSE_, _MODE_) /* empty */
3000 #endif
3001 
3002 /*--------------------------------------------------
3003  * parse_start - open the PARSE devices and initialize data for processing
3004  */
3005 static int
3006 parse_start(
3007 	int sysunit,
3008 	struct peer *peer
3009 	)
3010 {
3011 	u_int unit;
3012 	int fd232;
3013 #ifdef HAVE_TERMIOS
3014 	struct termios tio;		/* NEEDED FOR A LONG TIME ! */
3015 #endif
3016 #ifdef HAVE_SYSV_TTYS
3017 	struct termio tio;		/* NEEDED FOR A LONG TIME ! */
3018 #endif
3019 	struct parseunit * parse;
3020 	char parsedev[sizeof(PARSEDEVICE)+20];
3021 	char parseppsdev[sizeof(PARSEPPSDEVICE)+20];
3022 	parsectl_t tmp_ctl;
3023 	u_int type;
3024 
3025 	/*
3026 	 * get out Copyright information once
3027 	 */
3028 	if (!notice)
3029         {
3030 		NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
3031 			msyslog(LOG_INFO, "NTP PARSE support: Copyright (c) 1989-2009, Frank Kardel");
3032 		notice = 1;
3033 	}
3034 
3035 	type = CLK_TYPE(peer);
3036 	unit = CLK_UNIT(peer);
3037 
3038 	if ((type == (u_int)~0) || (parse_clockinfo[type].cl_description == (char *)0))
3039 	{
3040 		msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: unsupported clock type %d (max %d)",
3041 			unit, CLK_REALTYPE(peer), ncltypes-1);
3042 		return 0;
3043 	}
3044 
3045 	/*
3046 	 * Unit okay, attempt to open the device.
3047 	 */
3048 	(void) snprintf(parsedev, sizeof(parsedev), PARSEDEVICE, unit);
3049 	(void) snprintf(parseppsdev, sizeof(parsedev), PARSEPPSDEVICE, unit);
3050 
3051 #ifndef O_NOCTTY
3052 #define O_NOCTTY 0
3053 #endif
3054 #ifndef O_NONBLOCK
3055 #define O_NONBLOCK 0
3056 #endif
3057 
3058 	fd232 = tty_open(parsedev, O_RDWR | O_NOCTTY | O_NONBLOCK, 0777);
3059 
3060 	if (fd232 == -1)
3061 	{
3062 		msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: open of %s failed: %m", unit, parsedev);
3063 		return 0;
3064 	}
3065 
3066 	parse = emalloc_zero(sizeof(*parse));
3067 
3068 	parse->generic = peer->procptr;	 /* link up */
3069 	parse->generic->unitptr = (caddr_t)parse; /* link down */
3070 
3071 	/*
3072 	 * Set up the structures
3073 	 */
3074 	parse->generic->timestarted    = current_time;
3075 	parse->lastchange     = current_time;
3076 
3077 	parse->flags          = 0;
3078 	parse->pollneeddata   = 0;
3079 	parse->laststatistic  = current_time;
3080 	parse->lastformat     = (unsigned short)~0;	/* assume no format known */
3081 	parse->timedata.parse_status = (unsigned short)~0;	/* be sure to mark initial status change */
3082 	parse->lastmissed     = 0;	/* assume got everything */
3083 	parse->ppsserial      = 0;
3084 	parse->ppsfd	      = -1;
3085 	parse->localdata      = (void *)0;
3086 	parse->localstate     = 0;
3087 	parse->kv             = (struct ctl_var *)0;
3088 
3089 	clear_err(parse, ERR_ALL);
3090 
3091 	parse->parse_type     = &parse_clockinfo[type];
3092 
3093 	parse->maxunsync      = parse->parse_type->cl_maxunsync;
3094 
3095 	parse->generic->fudgetime1 = parse->parse_type->cl_basedelay;
3096 
3097 	parse->generic->fudgetime2 = 0.0;
3098 	parse->ppsphaseadjust = parse->generic->fudgetime2;
3099 
3100 	parse->generic->clockdesc  = parse->parse_type->cl_description;
3101 
3102 	peer->rootdelay       = parse->parse_type->cl_rootdelay;
3103 	peer->sstclktype      = parse->parse_type->cl_type;
3104 	peer->precision       = sys_precision;
3105 
3106 	peer->stratum         = STRATUM_REFCLOCK;
3107 
3108 	if (peer->stratum <= 1)
3109 	    memmove((char *)&parse->generic->refid, parse->parse_type->cl_id, 4);
3110 	else
3111 	    parse->generic->refid = htonl(PARSEHSREFID);
3112 
3113 	parse->generic->io.fd = fd232;
3114 
3115 	parse->peer = peer;		/* marks it also as busy */
3116 
3117 	/*
3118 	 * configure terminal line
3119 	 */
3120 	if (TTY_GETATTR(fd232, &tio) == -1)
3121 	{
3122 		msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: tcgetattr(%d, &tio): %m", unit, fd232);
3123 		parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */
3124 		return 0;
3125 	}
3126 	else
3127 	{
3128 #ifndef _PC_VDISABLE
3129 		memset((char *)tio.c_cc, 0, sizeof(tio.c_cc));
3130 #else
3131 		int disablec;
3132 		errno = 0;		/* pathconf can deliver -1 without changing errno ! */
3133 
3134 		disablec = fpathconf(parse->generic->io.fd, _PC_VDISABLE);
3135 		if (disablec == -1 && errno)
3136 		{
3137 			msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: fpathconf(fd, _PC_VDISABLE): %m", CLK_UNIT(parse->peer));
3138 			memset((char *)tio.c_cc, 0, sizeof(tio.c_cc)); /* best guess */
3139 		}
3140 		else
3141 		    if (disablec != -1)
3142 			memset((char *)tio.c_cc, disablec, sizeof(tio.c_cc));
3143 #endif
3144 
3145 #if defined (VMIN) || defined(VTIME)
3146 		if ((parse_clockinfo[type].cl_lflag & ICANON) == 0)
3147 		{
3148 #ifdef VMIN
3149 			tio.c_cc[VMIN]   = 1;
3150 #endif
3151 #ifdef VTIME
3152 			tio.c_cc[VTIME]  = 0;
3153 #endif
3154 		}
3155 #endif
3156 
3157 		tio.c_cflag = parse_clockinfo[type].cl_cflag;
3158 		tio.c_iflag = parse_clockinfo[type].cl_iflag;
3159 		tio.c_oflag = parse_clockinfo[type].cl_oflag;
3160 		tio.c_lflag = parse_clockinfo[type].cl_lflag;
3161 
3162 
3163 #ifdef HAVE_TERMIOS
3164 		if ((cfsetospeed(&tio, parse_clockinfo[type].cl_speed) == -1) ||
3165 		    (cfsetispeed(&tio, parse_clockinfo[type].cl_speed) == -1))
3166 		{
3167 			msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: tcset{i,o}speed(&tio, speed): %m", unit);
3168 			parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */
3169 			return 0;
3170 		}
3171 #else
3172 		tio.c_cflag     |= parse_clockinfo[type].cl_speed;
3173 #endif
3174 
3175 		/*
3176 		 * set up pps device
3177 		 * if the PARSEPPSDEVICE can be opened that will be used
3178 		 * for PPS else PARSEDEVICE will be used
3179 		 */
3180 		parse->ppsfd = tty_open(parseppsdev, O_RDWR | O_NOCTTY | O_NONBLOCK, 0777);
3181 
3182 		if (parse->ppsfd == -1)
3183 		{
3184 			parse->ppsfd = fd232;
3185 		}
3186 
3187 /*
3188  * Linux PPS - the old way
3189  */
3190 #if defined(HAVE_TIO_SERIAL_STUFF)		/* Linux hack: define PPS interface */
3191 		{
3192 			struct serial_struct	ss;
3193 			if (ioctl(parse->ppsfd, TIOCGSERIAL, &ss) < 0 ||
3194 			    (
3195 #ifdef ASYNC_LOW_LATENCY
3196 			     ss.flags |= ASYNC_LOW_LATENCY,
3197 #endif
3198 #ifndef HAVE_PPSAPI
3199 #ifdef ASYNC_PPS_CD_NEG
3200 			     ss.flags |= ASYNC_PPS_CD_NEG,
3201 #endif
3202 #endif
3203 			     ioctl(parse->ppsfd, TIOCSSERIAL, &ss)) < 0) {
3204 				msyslog(LOG_NOTICE, "refclock_parse: TIOCSSERIAL fd %d, %m", parse->ppsfd);
3205 				msyslog(LOG_NOTICE,
3206 					"refclock_parse: optional PPS processing not available");
3207 			} else {
3208 				parse->flags    |= PARSE_PPSCLOCK;
3209 #ifdef ASYNC_PPS_CD_NEG
3210 				NLOG(NLOG_CLOCKINFO)
3211 				  msyslog(LOG_INFO,
3212 					  "refclock_parse: PPS detection on");
3213 #endif
3214 			}
3215 		}
3216 #endif
3217 
3218 /*
3219  * SUN the Solaris way
3220  */
3221 #ifdef HAVE_TIOCSPPS			/* SUN PPS support */
3222 		if (CLK_PPS(parse->peer))
3223 		    {
3224 			int i = 1;
3225 
3226 			if (ioctl(parse->ppsfd, TIOCSPPS, (caddr_t)&i) == 0)
3227 			    {
3228 				parse->flags |= PARSE_PPSCLOCK;
3229 			    }
3230 		    }
3231 #endif
3232 
3233 /*
3234  * PPS via PPSAPI
3235  */
3236 #if defined(HAVE_PPSAPI)
3237 		parse->hardppsstate = PARSE_HARDPPS_DISABLE;
3238 		if (CLK_PPS(parse->peer))
3239 		{
3240 		  if (!refclock_ppsapi(parse->ppsfd, &parse->atom))
3241 		    {
3242 		      msyslog(LOG_NOTICE, "PARSE receiver #%d: parse_start: could not set up PPS: %m", CLK_UNIT(parse->peer));
3243 		    }
3244 		  else
3245 		    {
3246 		      parse_ppsapi(parse);
3247 		    }
3248 		}
3249 #endif
3250 
3251 		if (TTY_SETATTR(fd232, &tio) == -1)
3252 		{
3253 			msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: tcsetattr(%d, &tio): %m", unit, fd232);
3254 			parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */
3255 			return 0;
3256 		}
3257 	}
3258 
3259 	/*
3260 	 * pick correct input machine
3261 	 */
3262 	parse->generic->io.srcclock = peer;
3263 	parse->generic->io.datalen = 0;
3264 
3265 	parse->binding = init_iobinding(parse);
3266 
3267 	if (parse->binding == (bind_t *)0)
3268 		{
3269 			msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: io sub system initialisation failed.", CLK_UNIT(parse->peer));
3270 			parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */
3271 			return 0;			/* well, ok - special initialisation broke */
3272 		}
3273 
3274 	parse->generic->io.clock_recv = parse->binding->bd_receive; /* pick correct receive routine */
3275 	parse->generic->io.io_input   = parse->binding->bd_io_input; /* pick correct input routine */
3276 
3277 	/*
3278 	 * as we always(?) get 8 bit chars we want to be
3279 	 * sure, that the upper bits are zero for less
3280 	 * than 8 bit I/O - so we pass that information on.
3281 	 * note that there can be only one bit count format
3282 	 * per file descriptor
3283 	 */
3284 
3285 	switch (tio.c_cflag & CSIZE)
3286 	{
3287 	    case CS5:
3288 		tmp_ctl.parsesetcs.parse_cs = PARSE_IO_CS5;
3289 		break;
3290 
3291 	    case CS6:
3292 		tmp_ctl.parsesetcs.parse_cs = PARSE_IO_CS6;
3293 		break;
3294 
3295 	    case CS7:
3296 		tmp_ctl.parsesetcs.parse_cs = PARSE_IO_CS7;
3297 		break;
3298 
3299 	    case CS8:
3300 		tmp_ctl.parsesetcs.parse_cs = PARSE_IO_CS8;
3301 		break;
3302 	}
3303 
3304 	if (!PARSE_SETCS(parse, &tmp_ctl))
3305 	{
3306 		msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: parse_setcs() FAILED.", unit);
3307 		parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */
3308 		return 0;			/* well, ok - special initialisation broke */
3309 	}
3310 <<<<<<< refclock_parse.c
3311 
3312 	strlcpy(tmp_ctl.parseformat.parse_buffer, parse->parse_type->cl_format, sizeof(tmp_ctl.parseformat.parse_buffer));
3313 	tmp_ctl.parseformat.parse_count = strlen(tmp_ctl.parseformat.parse_buffer);
3314 =======
3315 
3316 	tmp_ctl.parseformat.parse_count = strlcpy(tmp_ctl.parseformat.parse_buffer,
3317 						  parse->parse_type->cl_format,
3318 						  sizeof(tmp_ctl.parseformat.parse_buffer));
3319 	if (tmp_ctl.parseformat.parse_count >= sizeof(tmp_ctl.parseformat.parse_buffer))
3320 		tmp_ctl.parseformat.parse_count = sizeof(tmp_ctl.parseformat.parse_buffer) - 1;
3321 >>>>>>> 1.1.1.3
3322 
3323 	if (!PARSE_SETFMT(parse, &tmp_ctl))
3324 	{
3325 		msyslog(LOG_ERR, "PARSE receiver #%d: parse_start: parse_setfmt() FAILED.", unit);
3326 		parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */
3327 		return 0;			/* well, ok - special initialisation broke */
3328 	}
3329 
3330 	/*
3331 	 * get rid of all IO accumulated so far
3332 	 */
3333 #ifdef HAVE_TERMIOS
3334 	(void) tcflush(parse->generic->io.fd, TCIOFLUSH);
3335 #else
3336 #if defined(TCFLSH) && defined(TCIOFLUSH)
3337 	{
3338 		int flshcmd = TCIOFLUSH;
3339 
3340 		(void) ioctl(parse->generic->io.fd, TCFLSH, (caddr_t)&flshcmd);
3341 	}
3342 #endif
3343 #endif
3344 
3345 	/*
3346 	 * try to do any special initializations
3347 	 */
3348 	if (parse->parse_type->cl_init)
3349 		{
3350 			if (parse->parse_type->cl_init(parse))
3351 				{
3352 					parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */
3353 					return 0;		/* well, ok - special initialisation broke */
3354 				}
3355 		}
3356 
3357 	/*
3358 	 * Insert in async io device list.
3359 	 */
3360 	if (!io_addclock(&parse->generic->io))
3361         {
3362 		msyslog(LOG_ERR,
3363 			"PARSE receiver #%d: parse_start: addclock %s fails (ABORT - clock type requires async io)", CLK_UNIT(parse->peer), parsedev);
3364 		parse_shutdown(CLK_UNIT(parse->peer), peer); /* let our cleaning staff do the work */
3365 		return 0;
3366 	}
3367 
3368 	/*
3369 	 * print out configuration
3370 	 */
3371 	NLOG(NLOG_CLOCKINFO)
3372 		{
3373 			/* conditional if clause for conditional syslog */
3374 			msyslog(LOG_INFO, "PARSE receiver #%d: reference clock \"%s\" (I/O device %s, PPS device %s) added",
3375 				CLK_UNIT(parse->peer),
3376 				parse->parse_type->cl_description, parsedev,
3377 				(parse->ppsfd != parse->generic->io.fd) ? parseppsdev : parsedev);
3378 
3379 			msyslog(LOG_INFO, "PARSE receiver #%d: Stratum %d, trust time %s, precision %d",
3380 				CLK_UNIT(parse->peer),
3381 				parse->peer->stratum,
3382 				l_mktime(parse->maxunsync), parse->peer->precision);
3383 
3384 			msyslog(LOG_INFO, "PARSE receiver #%d: rootdelay %.6f s, phase adjustment %.6f s, PPS phase adjustment %.6f s, %s IO handling",
3385 				CLK_UNIT(parse->peer),
3386 				parse->parse_type->cl_rootdelay,
3387 				parse->generic->fudgetime1,
3388 				parse->ppsphaseadjust,
3389                                 parse->binding->bd_description);
3390 
3391 			msyslog(LOG_INFO, "PARSE receiver #%d: Format recognition: %s", CLK_UNIT(parse->peer),
3392 				parse->parse_type->cl_format);
3393                         msyslog(LOG_INFO, "PARSE receiver #%d: %sPPS support%s", CLK_UNIT(parse->peer),
3394 				CLK_PPS(parse->peer) ? "" : "NO ",
3395 				CLK_PPS(parse->peer) ?
3396 #ifdef PPS_METHOD
3397 				" (implementation " PPS_METHOD ")"
3398 #else
3399 				""
3400 #endif
3401 				: ""
3402 				);
3403 		}
3404 
3405 	return 1;
3406 }
3407 
3408 /*--------------------------------------------------
3409  * parse_ctl - process changes on flags/time values
3410  */
3411 static void
3412 parse_ctl(
3413 	    struct parseunit *parse,
3414 	    const struct refclockstat *in
3415 	    )
3416 {
3417         if (in)
3418 	{
3419 		if (in->haveflags & (CLK_HAVEFLAG1|CLK_HAVEFLAG2|CLK_HAVEFLAG3|CLK_HAVEFLAG4))
3420 		{
3421 		  parse->flags = (parse->flags & ~(CLK_FLAG1|CLK_FLAG2|CLK_FLAG3|CLK_FLAG4)) |
3422 		    (in->flags & (CLK_FLAG1|CLK_FLAG2|CLK_FLAG3|CLK_FLAG4));
3423 #if defined(HAVE_PPSAPI)
3424 		  if (CLK_PPS(parse->peer))
3425 		    {
3426 		      parse_ppsapi(parse);
3427 		    }
3428 #endif
3429 		}
3430 
3431 		if (in->haveflags & CLK_HAVETIME1)
3432                 {
3433 		  parse->generic->fudgetime1 = in->fudgetime1;
3434 		  msyslog(LOG_INFO, "PARSE receiver #%d: new phase adjustment %.6f s",
3435 			  CLK_UNIT(parse->peer),
3436 			  parse->generic->fudgetime1);
3437 		}
3438 
3439 		if (in->haveflags & CLK_HAVETIME2)
3440                 {
3441 		  parse->generic->fudgetime2 = in->fudgetime2;
3442 		  if (parse->flags & PARSE_TRUSTTIME)
3443 		    {
3444 		      parse->maxunsync = (u_long)ABS(in->fudgetime2);
3445 		      msyslog(LOG_INFO, "PARSE receiver #%d: new trust time %s",
3446 			      CLK_UNIT(parse->peer),
3447 			      l_mktime(parse->maxunsync));
3448 		    }
3449 		  else
3450 		    {
3451 		      parse->ppsphaseadjust = in->fudgetime2;
3452 		      msyslog(LOG_INFO, "PARSE receiver #%d: new PPS phase adjustment %.6f s",
3453 			  CLK_UNIT(parse->peer),
3454 			      parse->ppsphaseadjust);
3455 #if defined(HAVE_PPSAPI)
3456 		      if (CLK_PPS(parse->peer))
3457 		      {
3458 			      parse_ppsapi(parse);
3459 		      }
3460 #endif
3461 		    }
3462 		}
3463 	}
3464 }
3465 
3466 /*--------------------------------------------------
3467  * parse_poll - called by the transmit procedure
3468  */
3469 static void
3470 parse_poll(
3471 	int unit,
3472 	struct peer *peer
3473 	)
3474 {
3475 	struct parseunit *parse = peer->procptr->unitptr;
3476 
3477 	if (peer != parse->peer)
3478 	{
3479 		msyslog(LOG_ERR,
3480 			"PARSE receiver #%d: poll: INTERNAL: peer incorrect",
3481 			unit);
3482 		return;
3483 	}
3484 
3485 	/*
3486 	 * Update clock stat counters
3487 	 */
3488 	parse->generic->polls++;
3489 
3490 	if (parse->pollneeddata &&
3491 	    ((int)(current_time - parse->pollneeddata) > (1<<(max(min(parse->peer->hpoll, parse->peer->ppoll), parse->peer->minpoll)))))
3492 	{
3493 		/*
3494 		 * start worrying when exceeding a poll inteval
3495 		 * bad news - didn't get a response last time
3496 		 */
3497 		parse->lastmissed = current_time;
3498 		parse_event(parse, CEVNT_TIMEOUT);
3499 
3500 		ERR(ERR_NODATA)
3501 			msyslog(LOG_WARNING, "PARSE receiver #%d: no data from device within poll interval (check receiver / wiring)", CLK_UNIT(parse->peer));
3502 	}
3503 
3504 	/*
3505 	 * we just mark that we want the next sample for the clock filter
3506 	 */
3507 	parse->pollneeddata = current_time;
3508 
3509 	if (parse->parse_type->cl_poll)
3510 	{
3511 		parse->parse_type->cl_poll(parse);
3512 	}
3513 
3514 	cparse_statistics(parse);
3515 
3516 	return;
3517 }
3518 
3519 #define LEN_STATES 300		/* length of state string */
3520 
3521 /*--------------------------------------------------
3522  * parse_control - set fudge factors, return statistics
3523  */
3524 static void
3525 parse_control(
3526 	int unit,
3527 	const struct refclockstat *in,
3528 	struct refclockstat *out,
3529 	struct peer *peer
3530 	)
3531 {
3532 	struct parseunit *parse = peer->procptr->unitptr;
3533 	parsectl_t tmpctl;
3534 
3535 	static char outstatus[400];	/* status output buffer */
3536 
3537 	if (out)
3538 	{
3539 		out->lencode       = 0;
3540 		out->p_lastcode    = 0;
3541 		out->kv_list       = (struct ctl_var *)0;
3542 	}
3543 
3544 	if (!parse || !parse->peer)
3545 	{
3546 		msyslog(LOG_ERR, "PARSE receiver #%d: parse_control: unit invalid (UNIT INACTIVE)",
3547 			unit);
3548 		return;
3549 	}
3550 
3551 	unit = CLK_UNIT(parse->peer);
3552 
3553 	/*
3554 	 * handle changes
3555 	 */
3556 	parse_ctl(parse, in);
3557 
3558 	/*
3559 	 * supply data
3560 	 */
3561 	if (out)
3562 	{
3563 		u_long sum = 0;
3564 		char *tt, *start;
3565 		int i;
3566 
3567 		outstatus[0] = '\0';
3568 
3569 		out->type       = REFCLK_PARSE;
3570 
3571 		/*
3572 		 * keep fudgetime2 in sync with TRUSTTIME/MAXUNSYNC flag1
3573 		 */
3574 		parse->generic->fudgetime2 = (parse->flags & PARSE_TRUSTTIME) ? (double)parse->maxunsync : parse->ppsphaseadjust;
3575 
3576 		/*
3577 		 * figure out skew between PPS and RS232 - just for informational
3578 		 * purposes
3579 		 */
3580 		if (PARSE_SYNC(parse->timedata.parse_state))
3581 		{
3582 			if (PARSE_PPS(parse->timedata.parse_state) && PARSE_TIMECODE(parse->timedata.parse_state))
3583 			{
3584 				l_fp off;
3585 
3586 				/*
3587 				 * we have a PPS and RS232 signal - calculate the skew
3588 				 * WARNING: assumes on TIMECODE == PULSE (timecode after pulse)
3589 				 */
3590 				off = parse->timedata.parse_stime.fp;
3591 				L_SUB(&off, &parse->timedata.parse_ptime.fp); /* true offset */
3592 				tt = add_var(&out->kv_list, 80, RO);
3593 				snprintf(tt, 80, "refclock_ppsskew=%s", lfptoms(&off, 6));
3594 			}
3595 		}
3596 
3597 		if (PARSE_PPS(parse->timedata.parse_state))
3598 		{
3599 			tt = add_var(&out->kv_list, 80, RO|DEF);
3600 			snprintf(tt, 80, "refclock_ppstime=\"%s\"", gmprettydate(&parse->timedata.parse_ptime.fp));
3601 		}
3602 
3603 		start = tt = add_var(&out->kv_list, 128, RO|DEF);
3604 		tt = ap(start, 128, tt, "refclock_time=\"");
3605 
3606 		if (parse->timedata.parse_time.fp.l_ui == 0)
3607 		{
3608 <<<<<<< refclock_parse.c
3609 			tt = ap(start, 128, tt, "<UNDEFINED>\"");
3610 =======
3611 			strlcpy(tt, "<UNDEFINED>\"", BUFFER_SIZES(start, tt, 128));
3612 >>>>>>> 1.1.1.3
3613 		}
3614 		else
3615 		{
3616 			tt = ap(start, 128, tt, "%s\"",
3617 			    gmprettydate(&parse->timedata.parse_time.fp));
3618 		}
3619 
3620 		if (!PARSE_GETTIMECODE(parse, &tmpctl))
3621 		{
3622 			ERR(ERR_INTERNAL)
3623 				msyslog(LOG_ERR, "PARSE receiver #%d: parse_control: parse_timecode() FAILED", unit);
3624 		}
3625 		else
3626 		{
3627 			start = tt = add_var(&out->kv_list, 512, RO|DEF);
3628 			tt = ap(start, 512, tt, "refclock_status=\"");
3629 
3630 			/*
3631 			 * copy PPS flags from last read transaction (informational only)
3632 			 */
3633 			tmpctl.parsegettc.parse_state |= parse->timedata.parse_state &
3634 				(PARSEB_PPS|PARSEB_S_PPS);
3635 
3636 			(void)parsestate(tmpctl.parsegettc.parse_state, tt, BUFFER_SIZES(start, tt, 512));
3637 
3638 			tt += strlen(tt);
3639 
3640 <<<<<<< refclock_parse.c
3641 			tt = ap(start, 512, tt, "\"");
3642 =======
3643 			strlcat(tt, "\"", BUFFER_SIZES(start, tt, 512));
3644 >>>>>>> 1.1.1.3
3645 
3646 			if (tmpctl.parsegettc.parse_count)
3647 			    mkascii(outstatus+strlen(outstatus), (int)(sizeof(outstatus)- strlen(outstatus) - 1),
3648 				    tmpctl.parsegettc.parse_buffer, (unsigned)(tmpctl.parsegettc.parse_count));
3649 
3650 		}
3651 
3652 		tmpctl.parseformat.parse_format = tmpctl.parsegettc.parse_format;
3653 
3654 		if (!PARSE_GETFMT(parse, &tmpctl))
3655 		{
3656 			ERR(ERR_INTERNAL)
3657 				msyslog(LOG_ERR, "PARSE receiver #%d: parse_control: parse_getfmt() FAILED", unit);
3658 		}
3659 		else
3660 		{
3661 			int count = tmpctl.parseformat.parse_count - 1;
3662 
3663 			start = tt = add_var(&out->kv_list, 80, RO|DEF);
3664 			tt = ap(start, 80, tt, "refclock_format=\"");
3665 
3666 			if (count > 0) {
3667 				tt = ap(start, 80, tt, "%*.*s",
3668 			        	count,
3669 			        	count,
3670 			        	tmpctl.parseformat.parse_buffer);
3671 			}
3672 
3673 <<<<<<< refclock_parse.c
3674 			tt = ap(start, 80, tt, "\"");
3675 =======
3676 			strlcat(tt, tmpctl.parseformat.parse_buffer, 80);
3677 			strlcat(tt,"\"", 80);
3678 >>>>>>> 1.1.1.3
3679 		}
3680 
3681 		/*
3682 		 * gather state statistics
3683 		 */
3684 
3685 		start = tt = add_var(&out->kv_list, LEN_STATES, RO|DEF);
3686 <<<<<<< refclock_parse.c
3687 		tt = ap(start, LEN_STATES, tt, "refclock_states=\"");
3688 =======
3689 		strlcpy(tt, "refclock_states=\"", LEN_STATES);
3690 		tt += strlen(tt);
3691 >>>>>>> 1.1.1.3
3692 
3693 		for (i = 0; i <= CEVNT_MAX; i++)
3694 		{
3695 			u_long s_time;
3696 			u_long d = current_time - parse->generic->timestarted;
3697 			u_long percent;
3698 
3699 			percent = s_time = PARSE_STATETIME(parse, i);
3700 
3701 			while (((u_long)(~0) / 10000) < percent)
3702 			{
3703 				percent /= 10;
3704 				d       /= 10;
3705 			}
3706 
3707 			if (d)
3708 			    percent = (percent * 10000) / d;
3709 			else
3710 			    percent = 10000;
3711 
3712 			if (s_time)
3713 			{
3714 				char item[80];
3715 				int count;
3716 
3717 				snprintf(item, 80, "%s%s%s: %s (%d.%02d%%)",
3718 					sum ? "; " : "",
3719 					(parse->generic->currentstatus == i) ? "*" : "",
3720 					clockstatus((unsigned int)i),
3721 					l_mktime(s_time),
3722 					(int)(percent / 100), (int)(percent % 100));
3723 				if ((count = strlen(item)) < (LEN_STATES - 40 - (tt - start)))
3724 					{
3725 <<<<<<< refclock_parse.c
3726 						tt = ap(start, LEN_STATES, tt,
3727 						    "%s", item);
3728 =======
3729 						strlcpy(tt, item, BUFFER_SIZES(start, tt, LEN_STATES));
3730 						tt  += count;
3731 >>>>>>> 1.1.1.3
3732 					}
3733 				sum += s_time;
3734 			}
3735 		}
3736 
3737 		tt = ap(start, LEN_STATES, tt,
3738 		    "; running time: %s\"", l_mktime(sum));
3739 
3740 		tt = add_var(&out->kv_list, 32, RO);
3741 		snprintf(tt, 32,  "refclock_id=\"%s\"", parse->parse_type->cl_id);
3742 
3743 		tt = add_var(&out->kv_list, 80, RO);
3744 		snprintf(tt, 80,  "refclock_iomode=\"%s\"", parse->binding->bd_description);
3745 
3746 		tt = add_var(&out->kv_list, 128, RO);
3747 		snprintf(tt, 128, "refclock_driver_version=\"%s\"", rcsid);
3748 
3749 		{
3750 			struct ctl_var *k;
3751 
3752 			k = parse->kv;
3753 			while (k && !(k->flags & EOV))
3754 			{
3755 				set_var(&out->kv_list, k->text, strlen(k->text)+1, k->flags);
3756 				k++;
3757 			}
3758 		}
3759 
3760 		out->lencode       = strlen(outstatus);
3761 		out->p_lastcode    = outstatus;
3762 	}
3763 }
3764 
3765 /**===========================================================================
3766  ** processing routines
3767  **/
3768 
3769 /*--------------------------------------------------
3770  * event handling - note that nominal events will also be posted
3771  * keep track of state dwelling times
3772  */
3773 static void
3774 parse_event(
3775 	struct parseunit *parse,
3776 	int event
3777 	)
3778 {
3779 	if (parse->generic->currentstatus != (u_char) event)
3780 	{
3781 		parse->statetime[parse->generic->currentstatus] += current_time - parse->lastchange;
3782 		parse->lastchange              = current_time;
3783 
3784 		if (parse->parse_type->cl_event)
3785 		    parse->parse_type->cl_event(parse, event);
3786 
3787 		if (event == CEVNT_NOMINAL)
3788 		{
3789 			NLOG(NLOG_CLOCKSTATUS)
3790 				msyslog(LOG_INFO, "PARSE receiver #%d: SYNCHRONIZED",
3791 					CLK_UNIT(parse->peer));
3792 		}
3793 
3794 		refclock_report(parse->peer, event);
3795 	}
3796 }
3797 
3798 /*--------------------------------------------------
3799  * process a PARSE time sample
3800  */
3801 static void
3802 parse_process(
3803 	struct parseunit *parse,
3804 	parsetime_t      *parsetime
3805 	)
3806 {
3807 	l_fp off, rectime, reftime;
3808 	double fudge;
3809 
3810 	/* silence warning: 'off.Ul_i.Xl_i' may be used uninitialized in this function */
3811 	ZERO(off);
3812 
3813 	/*
3814 	 * check for changes in conversion status
3815 	 * (only one for each new status !)
3816 	 */
3817 	if (((parsetime->parse_status & CVT_MASK) != CVT_OK) &&
3818 	    ((parsetime->parse_status & CVT_MASK) != CVT_NONE) &&
3819 	    (parse->timedata.parse_status != parsetime->parse_status))
3820 	{
3821 		char buffer[400];
3822 
3823 		NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
3824 			msyslog(LOG_WARNING, "PARSE receiver #%d: conversion status \"%s\"",
3825 				CLK_UNIT(parse->peer), parsestatus(parsetime->parse_status, buffer, sizeof(buffer)));
3826 
3827 		if ((parsetime->parse_status & CVT_MASK) == CVT_FAIL)
3828 		{
3829 			/*
3830 			 * tell more about the story - list time code
3831 			 * there is a slight change for a race condition and
3832 			 * the time code might be overwritten by the next packet
3833 			 */
3834 			parsectl_t tmpctl;
3835 
3836 			if (!PARSE_GETTIMECODE(parse, &tmpctl))
3837 			{
3838 				ERR(ERR_INTERNAL)
3839 					msyslog(LOG_ERR, "PARSE receiver #%d: parse_process: parse_timecode() FAILED", CLK_UNIT(parse->peer));
3840 			}
3841 			else
3842 			{
3843 				ERR(ERR_BADDATA)
3844 					msyslog(LOG_WARNING, "PARSE receiver #%d: FAILED TIMECODE: \"%s\" (check receiver configuration / wiring)",
3845 						CLK_UNIT(parse->peer), mkascii(buffer, sizeof buffer, tmpctl.parsegettc.parse_buffer, (unsigned)(tmpctl.parsegettc.parse_count - 1)));
3846 			}
3847 		}
3848 	}
3849 
3850 	/*
3851 	 * examine status and post appropriate events
3852 	 */
3853 	if ((parsetime->parse_status & CVT_MASK) != CVT_OK)
3854 	{
3855 		/*
3856 		 * got bad data - tell the rest of the system
3857 		 */
3858 		switch (parsetime->parse_status & CVT_MASK)
3859 		{
3860 		case CVT_NONE:
3861 			if ((parsetime->parse_status & CVT_ADDITIONAL) &&
3862 			    parse->parse_type->cl_message)
3863 				parse->parse_type->cl_message(parse, parsetime);
3864 			/*
3865 			 * save PPS information that comes piggyback
3866 			 */
3867 			if (PARSE_PPS(parsetime->parse_state))
3868 			  {
3869 			    parse->timedata.parse_state |= PARSEB_PPS|PARSEB_S_PPS;
3870 			    parse->timedata.parse_ptime  = parsetime->parse_ptime;
3871 			  }
3872 			break; 		/* well, still waiting - timeout is handled at higher levels */
3873 
3874 		case CVT_FAIL:
3875 			if (parsetime->parse_status & CVT_BADFMT)
3876 			{
3877 				parse_event(parse, CEVNT_BADREPLY);
3878 			}
3879 			else
3880 				if (parsetime->parse_status & CVT_BADDATE)
3881 				{
3882 					parse_event(parse, CEVNT_BADDATE);
3883 				}
3884 				else
3885 					if (parsetime->parse_status & CVT_BADTIME)
3886 					{
3887 						parse_event(parse, CEVNT_BADTIME);
3888 					}
3889 					else
3890 					{
3891 						parse_event(parse, CEVNT_BADREPLY); /* for the lack of something better */
3892 					}
3893 		}
3894 		return;			/* skip the rest - useless */
3895 	}
3896 
3897 	/*
3898 	 * check for format changes
3899 	 * (in case somebody has swapped clocks 8-)
3900 	 */
3901 	if (parse->lastformat != parsetime->parse_format)
3902 	{
3903 		parsectl_t tmpctl;
3904 
3905 		tmpctl.parseformat.parse_format = parsetime->parse_format;
3906 
3907 		if (!PARSE_GETFMT(parse, &tmpctl))
3908 		{
3909 			ERR(ERR_INTERNAL)
3910 				msyslog(LOG_ERR, "PARSE receiver #%d: parse_getfmt() FAILED", CLK_UNIT(parse->peer));
3911 		}
3912 		else
3913 		{
3914 			NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
3915 				msyslog(LOG_INFO, "PARSE receiver #%d: packet format \"%s\"",
3916 					CLK_UNIT(parse->peer), tmpctl.parseformat.parse_buffer);
3917 		}
3918 		parse->lastformat = parsetime->parse_format;
3919 	}
3920 
3921 	/*
3922 	 * now, any changes ?
3923 	 */
3924 	if ((parse->timedata.parse_state ^ parsetime->parse_state) &
3925 	    ~(unsigned)(PARSEB_PPS|PARSEB_S_PPS))
3926 	{
3927 		char tmp1[200];
3928 		char tmp2[200];
3929 		/*
3930 		 * something happend - except for PPS events
3931 		 */
3932 
3933 		(void) parsestate(parsetime->parse_state, tmp1, sizeof(tmp1));
3934 		(void) parsestate(parse->timedata.parse_state, tmp2, sizeof(tmp2));
3935 
3936 		NLOG(NLOG_CLOCKINFO) /* conditional if clause for conditional syslog */
3937 			msyslog(LOG_INFO,"PARSE receiver #%d: STATE CHANGE: %s -> %s",
3938 				CLK_UNIT(parse->peer), tmp2, tmp1);
3939 	}
3940 
3941 	/*
3942 	 * carry on PPS information if still usable
3943 	 */
3944 	if (PARSE_PPS(parse->timedata.parse_state) && !PARSE_PPS(parsetime->parse_state))
3945         {
3946 	        parsetime->parse_state |= PARSEB_PPS|PARSEB_S_PPS;
3947 		parsetime->parse_ptime  = parse->timedata.parse_ptime;
3948 	}
3949 
3950 	/*
3951 	 * remember for future
3952 	 */
3953 	parse->timedata = *parsetime;
3954 
3955 	/*
3956 	 * check to see, whether the clock did a complete powerup or lost PZF signal
3957 	 * and post correct events for current condition
3958 	 */
3959 	if (PARSE_POWERUP(parsetime->parse_state))
3960 	{
3961 		/*
3962 		 * this is bad, as we have completely lost synchronisation
3963 		 * well this is a problem with the receiver here
3964 		 * for PARSE Meinberg DCF77 receivers the lost synchronisation
3965 		 * is true as it is the powerup state and the time is taken
3966 		 * from a crude real time clock chip
3967 		 * for the PZF/GPS series this is only partly true, as
3968 		 * PARSE_POWERUP only means that the pseudo random
3969 		 * phase shift sequence cannot be found. this is only
3970 		 * bad, if we have never seen the clock in the SYNC
3971 		 * state, where the PHASE and EPOCH are correct.
3972 		 * for reporting events the above business does not
3973 		 * really matter, but we can use the time code
3974 		 * even in the POWERUP state after having seen
3975 		 * the clock in the synchronized state (PZF class
3976 		 * receivers) unless we have had a telegram disruption
3977 		 * after having seen the clock in the SYNC state. we
3978 		 * thus require having seen the clock in SYNC state
3979 		 * *after* having missed telegrams (noresponse) from
3980 		 * the clock. one problem remains: we might use erroneously
3981 		 * POWERUP data if the disruption is shorter than 1 polling
3982 		 * interval. fortunately powerdowns last usually longer than 64
3983 		 * seconds and the receiver is at least 2 minutes in the
3984 		 * POWERUP or NOSYNC state before switching to SYNC
3985 		 * for GPS receivers this can mean antenna problems and other causes.
3986 		 * the additional grace period can be enables by a clock
3987 		 * mode having the PARSE_F_POWERUPTRUST flag in cl_flag set.
3988 		 */
3989 		parse_event(parse, CEVNT_FAULT);
3990 		NLOG(NLOG_CLOCKSTATUS)
3991 			ERR(ERR_BADSTATUS)
3992 			msyslog(LOG_ERR,"PARSE receiver #%d: NOT SYNCHRONIZED/RECEIVER PROBLEMS",
3993 				CLK_UNIT(parse->peer));
3994 	}
3995 	else
3996 	{
3997 		/*
3998 		 * we have two states left
3999 		 *
4000 		 * SYNC:
4001 		 *  this state means that the EPOCH (timecode) and PHASE
4002 		 *  information has be read correctly (at least two
4003 		 *  successive PARSE timecodes were received correctly)
4004 		 *  this is the best possible state - full trust
4005 		 *
4006 		 * NOSYNC:
4007 		 *  The clock should be on phase with respect to the second
4008 		 *  signal, but the timecode has not been received correctly within
4009 		 *  at least the last two minutes. this is a sort of half baked state
4010 		 *  for PARSE Meinberg DCF77 clocks this is bad news (clock running
4011 		 *  without timecode confirmation)
4012 		 *  PZF 535 has also no time confirmation, but the phase should be
4013 		 *  very precise as the PZF signal can be decoded
4014 		 */
4015 
4016 		if (PARSE_SYNC(parsetime->parse_state))
4017 		{
4018 			/*
4019 			 * currently completely synchronized - best possible state
4020 			 */
4021 			parse->lastsync = current_time;
4022 			clear_err(parse, ERR_BADSTATUS);
4023 		}
4024 		else
4025 		{
4026 			/*
4027 			 * we have had some problems receiving the time code
4028 			 */
4029 			parse_event(parse, CEVNT_PROP);
4030 			NLOG(NLOG_CLOCKSTATUS)
4031 				ERR(ERR_BADSTATUS)
4032 				msyslog(LOG_ERR,"PARSE receiver #%d: TIMECODE NOT CONFIRMED",
4033 					CLK_UNIT(parse->peer));
4034 		}
4035 	}
4036 
4037 	fudge = parse->generic->fudgetime1; /* standard RS232 Fudgefactor */
4038 
4039 	if (PARSE_TIMECODE(parsetime->parse_state))
4040 	{
4041 		rectime = parsetime->parse_stime.fp;
4042 		off = reftime = parsetime->parse_time.fp;
4043 
4044 		L_SUB(&off, &rectime); /* prepare for PPS adjustments logic */
4045 
4046 #ifdef DEBUG
4047 		if (debug > 3)
4048 			printf("PARSE receiver #%d: Reftime %s, Recvtime %s - initial offset %s\n",
4049 			       CLK_UNIT(parse->peer),
4050 			       prettydate(&reftime),
4051 			       prettydate(&rectime),
4052 			       lfptoa(&off,6));
4053 #endif
4054 	}
4055 
4056 	if (PARSE_PPS(parsetime->parse_state) && CLK_PPS(parse->peer))
4057 	{
4058 		l_fp offset;
4059 		double ppsphaseadjust = parse->ppsphaseadjust;
4060 
4061 #ifdef HAVE_PPSAPI
4062 		/*
4063 		 * set fudge = 0.0 if already included in PPS time stamps
4064 		 */
4065 		if (parse->atom.pps_params.mode & (PPS_OFFSETCLEAR|PPS_OFFSETASSERT))
4066 		        {
4067 			        ppsphaseadjust = 0.0;
4068 			}
4069 #endif
4070 
4071 		/*
4072 		 * we have a PPS signal - much better than the RS232 stuff (we hope)
4073 		 */
4074 		offset = parsetime->parse_ptime.fp;
4075 
4076 #ifdef DEBUG
4077 		if (debug > 3)
4078 			printf("PARSE receiver #%d: PPStime %s\n",
4079 				CLK_UNIT(parse->peer),
4080 				prettydate(&offset));
4081 #endif
4082 		if (PARSE_TIMECODE(parsetime->parse_state))
4083 		{
4084 			if (M_ISGEQ(off.l_i, off.l_uf, -1, 0x80000000) &&
4085 			    M_ISGEQ(0, 0x7fffffff, off.l_i, off.l_uf))
4086 			{
4087 				fudge = ppsphaseadjust; /* pick PPS fudge factor */
4088 
4089 				/*
4090 				 * RS232 offsets within [-0.5..0.5[ - take PPS offsets
4091 				 */
4092 
4093 				if (parse->parse_type->cl_flags & PARSE_F_PPSONSECOND)
4094 				{
4095 					reftime = off = offset;
4096 					if (reftime.l_uf & 0x80000000)
4097 						reftime.l_ui++;
4098 					reftime.l_uf = 0;
4099 
4100 
4101 					/*
4102 					 * implied on second offset
4103 					 */
4104 					off.l_uf = ~off.l_uf; /* map [0.5..1[ -> [-0.5..0[ */
4105 					off.l_i = (off.l_uf & 0x8000000) ? -1 : 0; /* sign extend */
4106 				}
4107 				else
4108 				{
4109 					/*
4110 					 * time code describes pulse
4111 					 */
4112 					reftime = off = parsetime->parse_time.fp;
4113 
4114 					L_SUB(&off, &offset); /* true offset */
4115 				}
4116 			}
4117 			/*
4118 			 * take RS232 offset when PPS when out of bounds
4119 			 */
4120 		}
4121 		else
4122 		{
4123 			fudge = ppsphaseadjust; /* pick PPS fudge factor */
4124 			/*
4125 			 * Well, no time code to guide us - assume on second pulse
4126 			 * and pray, that we are within [-0.5..0.5[
4127 			 */
4128 			off = offset;
4129 			reftime = offset;
4130 			if (reftime.l_uf & 0x80000000)
4131 				reftime.l_ui++;
4132 			reftime.l_uf = 0;
4133 			/*
4134 			 * implied on second offset
4135 			 */
4136 			off.l_uf = ~off.l_uf; /* map [0.5..1[ -> [-0.5..0[ */
4137 			off.l_i = (off.l_uf & 0x80000000) ? -1 : 0; /* sign extend */
4138 		}
4139 	}
4140 	else
4141 	{
4142 		if (!PARSE_TIMECODE(parsetime->parse_state))
4143 		{
4144 			/*
4145 			 * Well, no PPS, no TIMECODE, no more work ...
4146 			 */
4147 			if ((parsetime->parse_status & CVT_ADDITIONAL) &&
4148 			    parse->parse_type->cl_message)
4149 				parse->parse_type->cl_message(parse, parsetime);
4150 			return;
4151 		}
4152 	}
4153 
4154 #ifdef DEBUG
4155 	if (debug > 3)
4156 		printf("PARSE receiver #%d: Reftime %s, Recvtime %s - final offset %s\n",
4157 			CLK_UNIT(parse->peer),
4158 			prettydate(&reftime),
4159 			prettydate(&rectime),
4160 			lfptoa(&off,6));
4161 #endif
4162 
4163 
4164 	rectime = reftime;
4165 	L_SUB(&rectime, &off);	/* just to keep the ntp interface happy */
4166 
4167 #ifdef DEBUG
4168 	if (debug > 3)
4169 		printf("PARSE receiver #%d: calculated Reftime %s, Recvtime %s\n",
4170 			CLK_UNIT(parse->peer),
4171 			prettydate(&reftime),
4172 			prettydate(&rectime));
4173 #endif
4174 
4175 	if ((parsetime->parse_status & CVT_ADDITIONAL) &&
4176 	    parse->parse_type->cl_message)
4177 		parse->parse_type->cl_message(parse, parsetime);
4178 
4179 	if (PARSE_SYNC(parsetime->parse_state))
4180 	{
4181 		/*
4182 		 * log OK status
4183 		 */
4184 		parse_event(parse, CEVNT_NOMINAL);
4185 	}
4186 
4187 	clear_err(parse, ERR_BADIO);
4188 	clear_err(parse, ERR_BADDATA);
4189 	clear_err(parse, ERR_NODATA);
4190 	clear_err(parse, ERR_INTERNAL);
4191 
4192 	/*
4193 	 * and now stick it into the clock machine
4194 	 * samples are only valid iff lastsync is not too old and
4195 	 * we have seen the clock in sync at least once
4196 	 * after the last time we didn't see an expected data telegram
4197 	 * at startup being not in sync is also bad just like
4198 	 * POWERUP state unless PARSE_F_POWERUPTRUST is set
4199 	 * see the clock states section above for more reasoning
4200 	 */
4201 	if (((current_time - parse->lastsync) > parse->maxunsync)           ||
4202 	    (parse->lastsync < parse->lastmissed)                           ||
4203 	    ((parse->lastsync == 0) && !PARSE_SYNC(parsetime->parse_state)) ||
4204 	    (((parse->parse_type->cl_flags & PARSE_F_POWERUPTRUST) == 0) &&
4205 	     PARSE_POWERUP(parsetime->parse_state)))
4206 	{
4207 		parse->generic->leap = LEAP_NOTINSYNC;
4208 		parse->lastsync = 0;	/* wait for full sync again */
4209 	}
4210 	else
4211 	{
4212 		if (PARSE_LEAPADD(parsetime->parse_state))
4213 		{
4214 			/*
4215 			 * we pick this state also for time code that pass leap warnings
4216 			 * without direction information (as earth is currently slowing
4217 			 * down).
4218 			 */
4219 			parse->generic->leap = (parse->flags & PARSE_LEAP_DELETE) ? LEAP_DELSECOND : LEAP_ADDSECOND;
4220 		}
4221 		else
4222 		    if (PARSE_LEAPDEL(parsetime->parse_state))
4223 		    {
4224 			    parse->generic->leap = LEAP_DELSECOND;
4225 		    }
4226 		    else
4227 		    {
4228 			    parse->generic->leap = LEAP_NOWARNING;
4229 		    }
4230 	}
4231 
4232 	if (parse->generic->leap != LEAP_NOTINSYNC)
4233 	{
4234 	        /*
4235 		 * only good/trusted samples are interesting
4236 		 */
4237 #ifdef DEBUG
4238 	        if (debug > 2)
4239 		        {
4240 			        printf("PARSE receiver #%d: refclock_process_offset(reftime=%s, rectime=%s, Fudge=%f)\n",
4241 				       CLK_UNIT(parse->peer),
4242 				       prettydate(&reftime),
4243 				       prettydate(&rectime),
4244 				       fudge);
4245 			}
4246 #endif
4247 		parse->generic->lastref = reftime;
4248 
4249 		refclock_process_offset(parse->generic, reftime, rectime, fudge);
4250 
4251 #ifdef HAVE_PPSAPI
4252 		/*
4253 		 * pass PPS information on to PPS clock
4254 		 */
4255 		if (PARSE_PPS(parsetime->parse_state) && CLK_PPS(parse->peer))
4256 		        {
4257 			  /* refclock_pps includes fudgetime1 - we keep the RS232 offset in there :-( */
4258 			        double savedtime1 = parse->generic->fudgetime1;
4259 
4260 				parse->generic->fudgetime1 = fudge;
4261 
4262 				if (refclock_pps(parse->peer, &parse->atom,
4263 						 parse->flags & (CLK_FLAG1|CLK_FLAG2|CLK_FLAG3|CLK_FLAG4))) {
4264 					parse->peer->flags |= FLAG_PPS;
4265 				} else {
4266 					parse->peer->flags &= ~FLAG_PPS;
4267 				}
4268 
4269 				parse->generic->fudgetime1 = savedtime1;
4270 
4271 				parse_hardpps(parse, PARSE_HARDPPS_ENABLE);
4272 			}
4273 #endif
4274 	} else {
4275 	        parse_hardpps(parse, PARSE_HARDPPS_DISABLE);
4276 		parse->peer->flags &= ~FLAG_PPS;
4277 	}
4278 
4279 	/*
4280 	 * ready, unless the machine wants a sample or
4281 	 * we are in fast startup mode (peer->dist > MAXDISTANCE)
4282 	 */
4283 	if (!parse->pollneeddata && parse->peer->disp <= MAXDISTANCE)
4284 	    return;
4285 
4286 	parse->pollneeddata = 0;
4287 
4288 	parse->timedata.parse_state &= ~(unsigned)(PARSEB_PPS|PARSEB_S_PPS);
4289 
4290 	refclock_receive(parse->peer);
4291 }
4292 
4293 /**===========================================================================
4294  ** special code for special clocks
4295  **/
4296 
4297 static void
4298 mk_utcinfo(
4299 	   char *t,
4300 	   int wnt,
4301 	   int wnlsf,
4302 	   int dn,
4303 	   int dtls,
4304 	   int dtlsf,
4305 	   int size
4306 	   )
4307 {
4308   l_fp leapdate;
4309   char *start = t;
4310 
4311   snprintf(t, size, "current correction %d sec", dtls);
4312   t += strlen(t);
4313 
4314   if (wnlsf < 990)
4315     wnlsf += 1024;
4316 
4317   if (wnt < 990)
4318     wnt += 1024;
4319 
4320   gpstolfp((unsigned short)wnlsf, (unsigned short)dn, 0, &leapdate);
4321 
4322   if ((dtlsf != dtls) &&
4323       ((wnlsf - wnt) < 52))
4324     {
4325 	    snprintf(t, BUFFER_SIZES(start, t, size), ", next correction %d sec on %s, new GPS-UTC offset %d",
4326 	      dtlsf - dtls, gmprettydate(&leapdate), dtlsf);
4327     }
4328   else
4329     {
4330 	    snprintf(t, BUFFER_SIZES(start, t, size), ", last correction on %s",
4331 	      gmprettydate(&leapdate));
4332     }
4333 }
4334 
4335 #ifdef CLOCK_MEINBERG
4336 /**===========================================================================
4337  ** Meinberg GPS166/GPS167 support
4338  **/
4339 
4340 /*------------------------------------------------------------
4341  * gps16x_message - process GPS16x messages
4342  */
4343 static void
4344 gps16x_message(
4345 	       struct parseunit *parse,
4346 	       parsetime_t      *parsetime
4347 	       )
4348 {
4349 	if (parse->timedata.parse_msglen && parsetime->parse_msg[0] == SOH)
4350 	{
4351 		GPS_MSG_HDR header;
4352 		unsigned char *bufp = (unsigned char *)parsetime->parse_msg + 1;
4353 
4354 #ifdef DEBUG
4355 		if (debug > 2)
4356 		{
4357 			char msgbuffer[600];
4358 
4359 			mkreadable(msgbuffer, sizeof(msgbuffer), (char *)parsetime->parse_msg, parsetime->parse_msglen, 1);
4360 			printf("PARSE receiver #%d: received message (%d bytes) >%s<\n",
4361 				CLK_UNIT(parse->peer),
4362 				parsetime->parse_msglen,
4363 				msgbuffer);
4364 		}
4365 #endif
4366 		get_mbg_header(&bufp, &header);
4367 		if (header.gps_hdr_csum == mbg_csum(parsetime->parse_msg + 1, 6) &&
4368 		    (header.gps_len == 0 ||
4369 		     (header.gps_len < sizeof(parsetime->parse_msg) &&
4370 		      header.gps_data_csum == mbg_csum(bufp, header.gps_len))))
4371 		{
4372 			/*
4373 			 * clean message
4374 			 */
4375 			switch (header.gps_cmd)
4376 			{
4377 			case GPS_SW_REV:
4378 				{
4379 					char buffer[64];
4380 					SW_REV gps_sw_rev;
4381 
4382 					get_mbg_sw_rev(&bufp, &gps_sw_rev);
4383 					snprintf(buffer, sizeof(buffer), "meinberg_gps_version=\"%x.%02x%s%s\"",
4384 						(gps_sw_rev.code >> 8) & 0xFF,
4385 						gps_sw_rev.code & 0xFF,
4386 						gps_sw_rev.name[0] ? " " : "",
4387 						gps_sw_rev.name);
4388 					set_var(&parse->kv, buffer, strlen(buffer)+1, RO|DEF);
4389 				}
4390 			break;
4391 
4392 			case GPS_STAT:
4393 				{
4394 					static struct state
4395 					{
4396 						unsigned short flag; /* status flag */
4397 						unsigned const char *string; /* bit name */
4398 					} states[] =
4399 					  {
4400 						  { TM_ANT_DISCONN, (const unsigned char *)"ANTENNA FAULTY" },
4401 						  { TM_SYN_FLAG,    (const unsigned char *)"NO SYNC SIGNAL" },
4402 						  { TM_NO_SYNC,     (const unsigned char *)"NO SYNC POWERUP" },
4403 						  { TM_NO_POS,      (const unsigned char *)"NO POSITION" },
4404 						  { 0, (const unsigned char *)"" }
4405 					  };
4406 					unsigned short status;
4407 					struct state *s = states;
4408 					char buffer[512];
4409 					char *p, *b;
4410 
4411 					status = get_lsb_short(&bufp);
4412 					p = b = buffer;
4413 					p = ap(buffer, sizeof(buffer), p,
4414 					    "meinberg_gps_status=\"[0x%04x] ",
4415 					    status);
4416 
4417 					if (status)
4418 					{
4419 						b = p;
4420 						while (s->flag)
4421 						{
4422 							if (status & s->flag)
4423 							{
4424 								if (p != b)
4425 								{
4426 									p = ap(buffer, sizeof(buffer), p, ", ");
4427 								}
4428 
4429 <<<<<<< refclock_parse.c
4430 								p = ap(buffer, sizeof(buffer), p, "%s", (const char *)s->string);
4431 =======
4432 								strlcat(p, (const char *)s->string, sizeof(buffer));
4433 >>>>>>> 1.1.1.3
4434 							}
4435 							s++;
4436 						}
4437 						p = ap(buffer, sizeof(buffer), p, "\"");
4438 					}
4439 					else
4440 					{
4441 <<<<<<< refclock_parse.c
4442 						p = ap(buffer, sizeof(buffer), p, "<OK>\"");
4443 =======
4444 						strlcat(buffer, "<OK>\"", sizeof(buffer));
4445 >>>>>>> 1.1.1.3
4446 					}
4447 
4448 					set_var(&parse->kv, buffer, strlen(buffer)+1, RO|DEF);
4449 				}
4450 			break;
4451 
4452 			case GPS_POS_XYZ:
4453 				{
4454 					XYZ xyz;
4455 					char buffer[256];
4456 
4457 					get_mbg_xyz(&bufp, xyz);
4458 					snprintf(buffer, sizeof(buffer), "gps_position(XYZ)=\"%s m, %s m, %s m\"",
4459 						mfptoa(xyz[XP].l_ui, xyz[XP].l_uf, 1),
4460 						mfptoa(xyz[YP].l_ui, xyz[YP].l_uf, 1),
4461 						mfptoa(xyz[ZP].l_ui, xyz[ZP].l_uf, 1));
4462 
4463 					set_var(&parse->kv, buffer, sizeof(buffer), RO|DEF);
4464 				}
4465 			break;
4466 
4467 			case GPS_POS_LLA:
4468 				{
4469 					LLA lla;
4470 					char buffer[256];
4471 
4472 					get_mbg_lla(&bufp, lla);
4473 
4474 					snprintf(buffer, sizeof(buffer), "gps_position(LLA)=\"%s deg, %s deg, %s m\"",
4475 						mfptoa(lla[LAT].l_ui, lla[LAT].l_uf, 4),
4476 						mfptoa(lla[LON].l_ui, lla[LON].l_uf, 4),
4477 						mfptoa(lla[ALT].l_ui, lla[ALT].l_uf, 1));
4478 
4479 					set_var(&parse->kv, buffer, sizeof(buffer), RO|DEF);
4480 				}
4481 			break;
4482 
4483 			case GPS_TZDL:
4484 				break;
4485 
4486 			case GPS_PORT_PARM:
4487 				break;
4488 
4489 			case GPS_SYNTH:
4490 				break;
4491 
4492 			case GPS_ANT_INFO:
4493 				{
4494 					ANT_INFO antinfo;
4495 					char buffer[512];
4496 					char *p, *q;
4497 
4498 					get_mbg_antinfo(&bufp, &antinfo);
4499 					p = buffer;
4500 					p = ap(buffer, sizeof(buffer), p, "meinberg_antenna_status=\"");
4501 					switch (antinfo.status)
4502 					{
4503 					case ANT_INVALID:
4504 <<<<<<< refclock_parse.c
4505 						p = ap(buffer, sizeof(buffer),
4506 						    p, "<OK>");
4507 =======
4508 						strlcat(p, "<OK>", BUFFER_SIZE(buffer, p));
4509 						p += strlen(p);
4510 >>>>>>> 1.1.1.3
4511 						break;
4512 
4513 					case ANT_DISCONN:
4514 <<<<<<< refclock_parse.c
4515 						q = ap(buffer, sizeof(buffer),
4516 						    p, "DISCONNECTED since ");
4517 =======
4518 						strlcat(p, "DISCONNECTED since ", BUFFER_SIZE(buffer, p));
4519 >>>>>>> 1.1.1.3
4520 						NLOG(NLOG_CLOCKSTATUS)
4521 							ERR(ERR_BADSTATUS)
4522 							msyslog(LOG_ERR,"PARSE receiver #%d: ANTENNA FAILURE: %s",
4523 								CLK_UNIT(parse->peer), p);
4524 
4525 						p = q;
4526 						mbg_tm_str(&p, &antinfo.tm_disconn, BUFFER_SIZE(buffer, p));
4527 						*p = '\0';
4528 						break;
4529 
4530 					case ANT_RECONN:
4531 <<<<<<< refclock_parse.c
4532 						p = ap(buffer, sizeof(buffer),
4533 						    p, "RECONNECTED on ");
4534 =======
4535 						strlcat(p, "RECONNECTED on ", BUFFER_SIZE(buffer, p));
4536 						p += strlen(p);
4537 >>>>>>> 1.1.1.3
4538 						mbg_tm_str(&p, &antinfo.tm_reconn, BUFFER_SIZE(buffer, p));
4539 						p = ap(buffer, sizeof(buffer),
4540 							p, ", reconnect clockoffset %c%ld.%07ld s, disconnect time ",
4541 							(antinfo.delta_t < 0) ? '-' : '+',
4542 							ABS(antinfo.delta_t) / 10000,
4543 							ABS(antinfo.delta_t) % 10000);
4544 						mbg_tm_str(&p, &antinfo.tm_disconn, BUFFER_SIZE(buffer, p));
4545 						*p = '\0';
4546 						break;
4547 
4548 					default:
4549 						p = ap(buffer, sizeof(buffer),
4550 						    p, "bad status 0x%04x",
4551 						    antinfo.status);
4552 						break;
4553 					}
4554 
4555 <<<<<<< refclock_parse.c
4556 					p = ap(buffer, sizeof(buffer), p, "\"");
4557 =======
4558 					strlcat(p, "\"", BUFFER_SIZE(buffer, p));
4559 >>>>>>> 1.1.1.3
4560 
4561 					set_var(&parse->kv, buffer, sizeof(buffer), RO|DEF);
4562 				}
4563 			break;
4564 
4565 			case GPS_UCAP:
4566 				break;
4567 
4568 			case GPS_CFGH:
4569 				{
4570 					CFGH cfgh;
4571 					char buffer[512];
4572 					char *p;
4573 
4574 					get_mbg_cfgh(&bufp, &cfgh);
4575 					if (cfgh.valid)
4576 					{
4577 						int i;
4578 
4579 						p = buffer;
4580 <<<<<<< refclock_parse.c
4581 						p = ap(buffer, sizeof(buffer),
4582 						    p, "gps_tot_51=\"");
4583 =======
4584 						strlcpy(buffer, "gps_tot_51=\"", BUFFER_SIZE(buffer, p));
4585 						p += strlen(p);
4586 >>>>>>> 1.1.1.3
4587 						mbg_tgps_str(&p, &cfgh.tot_51, BUFFER_SIZE(buffer, p));
4588 <<<<<<< refclock_parse.c
4589 						p = ap(buffer, sizeof(buffer),
4590 						    p, "\"");
4591 						set_var(&parse->kv, buffer, sizeof(buffer), RO);
4592 =======
4593 						strlcpy(p, "\"", BUFFER_SIZE(buffer, p));
4594 						set_var(&parse->kv, buffer, strlen(buffer)+1, RO);
4595 >>>>>>> 1.1.1.3
4596 
4597 						p = buffer;
4598 <<<<<<< refclock_parse.c
4599 						p = ap(buffer, sizeof(buffer),
4600 						    p, "gps_tot_63=\"");
4601 =======
4602 						strlcpy(buffer, "gps_tot_63=\"", BUFFER_SIZE(buffer, p));
4603 						p += strlen(p);
4604 >>>>>>> 1.1.1.3
4605 						mbg_tgps_str(&p, &cfgh.tot_63, BUFFER_SIZE(buffer, p));
4606 <<<<<<< refclock_parse.c
4607 						p = ap(buffer, sizeof(buffer),
4608 						    p, "\"");
4609 						set_var(&parse->kv, buffer, sizeof(buffer), RO);
4610 =======
4611 						strlcpy(p, "\"", BUFFER_SIZE(buffer, p));
4612 						set_var(&parse->kv, buffer, strlen(buffer)+1, RO);
4613 >>>>>>> 1.1.1.3
4614 
4615 						p = buffer;
4616 <<<<<<< refclock_parse.c
4617 						p = ap(buffer, sizeof(buffer),
4618 						    p, "gps_t0a=\"");
4619 =======
4620 						strlcpy(buffer, "gps_t0a=\"", BUFFER_SIZE(buffer, p));
4621 						p += strlen(p);
4622 >>>>>>> 1.1.1.3
4623 						mbg_tgps_str(&p, &cfgh.t0a, BUFFER_SIZE(buffer, p));
4624 <<<<<<< refclock_parse.c
4625 						p = ap(buffer, sizeof(buffer),
4626 						    p, "\"");
4627 						set_var(&parse->kv, buffer, sizeof(buffer), RO);
4628 =======
4629 						strlcpy(p, "\"", BUFFER_SIZE(buffer, p));
4630 						set_var(&parse->kv, buffer, strlen(buffer)+1, RO);
4631 >>>>>>> 1.1.1.3
4632 
4633 						for (i = MIN_SVNO; i < MAX_SVNO; i++)
4634 						{
4635 							p = buffer;
4636 							p = ap(buffer, sizeof(buffer), p, "gps_cfg[%d]=\"[0x%x] ", i, cfgh.cfg[i]);
4637 							switch (cfgh.cfg[i] & 0x7)
4638 							{
4639 							case 0:
4640 <<<<<<< refclock_parse.c
4641 								p = ap(buffer, sizeof(buffer), p, "BLOCK I");
4642 =======
4643 								strlcpy(p, "BLOCK I", BUFFER_SIZE(buffer, p));
4644 >>>>>>> 1.1.1.3
4645 								break;
4646 							case 1:
4647 <<<<<<< refclock_parse.c
4648 								p = ap(buffer, sizeof(buffer), p, "BLOCK II");
4649 =======
4650 								strlcpy(p, "BLOCK II", BUFFER_SIZE(buffer, p));
4651 >>>>>>> 1.1.1.3
4652 								break;
4653 							default:
4654 <<<<<<< refclock_parse.c
4655 								p = ap(buffer, sizeof(buffer), p, "bad CFG");
4656 =======
4657 								strlcpy(p, "bad CFG", BUFFER_SIZE(buffer, p));
4658 >>>>>>> 1.1.1.3
4659 								break;
4660 							}
4661 <<<<<<< refclock_parse.c
4662 							p = ap(buffer, sizeof(buffer), p, "\"");
4663 							set_var(&parse->kv, buffer, sizeof(buffer), RO);
4664 =======
4665 							strlcat(p, "\"", BUFFER_SIZE(buffer, p));
4666 							set_var(&parse->kv, buffer, strlen(buffer)+1, RO);
4667 >>>>>>> 1.1.1.3
4668 
4669 							p = buffer;
4670 							p = ap(buffer, sizeof(buffer), p, "gps_health[%d]=\"[0x%x] ", i, cfgh.health[i]);
4671 							switch ((cfgh.health[i] >> 5) & 0x7 )
4672 							{
4673 							case 0:
4674 <<<<<<< refclock_parse.c
4675 								p = ap(buffer, sizeof(buffer), p, "OK;");
4676 =======
4677 								strlcpy(p, "OK;", BUFFER_SIZE(buffer, p));
4678 >>>>>>> 1.1.1.3
4679 								break;
4680 							case 1:
4681 <<<<<<< refclock_parse.c
4682 								p = ap(buffer, sizeof(buffer), p, "PARITY;");
4683 =======
4684 								strlcpy(p, "PARITY;", BUFFER_SIZE(buffer, p));
4685 >>>>>>> 1.1.1.3
4686 								break;
4687 							case 2:
4688 <<<<<<< refclock_parse.c
4689 								p = ap(buffer, sizeof(buffer), p, "TLM/HOW;");
4690 =======
4691 								strlcpy(p, "TLM/HOW;", BUFFER_SIZE(buffer, p));
4692 >>>>>>> 1.1.1.3
4693 								break;
4694 							case 3:
4695 <<<<<<< refclock_parse.c
4696 								p = ap(buffer, sizeof(buffer), p, "Z-COUNT;");
4697 =======
4698 								strlcpy(p, "Z-COUNT;", BUFFER_SIZE(buffer, p));
4699 >>>>>>> 1.1.1.3
4700 								break;
4701 							case 4:
4702 <<<<<<< refclock_parse.c
4703 								p = ap(buffer, sizeof(buffer), p, "SUBFRAME 1,2,3;");
4704 =======
4705 								strlcpy(p, "SUBFRAME 1,2,3;", BUFFER_SIZE(buffer, p));
4706 >>>>>>> 1.1.1.3
4707 								break;
4708 							case 5:
4709 <<<<<<< refclock_parse.c
4710 								p = ap(buffer, sizeof(buffer), p, "SUBFRAME 4,5;");
4711 =======
4712 								strlcpy(p, "SUBFRAME 4,5;", BUFFER_SIZE(buffer, p));
4713 >>>>>>> 1.1.1.3
4714 								break;
4715 							case 6:
4716 <<<<<<< refclock_parse.c
4717 								p = ap(buffer, sizeof(buffer), p, "UPLOAD BAD;");
4718 =======
4719 								strlcpy(p, "UPLOAD BAD;", BUFFER_SIZE(buffer, p));
4720 >>>>>>> 1.1.1.3
4721 								break;
4722 							case 7:
4723 <<<<<<< refclock_parse.c
4724 								p = ap(buffer, sizeof(buffer), p, "DATA BAD;");
4725 =======
4726 								strlcpy(p, "DATA BAD;", BUFFER_SIZE(buffer, p));
4727 >>>>>>> 1.1.1.3
4728 								break;
4729 							}
4730 
4731 							switch (cfgh.health[i] & 0x1F)
4732 							{
4733 							case 0:
4734 <<<<<<< refclock_parse.c
4735 								p = ap(buffer, sizeof(buffer), p, "SIGNAL OK");
4736 =======
4737 								strlcpy(p, "SIGNAL OK", BUFFER_SIZE(buffer, p));
4738 >>>>>>> 1.1.1.3
4739 								break;
4740 							case 0x1C:
4741 <<<<<<< refclock_parse.c
4742 								p = ap(buffer, sizeof(buffer), p, "SV TEMP OUT");
4743 =======
4744 								strlcpy(p, "SV TEMP OUT", BUFFER_SIZE(buffer, p));
4745 >>>>>>> 1.1.1.3
4746 								break;
4747 							case 0x1D:
4748 <<<<<<< refclock_parse.c
4749 								p = ap(buffer, sizeof(buffer), p, "SV WILL BE TEMP OUT");
4750 =======
4751 								strlcpy(p, "SV WILL BE TEMP OUT", BUFFER_SIZE(buffer, p));
4752 >>>>>>> 1.1.1.3
4753 								break;
4754 							case 0x1E:
4755 								break;
4756 							case 0x1F:
4757 <<<<<<< refclock_parse.c
4758 								p = ap(buffer, sizeof(buffer), p, "MULTIPLE ERRS");
4759 =======
4760 								strlcpy(p, "MULTIPLE ERRS", BUFFER_SIZE(buffer, p));
4761 >>>>>>> 1.1.1.3
4762 								break;
4763 							default:
4764 <<<<<<< refclock_parse.c
4765 								p = ap(buffer, sizeof(buffer), p, "TRANSMISSION PROBLEMS");
4766 =======
4767 								strlcpy(p, "TRANSMISSION PROBLEMS", BUFFER_SIZE(buffer, p));
4768 >>>>>>> 1.1.1.3
4769 								break;
4770 							}
4771 
4772 <<<<<<< refclock_parse.c
4773 							p = ap(buffer, sizeof(buffer), p, "\"");
4774 							set_var(&parse->kv, buffer, sizeof(buffer), RO);
4775 =======
4776 							strlcat(p, "\"", sizeof(buffer));
4777 							set_var(&parse->kv, buffer, strlen(buffer)+1, RO);
4778 >>>>>>> 1.1.1.3
4779 						}
4780 					}
4781 				}
4782 			break;
4783 
4784 			case GPS_ALM:
4785 				break;
4786 
4787 			case GPS_EPH:
4788 				break;
4789 
4790 			case GPS_UTC:
4791 				{
4792 					UTC utc;
4793 					char buffer[512];
4794 					char *p;
4795 
4796 					p = buffer;
4797 
4798 					get_mbg_utc(&bufp, &utc);
4799 
4800 					if (utc.valid)
4801 					{
4802 <<<<<<< refclock_parse.c
4803 						p = ap(buffer, sizeof(buffer), p, "gps_utc_correction=\"");
4804 						mk_utcinfo(p, utc.t0t.wn, utc.WNlsf, utc.DNt, utc.delta_tls, utc.delta_tlsf, BUFFER_SIZE(buffer, p));
4805 =======
4806 						strlcpy(p, "gps_utc_correction=\"", sizeof(buffer));
4807 >>>>>>> 1.1.1.3
4808 						p += strlen(p);
4809 <<<<<<< refclock_parse.c
4810 						p = ap(buffer, sizeof(buffer), p, "\"");
4811 =======
4812 						mk_utcinfo(p, utc.t0t.wn, utc.WNlsf, utc.DNt, utc.delta_tls, utc.delta_tlsf, BUFFER_SIZE(buffer, p));
4813 						strlcat(p, "\"", BUFFER_SIZE(buffer, p));
4814 >>>>>>> 1.1.1.3
4815 					}
4816 					else
4817 					{
4818 <<<<<<< refclock_parse.c
4819 						p = ap(buffer, sizeof(buffer), p, "gps_utc_correction=\"<NO UTC DATA>\"");
4820 =======
4821 						strlcpy(p, "gps_utc_correction=\"<NO UTC DATA>\"", BUFFER_SIZE(buffer, p));
4822 >>>>>>> 1.1.1.3
4823 					}
4824 					set_var(&parse->kv, buffer, sizeof(buffer), RO|DEF);
4825 				}
4826 			break;
4827 
4828 			case GPS_IONO:
4829 				break;
4830 
4831 			case GPS_ASCII_MSG:
4832 				{
4833 					ASCII_MSG gps_ascii_msg;
4834 					char buffer[128];
4835 
4836 					get_mbg_ascii_msg(&bufp, &gps_ascii_msg);
4837 
4838 					if (gps_ascii_msg.valid)
4839 						{
4840 							char buffer1[128];
4841 							mkreadable(buffer1, sizeof(buffer1), gps_ascii_msg.s, strlen(gps_ascii_msg.s), (int)0);
4842 
4843 							snprintf(buffer, sizeof(buffer), "gps_message=\"%s\"", buffer1);
4844 						}
4845 					else
4846 <<<<<<< refclock_parse.c
4847 						snprintf(buffer, sizeof(buffer), "gps_message=<NONE>");
4848 =======
4849 						strlcpy(buffer, "gps_message=<NONE>", sizeof(buffer));
4850 >>>>>>> 1.1.1.3
4851 
4852 					set_var(&parse->kv, buffer, sizeof(buffer), RO|DEF);
4853 				}
4854 
4855 			break;
4856 
4857 			default:
4858 				break;
4859 			}
4860 		}
4861 		else
4862 		{
4863 			msyslog(LOG_DEBUG, "PARSE receiver #%d: gps16x_message: message checksum error: hdr_csum = 0x%x (expected 0x%lx), data_len = %d, data_csum = 0x%x (expected 0x%lx)",
4864 				CLK_UNIT(parse->peer),
4865 				header.gps_hdr_csum, mbg_csum(parsetime->parse_msg + 1, 6),
4866 				header.gps_len,
4867 				header.gps_data_csum, mbg_csum(bufp, (unsigned)((header.gps_len < sizeof(parsetime->parse_msg)) ? header.gps_len : 0)));
4868 		}
4869 	}
4870 
4871 	return;
4872 }
4873 
4874 /*------------------------------------------------------------
4875  * gps16x_poll - query the reciver peridically
4876  */
4877 static void
4878 gps16x_poll(
4879 	    struct peer *peer
4880 	    )
4881 {
4882 	struct parseunit *parse = peer->procptr->unitptr;
4883 
4884 	static GPS_MSG_HDR sequence[] =
4885 	{
4886 		{ GPS_SW_REV,          0, 0, 0 },
4887 		{ GPS_STAT,            0, 0, 0 },
4888 		{ GPS_UTC,             0, 0, 0 },
4889 		{ GPS_ASCII_MSG,       0, 0, 0 },
4890 		{ GPS_ANT_INFO,        0, 0, 0 },
4891 		{ GPS_CFGH,            0, 0, 0 },
4892 		{ GPS_POS_XYZ,         0, 0, 0 },
4893 		{ GPS_POS_LLA,         0, 0, 0 },
4894 		{ (unsigned short)~0,  0, 0, 0 }
4895 	};
4896 
4897 	int rtc;
4898 	unsigned char cmd_buffer[64];
4899 	unsigned char *outp = cmd_buffer;
4900 	GPS_MSG_HDR *header;
4901 
4902 	if (((poll_info_t *)parse->parse_type->cl_data)->rate)
4903 	{
4904 		parse->peer->procptr->nextaction = current_time + ((poll_info_t *)parse->parse_type->cl_data)->rate;
4905 	}
4906 
4907 	if (sequence[parse->localstate].gps_cmd == (unsigned short)~0)
4908 		parse->localstate = 0;
4909 
4910 	header = sequence + parse->localstate++;
4911 
4912 	*outp++ = SOH;		/* start command */
4913 
4914 	put_mbg_header(&outp, header);
4915 	outp = cmd_buffer + 1;
4916 
4917 	header->gps_hdr_csum = (short)mbg_csum(outp, 6);
4918 	put_mbg_header(&outp, header);
4919 
4920 #ifdef DEBUG
4921 	if (debug > 2)
4922 	{
4923 		char buffer[128];
4924 
4925 		mkreadable(buffer, sizeof(buffer), (char *)cmd_buffer, (unsigned)(outp - cmd_buffer), 1);
4926 		printf("PARSE receiver #%d: transmitted message #%ld (%d bytes) >%s<\n",
4927 		       CLK_UNIT(parse->peer),
4928 		       parse->localstate - 1,
4929 		       (int)(outp - cmd_buffer),
4930 		       buffer);
4931 	}
4932 #endif
4933 
4934 	rtc = write(parse->generic->io.fd, cmd_buffer, (unsigned long)(outp - cmd_buffer));
4935 
4936 	if (rtc < 0)
4937 	{
4938 		ERR(ERR_BADIO)
4939 			msyslog(LOG_ERR, "PARSE receiver #%d: gps16x_poll: failed to send cmd to clock: %m", CLK_UNIT(parse->peer));
4940 	}
4941 	else
4942 	if (rtc != outp - cmd_buffer)
4943 	{
4944 		ERR(ERR_BADIO)
4945 			msyslog(LOG_ERR, "PARSE receiver #%d: gps16x_poll: failed to send cmd incomplete (%d of %d bytes sent)", CLK_UNIT(parse->peer), rtc, (int)(outp - cmd_buffer));
4946 	}
4947 
4948 	clear_err(parse, ERR_BADIO);
4949 	return;
4950 }
4951 
4952 /*--------------------------------------------------
4953  * init routine - setup timer
4954  */
4955 static int
4956 gps16x_poll_init(
4957 	struct parseunit *parse
4958 	)
4959 {
4960 	if (((poll_info_t *)parse->parse_type->cl_data)->rate)
4961 	{
4962 		parse->peer->procptr->action = gps16x_poll;
4963 		gps16x_poll(parse->peer);
4964 	}
4965 
4966 	return 0;
4967 }
4968 
4969 #else
4970 static void
4971 gps16x_message(
4972 	       struct parseunit *parse,
4973 	       parsetime_t      *parsetime
4974 	       )
4975 {}
4976 static int
4977 gps16x_poll_init(
4978 	struct parseunit *parse
4979 	)
4980 {
4981 	return 1;
4982 }
4983 #endif /* CLOCK_MEINBERG */
4984 
4985 /**===========================================================================
4986  ** clock polling support
4987  **/
4988 
4989 /*--------------------------------------------------
4990  * direct poll routine
4991  */
4992 static void
4993 poll_dpoll(
4994 	struct parseunit *parse
4995 	)
4996 {
4997 	int rtc;
4998 	const char *ps = ((poll_info_t *)parse->parse_type->cl_data)->string;
4999 	int   ct = ((poll_info_t *)parse->parse_type->cl_data)->count;
5000 
5001 	rtc = write(parse->generic->io.fd, ps, (unsigned long)ct);
5002 	if (rtc < 0)
5003 	{
5004 		ERR(ERR_BADIO)
5005 			msyslog(LOG_ERR, "PARSE receiver #%d: poll_dpoll: failed to send cmd to clock: %m", CLK_UNIT(parse->peer));
5006 	}
5007 	else
5008 	    if (rtc != ct)
5009 	    {
5010 		    ERR(ERR_BADIO)
5011 			    msyslog(LOG_ERR, "PARSE receiver #%d: poll_dpoll: failed to send cmd incomplete (%d of %d bytes sent)", CLK_UNIT(parse->peer), rtc, ct);
5012 	    }
5013 	clear_err(parse, ERR_BADIO);
5014 }
5015 
5016 /*--------------------------------------------------
5017  * periodic poll routine
5018  */
5019 static void
5020 poll_poll(
5021 	struct peer *peer
5022 	)
5023 {
5024 	struct parseunit *parse = peer->procptr->unitptr;
5025 
5026 	if (parse->parse_type->cl_poll)
5027 		parse->parse_type->cl_poll(parse);
5028 
5029 	if (((poll_info_t *)parse->parse_type->cl_data)->rate)
5030 	{
5031 		parse->peer->procptr->nextaction = current_time + ((poll_info_t *)parse->parse_type->cl_data)->rate;
5032 	}
5033 }
5034 
5035 /*--------------------------------------------------
5036  * init routine - setup timer
5037  */
5038 static int
5039 poll_init(
5040 	struct parseunit *parse
5041 	)
5042 {
5043 	if (((poll_info_t *)parse->parse_type->cl_data)->rate)
5044 	{
5045 		parse->peer->procptr->action = poll_poll;
5046 		poll_poll(parse->peer);
5047 	}
5048 
5049 	return 0;
5050 }
5051 
5052 /**===========================================================================
5053  ** Trimble support
5054  **/
5055 
5056 /*-------------------------------------------------------------
5057  * trimble TAIP init routine - setup EOL and then do poll_init.
5058  */
5059 static int
5060 trimbletaip_init(
5061 	struct parseunit *parse
5062 	)
5063 {
5064 #ifdef HAVE_TERMIOS
5065 	struct termios tio;
5066 #endif
5067 #ifdef HAVE_SYSV_TTYS
5068 	struct termio tio;
5069 #endif
5070 	/*
5071 	 * configure terminal line for trimble receiver
5072 	 */
5073 	if (TTY_GETATTR(parse->generic->io.fd, &tio) == -1)
5074 	{
5075 		msyslog(LOG_ERR, "PARSE receiver #%d: trimbletaip_init: tcgetattr(fd, &tio): %m", CLK_UNIT(parse->peer));
5076 		return 0;
5077 	}
5078 	else
5079 	{
5080 		tio.c_cc[VEOL] = TRIMBLETAIP_EOL;
5081 
5082 		if (TTY_SETATTR(parse->generic->io.fd, &tio) == -1)
5083 		{
5084 			msyslog(LOG_ERR, "PARSE receiver #%d: trimbletaip_init: tcsetattr(fd, &tio): %m", CLK_UNIT(parse->peer));
5085 			return 0;
5086 		}
5087 	}
5088 	return poll_init(parse);
5089 }
5090 
5091 /*--------------------------------------------------
5092  * trimble TAIP event routine - reset receiver upon data format trouble
5093  */
5094 static const char *taipinit[] = {
5095 	">FPV00000000<",
5096 	">SRM;ID_FLAG=F;CS_FLAG=T;EC_FLAG=F;FR_FLAG=T;CR_FLAG=F<",
5097 	">FTM00020001<",
5098 	(char *)0
5099 };
5100 
5101 static void
5102 trimbletaip_event(
5103 	struct parseunit *parse,
5104 	int event
5105 	)
5106 {
5107 	switch (event)
5108 	{
5109 	    case CEVNT_BADREPLY:	/* reset on garbled input */
5110 	    case CEVNT_TIMEOUT:		/* reset on no input */
5111 		    {
5112 			    const char **iv;
5113 
5114 			    iv = taipinit;
5115 			    while (*iv)
5116 			    {
5117 				    int rtc = write(parse->generic->io.fd, *iv, strlen(*iv));
5118 				    if (rtc < 0)
5119 				    {
5120 					    msyslog(LOG_ERR, "PARSE receiver #%d: trimbletaip_event: failed to send cmd to clock: %m", CLK_UNIT(parse->peer));
5121 					    return;
5122 				    }
5123 				    else
5124 				    {
5125 					    if (rtc != (int)strlen(*iv))
5126 					    {
5127 						    msyslog(LOG_ERR, "PARSE receiver #%d: trimbletaip_event: failed to send cmd incomplete (%d of %d bytes sent)",
5128 							    CLK_UNIT(parse->peer), rtc, (int)strlen(*iv));
5129 						    return;
5130 					    }
5131 				    }
5132 				    iv++;
5133 			    }
5134 
5135 			    NLOG(NLOG_CLOCKINFO)
5136 				    ERR(ERR_BADIO)
5137 				    msyslog(LOG_ERR, "PARSE receiver #%d: trimbletaip_event: RECEIVER INITIALIZED",
5138 					    CLK_UNIT(parse->peer));
5139 		    }
5140 		    break;
5141 
5142 	    default:			/* ignore */
5143 		break;
5144 	}
5145 }
5146 
5147 /*
5148  * This driver supports the Trimble SVee Six Plus GPS receiver module.
5149  * It should support other Trimble receivers which use the Trimble Standard
5150  * Interface Protocol (see below).
5151  *
5152  * The module has a serial I/O port for command/data and a 1 pulse-per-second
5153  * output, about 1 microsecond wide. The leading edge of the pulse is
5154  * coincident with the change of the GPS second. This is the same as
5155  * the change of the UTC second +/- ~1 microsecond. Some other clocks
5156  * specifically use a feature in the data message as a timing reference, but
5157  * the SVee Six Plus does not do this. In fact there is considerable jitter
5158  * on the timing of the messages, so this driver only supports the use
5159  * of the PPS pulse for accurate timing. Where it is determined that
5160  * the offset is way off, when first starting up ntpd for example,
5161  * the timing of the data stream is used until the offset becomes low enough
5162  * (|offset| < CLOCK_MAX), at which point the pps offset is used.
5163  *
5164  * It can use either option for receiving PPS information - the 'ppsclock'
5165  * stream pushed onto the serial data interface to timestamp the Carrier
5166  * Detect interrupts, where the 1PPS connects to the CD line. This only
5167  * works on SunOS 4.1.x currently. To select this, define PPSPPS in
5168  * Config.local. The other option is to use a pulse-stretcher/level-converter
5169  * to convert the PPS pulse into a RS232 start pulse & feed this into another
5170  * tty port. To use this option, define PPSCLK in Config.local. The pps input,
5171  * by whichever method, is handled in ntp_loopfilter.c
5172  *
5173  * The receiver uses a serial message protocol called Trimble Standard
5174  * Interface Protocol (it can support others but this driver only supports
5175  * TSIP). Messages in this protocol have the following form:
5176  *
5177  * <DLE><id> ... <data> ... <DLE><ETX>
5178  *
5179  * Any bytes within the <data> portion of value 10 hex (<DLE>) are doubled
5180  * on transmission and compressed back to one on reception. Otherwise
5181  * the values of data bytes can be anything. The serial interface is RS-422
5182  * asynchronous using 9600 baud, 8 data bits with odd party (**note** 9 bits
5183  * in total!), and 1 stop bit. The protocol supports byte, integer, single,
5184  * and double datatypes. Integers are two bytes, sent most significant first.
5185  * Singles are IEEE754 single precision floating point numbers (4 byte) sent
5186  * sign & exponent first. Doubles are IEEE754 double precision floating point
5187  * numbers (8 byte) sent sign & exponent first.
5188  * The receiver supports a large set of messages, only a small subset of
5189  * which are used here. From driver to receiver the following are used:
5190  *
5191  *  ID    Description
5192  *
5193  *  21    Request current time
5194  *  22    Mode Select
5195  *  2C    Set/Request operating parameters
5196  *  2F    Request UTC info
5197  *  35    Set/Request I/O options
5198 
5199  * From receiver to driver the following are recognised:
5200  *
5201  *  ID    Description
5202  *
5203  *  41    GPS Time
5204  *  44    Satellite selection, PDOP, mode
5205  *  46    Receiver health
5206  *  4B    Machine code/status
5207  *  4C    Report operating parameters (debug only)
5208  *  4F    UTC correction data (used to get leap second warnings)
5209  *  55    I/O options (debug only)
5210  *
5211  * All others are accepted but ignored.
5212  *
5213  */
5214 
5215 #define PI		3.1415926535898	/* lots of sig figs */
5216 #define D2R		PI/180.0
5217 
5218 /*-------------------------------------------------------------------
5219  * sendcmd, sendbyte, sendetx, sendflt, sendint implement the command
5220  * interface to the receiver.
5221  *
5222  * CAVEAT: the sendflt, sendint routines are byte order dependend and
5223  * float implementation dependend - these must be converted to portable
5224  * versions !
5225  *
5226  * CURRENT LIMITATION: float implementation. This runs only on systems
5227  * with IEEE754 floats as native floats
5228  */
5229 
5230 typedef struct trimble
5231 {
5232 	u_long last_msg;	/* last message received */
5233 	u_long last_reset;	/* last time a reset was issued */
5234 	u_char qtracking;	/* query tracking status */
5235 	u_long ctrack;		/* current tracking set */
5236 	u_long ltrack;		/* last tracking set */
5237 } trimble_t;
5238 
5239 union uval {
5240 	u_char  bd[8];
5241 	int     iv;
5242 	float   fv;
5243 	double  dv;
5244 };
5245 
5246 struct txbuf
5247 {
5248 	short idx;			/* index to first unused byte */
5249 	u_char *txt;			/* pointer to actual data buffer */
5250 };
5251 
5252 void	sendcmd		(struct txbuf *buf, int c);
5253 void	sendbyte	(struct txbuf *buf, int b);
5254 void	sendetx		(struct txbuf *buf, struct parseunit *parse);
5255 void	sendint		(struct txbuf *buf, int a);
5256 void	sendflt		(struct txbuf *buf, double a);
5257 
5258 void
5259 sendcmd(
5260 	struct txbuf *buf,
5261 	int c
5262 	)
5263 {
5264 	buf->txt[0] = DLE;
5265 	buf->txt[1] = (u_char)c;
5266 	buf->idx = 2;
5267 }
5268 
5269 void	sendcmd		(struct txbuf *buf, int c);
5270 void	sendbyte	(struct txbuf *buf, int b);
5271 void	sendetx		(struct txbuf *buf, struct parseunit *parse);
5272 void	sendint		(struct txbuf *buf, int a);
5273 void	sendflt		(struct txbuf *buf, double a);
5274 
5275 void
5276 sendbyte(
5277 	struct txbuf *buf,
5278 	int b
5279 	)
5280 {
5281 	if (b == DLE)
5282 	    buf->txt[buf->idx++] = DLE;
5283 	buf->txt[buf->idx++] = (u_char)b;
5284 }
5285 
5286 void
5287 sendetx(
5288 	struct txbuf *buf,
5289 	struct parseunit *parse
5290 	)
5291 {
5292 	buf->txt[buf->idx++] = DLE;
5293 	buf->txt[buf->idx++] = ETX;
5294 
5295 	if (write(parse->generic->io.fd, buf->txt, (unsigned long)buf->idx) != buf->idx)
5296 	{
5297 		ERR(ERR_BADIO)
5298 			msyslog(LOG_ERR, "PARSE receiver #%d: sendetx: failed to send cmd to clock: %m", CLK_UNIT(parse->peer));
5299 	}
5300 	else
5301 	{
5302 #ifdef DEBUG
5303 	  if (debug > 2)
5304 	  {
5305 		  char buffer[256];
5306 
5307 		  mkreadable(buffer, sizeof(buffer), (char *)buf->txt, (unsigned)buf->idx, 1);
5308 		  printf("PARSE receiver #%d: transmitted message (%d bytes) >%s<\n",
5309 			 CLK_UNIT(parse->peer),
5310 			 buf->idx, buffer);
5311 	  }
5312 #endif
5313 		clear_err(parse, ERR_BADIO);
5314 	}
5315 }
5316 
5317 void
5318 sendint(
5319 	struct txbuf *buf,
5320 	int a
5321 	)
5322 {
5323 	/* send 16bit int, msbyte first */
5324 	sendbyte(buf, (u_char)((a>>8) & 0xff));
5325 	sendbyte(buf, (u_char)(a & 0xff));
5326 }
5327 
5328 void
5329 sendflt(
5330 	struct txbuf *buf,
5331 	double a
5332 	)
5333 {
5334 	int i;
5335 	union uval uval;
5336 
5337 	uval.fv = a;
5338 #ifdef WORDS_BIGENDIAN
5339 	for (i=0; i<=3; i++)
5340 #else
5341 	    for (i=3; i>=0; i--)
5342 #endif
5343 		sendbyte(buf, uval.bd[i]);
5344 }
5345 
5346 #define TRIM_POS_OPT	0x13	/* output position with high precision */
5347 #define TRIM_TIME_OPT	0x03	/* use UTC time stamps, on second */
5348 
5349 /*--------------------------------------------------
5350  * trimble TSIP setup routine
5351  */
5352 static int
5353 trimbletsip_setup(
5354 		  struct parseunit *parse,
5355 		  const char *reason
5356 		  )
5357 {
5358 	u_char buffer[256];
5359 	struct txbuf buf;
5360 	trimble_t *t = parse->localdata;
5361 
5362 	if (t && t->last_reset &&
5363 	    ((t->last_reset + TRIMBLE_RESET_HOLDOFF) > current_time)) {
5364 		return 1;	/* not yet */
5365 	}
5366 
5367 	if (t)
5368 		t->last_reset = current_time;
5369 
5370 	buf.txt = buffer;
5371 
5372 	sendcmd(&buf, CMD_CVERSION);	/* request software versions */
5373 	sendetx(&buf, parse);
5374 
5375 	sendcmd(&buf, CMD_COPERPARAM);	/* set operating parameters */
5376 	sendbyte(&buf, 4);	/* static */
5377 	sendflt(&buf, 5.0*D2R);	/* elevation angle mask = 10 deg XXX */
5378 	sendflt(&buf, 4.0);	/* s/n ratio mask = 6 XXX */
5379 	sendflt(&buf, 12.0);	/* PDOP mask = 12 */
5380 	sendflt(&buf, 8.0);	/* PDOP switch level = 8 */
5381 	sendetx(&buf, parse);
5382 
5383 	sendcmd(&buf, CMD_CMODESEL);	/* fix mode select */
5384 	sendbyte(&buf, 1);	/* time transfer mode */
5385 	sendetx(&buf, parse);
5386 
5387 	sendcmd(&buf, CMD_CMESSAGE);	/* request system message */
5388 	sendetx(&buf, parse);
5389 
5390 	sendcmd(&buf, CMD_CSUPER);	/* superpacket fix */
5391 	sendbyte(&buf, 0x2);	/* binary mode */
5392 	sendetx(&buf, parse);
5393 
5394 	sendcmd(&buf, CMD_CIOOPTIONS);	/* set I/O options */
5395 	sendbyte(&buf, TRIM_POS_OPT);	/* position output */
5396 	sendbyte(&buf, 0x00);	/* no velocity output */
5397 	sendbyte(&buf, TRIM_TIME_OPT);	/* UTC, compute on seconds */
5398 	sendbyte(&buf, 0x00);	/* no raw measurements */
5399 	sendetx(&buf, parse);
5400 
5401 	sendcmd(&buf, CMD_CUTCPARAM);	/* request UTC correction data */
5402 	sendetx(&buf, parse);
5403 
5404 	NLOG(NLOG_CLOCKINFO)
5405 		ERR(ERR_BADIO)
5406 		msyslog(LOG_ERR, "PARSE receiver #%d: trimbletsip_setup: RECEIVER RE-INITIALIZED (%s)", CLK_UNIT(parse->peer), reason);
5407 
5408 	return 0;
5409 }
5410 
5411 /*--------------------------------------------------
5412  * TRIMBLE TSIP check routine
5413  */
5414 static void
5415 trimble_check(
5416 	      struct peer *peer
5417 	      )
5418 {
5419 	struct parseunit *parse = peer->procptr->unitptr;
5420 	trimble_t *t = parse->localdata;
5421 	u_char buffer[256];
5422 	struct txbuf buf;
5423 	buf.txt = buffer;
5424 
5425 	if (t)
5426 	{
5427 		if (current_time > t->last_msg + TRIMBLETSIP_IDLE_TIME)
5428 			(void)trimbletsip_setup(parse, "message timeout");
5429 	}
5430 
5431 	poll_poll(parse->peer);	/* emit query string and re-arm timer */
5432 
5433 	if (t && t->qtracking)
5434 	{
5435 		u_long oldsats = t->ltrack & ~t->ctrack;
5436 
5437 		t->qtracking = 0;
5438 		t->ltrack = t->ctrack;
5439 
5440 		if (oldsats)
5441 		{
5442 			int i;
5443 
5444 			for (i = 0; oldsats; i++) {
5445 				if (oldsats & (1 << i))
5446 					{
5447 						sendcmd(&buf, CMD_CSTATTRACK);
5448 						sendbyte(&buf, i+1);	/* old sat */
5449 						sendetx(&buf, parse);
5450 					}
5451 				oldsats &= ~(1 << i);
5452 			}
5453 		}
5454 
5455 		sendcmd(&buf, CMD_CSTATTRACK);
5456 		sendbyte(&buf, 0x00);	/* current tracking set */
5457 		sendetx(&buf, parse);
5458 	}
5459 }
5460 
5461 /*--------------------------------------------------
5462  * TRIMBLE TSIP end routine
5463  */
5464 static void
5465 trimbletsip_end(
5466 	      struct parseunit *parse
5467 	      )
5468 {	trimble_t *t = parse->localdata;
5469 
5470 	if (t)
5471 	{
5472 		free(t);
5473 		parse->localdata = NULL;
5474 	}
5475 	parse->peer->procptr->nextaction = 0;
5476 	parse->peer->procptr->action = NULL;
5477 }
5478 
5479 /*--------------------------------------------------
5480  * TRIMBLE TSIP init routine
5481  */
5482 static int
5483 trimbletsip_init(
5484 	struct parseunit *parse
5485 	)
5486 {
5487 #if defined(VEOL) || defined(VEOL2)
5488 #ifdef HAVE_TERMIOS
5489 	struct termios tio;		/* NEEDED FOR A LONG TIME ! */
5490 #endif
5491 #ifdef HAVE_SYSV_TTYS
5492 	struct termio tio;		/* NEEDED FOR A LONG TIME ! */
5493 #endif
5494 	/*
5495 	 * allocate local data area
5496 	 */
5497 	if (!parse->localdata)
5498 	{
5499 		trimble_t *t;
5500 
5501 		t = (trimble_t *)(parse->localdata = emalloc(sizeof(trimble_t)));
5502 
5503 		if (t)
5504 		{
5505 			memset((char *)t, 0, sizeof(trimble_t));
5506 			t->last_msg = current_time;
5507 		}
5508 	}
5509 
5510 	parse->peer->procptr->action     = trimble_check;
5511 	parse->peer->procptr->nextaction = current_time;
5512 
5513 	/*
5514 	 * configure terminal line for ICANON mode with VEOL characters
5515 	 */
5516 	if (TTY_GETATTR(parse->generic->io.fd, &tio) == -1)
5517 	{
5518 		msyslog(LOG_ERR, "PARSE receiver #%d: trimbletsip_init: tcgetattr(%d, &tio): %m", CLK_UNIT(parse->peer), parse->generic->io.fd);
5519 		return 0;
5520 	}
5521 	else
5522 	{
5523 		if ((parse_clockinfo[CLK_TYPE(parse->peer)].cl_lflag & ICANON))
5524 		{
5525 #ifdef VEOL
5526 			tio.c_cc[VEOL]  = ETX;
5527 #endif
5528 #ifdef VEOL2
5529 			tio.c_cc[VEOL2]  = DLE;
5530 #endif
5531 		}
5532 
5533 		if (TTY_SETATTR(parse->generic->io.fd, &tio) == -1)
5534 		{
5535 			msyslog(LOG_ERR, "PARSE receiver #%d: trimbletsip_init: tcsetattr(%d, &tio): %m", CLK_UNIT(parse->peer), parse->generic->io.fd);
5536 			return 0;
5537 		}
5538 	}
5539 #endif
5540 	return trimbletsip_setup(parse, "initial startup");
5541 }
5542 
5543 /*------------------------------------------------------------
5544  * trimbletsip_event - handle Trimble events
5545  * simple evente handler - attempt to re-initialize receiver
5546  */
5547 static void
5548 trimbletsip_event(
5549 	struct parseunit *parse,
5550 	int event
5551 	)
5552 {
5553 	switch (event)
5554 	{
5555 	    case CEVNT_BADREPLY:	/* reset on garbled input */
5556 	    case CEVNT_TIMEOUT:		/* reset on no input */
5557 		    (void)trimbletsip_setup(parse, "event BAD_REPLY/TIMEOUT");
5558 		    break;
5559 
5560 	    default:			/* ignore */
5561 		break;
5562 	}
5563 }
5564 
5565 /*
5566  * getflt, getint convert fields in the incoming data into the
5567  * appropriate type of item
5568  *
5569  * CAVEAT: these routines are currently definitely byte order dependent
5570  * and assume Representation(float) == IEEE754
5571  * These functions MUST be converted to portable versions (especially
5572  * converting the float representation into ntp_fp formats in order
5573  * to avoid floating point operations at all!
5574  */
5575 
5576 static float
5577 getflt(
5578 	u_char *bp
5579 	)
5580 {
5581 	union uval uval;
5582 
5583 #ifdef WORDS_BIGENDIAN
5584 	uval.bd[0] = *bp++;
5585 	uval.bd[1] = *bp++;
5586 	uval.bd[2] = *bp++;
5587 	uval.bd[3] = *bp;
5588 #else  /* ! WORDS_BIGENDIAN */
5589 	uval.bd[3] = *bp++;
5590 	uval.bd[2] = *bp++;
5591 	uval.bd[1] = *bp++;
5592 	uval.bd[0] = *bp;
5593 #endif /* ! WORDS_BIGENDIAN */
5594 	return uval.fv;
5595 }
5596 
5597 static double
5598 getdbl(
5599 	u_char *bp
5600 	)
5601 {
5602 	union uval uval;
5603 
5604 #ifdef WORDS_BIGENDIAN
5605 	uval.bd[0] = *bp++;
5606 	uval.bd[1] = *bp++;
5607 	uval.bd[2] = *bp++;
5608 	uval.bd[3] = *bp++;
5609 	uval.bd[4] = *bp++;
5610 	uval.bd[5] = *bp++;
5611 	uval.bd[6] = *bp++;
5612 	uval.bd[7] = *bp;
5613 #else  /* ! WORDS_BIGENDIAN */
5614 	uval.bd[7] = *bp++;
5615 	uval.bd[6] = *bp++;
5616 	uval.bd[5] = *bp++;
5617 	uval.bd[4] = *bp++;
5618 	uval.bd[3] = *bp++;
5619 	uval.bd[2] = *bp++;
5620 	uval.bd[1] = *bp++;
5621 	uval.bd[0] = *bp;
5622 #endif /* ! WORDS_BIGENDIAN */
5623 	return uval.dv;
5624 }
5625 
5626 static int
5627 getshort(
5628 	 unsigned char *p
5629 	 )
5630 {
5631 	return get_msb_short(&p);
5632 }
5633 
5634 /*--------------------------------------------------
5635  * trimbletsip_message - process trimble messages
5636  */
5637 #define RTOD (180.0 / 3.1415926535898)
5638 #define mb(_X_) (buffer[2+(_X_)]) /* shortcut for buffer access */
5639 
5640 static void
5641 trimbletsip_message(
5642 		    struct parseunit *parse,
5643 		    parsetime_t      *parsetime
5644 		    )
5645 {
5646 	unsigned char *buffer = parsetime->parse_msg;
5647 	unsigned int   size   = parsetime->parse_msglen;
5648 
5649 	if ((size < 4) ||
5650 	    (buffer[0]      != DLE) ||
5651 	    (buffer[size-1] != ETX) ||
5652 	    (buffer[size-2] != DLE))
5653 	{
5654 #ifdef DEBUG
5655 		if (debug > 2) {
5656 			size_t i;
5657 
5658 			printf("TRIMBLE BAD packet, size %d:\n	", size);
5659 			for (i = 0; i < size; i++) {
5660 				printf ("%2.2x, ", buffer[i]&0xff);
5661 				if (i%16 == 15) printf("\n\t");
5662 			}
5663 			printf("\n");
5664 		}
5665 #endif
5666 		return;
5667 	}
5668 	else
5669 	{
5670 		int var_flag;
5671 		trimble_t *tr = parse->localdata;
5672 		unsigned int cmd = buffer[1];
5673 		char pbuffer[200];
5674 		char *t = pbuffer;
5675 		cmd_info_t *s;
5676 
5677 #ifdef DEBUG
5678 		if (debug > 3) {
5679 			size_t i;
5680 
5681 			printf("TRIMBLE packet 0x%02x, size %d:\n	", cmd, size);
5682 			for (i = 0; i < size; i++) {
5683 				printf ("%2.2x, ", buffer[i]&0xff);
5684 				if (i%16 == 15) printf("\n\t");
5685 			}
5686 			printf("\n");
5687 		}
5688 #endif
5689 
5690 		if (tr)
5691 			tr->last_msg = current_time;
5692 
5693 		s = trimble_convert(cmd, trimble_rcmds);
5694 
5695 		if (s)
5696 		{
5697 			t = ap(pbuffer, sizeof(pbuffer), t, "%s=\"", s->varname);
5698 		}
5699 		else
5700 		{
5701 			DPRINTF(1, ("TRIMBLE UNKNOWN COMMAND 0x%02x\n", cmd));
5702 			return;
5703 		}
5704 
5705 		var_flag = s->varmode;
5706 
5707 		switch(cmd)
5708 		{
5709 		case CMD_RCURTIME:
5710 			t = ap(pbuffer, sizeof(pbuffer), t, "%f, %d, %f",
5711 				 getflt((unsigned char *)&mb(0)), getshort((unsigned char *)&mb(4)),
5712 				 getflt((unsigned char *)&mb(6)));
5713 			break;
5714 
5715 		case CMD_RBEST4:
5716 <<<<<<< refclock_parse.c
5717 			t = ap(pbuffer, sizeof(pbuffer), t, "mode: ");
5718 =======
5719 			strlcpy(t, "mode: ", BUFFER_SIZE(pbuffer, t));
5720 			t += strlen(t);
5721 >>>>>>> 1.1.1.3
5722 			switch (mb(0) & 0xF)
5723 			{
5724 			default:
5725 				t = ap(pbuffer, sizeof(pbuffer), t,
5726 				    "0x%x", mb(0) & 0x7);
5727 				break;
5728 
5729 			case 1:
5730 <<<<<<< refclock_parse.c
5731 				t = ap(pbuffer, sizeof(pbuffer), t, "0D");
5732 =======
5733 				strlcpy(t, "0D", BUFFER_SIZE(pbuffer, t));
5734 >>>>>>> 1.1.1.3
5735 				break;
5736 
5737 			case 3:
5738 <<<<<<< refclock_parse.c
5739 				t = ap(pbuffer, sizeof(pbuffer), t, "2D");
5740 =======
5741 				strlcpy(t, "2D", BUFFER_SIZE(pbuffer, t));
5742 >>>>>>> 1.1.1.3
5743 				break;
5744 
5745 			case 4:
5746 <<<<<<< refclock_parse.c
5747 				t = ap(pbuffer, sizeof(pbuffer), t, "3D");
5748 =======
5749 				strlcpy(t, "3D", BUFFER_SIZE(pbuffer, t));
5750 >>>>>>> 1.1.1.3
5751 				break;
5752 			}
5753 			if (mb(0) & 0x10)
5754 <<<<<<< refclock_parse.c
5755 				t = ap(pbuffer, sizeof(pbuffer), t, "-MANUAL, ");
5756 =======
5757 				strlcpy(t, "-MANUAL, ", BUFFER_SIZE(pbuffer, t));
5758 >>>>>>> 1.1.1.3
5759 			else
5760 <<<<<<< refclock_parse.c
5761 				t = ap(pbuffer, sizeof(pbuffer), t, "-AUTO, ");
5762 =======
5763 				strlcpy(t, "-AUTO, ", BUFFER_SIZE(pbuffer, t));
5764 			t += strlen(t);
5765 >>>>>>> 1.1.1.3
5766 
5767 			t = ap(pbuffer, sizeof(pbuffer), t, "satellites %02d %02d %02d %02d, PDOP %.2f, HDOP %.2f, VDOP %.2f, TDOP %.2f",
5768 				mb(1), mb(2), mb(3), mb(4),
5769 				getflt((unsigned char *)&mb(5)),
5770 				getflt((unsigned char *)&mb(9)),
5771 				getflt((unsigned char *)&mb(13)),
5772 				getflt((unsigned char *)&mb(17)));
5773 
5774 			break;
5775 
5776 		case CMD_RVERSION:
5777 			t = ap(pbuffer, sizeof(pbuffer), t, "%d.%d (%d/%d/%d)",
5778 				mb(0)&0xff, mb(1)&0xff, 1900+(mb(4)&0xff), mb(2)&0xff, mb(3)&0xff);
5779 			break;
5780 
5781 		case CMD_RRECVHEALTH:
5782 		{
5783 			static const char *msgs[] =
5784 			{
5785 				"Battery backup failed",
5786 				"Signal processor error",
5787 				"Alignment error, channel or chip 1",
5788 				"Alignment error, channel or chip 2",
5789 				"Antenna feed line fault",
5790 				"Excessive ref freq. error",
5791 				"<BIT 6>",
5792 				"<BIT 7>"
5793 			};
5794 
5795 			int i, bits;
5796 
5797 			switch (mb(0) & 0xFF)
5798 			{
5799 			default:
5800 				t = ap(pbuffer, sizeof(pbuffer), t, "illegal value 0x%02x", mb(0) & 0xFF);
5801 				break;
5802 			case 0x00:
5803 <<<<<<< refclock_parse.c
5804 				t = ap(pbuffer, sizeof(pbuffer), t, "doing position fixes", BUFFER_SIZE(pbuffer, t));
5805 =======
5806 				strlcpy(t, "doing position fixes", BUFFER_SIZE(pbuffer, t));
5807 >>>>>>> 1.1.1.3
5808 				break;
5809 			case 0x01:
5810 <<<<<<< refclock_parse.c
5811 				t = ap(pbuffer, sizeof(pbuffer), t, "no GPS time yet", BUFFER_SIZE(pbuffer, t));
5812 =======
5813 				strlcpy(t, "no GPS time yet", BUFFER_SIZE(pbuffer, t));
5814 >>>>>>> 1.1.1.3
5815 				break;
5816 			case 0x03:
5817 <<<<<<< refclock_parse.c
5818 				t = ap(pbuffer, sizeof(pbuffer), t, "PDOP too high", BUFFER_SIZE(pbuffer, t));
5819 =======
5820 				strlcpy(t, "PDOP too high", BUFFER_SIZE(pbuffer, t));
5821 >>>>>>> 1.1.1.3
5822 				break;
5823 			case 0x08:
5824 <<<<<<< refclock_parse.c
5825 				t = ap(pbuffer, sizeof(pbuffer), t, "no usable satellites", BUFFER_SIZE(pbuffer, t));
5826 =======
5827 				strlcpy(t, "no usable satellites", BUFFER_SIZE(pbuffer, t));
5828 >>>>>>> 1.1.1.3
5829 				break;
5830 			case 0x09:
5831 <<<<<<< refclock_parse.c
5832 				t = ap(pbuffer, sizeof(pbuffer), t, "only ONE usable satellite", BUFFER_SIZE(pbuffer, t));
5833 =======
5834 				strlcpy(t, "only ONE usable satellite", BUFFER_SIZE(pbuffer, t));
5835 >>>>>>> 1.1.1.3
5836 				break;
5837 			case 0x0A:
5838 <<<<<<< refclock_parse.c
5839 				t = ap(pbuffer, sizeof(pbuffer), t, "only TWO usable satellites", BUFFER_SIZE(pbuffer, t));
5840 =======
5841 				strlcpy(t, "only TWO usable satellites", BUFFER_SIZE(pbuffer, t));
5842 >>>>>>> 1.1.1.3
5843 				break;
5844 			case 0x0B:
5845 <<<<<<< refclock_parse.c
5846 				t = ap(pbuffer, sizeof(pbuffer), t, "only THREE usable satellites", BUFFER_SIZE(pbuffer, t));
5847 =======
5848 				strlcpy(t, "only THREE usable satellites", BUFFER_SIZE(pbuffer, t));
5849 >>>>>>> 1.1.1.3
5850 				break;
5851 			case 0x0C:
5852 <<<<<<< refclock_parse.c
5853 				t = ap(pbuffer, sizeof(pbuffer), t, "the chosen satellite is unusable", BUFFER_SIZE(pbuffer, t));
5854 =======
5855 				strlcpy(t, "the chosen satellite is unusable", BUFFER_SIZE(pbuffer, t));
5856 >>>>>>> 1.1.1.3
5857 				break;
5858 			}
5859 
5860 			bits = mb(1) & 0xFF;
5861 
5862 			for (i = 0; i < 8; i++)
5863 				if (bits & (0x1<<i))
5864 				{
5865 					t = ap(pbuffer, sizeof(pbuffer), t, ", %s", msgs[i]);
5866 				}
5867 		}
5868 		break;
5869 
5870 		case CMD_RMESSAGE:
5871 			mkreadable(t, (int)BUFFER_SIZE(pbuffer, t), (char *)&mb(0), (unsigned)(size - 2 - (&mb(0) - buffer)), 0);
5872 			break;
5873 
5874 		case CMD_RMACHSTAT:
5875 		{
5876 			static const char *msgs[] =
5877 			{
5878 				"Synthesizer Fault",
5879 				"Battery Powered Time Clock Fault",
5880 				"A-to-D Converter Fault",
5881 				"The almanac stored in the receiver is not complete and current",
5882 				"<BIT 4>",
5883 				"<BIT 5",
5884 				"<BIT 6>",
5885 				"<BIT 7>"
5886 			};
5887 
5888 			int i, bits;
5889 
5890 			t = ap(pbuffer, sizeof(pbuffer), t, "machine id 0x%02x", mb(0) & 0xFF);
5891 			bits = mb(1) & 0xFF;
5892 
5893 			for (i = 0; i < 8; i++)
5894 				if (bits & (0x1<<i))
5895 				{
5896 					t = ap(pbuffer, sizeof(pbuffer), t, ", %s", msgs[i]);
5897 				}
5898 
5899 			t = ap(pbuffer, sizeof(pbuffer), t, ", Superpackets %ssupported", (mb(2) & 0xFF) ? "" :"un" );
5900 		}
5901 		break;
5902 
5903 		case CMD_ROPERPARAM:
5904 			t = ap(pbuffer, sizeof(pbuffer), t, "%2x %.1f %.1f %.1f %.1f",
5905 				mb(0), getflt((unsigned char *)&mb(1)), getflt((unsigned char *)&mb(5)),
5906 				getflt((unsigned char *)&mb(9)), getflt((unsigned char *)&mb(13)));
5907 			break;
5908 
5909 		case CMD_RUTCPARAM:
5910 		{
5911 			float t0t = getflt((unsigned char *)&mb(14));
5912 			short wnt = getshort((unsigned char *)&mb(18));
5913 			short dtls = getshort((unsigned char *)&mb(12));
5914 			short wnlsf = getshort((unsigned char *)&mb(20));
5915 			short dn = getshort((unsigned char *)&mb(22));
5916 			short dtlsf = getshort((unsigned char *)&mb(24));
5917 
5918 			if ((int)t0t != 0)
5919 			{
5920 				mk_utcinfo(t, wnt, wnlsf, dn, dtls, dtlsf, BUFFER_SIZE(pbuffer, t));
5921 			}
5922 			else
5923 <<<<<<< refclock_parse.c
5924 			  {
5925 			    t = ap(pbuffer, sizeof(pbuffer), t, "<NO UTC DATA>");
5926 			  }
5927 =======
5928 			{
5929 				strlcpy(t, "<NO UTC DATA>", BUFFER_SIZE(pbuffer, t));
5930 			}
5931 >>>>>>> 1.1.1.3
5932 		}
5933 		break;
5934 
5935 		case CMD_RSAT1BIAS:
5936 			t = ap(pbuffer, sizeof(pbuffer), t, "%.1fm %.2fm/s at %.1fs",
5937 				getflt(&mb(0)), getflt(&mb(4)), getflt(&mb(8)));
5938 			break;
5939 
5940 		case CMD_RIOOPTIONS:
5941 		{
5942 			t = ap(pbuffer, sizeof(pbuffer), t, "%02x %02x %02x %02x",
5943 				mb(0), mb(1), mb(2), mb(3));
5944 			if (mb(0) != TRIM_POS_OPT ||
5945 			    mb(2) != TRIM_TIME_OPT)
5946 			{
5947 				(void)trimbletsip_setup(parse, "bad io options");
5948 			}
5949 		}
5950 		break;
5951 
5952 		case CMD_RSPOSXYZ:
5953 		{
5954 			double x = getflt((unsigned char *)&mb(0));
5955 			double y = getflt((unsigned char *)&mb(4));
5956 			double z = getflt((unsigned char *)&mb(8));
5957 			double f = getflt((unsigned char *)&mb(12));
5958 
5959 			if (f > 0.0)
5960 <<<<<<< refclock_parse.c
5961 			  t = ap(pbuffer, sizeof(pbuffer), t, "x= %.1fm, y= %.1fm, z= %.1fm, time_of_fix= %f sec",
5962 				  x, y, z,
5963 				  f);
5964 =======
5965 				snprintf(t, BUFFER_SIZE(pbuffer, t), "x= %.1fm, y= %.1fm, z= %.1fm, time_of_fix= %f sec",
5966 					 x, y, z,
5967 					 f);
5968 >>>>>>> 1.1.1.3
5969 			else
5970 				return;
5971 		}
5972 		break;
5973 
5974 		case CMD_RSLLAPOS:
5975 		{
5976 			double lat = getflt((unsigned char *)&mb(0));
5977 			double lng = getflt((unsigned char *)&mb(4));
5978 			double f   = getflt((unsigned char *)&mb(12));
5979 
5980 			if (f > 0.0)
5981 <<<<<<< refclock_parse.c
5982 			  t = ap(pbuffer, sizeof(pbuffer), t, "lat %f %c, long %f %c, alt %.2fm",
5983 				  ((lat < 0.0) ? (-lat) : (lat))*RTOD, (lat < 0.0 ? 'S' : 'N'),
5984 				  ((lng < 0.0) ? (-lng) : (lng))*RTOD, (lng < 0.0 ? 'W' : 'E'),
5985 				  getflt((unsigned char *)&mb(8)));
5986 =======
5987 				snprintf(t, BUFFER_SIZE(pbuffer, t), "lat %f %c, long %f %c, alt %.2fm",
5988 					 ((lat < 0.0) ? (-lat) : (lat))*RTOD, (lat < 0.0 ? 'S' : 'N'),
5989 					 ((lng < 0.0) ? (-lng) : (lng))*RTOD, (lng < 0.0 ? 'W' : 'E'),
5990 					 getflt((unsigned char *)&mb(8)));
5991 >>>>>>> 1.1.1.3
5992 			else
5993 				return;
5994 		}
5995 		break;
5996 
5997 		case CMD_RDOUBLEXYZ:
5998 		{
5999 			double x = getdbl((unsigned char *)&mb(0));
6000 			double y = getdbl((unsigned char *)&mb(8));
6001 			double z = getdbl((unsigned char *)&mb(16));
6002 <<<<<<< refclock_parse.c
6003 			t = ap(pbuffer, sizeof(pbuffer), t, "x= %.1fm, y= %.1fm, z= %.1fm",
6004 				x, y, z);
6005 =======
6006 			snprintf(t, BUFFER_SIZE(pbuffer, t), "x= %.1fm, y= %.1fm, z= %.1fm",
6007 				 x, y, z);
6008 >>>>>>> 1.1.1.3
6009 		}
6010 		break;
6011 
6012 		case CMD_RDOUBLELLA:
6013 		{
6014 			double lat = getdbl((unsigned char *)&mb(0));
6015 			double lng = getdbl((unsigned char *)&mb(8));
6016 			t = ap(pbuffer, sizeof(pbuffer), t, "lat %f %c, lon %f %c, alt %.2fm",
6017 				((lat < 0.0) ? (-lat) : (lat))*RTOD, (lat < 0.0 ? 'S' : 'N'),
6018 				((lng < 0.0) ? (-lng) : (lng))*RTOD, (lng < 0.0 ? 'W' : 'E'),
6019 				getdbl((unsigned char *)&mb(16)));
6020 		}
6021 		break;
6022 
6023 		case CMD_RALLINVIEW:
6024 		{
6025 			int i, sats;
6026 
6027 <<<<<<< refclock_parse.c
6028 			t = ap(pbuffer, sizeof(pbuffer), t, "mode: ");
6029 =======
6030 			strlcpy(t, "mode: ", BUFFER_SIZE(pbuffer, t));
6031 			t += strlen(t);
6032 >>>>>>> 1.1.1.3
6033 			switch (mb(0) & 0x7)
6034 			{
6035 			default:
6036 				t = ap(pbuffer, sizeof(pbuffer), t, "0x%x", mb(0) & 0x7);
6037 				break;
6038 
6039 			case 3:
6040 <<<<<<< refclock_parse.c
6041 				t = ap(pbuffer, sizeof(pbuffer), t, "2D");
6042 =======
6043 				strlcpy(t, "2D", BUFFER_SIZE(pbuffer, t));
6044 >>>>>>> 1.1.1.3
6045 				break;
6046 
6047 			case 4:
6048 <<<<<<< refclock_parse.c
6049 				t = ap(pbuffer, sizeof(pbuffer), t, "3D");
6050 =======
6051 				strlcpy(t, "3D", BUFFER_SIZE(pbuffer, t));
6052 >>>>>>> 1.1.1.3
6053 				break;
6054 			}
6055 			if (mb(0) & 0x8)
6056 <<<<<<< refclock_parse.c
6057 				t = ap(pbuffer, sizeof(pbuffer), t, "-MANUAL, ");
6058 =======
6059 				strlcpy(t, "-MANUAL, ", BUFFER_SIZE(pbuffer, t));
6060 >>>>>>> 1.1.1.3
6061 			else
6062 <<<<<<< refclock_parse.c
6063 				t = ap(pbuffer, sizeof(pbuffer), t, "-AUTO, ");
6064 =======
6065 				strlcpy(t, "-AUTO, ", BUFFER_SIZE(pbuffer, t));
6066 			t += strlen(t);
6067 >>>>>>> 1.1.1.3
6068 
6069 			sats = (mb(0)>>4) & 0xF;
6070 
6071 			t = ap(pbuffer, sizeof(pbuffer), t, "PDOP %.2f, HDOP %.2f, VDOP %.2f, TDOP %.2f, %d satellite%s in view: ",
6072 				getflt((unsigned char *)&mb(1)),
6073 				getflt((unsigned char *)&mb(5)),
6074 				getflt((unsigned char *)&mb(9)),
6075 				getflt((unsigned char *)&mb(13)),
6076 				sats, (sats == 1) ? "" : "s");
6077 
6078 			for (i=0; i < sats; i++)
6079 			{
6080 				t = ap(pbuffer, sizeof(pbuffer), t, "%s%02d", i ? ", " : "", mb(17+i));
6081 				if (tr)
6082 					tr->ctrack |= (1 << (mb(17+i)-1));
6083 			}
6084 
6085 			if (tr)
6086 			{	/* mark for tracking status query */
6087 				tr->qtracking = 1;
6088 			}
6089 		}
6090 		break;
6091 
6092 		case CMD_RSTATTRACK:
6093 		{
6094 			t = ap(pbuffer, sizeof(pbuffer), t-2, "[%02d]=\"", mb(0)); /* add index to var name */
6095 			if (getflt((unsigned char *)&mb(4)) < 0.0)
6096 			{
6097 <<<<<<< refclock_parse.c
6098 				t = ap(pbuffer, sizeof(pbuffer), t, "<NO MEASUREMENTS>");
6099 =======
6100 				strlcpy(t, "<NO MEASUREMENTS>", BUFFER_SIZE(pbuffer, t));
6101 >>>>>>> 1.1.1.3
6102 				var_flag &= ~DEF;
6103 			}
6104 			else
6105 			{
6106 				t = ap(pbuffer, sizeof(pbuffer), t, "ch=%d, acq=%s, eph=%d, signal_level= %5.2f, elevation= %5.2f, azimuth= %6.2f",
6107 					(mb(1) & 0xFF)>>3,
6108 					mb(2) ? ((mb(2) == 1) ? "ACQ" : "SRCH") : "NEVER",
6109 					mb(3),
6110 					getflt((unsigned char *)&mb(4)),
6111 					getflt((unsigned char *)&mb(12)) * RTOD,
6112 					getflt((unsigned char *)&mb(16)) * RTOD);
6113 				if (mb(20))
6114 				{
6115 					var_flag &= ~DEF;
6116 <<<<<<< refclock_parse.c
6117 					t = ap(pbuffer, sizeof(pbuffer), t, ", OLD");
6118 =======
6119 					strlcpy(t, ", OLD", BUFFER_SIZE(pbuffer, t));
6120 >>>>>>> 1.1.1.3
6121 				}
6122 				if (mb(22))
6123 				{
6124 					if (mb(22) == 1)
6125 <<<<<<< refclock_parse.c
6126 						t = ap(pbuffer, sizeof(pbuffer), t, ", BAD PARITY");
6127 =======
6128 						strlcpy(t, ", BAD PARITY", BUFFER_SIZE(pbuffer, t));
6129 >>>>>>> 1.1.1.3
6130 					else
6131 						if (mb(22) == 2)
6132 <<<<<<< refclock_parse.c
6133 							t = ap(pbuffer, sizeof(pbuffer), t, ", BAD EPH HEALTH");
6134 =======
6135 							strlcpy(t, ", BAD EPH HEALTH", BUFFER_SIZE(pbuffer, t));
6136 >>>>>>> 1.1.1.3
6137 				}
6138 				if (mb(23))
6139 <<<<<<< refclock_parse.c
6140 					t = ap(pbuffer, sizeof(pbuffer), t, ", collecting data");
6141 =======
6142 					strlcpy(t, ", collecting data", BUFFER_SIZE(pbuffer, t));
6143 >>>>>>> 1.1.1.3
6144 			}
6145 		}
6146 		break;
6147 
6148 		default:
6149 <<<<<<< refclock_parse.c
6150 			t = ap(pbuffer, sizeof(pbuffer), t, "<UNDECODED>");
6151 =======
6152 			strlcpy(t, "<UNDECODED>", BUFFER_SIZE(pbuffer, t));
6153 >>>>>>> 1.1.1.3
6154 			break;
6155 		}
6156 
6157 <<<<<<< refclock_parse.c
6158 		t = ap(pbuffer, sizeof(pbuffer), t,"\"");
6159 =======
6160 		strlcpy(t,"\"", BUFFER_SIZE(pbuffer, t));
6161 >>>>>>> 1.1.1.3
6162 		set_var(&parse->kv, pbuffer, sizeof(pbuffer), var_flag);
6163 	}
6164 }
6165 
6166 
6167 /**============================================================
6168  ** RAWDCF support
6169  **/
6170 
6171 /*--------------------------------------------------
6172  * rawdcf_init_1 - set up modem lines for RAWDCF receivers
6173  * SET DTR line
6174  */
6175 #if defined(TIOCMSET) && (defined(TIOCM_DTR) || defined(CIOCM_DTR))
6176 static int
6177 rawdcf_init_1(
6178 	struct parseunit *parse
6179 	)
6180 {
6181 	/* fixed 2000 for using with Linux by Wolfram Pienkoss <wp@bszh.de> */
6182 	/*
6183 	 * You can use the RS232 to supply the power for a DCF77 receiver.
6184 	 * Here a voltage between the DTR and the RTS line is used. Unfortunately
6185 	 * the name has changed from CIOCM_DTR to TIOCM_DTR recently.
6186 	 */
6187 	int sl232;
6188 
6189 	if (ioctl(parse->generic->io.fd, TIOCMGET, (caddr_t)&sl232) == -1)
6190 	{
6191 		msyslog(LOG_NOTICE, "PARSE receiver #%d: rawdcf_init_1: WARNING: ioctl(fd, TIOCMGET, [C|T]IOCM_DTR): %m", CLK_UNIT(parse->peer));
6192 		return 0;
6193 	}
6194 
6195 #ifdef TIOCM_DTR
6196 	sl232 = (sl232 & ~TIOCM_RTS) | TIOCM_DTR;	/* turn on DTR, clear RTS for power supply */
6197 #else
6198 	sl232 = (sl232 & ~CIOCM_RTS) | CIOCM_DTR;	/* turn on DTR, clear RTS for power supply */
6199 #endif
6200 
6201 	if (ioctl(parse->generic->io.fd, TIOCMSET, (caddr_t)&sl232) == -1)
6202 	{
6203 		msyslog(LOG_NOTICE, "PARSE receiver #%d: rawdcf_init_1: WARNING: ioctl(fd, TIOCMSET, [C|T]IOCM_DTR): %m", CLK_UNIT(parse->peer));
6204 	}
6205 	return 0;
6206 }
6207 #else
6208 static int
6209 rawdcfdtr_init_1(
6210 	struct parseunit *parse
6211 	)
6212 {
6213 	msyslog(LOG_NOTICE, "PARSE receiver #%d: rawdcf_init_1: WARNING: OS interface incapable of setting DTR to power DCF modules", CLK_UNIT(parse->peer));
6214 	return 0;
6215 }
6216 #endif  /* DTR initialisation type */
6217 
6218 /*--------------------------------------------------
6219  * rawdcf_init_2 - set up modem lines for RAWDCF receivers
6220  * CLR DTR line, SET RTS line
6221  */
6222 #if defined(TIOCMSET) &&  (defined(TIOCM_RTS) || defined(CIOCM_RTS))
6223 static int
6224 rawdcf_init_2(
6225 	struct parseunit *parse
6226 	)
6227 {
6228 	/* fixed 2000 for using with Linux by Wolfram Pienkoss <wp@bszh.de> */
6229 	/*
6230 	 * You can use the RS232 to supply the power for a DCF77 receiver.
6231 	 * Here a voltage between the DTR and the RTS line is used. Unfortunately
6232 	 * the name has changed from CIOCM_DTR to TIOCM_DTR recently.
6233 	 */
6234 	int sl232;
6235 
6236 	if (ioctl(parse->generic->io.fd, TIOCMGET, (caddr_t)&sl232) == -1)
6237 	{
6238 		msyslog(LOG_NOTICE, "PARSE receiver #%d: rawdcf_init_2: WARNING: ioctl(fd, TIOCMGET, [C|T]IOCM_RTS): %m", CLK_UNIT(parse->peer));
6239 		return 0;
6240 	}
6241 
6242 #ifdef TIOCM_RTS
6243 	sl232 = (sl232 & ~TIOCM_DTR) | TIOCM_RTS;	/* turn on RTS, clear DTR for power supply */
6244 #else
6245 	sl232 = (sl232 & ~CIOCM_DTR) | CIOCM_RTS;	/* turn on RTS, clear DTR for power supply */
6246 #endif
6247 
6248 	if (ioctl(parse->generic->io.fd, TIOCMSET, (caddr_t)&sl232) == -1)
6249 	{
6250 		msyslog(LOG_NOTICE, "PARSE receiver #%d: rawdcf_init_2: WARNING: ioctl(fd, TIOCMSET, [C|T]IOCM_RTS): %m", CLK_UNIT(parse->peer));
6251 	}
6252 	return 0;
6253 }
6254 #else
6255 static int
6256 rawdcf_init_2(
6257 	struct parseunit *parse
6258 	)
6259 {
6260 	msyslog(LOG_NOTICE, "PARSE receiver #%d: rawdcf_init_2: WARNING: OS interface incapable of setting RTS to power DCF modules", CLK_UNIT(parse->peer));
6261 	return 0;
6262 }
6263 #endif  /* DTR initialisation type */
6264 
6265 #else	/* defined(REFCLOCK) && defined(PARSE) */
6266 NONEMPTY_TRANSLATION_UNIT
6267 #endif	/* defined(REFCLOCK) && defined(PARSE) */
6268 
6269 /*
6270  * History:
6271  *
6272  * refclock_parse.c,v
6273  * Revision 4.81  2009/05/01 10:15:29  kardel
6274  * use new refclock_ppsapi interface
6275  *
6276  * Revision 4.80  2007/08/11 12:06:29  kardel
6277  * update comments wrt/ to PPS
6278  *
6279  * Revision 4.79  2007/08/11 11:52:23  kardel
6280  * - terminate io bindings before io_closeclock() will close our file descriptor
6281  *
6282  * Revision 4.78  2006/12/22 20:08:27  kardel
6283  * Bug 746 (RFE): add configuration for Expert mouseCLOCK USB v2.0 as mode 19
6284  *
6285  * Revision 4.77  2006/08/05 07:44:49  kardel
6286  * support optionally separate PPS devices via /dev/refclockpps-{0..3}
6287  *
6288  * Revision 4.76  2006/06/22 18:40:47  kardel
6289  * clean up signedness (gcc 4)
6290  *
6291  * Revision 4.75  2006/06/22 16:58:10  kardel
6292  * Bug #632: call parse_ppsapi() in parse_ctl() when updating
6293  * the PPS offset. Fix sign of offset passed to kernel.
6294  *
6295  * Revision 4.74  2006/06/18 21:18:37  kardel
6296  * NetBSD Coverity CID 3796: possible NULL deref
6297  *
6298  * Revision 4.73  2006/05/26 14:23:46  kardel
6299  * cleanup of copyright info
6300  *
6301  * Revision 4.72  2006/05/26 14:19:43  kardel
6302  * cleanup of ioctl cruft
6303  *
6304  * Revision 4.71  2006/05/26 14:15:57  kardel
6305  * delay adding refclock to async refclock io after all initializations
6306  *
6307  * Revision 4.70  2006/05/25 18:20:50  kardel
6308  * bug #619
6309  * terminate parse io engine after de-registering
6310  * from refclock io engine
6311  *
6312  * Revision 4.69  2006/05/25 17:28:02  kardel
6313  * complete refclock io structure initialization *before* inserting it into the
6314  * refclock input machine (avoids null pointer deref) (bug #619)
6315  *
6316  * Revision 4.68  2006/05/01 17:02:51  kardel
6317  * copy receiver method also for newlwy created receive buffers
6318  *
6319  * Revision 4.67  2006/05/01 14:37:29  kardel
6320  * If an input buffer parses into more than one message do insert the
6321  * parsed message in a new input buffer instead of processing it
6322  * directly. This avoids deed complicated processing in signal
6323  * handling.
6324  *
6325  * Revision 4.66  2006/03/18 00:45:30  kardel
6326  * coverity fixes found in NetBSD coverity scan
6327  *
6328  * Revision 4.65  2006/01/26 06:08:33  kardel
6329  * output errno on PPS setup failure
6330  *
6331  * Revision 4.64  2005/11/09 20:44:47  kardel
6332  * utilize full PPS timestamp resolution from PPS API
6333  *
6334  * Revision 4.63  2005/10/07 22:10:25  kardel
6335  * bounded buffer implementation
6336  *
6337  * Revision 4.62.2.2  2005/09/25 10:20:16  kardel
6338  * avoid unexpected buffer overflows due to sprintf("%f") on strange floats:
6339  * replace almost all str* and *printf functions be their buffer bounded
6340  * counterparts
6341  *
6342  * Revision 4.62.2.1  2005/08/27 16:19:27  kardel
6343  * limit re-set rate of trimble clocks
6344  *
6345  * Revision 4.62  2005/08/06 17:40:00  kardel
6346  * cleanup size handling wrt/ to buffer boundaries
6347  *
6348  * Revision 4.61  2005/07/27 21:16:19  kardel
6349  * fix a long (> 11 years) misconfiguration wrt/ Meinberg cflag factory
6350  * default setup. CSTOPB was missing for the 7E2 default data format of
6351  * the DCF77 clocks.
6352  *
6353  * Revision 4.60  2005/07/17 21:14:44  kardel
6354  * change contents of version string to include the RCS/CVS Id
6355  *
6356  * Revision 4.59  2005/07/06 06:56:38  kardel
6357  * syntax error
6358  *
6359  * Revision 4.58  2005/07/04 13:10:40  kardel
6360  * fix bug 455: tripping over NULL pointer on cleanup
6361  * fix shadow storage logic for ppsphaseadjust and trustime wrt/ time2
6362  * fix compiler warnings for some platforms wrt/ printf formatstrings and
6363  *     varying structure element sizes
6364  * reorder assignment in binding to avoid tripping over NULL pointers
6365  *
6366  * Revision 4.57  2005/06/25 09:25:19  kardel
6367  * sort out log output sequence
6368  *
6369  * Revision 4.56  2005/06/14 21:47:27  kardel
6370  * collect samples only if samples are ok (sync or trusted flywheel)
6371  * propagate pps phase adjustment value to kernel via PPSAPI to help HARDPPS
6372  * en- and dis-able HARDPPS in correlation to receiver sync state
6373  *
6374  * Revision 4.55  2005/06/02 21:28:31  kardel
6375  * clarify trust logic
6376  *
6377  * Revision 4.54  2005/06/02 17:06:49  kardel
6378  * change status reporting to use fixed refclock_report()
6379  *
6380  * Revision 4.53  2005/06/02 16:33:31  kardel
6381  * fix acceptance of clocks unsync clocks right at start
6382  *
6383  * Revision 4.52  2005/05/26 21:55:06  kardel
6384  * cleanup status reporting
6385  *
6386  * Revision 4.51  2005/05/26 19:19:14  kardel
6387  * implement fast refclock startup
6388  *
6389  * Revision 4.50  2005/04/16 20:51:35  kardel
6390  * set pps_enable = 1 when binding a kernel PPS source
6391  *
6392  * Revision 4.49  2005/04/16 17:29:26  kardel
6393  * add non polling clock type 18 for just listenning to Meinberg clocks
6394  *
6395  * Revision 4.48  2005/04/16 16:22:27  kardel
6396  * bk sync 20050415 ntp-dev
6397  *
6398  * Revision 4.47  2004/11/29 10:42:48  kardel
6399  * bk sync ntp-dev 20041129
6400  *
6401  * Revision 4.46  2004/11/29 10:26:29  kardel
6402  * keep fudgetime2 in sync with trusttime/ppsphaseadjust depending in flag1
6403  *
6404  * Revision 4.45  2004/11/14 20:53:20  kardel
6405  * clear PPS flags after using them
6406  *
6407  * Revision 4.44  2004/11/14 15:29:41  kardel
6408  * support PPSAPI, upgrade Copyright to Berkeley style
6409  *
6410  * Revision 4.43  2001/05/26 22:53:16  kardel
6411  * 20010526 reconcilation
6412  *
6413  * Revision 4.42  2000/05/14 15:31:51  kardel
6414  * PPSAPI && RAWDCF modemline support
6415  *
6416  * Revision 4.41  2000/04/09 19:50:45  kardel
6417  * fixed rawdcfdtr_init() -> rawdcf_init_1
6418  *
6419  * Revision 4.40  2000/04/09 15:27:55  kardel
6420  * modem line fiddle in rawdcf_init_2
6421  *
6422  * Revision 4.39  2000/03/18 09:16:55  kardel
6423  * PPSAPI integration
6424  *
6425  * Revision 4.38  2000/03/05 20:25:06  kardel
6426  * support PPSAPI
6427  *
6428  * Revision 4.37  2000/03/05 20:11:14  kardel
6429  * 4.0.99g reconcilation
6430  *
6431  * Revision 4.36  1999/11/28 17:18:20  kardel
6432  * disabled burst mode
6433  *
6434  * Revision 4.35  1999/11/28 09:14:14  kardel
6435  * RECON_4_0_98F
6436  *
6437  * Revision 4.34  1999/05/14 06:08:05  kardel
6438  * store current_time in a suitable container (u_long)
6439  *
6440  * Revision 4.33  1999/05/13 21:48:38  kardel
6441  * double the no response timeout interval
6442  *
6443  * Revision 4.32  1999/05/13 20:09:13  kardel
6444  * complain only about missing polls after a full poll interval
6445  *
6446  * Revision 4.31  1999/05/13 19:59:32  kardel
6447  * add clock type 16 for RTS set DTR clr in RAWDCF
6448  *
6449  * Revision 4.30  1999/02/28 20:36:43  kardel
6450  * fixed printf fmt
6451  *
6452  * Revision 4.29  1999/02/28 19:58:23  kardel
6453  * updated copyright information
6454  *
6455  * Revision 4.28  1999/02/28 19:01:50  kardel
6456  * improved debug out on sent Meinberg messages
6457  *
6458  * Revision 4.27  1999/02/28 18:05:55  kardel
6459  * no linux/ppsclock.h stuff
6460  *
6461  * Revision 4.26  1999/02/28 15:27:27  kardel
6462  * wharton clock integration
6463  *
6464  * Revision 4.25  1999/02/28 14:04:46  kardel
6465  * added missing double quotes to UTC information string
6466  *
6467  * Revision 4.24  1999/02/28 12:06:50  kardel
6468  * (parse_control): using gmprettydate instead of prettydate()
6469  * (mk_utcinfo): new function for formatting GPS derived UTC information
6470  * (gps16x_message): changed to use mk_utcinfo()
6471  * (trimbletsip_message): changed to use mk_utcinfo()
6472  * ignoring position information in unsynchronized mode
6473  * (parse_start): augument linux support for optional ASYNC_LOW_LATENCY
6474  *
6475  * Revision 4.23  1999/02/23 19:47:53  kardel
6476  * fixed #endifs
6477  * (stream_receive): fixed formats
6478  *
6479  * Revision 4.22  1999/02/22 06:21:02  kardel
6480  * use new autoconfig symbols
6481  *
6482  * Revision 4.21  1999/02/21 12:18:13  kardel
6483  * 4.91f reconcilation
6484  *
6485  * Revision 4.20  1999/02/21 10:53:36  kardel
6486  * initial Linux PPSkit version
6487  *
6488  * Revision 4.19  1999/02/07 09:10:45  kardel
6489  * clarify STREAMS mitigation rules in comment
6490  *
6491  * Revision 4.18  1998/12/20 23:45:34  kardel
6492  * fix types and warnings
6493  *
6494  * Revision 4.17  1998/11/15 21:24:51  kardel
6495  * cannot access mbg_ routines when CLOCK_MEINBERG
6496  * is not defined
6497  *
6498  * Revision 4.16  1998/11/15 20:28:17  kardel
6499  * Release 4.0.73e13 reconcilation
6500  *
6501  * Revision 4.15  1998/08/22 21:56:08  kardel
6502  * fixed IO handling for non-STREAM IO
6503  *
6504  * Revision 4.14  1998/08/16 19:00:48  kardel
6505  * (gps16x_message): reduced UTC parameter information (dropped A0,A1)
6506  * made uval a local variable (killed one of the last globals)
6507  * (sendetx): added logging of messages when in debug mode
6508  * (trimble_check): added periodic checks to facilitate re-initialization
6509  * (trimbletsip_init): made use of EOL character if in non-kernel operation
6510  * (trimbletsip_message): extended message interpretation
6511  * (getdbl): fixed data conversion
6512  *
6513  * Revision 4.13  1998/08/09 22:29:13  kardel
6514  * Trimble TSIP support
6515  *
6516  * Revision 4.12  1998/07/11 10:05:34  kardel
6517  * Release 4.0.73d reconcilation
6518  *
6519  * Revision 4.11  1998/06/14 21:09:42  kardel
6520  * Sun acc cleanup
6521  *
6522  * Revision 4.10  1998/06/13 12:36:45  kardel
6523  * signed/unsigned, name clashes
6524  *
6525  * Revision 4.9  1998/06/12 15:30:00  kardel
6526  * prototype fixes
6527  *
6528  * Revision 4.8  1998/06/12 11:19:42  kardel
6529  * added direct input processing routine for refclocks in
6530  * order to avaiod that single character io gobbles up all
6531  * receive buffers and drops input data. (Problem started
6532  * with fast machines so a character a buffer was possible
6533  * one of the few cases where faster machines break existing
6534  * allocation algorithms)
6535  *
6536  * Revision 4.7  1998/06/06 18:35:20  kardel
6537  * (parse_start): added BURST mode initialisation
6538  *
6539  * Revision 4.6  1998/05/27 06:12:46  kardel
6540  * RAWDCF_BASEDELAY default added
6541  * old comment removed
6542  * casts for ioctl()
6543  *
6544  * Revision 4.5  1998/05/25 22:05:09  kardel
6545  * RAWDCF_SETDTR option removed
6546  * clock type 14 attempts to set DTR for
6547  * power supply of RAWDCF receivers
6548  *
6549  * Revision 4.4  1998/05/24 16:20:47  kardel
6550  * updated comments referencing Meinberg clocks
6551  * added RAWDCF clock with DTR set option as type 14
6552  *
6553  * Revision 4.3  1998/05/24 10:48:33  kardel
6554  * calibrated CONRAD RAWDCF default fudge factor
6555  *
6556  * Revision 4.2  1998/05/24 09:59:35  kardel
6557  * corrected version information (ntpq support)
6558  *
6559  * Revision 4.1  1998/05/24 09:52:31  kardel
6560  * use fixed format only (new IO model)
6561  * output debug to stdout instead of msyslog()
6562  * don't include >"< in ASCII output in order not to confuse
6563  * ntpq parsing
6564  *
6565  * Revision 4.0  1998/04/10 19:52:11  kardel
6566  * Start 4.0 release version numbering
6567  *
6568  * Revision 1.2  1998/04/10 19:28:04  kardel
6569  * initial NTP VERSION 4 integration of PARSE with GPS166 binary support
6570  * derived from 3.105.1.2 from V3 tree
6571  *
6572  * Revision information 3.1 - 3.105 from log deleted 1998/04/10 kardel
6573  *
6574  */
6575