Annotation of embedaddon/ntp/libparse/parse.c, revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>