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