Annotation of embedaddon/ntp/libparse/parse.c, revision 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>