xref: /freebsd/contrib/ntp/libparse/parse.c (revision f5f40dd63bc7acbb5312b26ac1ea1103c12352a6)
1c0b746e5SOllivier Robert /*
2ea906c41SOllivier Robert  * /src/NTP/ntp4-dev/libparse/parse.c,v 4.20 2005/08/06 17:39:40 kardel RELEASE_20050806_A
3c0b746e5SOllivier Robert  *
4ea906c41SOllivier Robert  * parse.c,v 4.20 2005/08/06 17:39:40 kardel RELEASE_20050806_A
5c0b746e5SOllivier Robert  *
6c0b746e5SOllivier Robert  * Parser module for reference clock
7c0b746e5SOllivier Robert  *
8c0b746e5SOllivier Robert  * PARSEKERNEL define switches between two personalities of the module
9c0b746e5SOllivier Robert  * if PARSEKERNEL is defined this module can be used
10c0b746e5SOllivier Robert  * as kernel module. In this case the time stamps will be
11c0b746e5SOllivier Robert  * a struct timeval.
12c0b746e5SOllivier Robert  * when PARSEKERNEL is not defined NTP time stamps will be used.
13c0b746e5SOllivier Robert  *
14ea906c41SOllivier Robert  * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
15a25439b6SCy Schubert  * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universitaet Erlangen-Nuernberg, Germany
16c0b746e5SOllivier Robert  *
17ea906c41SOllivier Robert  * Redistribution and use in source and binary forms, with or without
18ea906c41SOllivier Robert  * modification, are permitted provided that the following conditions
19ea906c41SOllivier Robert  * are met:
20ea906c41SOllivier Robert  * 1. Redistributions of source code must retain the above copyright
21ea906c41SOllivier Robert  *    notice, this list of conditions and the following disclaimer.
22ea906c41SOllivier Robert  * 2. Redistributions in binary form must reproduce the above copyright
23ea906c41SOllivier Robert  *    notice, this list of conditions and the following disclaimer in the
24ea906c41SOllivier Robert  *    documentation and/or other materials provided with the distribution.
25ea906c41SOllivier Robert  * 3. Neither the name of the author nor the names of its contributors
26ea906c41SOllivier Robert  *    may be used to endorse or promote products derived from this software
27ea906c41SOllivier Robert  *    without specific prior written permission.
28ea906c41SOllivier Robert  *
29ea906c41SOllivier Robert  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
30ea906c41SOllivier Robert  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31ea906c41SOllivier Robert  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32ea906c41SOllivier Robert  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
33ea906c41SOllivier Robert  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34ea906c41SOllivier Robert  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35ea906c41SOllivier Robert  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36ea906c41SOllivier Robert  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37ea906c41SOllivier Robert  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38ea906c41SOllivier Robert  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39ea906c41SOllivier Robert  * SUCH DAMAGE.
40c0b746e5SOllivier Robert  *
41c0b746e5SOllivier Robert  */
42c0b746e5SOllivier Robert 
43c0b746e5SOllivier Robert #ifdef HAVE_CONFIG_H
44c0b746e5SOllivier Robert # include <config.h>
45c0b746e5SOllivier Robert #endif
46c0b746e5SOllivier Robert 
47c0b746e5SOllivier Robert #if defined(REFCLOCK) && defined(CLOCK_PARSE)
48c0b746e5SOllivier Robert 
49c0b746e5SOllivier Robert #if	!(defined(lint) || defined(__GNUC__))
50ea906c41SOllivier Robert static char rcsid[] = "parse.c,v 4.20 2005/08/06 17:39:40 kardel RELEASE_20050806_A";
51c0b746e5SOllivier Robert #endif
52c0b746e5SOllivier Robert 
53c0b746e5SOllivier Robert #include "ntp_fp.h"
542b15cb3dSCy Schubert #include "timevalops.h"
55c0b746e5SOllivier Robert #include "ntp_calendar.h"
56c0b746e5SOllivier Robert #include "ntp_stdlib.h"
57c0b746e5SOllivier Robert #include "ntp_machine.h"
58c0b746e5SOllivier Robert #include "ntp.h"		/* (get Y2KFixes definitions) 	Y2KFixes */
59c0b746e5SOllivier Robert 
60c0b746e5SOllivier Robert #include "parse.h"
61c0b746e5SOllivier Robert 
62c0b746e5SOllivier Robert #ifndef PARSESTREAM
63c0b746e5SOllivier Robert # include <stdio.h>
64c0b746e5SOllivier Robert #else
65c0b746e5SOllivier Robert # include "sys/parsestreams.h"
66c0b746e5SOllivier Robert #endif
67c0b746e5SOllivier Robert 
68c0b746e5SOllivier Robert extern clockformat_t *clockformats[];
69c0b746e5SOllivier Robert extern unsigned short nformats;
70c0b746e5SOllivier Robert 
712b15cb3dSCy Schubert static u_long timepacket (parse_t *);
72c0b746e5SOllivier Robert 
73c0b746e5SOllivier Robert /*
74c0b746e5SOllivier Robert  * strings support usually not in kernel - duplicated, but what the heck
75c0b746e5SOllivier Robert  */
76c0b746e5SOllivier Robert static int
77c0b746e5SOllivier Robert Strlen(
78c0b746e5SOllivier Robert 	register const char *s
79c0b746e5SOllivier Robert 	)
80c0b746e5SOllivier Robert {
81c0b746e5SOllivier Robert 	register int c;
82c0b746e5SOllivier Robert 
83c0b746e5SOllivier Robert 	c = 0;
84c0b746e5SOllivier Robert 	if (s)
85c0b746e5SOllivier Robert 	{
86c0b746e5SOllivier Robert 		while (*s++)
87c0b746e5SOllivier Robert 		{
88c0b746e5SOllivier Robert 			c++;
89c0b746e5SOllivier Robert 		}
90c0b746e5SOllivier Robert 	}
91c0b746e5SOllivier Robert 	return c;
92c0b746e5SOllivier Robert }
93c0b746e5SOllivier Robert 
94c0b746e5SOllivier Robert static int
95c0b746e5SOllivier Robert Strcmp(
96c0b746e5SOllivier Robert 	register const char *s,
97c0b746e5SOllivier Robert 	register const char *t
98c0b746e5SOllivier Robert 	)
99c0b746e5SOllivier Robert {
100c0b746e5SOllivier Robert 	register int c = 0;
101c0b746e5SOllivier Robert 
102c0b746e5SOllivier Robert 	if (!s || !t || (s == t))
103c0b746e5SOllivier Robert 	{
104c0b746e5SOllivier Robert 		return 0;
105c0b746e5SOllivier Robert 	}
106c0b746e5SOllivier Robert 
107c0b746e5SOllivier Robert 	while (!(c = *s++ - *t++) && *s && *t)
108c0b746e5SOllivier Robert 	    /* empty loop */;
109c0b746e5SOllivier Robert 
110c0b746e5SOllivier Robert 	return c;
111c0b746e5SOllivier Robert }
112c0b746e5SOllivier Robert 
113c0b746e5SOllivier Robert int
114c0b746e5SOllivier Robert parse_timedout(
115c0b746e5SOllivier Robert 	       parse_t *parseio,
116c0b746e5SOllivier Robert 	       timestamp_t *tstamp,
117c0b746e5SOllivier Robert 	       struct timeval *del
118c0b746e5SOllivier Robert 	       )
119c0b746e5SOllivier Robert {
120c0b746e5SOllivier Robert 	struct timeval delta;
121c0b746e5SOllivier Robert 
122c0b746e5SOllivier Robert #ifdef PARSEKERNEL
123c0b746e5SOllivier Robert 	delta.tv_sec = tstamp->tv.tv_sec - parseio->parse_lastchar.tv.tv_sec;
124c0b746e5SOllivier Robert 	delta.tv_usec = tstamp->tv.tv_usec - parseio->parse_lastchar.tv.tv_usec;
125c0b746e5SOllivier Robert 	if (delta.tv_usec < 0)
126c0b746e5SOllivier Robert 	{
127c0b746e5SOllivier Robert 		delta.tv_sec  -= 1;
128c0b746e5SOllivier Robert 		delta.tv_usec += 1000000;
129c0b746e5SOllivier Robert 	}
130c0b746e5SOllivier Robert #else
131c0b746e5SOllivier Robert 	l_fp delt;
132c0b746e5SOllivier Robert 
133c0b746e5SOllivier Robert 	delt = tstamp->fp;
134c0b746e5SOllivier Robert 	L_SUB(&delt, &parseio->parse_lastchar.fp);
135c0b746e5SOllivier Robert 	TSTOTV(&delt, &delta);
136c0b746e5SOllivier Robert #endif
137c0b746e5SOllivier Robert 
138c0b746e5SOllivier Robert 	if (timercmp(&delta, del, >))
139c0b746e5SOllivier Robert 	{
140c0b746e5SOllivier Robert 		parseprintf(DD_PARSE, ("parse: timedout: TRUE\n"));
141c0b746e5SOllivier Robert 		return 1;
142c0b746e5SOllivier Robert 	}
143c0b746e5SOllivier Robert 	else
144c0b746e5SOllivier Robert 	{
145c0b746e5SOllivier Robert 		parseprintf(DD_PARSE, ("parse: timedout: FALSE\n"));
146c0b746e5SOllivier Robert 		return 0;
147c0b746e5SOllivier Robert 	}
148c0b746e5SOllivier Robert }
149c0b746e5SOllivier Robert 
150c0b746e5SOllivier Robert /*ARGSUSED*/
151c0b746e5SOllivier Robert int
152c0b746e5SOllivier Robert parse_ioinit(
153c0b746e5SOllivier Robert 	register parse_t *parseio
154c0b746e5SOllivier Robert 	)
155c0b746e5SOllivier Robert {
156c0b746e5SOllivier Robert 	parseprintf(DD_PARSE, ("parse_iostart\n"));
157c0b746e5SOllivier Robert 
158c0b746e5SOllivier Robert 	parseio->parse_plen = 0;
159c0b746e5SOllivier Robert 	parseio->parse_pdata = (void *)0;
160c0b746e5SOllivier Robert 
161c0b746e5SOllivier Robert 	parseio->parse_data = 0;
162c0b746e5SOllivier Robert 	parseio->parse_ldata = 0;
163c0b746e5SOllivier Robert 	parseio->parse_dsize = 0;
164c0b746e5SOllivier Robert 
165c0b746e5SOllivier Robert 	parseio->parse_badformat = 0;
166c0b746e5SOllivier Robert 	parseio->parse_ioflags   = PARSE_IO_CS7;	/* usual unix default */
167c0b746e5SOllivier Robert 	parseio->parse_index     = 0;
168c0b746e5SOllivier Robert 	parseio->parse_ldsize    = 0;
169c0b746e5SOllivier Robert 
170c0b746e5SOllivier Robert 	return 1;
171c0b746e5SOllivier Robert }
172c0b746e5SOllivier Robert 
173c0b746e5SOllivier Robert /*ARGSUSED*/
174c0b746e5SOllivier Robert void
175c0b746e5SOllivier Robert parse_ioend(
176c0b746e5SOllivier Robert 	register parse_t *parseio
177c0b746e5SOllivier Robert 	)
178c0b746e5SOllivier Robert {
179c0b746e5SOllivier Robert 	parseprintf(DD_PARSE, ("parse_ioend\n"));
180c0b746e5SOllivier Robert 
181c0b746e5SOllivier Robert 	if (parseio->parse_pdata)
182c0b746e5SOllivier Robert 	    FREE(parseio->parse_pdata, parseio->parse_plen);
183c0b746e5SOllivier Robert 
184c0b746e5SOllivier Robert 	if (parseio->parse_data)
185c0b746e5SOllivier Robert 	    FREE(parseio->parse_data, (unsigned)(parseio->parse_dsize * 2 + 2));
186c0b746e5SOllivier Robert }
187c0b746e5SOllivier Robert 
188c0b746e5SOllivier Robert unsigned int
189c0b746e5SOllivier Robert parse_restart(
190c0b746e5SOllivier Robert 	      parse_t *parseio,
191a25439b6SCy Schubert 	      char ch
192c0b746e5SOllivier Robert 	      )
193c0b746e5SOllivier Robert {
194c0b746e5SOllivier Robert 	unsigned int updated = PARSE_INP_SKIP;
195c0b746e5SOllivier Robert 
196c0b746e5SOllivier Robert 	/*
197c0b746e5SOllivier Robert 	 * re-start packet - timeout - overflow - start symbol
198c0b746e5SOllivier Robert 	 */
199c0b746e5SOllivier Robert 
200c0b746e5SOllivier Robert 	if (parseio->parse_index)
201c0b746e5SOllivier Robert 	{
202c0b746e5SOllivier Robert 		/*
203c0b746e5SOllivier Robert 		 * filled buffer - thus not end character found
204c0b746e5SOllivier Robert 		 * do processing now
205c0b746e5SOllivier Robert 		 */
206c0b746e5SOllivier Robert 		parseio->parse_data[parseio->parse_index] = '\0';
207c0b746e5SOllivier Robert 		memcpy(parseio->parse_ldata, parseio->parse_data, (unsigned)(parseio->parse_index+1));
208ea906c41SOllivier Robert 		parseio->parse_ldsize = parseio->parse_index;
209c0b746e5SOllivier Robert 		updated = PARSE_INP_TIME;
210c0b746e5SOllivier Robert 	}
211c0b746e5SOllivier Robert 
212c0b746e5SOllivier Robert 	parseio->parse_index = 1;
213c0b746e5SOllivier Robert 	parseio->parse_data[0] = ch;
214c0b746e5SOllivier Robert 	parseprintf(DD_PARSE, ("parse: parse_restart: buffer start (updated = %x)\n", updated));
215c0b746e5SOllivier Robert 	return updated;
216c0b746e5SOllivier Robert }
217c0b746e5SOllivier Robert 
218c0b746e5SOllivier Robert unsigned int
219c0b746e5SOllivier Robert parse_addchar(
220c0b746e5SOllivier Robert 	      parse_t *parseio,
221a25439b6SCy Schubert 	      char ch
222c0b746e5SOllivier Robert 	      )
223c0b746e5SOllivier Robert {
224c0b746e5SOllivier Robert 	/*
225c0b746e5SOllivier Robert 	 * add to buffer
226c0b746e5SOllivier Robert 	 */
227c0b746e5SOllivier Robert 	if (parseio->parse_index < parseio->parse_dsize)
228c0b746e5SOllivier Robert 	{
229c0b746e5SOllivier Robert 		/*
230c0b746e5SOllivier Robert 		 * collect into buffer
231c0b746e5SOllivier Robert 		 */
232c0b746e5SOllivier Robert 		parseprintf(DD_PARSE, ("parse: parse_addchar: buffer[%d] = 0x%x\n", parseio->parse_index, ch));
2332b15cb3dSCy Schubert 		parseio->parse_data[parseio->parse_index++] = (char)ch;
234c0b746e5SOllivier Robert 		return PARSE_INP_SKIP;
235c0b746e5SOllivier Robert 	}
236c0b746e5SOllivier Robert 	else
237c0b746e5SOllivier Robert 		/*
238c0b746e5SOllivier Robert 		 * buffer overflow - attempt to make the best of it
239c0b746e5SOllivier Robert 		 */
240c0b746e5SOllivier Robert 		return parse_restart(parseio, ch);
241c0b746e5SOllivier Robert }
242c0b746e5SOllivier Robert 
243c0b746e5SOllivier Robert unsigned int
244c0b746e5SOllivier Robert parse_end(
245c0b746e5SOllivier Robert 	  parse_t *parseio
246c0b746e5SOllivier Robert 	  )
247c0b746e5SOllivier Robert {
248c0b746e5SOllivier Robert 	/*
249c0b746e5SOllivier Robert 	 * message complete processing
250c0b746e5SOllivier Robert 	 */
251c0b746e5SOllivier Robert 	parseio->parse_data[parseio->parse_index] = '\0';
252c0b746e5SOllivier Robert 	memcpy(parseio->parse_ldata, parseio->parse_data, (unsigned)(parseio->parse_index+1));
253ea906c41SOllivier Robert 	parseio->parse_ldsize = parseio->parse_index;
254c0b746e5SOllivier Robert 	parseio->parse_index = 0;
255c0b746e5SOllivier Robert 	parseprintf(DD_PARSE, ("parse: parse_end: buffer end\n"));
256c0b746e5SOllivier Robert 	return PARSE_INP_TIME;
257c0b746e5SOllivier Robert }
258c0b746e5SOllivier Robert 
259c0b746e5SOllivier Robert /*ARGSUSED*/
260c0b746e5SOllivier Robert int
261c0b746e5SOllivier Robert parse_ioread(
262c0b746e5SOllivier Robert 	register parse_t *parseio,
263a25439b6SCy Schubert 	register char ch,
264c0b746e5SOllivier Robert 	register timestamp_t *tstamp
265c0b746e5SOllivier Robert 	)
266c0b746e5SOllivier Robert {
267a25439b6SCy Schubert 	register u_int updated = CVT_NONE;
268c0b746e5SOllivier Robert 	/*
269c0b746e5SOllivier Robert 	 * within STREAMS CSx (x < 8) chars still have the upper bits set
270c0b746e5SOllivier Robert 	 * so we normalize the characters by masking unecessary bits off.
271c0b746e5SOllivier Robert 	 */
272c0b746e5SOllivier Robert 	switch (parseio->parse_ioflags & PARSE_IO_CSIZE)
273c0b746e5SOllivier Robert 	{
274c0b746e5SOllivier Robert 	    case PARSE_IO_CS5:
275c0b746e5SOllivier Robert 		ch &= 0x1F;
276c0b746e5SOllivier Robert 		break;
277c0b746e5SOllivier Robert 
278c0b746e5SOllivier Robert 	    case PARSE_IO_CS6:
279c0b746e5SOllivier Robert 		ch &= 0x3F;
280c0b746e5SOllivier Robert 		break;
281c0b746e5SOllivier Robert 
282c0b746e5SOllivier Robert 	    case PARSE_IO_CS7:
283c0b746e5SOllivier Robert 		ch &= 0x7F;
284c0b746e5SOllivier Robert 		break;
285c0b746e5SOllivier Robert 
286c0b746e5SOllivier Robert 	    case PARSE_IO_CS8:
287a25439b6SCy Schubert 		ch &= (char) 0xFFU;
288c0b746e5SOllivier Robert 		break;
289c0b746e5SOllivier Robert 	}
290c0b746e5SOllivier Robert 
2913311ff84SXin LI 	parseprintf(DD_PARSE, ("parse_ioread(0x%p, char=0x%x, ..., ...)\n", (void*)parseio, ch & 0xFF));
292c0b746e5SOllivier Robert 
293c0b746e5SOllivier Robert 	if (!clockformats[parseio->parse_lformat]->convert)
294c0b746e5SOllivier Robert 	{
295c0b746e5SOllivier Robert 		parseprintf(DD_PARSE, ("parse_ioread: input dropped.\n"));
296c0b746e5SOllivier Robert 		return CVT_NONE;
297c0b746e5SOllivier Robert 	}
298c0b746e5SOllivier Robert 
299c0b746e5SOllivier Robert 	if (clockformats[parseio->parse_lformat]->input)
300c0b746e5SOllivier Robert 	{
301c0b746e5SOllivier Robert 		unsigned long input_status;
302c0b746e5SOllivier Robert 
303c0b746e5SOllivier Robert 		input_status = clockformats[parseio->parse_lformat]->input(parseio, ch, tstamp);
304c0b746e5SOllivier Robert 
305c0b746e5SOllivier Robert 		if (input_status & PARSE_INP_SYNTH)
306c0b746e5SOllivier Robert 		{
307c0b746e5SOllivier Robert 			updated = CVT_OK;
308c0b746e5SOllivier Robert 		}
309c0b746e5SOllivier Robert 
310c0b746e5SOllivier Robert 		if (input_status & PARSE_INP_TIME)	/* time sample is available */
311c0b746e5SOllivier Robert 		{
312a25439b6SCy Schubert 			updated = (u_int) timepacket(parseio);
313c0b746e5SOllivier Robert 		}
314c0b746e5SOllivier Robert 
315c0b746e5SOllivier Robert 		if (input_status & PARSE_INP_DATA) /* got additional data */
316c0b746e5SOllivier Robert 		{
317c0b746e5SOllivier Robert 			updated |= CVT_ADDITIONAL;
318c0b746e5SOllivier Robert 		}
319c0b746e5SOllivier Robert 	}
320c0b746e5SOllivier Robert 
321c0b746e5SOllivier Robert 
322c0b746e5SOllivier Robert 	/*
323c0b746e5SOllivier Robert 	 * remember last character time
324c0b746e5SOllivier Robert 	 */
325c0b746e5SOllivier Robert 	parseio->parse_lastchar = *tstamp;
326c0b746e5SOllivier Robert 
327c0b746e5SOllivier Robert #ifdef DEBUG
328c0b746e5SOllivier Robert 	if ((updated & CVT_MASK) != CVT_NONE)
329c0b746e5SOllivier Robert 	{
330c0b746e5SOllivier Robert 		parseprintf(DD_PARSE, ("parse_ioread: time sample accumulated (status=0x%x)\n", updated));
331c0b746e5SOllivier Robert 	}
332c0b746e5SOllivier Robert #endif
333c0b746e5SOllivier Robert 
334c0b746e5SOllivier Robert 	parseio->parse_dtime.parse_status = updated;
335c0b746e5SOllivier Robert 
336c0b746e5SOllivier Robert 	return (((updated & CVT_MASK) != CVT_NONE) ||
337c0b746e5SOllivier Robert 		((updated & CVT_ADDITIONAL) != 0));
338c0b746e5SOllivier Robert }
339c0b746e5SOllivier Robert 
340c0b746e5SOllivier Robert /*
341c0b746e5SOllivier Robert  * parse_iopps
342c0b746e5SOllivier Robert  *
343c0b746e5SOllivier Robert  * take status line indication and derive synchronisation information
344c0b746e5SOllivier Robert  * from it.
345c0b746e5SOllivier Robert  * It can also be used to decode a serial serial data format (such as the
346c0b746e5SOllivier Robert  * ONE, ZERO, MINUTE sync data stream from DCF77)
347c0b746e5SOllivier Robert  */
348c0b746e5SOllivier Robert /*ARGSUSED*/
349c0b746e5SOllivier Robert int
350c0b746e5SOllivier Robert parse_iopps(
351c0b746e5SOllivier Robert 	register parse_t *parseio,
352c0b746e5SOllivier Robert 	register int status,
353c0b746e5SOllivier Robert 	register timestamp_t *ptime
354c0b746e5SOllivier Robert 	)
355c0b746e5SOllivier Robert {
356a25439b6SCy Schubert 	register u_int updated = CVT_NONE;
357c0b746e5SOllivier Robert 
358c0b746e5SOllivier Robert 	/*
359c0b746e5SOllivier Robert 	 * PPS pulse information will only be delivered to ONE clock format
360c0b746e5SOllivier Robert 	 * this is either the last successful conversion module with a ppssync
361c0b746e5SOllivier Robert 	 * routine, or a fixed format with a ppssync routine
362c0b746e5SOllivier Robert 	 */
363c0b746e5SOllivier Robert 	parseprintf(DD_PARSE, ("parse_iopps: STATUS %s\n", (status == SYNC_ONE) ? "ONE" : "ZERO"));
364c0b746e5SOllivier Robert 
365c0b746e5SOllivier Robert 	if (clockformats[parseio->parse_lformat]->syncpps)
366c0b746e5SOllivier Robert 	{
367a25439b6SCy Schubert 		updated = (u_int) clockformats[parseio->parse_lformat]->syncpps(parseio, status == SYNC_ONE, ptime);
368c0b746e5SOllivier Robert 		parseprintf(DD_PARSE, ("parse_iopps: updated = 0x%x\n", updated));
369c0b746e5SOllivier Robert 	}
370c0b746e5SOllivier Robert 
371c0b746e5SOllivier Robert 	return (updated & CVT_MASK) != CVT_NONE;
372c0b746e5SOllivier Robert }
373c0b746e5SOllivier Robert 
374c0b746e5SOllivier Robert /*
375c0b746e5SOllivier Robert  * parse_iodone
376c0b746e5SOllivier Robert  *
377c0b746e5SOllivier Robert  * clean up internal status for new round
378c0b746e5SOllivier Robert  */
379c0b746e5SOllivier Robert /*ARGSUSED*/
380c0b746e5SOllivier Robert void
381c0b746e5SOllivier Robert parse_iodone(
382c0b746e5SOllivier Robert 	register parse_t *parseio
383c0b746e5SOllivier Robert 	)
384c0b746e5SOllivier Robert {
385c0b746e5SOllivier Robert 	/*
386c0b746e5SOllivier Robert 	 * we need to clean up certain flags for the next round
387c0b746e5SOllivier Robert 	 */
388c0b746e5SOllivier Robert 	parseprintf(DD_PARSE, ("parse_iodone: DONE\n"));
389c0b746e5SOllivier Robert 	parseio->parse_dtime.parse_state = 0; /* no problems with ISRs */
390c0b746e5SOllivier Robert }
391c0b746e5SOllivier Robert 
392c0b746e5SOllivier Robert /*---------- conversion implementation --------------------*/
393c0b746e5SOllivier Robert 
394c0b746e5SOllivier Robert /*
395c0b746e5SOllivier Robert  * convert a struct clock to UTC since Jan, 1st 1970 0:00 (the UNIX EPOCH)
396c0b746e5SOllivier Robert  */
397c0b746e5SOllivier Robert #define days_per_year(x)	((x) % 4 ? 365 : ((x % 400) ? ((x % 100) ? 366 : 365) : 366))
398c0b746e5SOllivier Robert 
399c0b746e5SOllivier Robert time_t
400c0b746e5SOllivier Robert parse_to_unixtime(
401c0b746e5SOllivier Robert 	register clocktime_t   *clock_time,
402c0b746e5SOllivier Robert 	register u_long *cvtrtc
403c0b746e5SOllivier Robert 	)
404c0b746e5SOllivier Robert {
405c0b746e5SOllivier Robert #define SETRTC(_X_)	{ if (cvtrtc) *cvtrtc = (_X_); }
406c0b746e5SOllivier Robert 	static int days_of_month[] =
407c0b746e5SOllivier Robert 	{
408c0b746e5SOllivier Robert 		0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
409c0b746e5SOllivier Robert 	};
410c0b746e5SOllivier Robert 	register int i;
411c0b746e5SOllivier Robert 	time_t t;
412c0b746e5SOllivier Robert 
413c0b746e5SOllivier Robert 	if (clock_time->utctime)
414c0b746e5SOllivier Robert 	    return clock_time->utctime;	/* if the conversion routine gets it right away - why not */
415c0b746e5SOllivier Robert 
416c0b746e5SOllivier Robert 	if ( clock_time->year < YEAR_PIVOT )			/* Y2KFixes [ */
417c0b746e5SOllivier Robert 	    clock_time->year += 100;	/* convert 20xx%100 to 20xx-1900 */
418c0b746e5SOllivier Robert 	if ( clock_time->year < YEAR_BREAK )	/* expand to full four-digits */
419c0b746e5SOllivier Robert 	    clock_time->year += 1900;
420c0b746e5SOllivier Robert 
421c0b746e5SOllivier Robert 	if (clock_time->year < 1970 )				/* Y2KFixes ] */
422c0b746e5SOllivier Robert 	{
423c0b746e5SOllivier Robert 		SETRTC(CVT_FAIL|CVT_BADDATE);
424c0b746e5SOllivier Robert 		return -1;
425c0b746e5SOllivier Robert 	}
426c0b746e5SOllivier Robert 
427c0b746e5SOllivier Robert 	/*
428c0b746e5SOllivier Robert 	 * sorry, slow section here - but it's not time critical anyway
429c0b746e5SOllivier Robert 	 */
430c0b746e5SOllivier Robert 	t = julian0(clock_time->year) - julian0(1970);		/* Y2kFixes */
431c0b746e5SOllivier Robert 				/* month */
432c0b746e5SOllivier Robert 	if (clock_time->month <= 0 || clock_time->month > 12)
433c0b746e5SOllivier Robert 	{
434c0b746e5SOllivier Robert 		SETRTC(CVT_FAIL|CVT_BADDATE);
435c0b746e5SOllivier Robert 		return -1;		/* bad month */
436c0b746e5SOllivier Robert 	}
437c0b746e5SOllivier Robert 
438c0b746e5SOllivier Robert #if 0								/* Y2KFixes */
439c0b746e5SOllivier Robert 				/* adjust leap year */
440c0b746e5SOllivier Robert 	if (clock_time->month < 3 && days_per_year(clock_time->year) == 366)
441c0b746e5SOllivier Robert 	    t--;
442c0b746e5SOllivier Robert #else								/* Y2KFixes [ */
443c0b746e5SOllivier Robert 	if ( clock_time->month >= 3  &&  isleap_4(clock_time->year) )
444c0b746e5SOllivier Robert 	    t++;		/* add one more if within leap year */
445c0b746e5SOllivier Robert #endif								/* Y2KFixes ] */
446c0b746e5SOllivier Robert 
447c0b746e5SOllivier Robert 	for (i = 1; i < clock_time->month; i++)
448c0b746e5SOllivier Robert 	{
449c0b746e5SOllivier Robert 		t += days_of_month[i];
450c0b746e5SOllivier Robert 	}
451c0b746e5SOllivier Robert 				/* day */
452c0b746e5SOllivier Robert 	if (clock_time->day < 1 || ((clock_time->month == 2 && days_per_year(clock_time->year) == 366) ?
453c0b746e5SOllivier Robert 			       clock_time->day > 29 : clock_time->day > days_of_month[clock_time->month]))
454c0b746e5SOllivier Robert 	{
455c0b746e5SOllivier Robert 		SETRTC(CVT_FAIL|CVT_BADDATE);
456c0b746e5SOllivier Robert 		return -1;		/* bad day */
457c0b746e5SOllivier Robert 	}
458c0b746e5SOllivier Robert 
459c0b746e5SOllivier Robert 	t += clock_time->day - 1;
460c0b746e5SOllivier Robert 				/* hour */
461c0b746e5SOllivier Robert 	if (clock_time->hour < 0 || clock_time->hour >= 24)
462c0b746e5SOllivier Robert 	{
463c0b746e5SOllivier Robert 		SETRTC(CVT_FAIL|CVT_BADTIME);
464c0b746e5SOllivier Robert 		return -1;		/* bad hour */
465c0b746e5SOllivier Robert 	}
466c0b746e5SOllivier Robert 
467c0b746e5SOllivier Robert 	t = TIMES24(t) + clock_time->hour;
468c0b746e5SOllivier Robert 
469c0b746e5SOllivier Robert 				/* min */
470c0b746e5SOllivier Robert 	if (clock_time->minute < 0 || clock_time->minute > 59)
471c0b746e5SOllivier Robert 	{
472c0b746e5SOllivier Robert 		SETRTC(CVT_FAIL|CVT_BADTIME);
473c0b746e5SOllivier Robert 		return -1;		/* bad min */
474c0b746e5SOllivier Robert 	}
475c0b746e5SOllivier Robert 
476c0b746e5SOllivier Robert 	t = TIMES60(t) + clock_time->minute;
477c0b746e5SOllivier Robert 				/* sec */
478c0b746e5SOllivier Robert 
479c0b746e5SOllivier Robert 	if (clock_time->second < 0 || clock_time->second > 60)	/* allow for LEAPs */
480c0b746e5SOllivier Robert 	{
481c0b746e5SOllivier Robert 		SETRTC(CVT_FAIL|CVT_BADTIME);
482c0b746e5SOllivier Robert 		return -1;		/* bad sec */
483c0b746e5SOllivier Robert 	}
484c0b746e5SOllivier Robert 
485c0b746e5SOllivier Robert 	t  = TIMES60(t) + clock_time->second;
486c0b746e5SOllivier Robert 
487c0b746e5SOllivier Robert 	t += clock_time->utcoffset;	/* warp to UTC */
488c0b746e5SOllivier Robert 
489c0b746e5SOllivier Robert 				/* done */
490c0b746e5SOllivier Robert 
491c0b746e5SOllivier Robert 	clock_time->utctime = t;		/* documentray only */
492c0b746e5SOllivier Robert 
493c0b746e5SOllivier Robert 	return t;
494c0b746e5SOllivier Robert }
495c0b746e5SOllivier Robert 
496c0b746e5SOllivier Robert /*--------------- format conversion -----------------------------------*/
497c0b746e5SOllivier Robert 
498c0b746e5SOllivier Robert int
499c0b746e5SOllivier Robert Stoi(
500c0b746e5SOllivier Robert 	const unsigned char *s,
501c0b746e5SOllivier Robert 	long *zp,
502c0b746e5SOllivier Robert 	int cnt
503c0b746e5SOllivier Robert 	)
504c0b746e5SOllivier Robert {
505c0b746e5SOllivier Robert 	char unsigned const *b = s;
506c0b746e5SOllivier Robert 	int f,z,v;
507c0b746e5SOllivier Robert 	char unsigned c;
508c0b746e5SOllivier Robert 
509c0b746e5SOllivier Robert 	f=z=v=0;
510c0b746e5SOllivier Robert 
511c0b746e5SOllivier Robert 	while(*s == ' ')
512c0b746e5SOllivier Robert 	    s++;
513c0b746e5SOllivier Robert 
514c0b746e5SOllivier Robert 	if (*s == '-')
515c0b746e5SOllivier Robert 	{
516c0b746e5SOllivier Robert 		s++;
517c0b746e5SOllivier Robert 		v = 1;
518c0b746e5SOllivier Robert 	}
519c0b746e5SOllivier Robert 	else
520c0b746e5SOllivier Robert 	    if (*s == '+')
521c0b746e5SOllivier Robert 		s++;
522c0b746e5SOllivier Robert 
523c0b746e5SOllivier Robert 	for(;;)
524c0b746e5SOllivier Robert 	{
525c0b746e5SOllivier Robert 		c = *s++;
526c0b746e5SOllivier Robert 		if (c == '\0' || c < '0' || c > '9' || (cnt && ((s-b) > cnt)))
527c0b746e5SOllivier Robert 		{
528c0b746e5SOllivier Robert 			if (f == 0)
529c0b746e5SOllivier Robert 			{
530c0b746e5SOllivier Robert 				return(-1);
531c0b746e5SOllivier Robert 			}
532c0b746e5SOllivier Robert 			if (v)
533c0b746e5SOllivier Robert 			    z = -z;
534c0b746e5SOllivier Robert 			*zp = z;
535c0b746e5SOllivier Robert 			return(0);
536c0b746e5SOllivier Robert 		}
537c0b746e5SOllivier Robert 		z = (z << 3) + (z << 1) + ( c - '0' );
538c0b746e5SOllivier Robert 		f=1;
539c0b746e5SOllivier Robert 	}
540c0b746e5SOllivier Robert }
541c0b746e5SOllivier Robert 
542c0b746e5SOllivier Robert int
543c0b746e5SOllivier Robert Strok(
544c0b746e5SOllivier Robert 	const unsigned char *s,
545c0b746e5SOllivier Robert 	const unsigned char *m
546c0b746e5SOllivier Robert 	)
547c0b746e5SOllivier Robert {
548c0b746e5SOllivier Robert 	if (!s || !m)
549c0b746e5SOllivier Robert 	    return 0;
550c0b746e5SOllivier Robert 
551c0b746e5SOllivier Robert 	while(*s && *m)
552c0b746e5SOllivier Robert 	{
553c0b746e5SOllivier Robert 		if ((*m == ' ') ? 1 : (*s == *m))
554c0b746e5SOllivier Robert 		{
555c0b746e5SOllivier Robert 			s++;
556c0b746e5SOllivier Robert 			m++;
557c0b746e5SOllivier Robert 		}
558c0b746e5SOllivier Robert 		else
559c0b746e5SOllivier Robert 		{
560c0b746e5SOllivier Robert 			return 0;
561c0b746e5SOllivier Robert 		}
562c0b746e5SOllivier Robert 	}
563c0b746e5SOllivier Robert 	return !*m;
564c0b746e5SOllivier Robert }
565c0b746e5SOllivier Robert 
566c0b746e5SOllivier Robert u_long
567c0b746e5SOllivier Robert updatetimeinfo(
568c0b746e5SOllivier Robert 	       register parse_t *parseio,
569c0b746e5SOllivier Robert 	       register u_long   flags
570c0b746e5SOllivier Robert 	       )
571c0b746e5SOllivier Robert {
572c0b746e5SOllivier Robert #ifdef PARSEKERNEL
573c0b746e5SOllivier Robert 	{
574c0b746e5SOllivier Robert 		int s = splhigh();
575c0b746e5SOllivier Robert #endif
576c0b746e5SOllivier Robert 
577c0b746e5SOllivier Robert 		parseio->parse_lstate          = parseio->parse_dtime.parse_state | flags | PARSEB_TIMECODE;
578c0b746e5SOllivier Robert 
579c0b746e5SOllivier Robert 		parseio->parse_dtime.parse_state = parseio->parse_lstate;
580c0b746e5SOllivier Robert 
581c0b746e5SOllivier Robert #ifdef PARSEKERNEL
582c0b746e5SOllivier Robert 		(void)splx((unsigned int)s);
583c0b746e5SOllivier Robert 	}
584c0b746e5SOllivier Robert #endif
585c0b746e5SOllivier Robert 
586c0b746e5SOllivier Robert 
587c0b746e5SOllivier Robert #ifdef PARSEKERNEL
588c0b746e5SOllivier Robert 	parseprintf(DD_PARSE, ("updatetimeinfo status=0x%x, time=%x\n", parseio->parse_dtime.parse_state,
589c0b746e5SOllivier Robert 			       parseio->parse_dtime.parse_time.tv.tv_sec));
590c0b746e5SOllivier Robert #else
591c0b746e5SOllivier Robert 	parseprintf(DD_PARSE, ("updatetimeinfo status=0x%lx, time=%x\n", (long)parseio->parse_dtime.parse_state,
592c0b746e5SOllivier Robert 	                       parseio->parse_dtime.parse_time.fp.l_ui));
593c0b746e5SOllivier Robert #endif
594c0b746e5SOllivier Robert 
595c0b746e5SOllivier Robert 	return CVT_OK;		/* everything fine and dandy... */
596c0b746e5SOllivier Robert }
597c0b746e5SOllivier Robert 
598c0b746e5SOllivier Robert 
599c0b746e5SOllivier Robert /*
600c0b746e5SOllivier Robert  * syn_simple
601c0b746e5SOllivier Robert  *
602c0b746e5SOllivier Robert  * handle a sync time stamp
603c0b746e5SOllivier Robert  */
604c0b746e5SOllivier Robert /*ARGSUSED*/
605c0b746e5SOllivier Robert void
606c0b746e5SOllivier Robert syn_simple(
607c0b746e5SOllivier Robert 	register parse_t *parseio,
608c0b746e5SOllivier Robert 	register timestamp_t *ts,
609c0b746e5SOllivier Robert 	register struct format *format,
610c0b746e5SOllivier Robert 	register u_long why
611c0b746e5SOllivier Robert 	)
612c0b746e5SOllivier Robert {
613c0b746e5SOllivier Robert 	parseio->parse_dtime.parse_stime = *ts;
614c0b746e5SOllivier Robert }
615c0b746e5SOllivier Robert 
616c0b746e5SOllivier Robert /*
617a25439b6SCy Schubert  * parse_pps_fnc_t pps_simple
618c0b746e5SOllivier Robert  *
619c0b746e5SOllivier Robert  * handle a pps time stamp
620c0b746e5SOllivier Robert  */
621c0b746e5SOllivier Robert /*ARGSUSED*/
622c0b746e5SOllivier Robert u_long
623c0b746e5SOllivier Robert pps_simple(
624c0b746e5SOllivier Robert 	register parse_t *parseio,
625c0b746e5SOllivier Robert 	register int status,
626c0b746e5SOllivier Robert 	register timestamp_t *ptime
627c0b746e5SOllivier Robert 	)
628c0b746e5SOllivier Robert {
629c0b746e5SOllivier Robert 	parseio->parse_dtime.parse_ptime  = *ptime;
630c0b746e5SOllivier Robert 	parseio->parse_dtime.parse_state |= PARSEB_PPS|PARSEB_S_PPS;
631c0b746e5SOllivier Robert 
632c0b746e5SOllivier Robert 	return CVT_NONE;
633c0b746e5SOllivier Robert }
634c0b746e5SOllivier Robert 
635c0b746e5SOllivier Robert /*
636a25439b6SCy Schubert  * parse_pps_fnc_t pps_one
637c0b746e5SOllivier Robert  *
638c0b746e5SOllivier Robert  * handle a pps time stamp in ONE edge
639c0b746e5SOllivier Robert  */
640c0b746e5SOllivier Robert /*ARGSUSED*/
641c0b746e5SOllivier Robert u_long
642c0b746e5SOllivier Robert pps_one(
643c0b746e5SOllivier Robert 	register parse_t *parseio,
644c0b746e5SOllivier Robert 	register int status,
645c0b746e5SOllivier Robert 	register timestamp_t *ptime
646c0b746e5SOllivier Robert 	)
647c0b746e5SOllivier Robert {
648c0b746e5SOllivier Robert 	if (status)
649c0b746e5SOllivier Robert 		return pps_simple(parseio, status, ptime);
650c0b746e5SOllivier Robert 
651c0b746e5SOllivier Robert 	return CVT_NONE;
652c0b746e5SOllivier Robert }
653c0b746e5SOllivier Robert 
654c0b746e5SOllivier Robert /*
655a25439b6SCy Schubert  * parse_pps_fnc_t pps_zero
656c0b746e5SOllivier Robert  *
657c0b746e5SOllivier Robert  * handle a pps time stamp in ZERO edge
658c0b746e5SOllivier Robert  */
659c0b746e5SOllivier Robert /*ARGSUSED*/
660c0b746e5SOllivier Robert u_long
661c0b746e5SOllivier Robert pps_zero(
662c0b746e5SOllivier Robert 	register parse_t *parseio,
663c0b746e5SOllivier Robert 	register int status,
664c0b746e5SOllivier Robert 	register timestamp_t *ptime
665c0b746e5SOllivier Robert 	)
666c0b746e5SOllivier Robert {
667c0b746e5SOllivier Robert 	if (!status)
668c0b746e5SOllivier Robert 		return pps_simple(parseio, status, ptime);
669c0b746e5SOllivier Robert 
670c0b746e5SOllivier Robert 	return CVT_NONE;
671c0b746e5SOllivier Robert }
672c0b746e5SOllivier Robert 
673c0b746e5SOllivier Robert /*
674c0b746e5SOllivier Robert  * timepacket
675c0b746e5SOllivier Robert  *
676c0b746e5SOllivier Robert  * process a data packet
677c0b746e5SOllivier Robert  */
678c0b746e5SOllivier Robert static u_long
679c0b746e5SOllivier Robert timepacket(
680c0b746e5SOllivier Robert 	register parse_t *parseio
681c0b746e5SOllivier Robert 	)
682c0b746e5SOllivier Robert {
683c0b746e5SOllivier Robert 	register unsigned short format;
684c0b746e5SOllivier Robert 	register time_t t;
685c0b746e5SOllivier Robert 	u_long cvtrtc;		/* current conversion result */
686c0b746e5SOllivier Robert 	clocktime_t clock_time;
687c0b746e5SOllivier Robert 
688c0b746e5SOllivier Robert 	memset((char *)&clock_time, 0, sizeof clock_time);
689c0b746e5SOllivier Robert 	format = parseio->parse_lformat;
690c0b746e5SOllivier Robert 
691c0b746e5SOllivier Robert 	if (format == (unsigned short)~0)
692c0b746e5SOllivier Robert 		return CVT_NONE;
693c0b746e5SOllivier Robert 
694c0b746e5SOllivier Robert 	switch ((cvtrtc = clockformats[format]->convert ?
695c0b746e5SOllivier Robert 		 clockformats[format]->convert((unsigned char *)parseio->parse_ldata, parseio->parse_ldsize, (struct format *)(clockformats[format]->data), &clock_time, parseio->parse_pdata) :
696c0b746e5SOllivier Robert 		 CVT_NONE) & CVT_MASK)
697c0b746e5SOllivier Robert 	{
698c0b746e5SOllivier Robert 	case CVT_FAIL:
699c0b746e5SOllivier Robert 		parseio->parse_badformat++;
700276da39aSCy Schubert 		return cvtrtc;
701c0b746e5SOllivier Robert 
702c0b746e5SOllivier Robert 	case CVT_NONE:
703c0b746e5SOllivier Robert 		/*
704c0b746e5SOllivier Robert 		 * too bad - pretend bad format
705c0b746e5SOllivier Robert 		 */
706c0b746e5SOllivier Robert 		parseio->parse_badformat++;
707276da39aSCy Schubert 		return CVT_NONE;
708c0b746e5SOllivier Robert 
709c0b746e5SOllivier Robert 	case CVT_OK:
710c0b746e5SOllivier Robert 		break;
711c0b746e5SOllivier Robert 
712c0b746e5SOllivier Robert 	case CVT_SKIP:
713c0b746e5SOllivier Robert 		return CVT_NONE;
714c0b746e5SOllivier Robert 
715c0b746e5SOllivier Robert 	default:
716c0b746e5SOllivier Robert 		/* shouldn't happen */
717c0b746e5SOllivier Robert #ifndef PARSEKERNEL
7182b15cb3dSCy Schubert 		msyslog(LOG_WARNING, "parse: INTERNAL error: bad return code of convert routine \"%s\"", clockformats[format]->name);
719c0b746e5SOllivier Robert #endif
720c0b746e5SOllivier Robert 		return CVT_FAIL|cvtrtc;
721c0b746e5SOllivier Robert 	}
722c0b746e5SOllivier Robert 
723c0b746e5SOllivier Robert 	if ((t = parse_to_unixtime(&clock_time, &cvtrtc)) == -1)
724c0b746e5SOllivier Robert 	{
725c0b746e5SOllivier Robert 		return CVT_FAIL|cvtrtc;
726c0b746e5SOllivier Robert 	}
727c0b746e5SOllivier Robert 
728c0b746e5SOllivier Robert 	/*
729c0b746e5SOllivier Robert 	 * time stamp
730c0b746e5SOllivier Robert 	 */
731c0b746e5SOllivier Robert #ifdef PARSEKERNEL
732c0b746e5SOllivier Robert 	parseio->parse_dtime.parse_time.tv.tv_sec  = t;
733c0b746e5SOllivier Robert 	parseio->parse_dtime.parse_time.tv.tv_usec = clock_time.usecond;
734c0b746e5SOllivier Robert #else
735a25439b6SCy Schubert 	parseio->parse_dtime.parse_time.fp.l_ui = (uint32_t) (t + JAN_1970);
736c0b746e5SOllivier Robert 	TVUTOTSF(clock_time.usecond, parseio->parse_dtime.parse_time.fp.l_uf);
737c0b746e5SOllivier Robert #endif
738c0b746e5SOllivier Robert 
739c0b746e5SOllivier Robert 	parseio->parse_dtime.parse_format       = format;
740c0b746e5SOllivier Robert 
741c0b746e5SOllivier Robert 	return updatetimeinfo(parseio, clock_time.flags);
742c0b746e5SOllivier Robert }
743c0b746e5SOllivier Robert 
744c0b746e5SOllivier Robert /*ARGSUSED*/
745c0b746e5SOllivier Robert int
746c0b746e5SOllivier Robert parse_timecode(
747c0b746e5SOllivier Robert 	parsectl_t *dct,
748c0b746e5SOllivier Robert 	parse_t    *parse
749c0b746e5SOllivier Robert 	)
750c0b746e5SOllivier Robert {
751c0b746e5SOllivier Robert 	dct->parsegettc.parse_state  = parse->parse_lstate;
752c0b746e5SOllivier Robert 	dct->parsegettc.parse_format = parse->parse_lformat;
753c0b746e5SOllivier Robert 	/*
754c0b746e5SOllivier Robert 	 * move out current bad packet count
755c0b746e5SOllivier Robert 	 * user program is expected to sum these up
756c0b746e5SOllivier Robert 	 * this is not a problem, as "parse" module are
757c0b746e5SOllivier Robert 	 * exclusive open only
758c0b746e5SOllivier Robert 	 */
759c0b746e5SOllivier Robert 	dct->parsegettc.parse_badformat = parse->parse_badformat;
760c0b746e5SOllivier Robert 	parse->parse_badformat = 0;
761c0b746e5SOllivier Robert 
762c0b746e5SOllivier Robert 	if (parse->parse_ldsize <= PARSE_TCMAX)
763c0b746e5SOllivier Robert 	{
764c0b746e5SOllivier Robert 		dct->parsegettc.parse_count = parse->parse_ldsize;
765c0b746e5SOllivier Robert 		memcpy(dct->parsegettc.parse_buffer, parse->parse_ldata, dct->parsegettc.parse_count);
766c0b746e5SOllivier Robert 		return 1;
767c0b746e5SOllivier Robert 	}
768c0b746e5SOllivier Robert 	else
769c0b746e5SOllivier Robert 	{
770c0b746e5SOllivier Robert 		return 0;
771c0b746e5SOllivier Robert 	}
772c0b746e5SOllivier Robert }
773c0b746e5SOllivier Robert 
774c0b746e5SOllivier Robert 
775c0b746e5SOllivier Robert /*ARGSUSED*/
776c0b746e5SOllivier Robert int
777c0b746e5SOllivier Robert parse_setfmt(
778c0b746e5SOllivier Robert 	parsectl_t *dct,
779c0b746e5SOllivier Robert 	parse_t    *parse
780c0b746e5SOllivier Robert 	)
781c0b746e5SOllivier Robert {
782c0b746e5SOllivier Robert 	if (dct->parseformat.parse_count <= PARSE_TCMAX)
783c0b746e5SOllivier Robert 	{
784c0b746e5SOllivier Robert 		if (dct->parseformat.parse_count)
785c0b746e5SOllivier Robert 		{
786c0b746e5SOllivier Robert 			register unsigned short i;
787c0b746e5SOllivier Robert 
788c0b746e5SOllivier Robert 			for (i = 0; i < nformats; i++)
789c0b746e5SOllivier Robert 			{
790c0b746e5SOllivier Robert 				if (!Strcmp(dct->parseformat.parse_buffer, clockformats[i]->name))
791c0b746e5SOllivier Robert 				{
792c0b746e5SOllivier Robert 					if (parse->parse_pdata)
793c0b746e5SOllivier Robert 						FREE(parse->parse_pdata, parse->parse_plen);
794c0b746e5SOllivier Robert 					parse->parse_pdata = 0;
795c0b746e5SOllivier Robert 
796c0b746e5SOllivier Robert 					parse->parse_plen = clockformats[i]->plen;
797c0b746e5SOllivier Robert 
798c0b746e5SOllivier Robert 					if (parse->parse_plen)
799c0b746e5SOllivier Robert 					{
800c0b746e5SOllivier Robert 						parse->parse_pdata = MALLOC(parse->parse_plen);
801c0b746e5SOllivier Robert 						if (!parse->parse_pdata)
802c0b746e5SOllivier Robert 						{
803c0b746e5SOllivier Robert 							parseprintf(DD_PARSE, ("set format failed: malloc for private data area failed\n"));
804c0b746e5SOllivier Robert 							return 0;
805c0b746e5SOllivier Robert 						}
806c0b746e5SOllivier Robert 						memset((char *)parse->parse_pdata, 0, parse->parse_plen);
807c0b746e5SOllivier Robert 					}
808c0b746e5SOllivier Robert 
809c0b746e5SOllivier Robert 					if (parse->parse_data)
810c0b746e5SOllivier Robert 						FREE(parse->parse_data, (unsigned)(parse->parse_dsize * 2 + 2));
811c0b746e5SOllivier Robert 					parse->parse_ldata = parse->parse_data = 0;
812c0b746e5SOllivier Robert 
813c0b746e5SOllivier Robert 					parse->parse_dsize = clockformats[i]->length;
814c0b746e5SOllivier Robert 
815c0b746e5SOllivier Robert 					if (parse->parse_dsize)
816c0b746e5SOllivier Robert 					{
817c0b746e5SOllivier Robert 						parse->parse_data = (char*)MALLOC((unsigned)(parse->parse_dsize * 2 + 2));
818c0b746e5SOllivier Robert 						if (!parse->parse_data)
819c0b746e5SOllivier Robert 						{
820c0b746e5SOllivier Robert 							if (parse->parse_pdata)
821c0b746e5SOllivier Robert 								FREE(parse->parse_pdata, parse->parse_plen);
822c0b746e5SOllivier Robert 							parse->parse_pdata = 0;
823c0b746e5SOllivier Robert 
824c0b746e5SOllivier Robert 							parseprintf(DD_PARSE, ("init failed: malloc for data area failed\n"));
825c0b746e5SOllivier Robert 							return 0;
826c0b746e5SOllivier Robert 						}
827c0b746e5SOllivier Robert 					}
828c0b746e5SOllivier Robert 
829c0b746e5SOllivier Robert 
830c0b746e5SOllivier Robert 					/*
831c0b746e5SOllivier Robert 					 * leave room for '\0'
832c0b746e5SOllivier Robert 					 */
833c0b746e5SOllivier Robert 					parse->parse_ldata     = parse->parse_data + parse->parse_dsize + 1;
834c0b746e5SOllivier Robert 
835c0b746e5SOllivier Robert 					parse->parse_lformat  = i;
836c0b746e5SOllivier Robert 
837c0b746e5SOllivier Robert 					return 1;
838c0b746e5SOllivier Robert 				}
839c0b746e5SOllivier Robert 			}
840c0b746e5SOllivier Robert 		}
841c0b746e5SOllivier Robert 	}
842c0b746e5SOllivier Robert 	return 0;
843c0b746e5SOllivier Robert }
844c0b746e5SOllivier Robert 
845c0b746e5SOllivier Robert /*ARGSUSED*/
846c0b746e5SOllivier Robert int
847c0b746e5SOllivier Robert parse_getfmt(
848c0b746e5SOllivier Robert 	parsectl_t *dct,
849c0b746e5SOllivier Robert 	parse_t    *parse
850c0b746e5SOllivier Robert 	)
851c0b746e5SOllivier Robert {
852c0b746e5SOllivier Robert 	if (dct->parseformat.parse_format < nformats &&
853c0b746e5SOllivier Robert 	    Strlen(clockformats[dct->parseformat.parse_format]->name) <= PARSE_TCMAX)
854c0b746e5SOllivier Robert 	{
855a25439b6SCy Schubert 		dct->parseformat.parse_count = (unsigned short) (Strlen(clockformats[dct->parseformat.parse_format]->name) + 1);
856c0b746e5SOllivier Robert 		memcpy(dct->parseformat.parse_buffer, clockformats[dct->parseformat.parse_format]->name, dct->parseformat.parse_count);
857c0b746e5SOllivier Robert 		return 1;
858c0b746e5SOllivier Robert 	}
859c0b746e5SOllivier Robert 	else
860c0b746e5SOllivier Robert 	{
861c0b746e5SOllivier Robert 		return 0;
862c0b746e5SOllivier Robert 	}
863c0b746e5SOllivier Robert }
864c0b746e5SOllivier Robert 
865c0b746e5SOllivier Robert /*ARGSUSED*/
866c0b746e5SOllivier Robert int
867c0b746e5SOllivier Robert parse_setcs(
868c0b746e5SOllivier Robert 	parsectl_t *dct,
869c0b746e5SOllivier Robert 	parse_t    *parse
870c0b746e5SOllivier Robert 	)
871c0b746e5SOllivier Robert {
872c0b746e5SOllivier Robert 	parse->parse_ioflags &= ~PARSE_IO_CSIZE;
873a25439b6SCy Schubert 	parse->parse_ioflags |= (int) (dct->parsesetcs.parse_cs & PARSE_IO_CSIZE);
874c0b746e5SOllivier Robert 	return 1;
875c0b746e5SOllivier Robert }
876c0b746e5SOllivier Robert 
877c0b746e5SOllivier Robert #else /* not (REFCLOCK && CLOCK_PARSE) */
878*f5f40dd6SCy Schubert NONEMPTY_TRANSLATION_UNIT
879c0b746e5SOllivier Robert #endif /* not (REFCLOCK && CLOCK_PARSE) */
880c0b746e5SOllivier Robert 
881c0b746e5SOllivier Robert /*
882c0b746e5SOllivier Robert  * History:
883c0b746e5SOllivier Robert  *
884c0b746e5SOllivier Robert  * parse.c,v
885ea906c41SOllivier Robert  * Revision 4.20  2005/08/06 17:39:40  kardel
886ea906c41SOllivier Robert  * cleanup size handling wrt/ to buffer boundaries
887ea906c41SOllivier Robert  *
888ea906c41SOllivier Robert  * Revision 4.19  2005/04/16 17:32:10  kardel
889ea906c41SOllivier Robert  * update copyright
890ea906c41SOllivier Robert  *
891ea906c41SOllivier Robert  * Revision 4.18  2004/11/14 16:11:05  kardel
892ea906c41SOllivier Robert  * update Id tags
893ea906c41SOllivier Robert  *
894ea906c41SOllivier Robert  * Revision 4.17  2004/11/14 15:29:41  kardel
895ea906c41SOllivier Robert  * support PPSAPI, upgrade Copyright to Berkeley style
896ea906c41SOllivier Robert  *
897a151a66cSOllivier Robert  * Revision 4.14  1999/11/28 09:13:52  kardel
898a151a66cSOllivier Robert  * RECON_4_0_98F
899a151a66cSOllivier Robert  *
900c0b746e5SOllivier Robert  * Revision 4.13  1999/02/28 11:50:20  kardel
901c0b746e5SOllivier Robert  * (timepacket): removed unecessary code
902c0b746e5SOllivier Robert  *
903c0b746e5SOllivier Robert  * Revision 4.12  1999/02/21 12:17:44  kardel
904c0b746e5SOllivier Robert  * 4.91f reconcilation
905c0b746e5SOllivier Robert  *
906c0b746e5SOllivier Robert  * Revision 4.11  1999/02/21 11:09:47  kardel
907c0b746e5SOllivier Robert  * unified debug output
908c0b746e5SOllivier Robert  *
909c0b746e5SOllivier Robert  * Revision 4.10  1998/12/20 23:45:30  kardel
910c0b746e5SOllivier Robert  * fix types and warnings
911c0b746e5SOllivier Robert  *
912c0b746e5SOllivier Robert  * Revision 4.9  1998/08/09 22:26:06  kardel
913c0b746e5SOllivier Robert  * Trimble TSIP support
914c0b746e5SOllivier Robert  *
915c0b746e5SOllivier Robert  * Revision 4.8  1998/06/14 21:09:39  kardel
916c0b746e5SOllivier Robert  * Sun acc cleanup
917c0b746e5SOllivier Robert  *
918c0b746e5SOllivier Robert  * Revision 4.7  1998/06/13 15:19:13  kardel
919c0b746e5SOllivier Robert  * fix mem*() to b*() function macro emulation
920c0b746e5SOllivier Robert  *
921c0b746e5SOllivier Robert  * Revision 4.6  1998/06/13 13:24:13  kardel
922c0b746e5SOllivier Robert  * printf fmt
923c0b746e5SOllivier Robert  *
924c0b746e5SOllivier Robert  * Revision 4.5  1998/06/13 13:01:10  kardel
925c0b746e5SOllivier Robert  * printf fmt
926c0b746e5SOllivier Robert  *
927c0b746e5SOllivier Robert  * Revision 4.4  1998/06/13 12:12:10  kardel
928c0b746e5SOllivier Robert  * bcopy/memcpy cleanup
929c0b746e5SOllivier Robert  * fix SVSV name clash
930c0b746e5SOllivier Robert  *
931c0b746e5SOllivier Robert  * Revision 4.3  1998/06/12 15:22:30  kardel
932c0b746e5SOllivier Robert  * fix prototypes
933c0b746e5SOllivier Robert  *
934c0b746e5SOllivier Robert  * Revision 4.2  1998/06/12 09:13:27  kardel
935c0b746e5SOllivier Robert  * conditional compile macros fixed
936c0b746e5SOllivier Robert  * printf prototype
937c0b746e5SOllivier Robert  *
938c0b746e5SOllivier Robert  * Revision 4.1  1998/05/24 09:39:55  kardel
939c0b746e5SOllivier Robert  * implementation of the new IO handling model
940c0b746e5SOllivier Robert  *
941c0b746e5SOllivier Robert  * Revision 4.0  1998/04/10 19:45:36  kardel
942c0b746e5SOllivier Robert  * Start 4.0 release version numbering
943c0b746e5SOllivier Robert  *
944c0b746e5SOllivier Robert  * from V3 3.46 log info deleted 1998/04/11 kardel
945c0b746e5SOllivier Robert  */
946