Annotation of libelwix/src/time.c, revision 1.2

1.2     ! misho       1: /*************************************************************************
        !             2: * (C) 2013 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
        !             3: *  by Michael Pounov <misho@elwix.org>
        !             4: *
        !             5: * $Author: misho $
        !             6: * $Id: time.c,v 1.1.2.6 2013/03/07 16:17:20 misho Exp $
        !             7: *
        !             8: **************************************************************************
        !             9: The ELWIX and AITNET software is distributed under the following
        !            10: terms:
        !            11: 
        !            12: All of the documentation and software included in the ELWIX and AITNET
        !            13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
        !            14: 
        !            15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
        !            16:        by Michael Pounov <misho@elwix.org>.  All rights reserved.
        !            17: 
        !            18: Redistribution and use in source and binary forms, with or without
        !            19: modification, are permitted provided that the following conditions
        !            20: are met:
        !            21: 1. Redistributions of source code must retain the above copyright
        !            22:    notice, this list of conditions and the following disclaimer.
        !            23: 2. Redistributions in binary form must reproduce the above copyright
        !            24:    notice, this list of conditions and the following disclaimer in the
        !            25:    documentation and/or other materials provided with the distribution.
        !            26: 3. All advertising materials mentioning features or use of this software
        !            27:    must display the following acknowledgement:
        !            28: This product includes software developed by Michael Pounov <misho@elwix.org>
        !            29: ELWIX - Embedded LightWeight unIX and its contributors.
        !            30: 4. Neither the name of AITNET nor the names of its contributors
        !            31:    may be used to endorse or promote products derived from this software
        !            32:    without specific prior written permission.
        !            33: 
        !            34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
        !            35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            37: ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            44: SUCH DAMAGE.
        !            45: */
        !            46: #include "global.h"
        !            47: 
        !            48: 
        !            49: struct stridx {
        !            50:        char    *str;
        !            51:        int     id;
        !            52: };
        !            53: 
        !            54: static struct stridx months[] = {
        !            55:        { "jan", 0 }, { "january", 0 },
        !            56:        { "feb", 1 }, { "february", 1 },
        !            57:        { "mar", 2 }, { "march", 2 },
        !            58:        { "apr", 3 }, { "april", 3 },
        !            59:        { "may", 4 },
        !            60:        { "jun", 5 }, { "june", 5 },
        !            61:        { "jul", 6 }, { "july", 6 },
        !            62:        { "aug", 7 }, { "august", 7 },
        !            63:        { "sep", 8 }, { "september", 8 },
        !            64:        { "oct", 9 }, { "october", 9 },
        !            65:        { "nov", 10 }, { "november", 10 },
        !            66:        { "dec", 11 }, { "december", 11 },
        !            67: };
        !            68: 
        !            69: static struct stridx wdays[] = {
        !            70:        { "sun", 0 }, { "sunday", 0 },
        !            71:        { "mon", 1 }, { "monday", 1 },
        !            72:        { "tue", 2 }, { "tuesday", 2 },
        !            73:        { "wed", 3 }, { "wednesday", 3 },
        !            74:        { "thu", 4 }, { "thursday", 4 },
        !            75:        { "fri", 5 }, { "friday", 5 },
        !            76:        { "sat", 6 }, { "saturday", 6 },
        !            77: };
        !            78: 
        !            79: static int
        !            80: stridx_compare(struct stridx * __restrict a, struct stridx * __restrict b)
        !            81: {
        !            82:        return strcmp(a->str, b->str);
        !            83: }
        !            84: 
        !            85: static int
        !            86: search4month(char * psMonth, int * __restrict id)
        !            87: {
        !            88:        static int sorted = 0;
        !            89:        struct stridx *el, item = { psMonth, 0 };
        !            90: 
        !            91:        if (!psMonth)
        !            92:                return -1;
        !            93: 
        !            94:        if (!sorted) {
        !            95:                qsort(months, sizeof(months) / sizeof(struct stridx), sizeof(struct stridx), 
        !            96:                                (int (*)(const void*, const void*)) stridx_compare);
        !            97:                sorted++;
        !            98:        }
        !            99: 
        !           100:        str_Lower(psMonth);
        !           101:        el = bsearch(&item, months, sizeof(months) / sizeof(struct stridx), sizeof(struct stridx), 
        !           102:                                (int (*)(const void*, const void*)) stridx_compare);
        !           103:        if (el && id)
        !           104:                *id = el->id;
        !           105: 
        !           106:        return !!el;
        !           107: }
        !           108: 
        !           109: static int
        !           110: search4wday(char * __restrict psWDay, int * __restrict id)
        !           111: {
        !           112:        static int sorted = 0;
        !           113:        struct stridx *el, item = { psWDay, 0 };
        !           114: 
        !           115:        if (!psWDay)
        !           116:                return -1;
        !           117: 
        !           118:        if (!sorted) {
        !           119:                qsort(wdays, sizeof(wdays) / sizeof(struct stridx), sizeof(struct stridx), 
        !           120:                                (int (*)(const void*, const void*)) stridx_compare);
        !           121:                sorted++;
        !           122:        }
        !           123: 
        !           124:        str_Lower(psWDay);
        !           125:        el = bsearch(&item, wdays, sizeof(wdays) / sizeof(struct stridx), sizeof(struct stridx), 
        !           126:                                (int (*)(const void*, const void*)) stridx_compare);
        !           127:        if (el && id)
        !           128:                *id = el->id;
        !           129: 
        !           130:        return !!el;
        !           131: }
        !           132: 
        !           133: 
        !           134: /*
        !           135:  * time_Parse() - Parse and make unix time from standart time strings ...
        !           136:  *
        !           137:  * @csTime = Time string
        !           138:  * return: =-1 error or !=-1 converted time 
        !           139:  */
        !           140: time_t
        !           141: time_Parse(const char *csTime)
        !           142: {
        !           143:        struct tm tm;
        !           144:        char *s;
        !           145:        int tm_sec, tm_min, tm_hour, tm_mday, tm_year, tm_mon, tm_wday;
        !           146:        char str_mon[512], str_wday[512];
        !           147:        time_t tim;
        !           148: 
        !           149:        memset(&tm, 0, sizeof tm);
        !           150:        memset(&str_mon, 0, sizeof str_mon);
        !           151:        memset(&str_wday, 0, sizeof str_wday);
        !           152: 
        !           153:        for (s = (char*) csTime; isspace(*s); s++);
        !           154: 
        !           155:        /*
        !           156:         * And do the sscanfs.  WARNING: you can add more formats here,
        !           157:         * but be careful!  You can easily screw up the parsing of existing
        !           158:         * formats when you add new ones.  The order is important.
        !           159:         */
        !           160: 
        !           161:        /* DD-mth-YY HH:MM:SS GMT */
        !           162:        if (sscanf(s, "%d-%400[a-zA-Z]-%d %d:%d:%d GMT", 
        !           163:                                &tm_mday, str_mon, &tm_year, 
        !           164:                                &tm_hour, &tm_min, &tm_sec) == 6 && 
        !           165:                        search4month(str_mon, &tm_mon)) {
        !           166:                tm.tm_mday = tm_mday;
        !           167:                tm.tm_mon = tm_mon;
        !           168:                tm.tm_year = tm_year;
        !           169:                tm.tm_hour = tm_hour;
        !           170:                tm.tm_min = tm_min;
        !           171:                tm.tm_sec = tm_sec;
        !           172:        }
        !           173:        /* DD mth YY HH:MM:SS GMT */
        !           174:        else if (sscanf(s, "%d %400[a-zA-Z] %d %d:%d:%d GMT", 
        !           175:                                &tm_mday, str_mon, &tm_year, 
        !           176:                                &tm_hour, &tm_min, &tm_sec) == 6 && 
        !           177:                        search4month(str_mon, &tm_mon)) {
        !           178:                tm.tm_mday = tm_mday;
        !           179:                tm.tm_mon = tm_mon;
        !           180:                tm.tm_year = tm_year;
        !           181:                tm.tm_hour = tm_hour;
        !           182:                tm.tm_min = tm_min;
        !           183:                tm.tm_sec = tm_sec;
        !           184:        }
        !           185:        /* HH:MM:SS GMT DD-mth-YY */
        !           186:        else if (sscanf(s, "%d:%d:%d GMT %d-%400[a-zA-Z]-%d", 
        !           187:                                &tm_hour, &tm_min, &tm_sec, 
        !           188:                                &tm_mday, str_mon, &tm_year) == 6 && 
        !           189:                        search4month(str_mon, &tm_mon)) {
        !           190:                tm.tm_hour = tm_hour;
        !           191:                tm.tm_min = tm_min;
        !           192:                tm.tm_sec = tm_sec;
        !           193:                tm.tm_mday = tm_mday;
        !           194:                tm.tm_mon = tm_mon;
        !           195:                tm.tm_year = tm_year;
        !           196:        }
        !           197:        /* HH:MM:SS GMT DD mth YY */
        !           198:        else if (sscanf(s, "%d:%d:%d GMT %d %400[a-zA-Z] %d", 
        !           199:                                &tm_hour, &tm_min, &tm_sec, 
        !           200:                                &tm_mday, str_mon, &tm_year) == 6 && 
        !           201:                        search4month(str_mon, &tm_mon)) {
        !           202:                tm.tm_hour = tm_hour;
        !           203:                tm.tm_min = tm_min;
        !           204:                tm.tm_sec = tm_sec;
        !           205:                tm.tm_mday = tm_mday;
        !           206:                tm.tm_mon = tm_mon;
        !           207:                tm.tm_year = tm_year;
        !           208:        }
        !           209:        /* wdy, DD-mth-YY HH:MM:SS GMT */
        !           210:        else if (sscanf(s, "%400[a-zA-Z], %d-%400[a-zA-Z]-%d %d:%d:%d GMT", 
        !           211:                                str_wday, &tm_mday, str_mon, 
        !           212:                                &tm_year, &tm_hour, &tm_min, &tm_sec) == 7 && 
        !           213:                        search4wday(str_wday, &tm_wday) && 
        !           214:                        search4month(str_mon, &tm_mon)) {
        !           215:                tm.tm_wday = tm_wday;
        !           216:                tm.tm_mday = tm_mday;
        !           217:                tm.tm_mon = tm_mon;
        !           218:                tm.tm_year = tm_year;
        !           219:                tm.tm_hour = tm_hour;
        !           220:                tm.tm_min = tm_min;
        !           221:                tm.tm_sec = tm_sec;
        !           222:        }
        !           223:        /* wdy, DD mth YY HH:MM:SS GMT */
        !           224:        else if (sscanf(s, "%400[a-zA-Z], %d %400[a-zA-Z] %d %d:%d:%d GMT", 
        !           225:                                str_wday, &tm_mday, str_mon, 
        !           226:                                &tm_year, &tm_hour, &tm_min, &tm_sec) == 7 && 
        !           227:                        search4wday(str_wday, &tm_wday) && 
        !           228:                        search4month(str_mon, &tm_mon)) {
        !           229:                tm.tm_wday = tm_wday;
        !           230:                tm.tm_mday = tm_mday;
        !           231:                tm.tm_mon = tm_mon;
        !           232:                tm.tm_year = tm_year;
        !           233:                tm.tm_hour = tm_hour;
        !           234:                tm.tm_min = tm_min;
        !           235:                tm.tm_sec = tm_sec;
        !           236:        }
        !           237:        /* wdy mth DD HH:MM:SS GMT YY */
        !           238:        else if (sscanf(s, "%400[a-zA-Z] %400[a-zA-Z] %d %d:%d:%d GMT %d", 
        !           239:                                str_wday, str_mon, &tm_mday, 
        !           240:                                &tm_hour, &tm_min, &tm_sec, &tm_year) == 7 && 
        !           241:                        search4wday(str_wday, &tm_wday) && 
        !           242:                        search4month(str_mon, &tm_mon)) {
        !           243:                tm.tm_wday = tm_wday;
        !           244:                tm.tm_mon = tm_mon;
        !           245:                tm.tm_mday = tm_mday;
        !           246:                tm.tm_hour = tm_hour;
        !           247:                tm.tm_min = tm_min;
        !           248:                tm.tm_sec = tm_sec;
        !           249:                tm.tm_year = tm_year;
        !           250:        } else {
        !           251:                elwix_SetErr(EINVAL, "Invalid date/time format");
        !           252:                return (time_t) -1;
        !           253:        }
        !           254: 
        !           255:        if (tm.tm_year > 1900)
        !           256:                tm.tm_year -= 1900;
        !           257:        else if (tm.tm_year < 70)
        !           258:                tm.tm_year += 100;
        !           259: 
        !           260:        if ((tim = timegm(&tm)) == (time_t) -1)
        !           261:                elwix_SetErr(EINVAL, "Invalid date/time format");
        !           262:        return tim;
        !           263: }

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