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