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