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