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