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