Annotation of embedaddon/dhcp/minires/ns_date.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (c) 2004,2007,2009 by Internet Systems Consortium, Inc. ("ISC")
                      3:  * Copyright (c) 1999-2003 by Internet Software Consortium
                      4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the above
                      7:  * copyright notice and this permission notice appear in all copies.
                      8:  *
                      9:  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
                     10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     11:  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
                     12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
                     15:  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     16:  *
                     17:  *   Internet Systems Consortium, Inc.
                     18:  *   950 Charter Street
                     19:  *   Redwood City, CA 94063
                     20:  *   <info@isc.org>
                     21:  *   https://www.isc.org/
                     22:  */
                     23: 
                     24: #ifndef lint
1.1.1.1 ! misho      25: static const char rcsid[] = "$Id: ns_date.c,v 1.6.310.2 2009/07/24 22:04:52 sar Exp $";
1.1       misho      26: #endif
                     27: 
                     28: /* Import. */
                     29: 
                     30: #include <ctype.h>
                     31: #include <errno.h>
                     32: #include <stdio.h>
                     33: #include <string.h>
                     34: #include <time.h>
                     35: 
                     36: #include <sys/types.h>
                     37: #include <netinet/in.h>
                     38: #include <sys/socket.h>
                     39: 
                     40: #include "minires/minires.h"
                     41: #include "arpa/nameser.h"
                     42: 
                     43: #ifdef SPRINTF_CHAR
                     44: # define SPRINTF(x) strlen(sprintf/**/x)
                     45: #else
                     46: # define SPRINTF(x) ((size_t)sprintf x)
                     47: #endif
                     48: 
                     49: /* Forward. */
                     50: 
                     51: static int     datepart(const char *, int, int, int, int *);
                     52: 
                     53: /* Public. */
                     54: 
                     55: /* Convert a date in ASCII into the number of seconds since
                     56:    1 January 1970 (GMT assumed).  Format is yyyymmddhhmmss, all
                     57:    digits required, no spaces allowed.  */
                     58: 
                     59: u_int32_t
                     60: ns_datetosecs(const char *cp, int *errp) {
                     61:        struct tm time;
                     62:        u_int32_t result;
                     63:        int mdays, i;
                     64:        static const int days_per_month[12] =
                     65:                {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
                     66: 
                     67:        if (strlen(cp) != 14) {
                     68:                *errp = 1;
                     69:                return (0);
                     70:        }
                     71:        *errp = 0;
                     72: 
                     73:        memset(&time, 0, sizeof time);
                     74:        time.tm_year  = datepart(cp +  0, 4, 1990, 9999, errp) - 1900;
                     75:        time.tm_mon   = datepart(cp +  4, 2,   01,   12, errp) - 1;
                     76:        time.tm_mday  = datepart(cp +  6, 2,   01,   31, errp);
                     77:        time.tm_hour  = datepart(cp +  8, 2,   00,   23, errp);
                     78:        time.tm_min   = datepart(cp + 10, 2,   00,   59, errp);
                     79:        time.tm_sec   = datepart(cp + 12, 2,   00,   59, errp);
                     80:        if (*errp)              /* Any parse errors? */
                     81:                return (0);
                     82: 
                     83:        /* 
                     84:         * OK, now because timegm() is not available in all environments,
                     85:         * we will do it by hand.  Roll up sleeves, curse the gods, begin!
                     86:         */
                     87: 
                     88: #define SECS_PER_DAY    ((u_int32_t)24*60*60)
                     89: #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
                     90: 
                     91:        result  = time.tm_sec;                          /* Seconds */
                     92:        result += time.tm_min * 60;                     /* Minutes */
                     93:        result += time.tm_hour * (60*60);               /* Hours */
                     94:        result += (time.tm_mday - 1) * SECS_PER_DAY;    /* Days */
                     95: 
                     96:        /* Months are trickier.  Look without leaping, then leap */
                     97:        mdays = 0;
                     98:        for (i = 0; i < time.tm_mon; i++)
                     99:                mdays += days_per_month[i];
                    100:        result += mdays * SECS_PER_DAY;                 /* Months */
                    101:        if (time.tm_mon > 1 && isleap(1900+time.tm_year))
                    102:                result += SECS_PER_DAY;         /* Add leapday for this year */
                    103: 
                    104:        /* First figure years without leapdays, then add them in.  */
                    105:        /* The loop is slow, FIXME, but simple and accurate.  */
                    106:        result += (time.tm_year - 70) * (SECS_PER_DAY*365); /* Years */
                    107:        for (i = 70; i < time.tm_year; i++)
                    108:                if (isleap(1900+i))
                    109:                        result += SECS_PER_DAY; /* Add leapday for prev year */
                    110: 
                    111:        return (result);
                    112: }
                    113: 
                    114: /* Private. */
                    115: 
                    116: /*
                    117:  * Parse part of a date.  Set error flag if any error.
                    118:  * Don't reset the flag if there is no error.
                    119:  */
                    120: static int
                    121: datepart(const char *buf, int size, int min, int max, int *errp) {
                    122:        int result = 0;
                    123:        int i;
                    124: 
                    125:        for (i = 0; i < size; i++) {
                    126:                if (!isdigit((unsigned char)buf[i]))
                    127:                        *errp = 1;
                    128:                result = (result * 10) + buf[i] - '0';
                    129:        }
                    130:        if (result < min)
                    131:                *errp = 1;
                    132:        if (result > max)
                    133:                *errp = 1;
                    134:        return (result);
                    135: }

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