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 P((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++] = 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 */ 950