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