]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ntp/libparse/parse.c
unfinished sblive driver, playback/mixer only for now - not enabled in
[FreeBSD/FreeBSD.git] / contrib / ntp / libparse / parse.c
1 /*
2  * /src/NTP/ntp-4/libparse/parse.c,v 4.14 1999/11/28 09:13:52 kardel RELEASE_19991128_A
3  *  
4  * parse.c,v 4.14 1999/11/28 09:13:52 kardel RELEASE_19991128_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.14 1999/11/28 09:13:52 kardel RELEASE_19991128_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.14  1999/11/28 09:13:52  kardel
873  * RECON_4_0_98F
874  *
875  * Revision 4.13  1999/02/28 11:50:20  kardel
876  * (timepacket): removed unecessary code
877  *
878  * Revision 4.12  1999/02/21 12:17:44  kardel
879  * 4.91f reconcilation
880  *
881  * Revision 4.11  1999/02/21 11:09:47  kardel
882  * unified debug output
883  *
884  * Revision 4.10  1998/12/20 23:45:30  kardel
885  * fix types and warnings
886  *
887  * Revision 4.9  1998/08/09 22:26:06  kardel
888  * Trimble TSIP support
889  *
890  * Revision 4.8  1998/06/14 21:09:39  kardel
891  * Sun acc cleanup
892  *
893  * Revision 4.7  1998/06/13 15:19:13  kardel
894  * fix mem*() to b*() function macro emulation
895  *
896  * Revision 4.6  1998/06/13 13:24:13  kardel
897  * printf fmt
898  *
899  * Revision 4.5  1998/06/13 13:01:10  kardel
900  * printf fmt
901  *
902  * Revision 4.4  1998/06/13 12:12:10  kardel
903  * bcopy/memcpy cleanup
904  * fix SVSV name clash
905  *
906  * Revision 4.3  1998/06/12 15:22:30  kardel
907  * fix prototypes
908  *
909  * Revision 4.2  1998/06/12 09:13:27  kardel
910  * conditional compile macros fixed
911  * printf prototype
912  *
913  * Revision 4.1  1998/05/24 09:39:55  kardel
914  * implementation of the new IO handling model
915  *
916  * Revision 4.0  1998/04/10 19:45:36  kardel
917  * Start 4.0 release version numbering
918  *
919  * from V3 3.46 log info deleted 1998/04/11 kardel
920  */