/contrib/ntp/libparse/parse.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 949 lines · 597 code · 127 blank · 225 comment · 98 complexity · 75ccdda4d8f1a1b00eb6b06e46c73ffe MD5 · raw file

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