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 */ 918