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