|
|
| version 1.1.2.1, 2013/03/05 13:09:51 | version 1.1.2.5, 2013/03/07 15:56:22 |
|---|---|
| Line 1 | Line 1 |
| /************************************************************************* | |
| * (C) 2013 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org> | |
| * by Michael Pounov <misho@elwix.org> | |
| * | |
| * $Author$ | |
| * $Id$ | |
| * | |
| ************************************************************************** | |
| The ELWIX and AITNET software is distributed under the following | |
| terms: | |
| All of the documentation and software included in the ELWIX and AITNET | |
| Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org> | |
| Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 | |
| by Michael Pounov <misho@elwix.org>. All rights reserved. | |
| Redistribution and use in source and binary forms, with or without | |
| modification, are permitted provided that the following conditions | |
| are met: | |
| 1. Redistributions of source code must retain the above copyright | |
| notice, this list of conditions and the following disclaimer. | |
| 2. Redistributions in binary form must reproduce the above copyright | |
| notice, this list of conditions and the following disclaimer in the | |
| documentation and/or other materials provided with the distribution. | |
| 3. All advertising materials mentioning features or use of this software | |
| must display the following acknowledgement: | |
| This product includes software developed by Michael Pounov <misho@elwix.org> | |
| ELWIX - Embedded LightWeight unIX and its contributors. | |
| 4. Neither the name of AITNET nor the names of its contributors | |
| may be used to endorse or promote products derived from this software | |
| without specific prior written permission. | |
| THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND | |
| ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
| FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
| OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
| OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
| SUCH DAMAGE. | |
| */ | |
| #include "global.h" | #include "global.h" |
| struct stridx { | |
| char *str; | |
| int id; | |
| }; | |
| static struct stridx months[] = { | |
| { "jan", 0 }, { "january", 0 }, | |
| { "feb", 1 }, { "february", 1 }, | |
| { "mar", 2 }, { "march", 2 }, | |
| { "apr", 3 }, { "april", 3 }, | |
| { "may", 4 }, | |
| { "jun", 5 }, { "june", 5 }, | |
| { "jul", 6 }, { "july", 6 }, | |
| { "aug", 7 }, { "august", 7 }, | |
| { "sep", 8 }, { "september", 8 }, | |
| { "oct", 9 }, { "october", 9 }, | |
| { "nov", 10 }, { "november", 10 }, | |
| { "dec", 11 }, { "december", 11 }, | |
| }; | |
| static struct stridx wdays[] = { | |
| { "sun", 0 }, { "sunday", 0 }, | |
| { "mon", 1 }, { "monday", 1 }, | |
| { "tue", 2 }, { "tuesday", 2 }, | |
| { "wed", 3 }, { "wednesday", 3 }, | |
| { "thu", 4 }, { "thursday", 4 }, | |
| { "fri", 5 }, { "friday", 5 }, | |
| { "sat", 6 }, { "saturday", 6 }, | |
| }; | |
| static int | |
| stridx_compare(struct stridx * __restrict a, struct stridx * __restrict b) | |
| { | |
| return strcmp(a->str, b->str); | |
| } | |
| static int | |
| search4month(char * __restrict psMonth, int * __restrict id) | |
| { | |
| static int sorted = 0; | |
| struct stridx *el; | |
| if (!psMonth) | |
| return -1; | |
| if (!sorted) { | |
| qsort(months, sizeof(months) / sizeof(struct stridx), sizeof(struct stridx), | |
| (int (*)(const void*, const void*)) stridx_compare); | |
| sorted++; | |
| } | |
| str_Lower(psMonth); | |
| el = bsearch(psMonth, months, sizeof(months) / sizeof(struct stridx), sizeof(struct stridx), | |
| (int (*)(const void*, const void*)) stridx_compare); | |
| if (el && id) | |
| *id = el->id; | |
| return !!el; | |
| } | |
| static int | |
| search4wday(char * __restrict psWDay, int * __restrict id) | |
| { | |
| static int sorted = 0; | |
| struct stridx *el; | |
| if (!psWDay) | |
| return -1; | |
| if (!sorted) { | |
| qsort(wdays, sizeof(wdays) / sizeof(struct stridx), sizeof(struct stridx), | |
| (int (*)(const void*, const void*)) stridx_compare); | |
| sorted++; | |
| } | |
| str_Lower(psWDay); | |
| el = bsearch(psWDay, wdays, sizeof(wdays) / sizeof(struct stridx), sizeof(struct stridx), | |
| (int (*)(const void*, const void*)) stridx_compare); | |
| if (el && id) | |
| *id = el->id; | |
| return !!el; | |
| } | |
| /* | |
| * time_Parse() - Parse and make unix time from standart time strings ... | |
| * | |
| * @csTime = Time string | |
| * return: =-1 error or !=-1 converted time | |
| */ | |
| time_t | |
| time_Parse(const char *csTime) | |
| { | |
| struct tm tm; | |
| char *s; | |
| int tm_sec, tm_min, tm_hour, tm_mday, tm_year, tm_mon, tm_wday; | |
| char str_mon[512], str_wday[512]; | |
| time_t tim; | |
| memset(&tm, 0, sizeof tm); | |
| memset(&str_mon, 0, sizeof str_mon); | |
| memset(&str_wday, 0, sizeof str_wday); | |
| for (s = (char*) csTime; isspace(*s); s++); | |
| /* | |
| * And do the sscanfs. WARNING: you can add more formats here, | |
| * but be careful! You can easily screw up the parsing of existing | |
| * formats when you add new ones. The order is important. | |
| */ | |
| /* DD-mth-YY HH:MM:SS GMT */ | |
| if (sscanf(s, "%d-%400[a-zA-Z]-%d %d:%d:%d GMT", | |
| &tm_mday, str_mon, &tm_year, | |
| &tm_hour, &tm_min, &tm_sec) == 6 && | |
| search4month(str_mon, &tm_mon)) { | |
| tm.tm_mday = tm_mday; | |
| tm.tm_mon = tm_mon; | |
| tm.tm_year = tm_year; | |
| tm.tm_hour = tm_hour; | |
| tm.tm_min = tm_min; | |
| tm.tm_sec = tm_sec; | |
| } | |
| /* DD mth YY HH:MM:SS GMT */ | |
| else if (sscanf(s, "%d %400[a-zA-Z] %d %d:%d:%d GMT", | |
| &tm_mday, str_mon, &tm_year, | |
| &tm_hour, &tm_min, &tm_sec) == 6 && | |
| search4month(str_mon, &tm_mon)) { | |
| tm.tm_mday = tm_mday; | |
| tm.tm_mon = tm_mon; | |
| tm.tm_year = tm_year; | |
| tm.tm_hour = tm_hour; | |
| tm.tm_min = tm_min; | |
| tm.tm_sec = tm_sec; | |
| } | |
| /* HH:MM:SS GMT DD-mth-YY */ | |
| else if (sscanf(s, "%d:%d:%d GMT %d-%400[a-zA-Z]-%d", | |
| &tm_hour, &tm_min, &tm_sec, | |
| &tm_mday, str_mon, &tm_year) == 6 && | |
| search4month(str_mon, &tm_mon)) { | |
| tm.tm_hour = tm_hour; | |
| tm.tm_min = tm_min; | |
| tm.tm_sec = tm_sec; | |
| tm.tm_mday = tm_mday; | |
| tm.tm_mon = tm_mon; | |
| tm.tm_year = tm_year; | |
| } | |
| /* HH:MM:SS GMT DD mth YY */ | |
| else if (sscanf(s, "%d:%d:%d GMT %d %400[a-zA-Z] %d", | |
| &tm_hour, &tm_min, &tm_sec, | |
| &tm_mday, str_mon, &tm_year) == 6 && | |
| search4month(str_mon, &tm_mon)) { | |
| tm.tm_hour = tm_hour; | |
| tm.tm_min = tm_min; | |
| tm.tm_sec = tm_sec; | |
| tm.tm_mday = tm_mday; | |
| tm.tm_mon = tm_mon; | |
| tm.tm_year = tm_year; | |
| } | |
| /* wdy, DD-mth-YY HH:MM:SS GMT */ | |
| else if (sscanf(s, "%400[a-zA-Z], %d-%400[a-zA-Z]-%d %d:%d:%d GMT", | |
| str_wday, &tm_mday, str_mon, | |
| &tm_year, &tm_hour, &tm_min, &tm_sec) == 7 && | |
| search4wday(str_wday, &tm_wday) && | |
| search4month(str_mon, &tm_mon)) { | |
| tm.tm_wday = tm_wday; | |
| tm.tm_mday = tm_mday; | |
| tm.tm_mon = tm_mon; | |
| tm.tm_year = tm_year; | |
| tm.tm_hour = tm_hour; | |
| tm.tm_min = tm_min; | |
| tm.tm_sec = tm_sec; | |
| } | |
| /* wdy, DD mth YY HH:MM:SS GMT */ | |
| else if (sscanf(s, "%400[a-zA-Z], %d %400[a-zA-Z] %d %d:%d:%d GMT", | |
| str_wday, &tm_mday, str_mon, | |
| &tm_year, &tm_hour, &tm_min, &tm_sec) == 7 && | |
| search4wday(str_wday, &tm_wday) && | |
| search4month(str_mon, &tm_mon)) { | |
| tm.tm_wday = tm_wday; | |
| tm.tm_mday = tm_mday; | |
| tm.tm_mon = tm_mon; | |
| tm.tm_year = tm_year; | |
| tm.tm_hour = tm_hour; | |
| tm.tm_min = tm_min; | |
| tm.tm_sec = tm_sec; | |
| } | |
| /* wdy mth DD HH:MM:SS GMT YY */ | |
| else if (sscanf(s, "%400[a-zA-Z] %400[a-zA-Z] %d %d:%d:%d GMT %d", | |
| str_wday, str_mon, &tm_mday, | |
| &tm_hour, &tm_min, &tm_sec, &tm_year) == 7 && | |
| search4wday(str_wday, &tm_wday) && | |
| search4month(str_mon, &tm_mon)) { | |
| tm.tm_wday = tm_wday; | |
| tm.tm_mon = tm_mon; | |
| tm.tm_mday = tm_mday; | |
| tm.tm_hour = tm_hour; | |
| tm.tm_min = tm_min; | |
| tm.tm_sec = tm_sec; | |
| tm.tm_year = tm_year; | |
| } else { | |
| elwix_SetErr(EINVAL, "Invalid date/time format"); | |
| return (time_t) -1; | |
| } | |
| if (tm.tm_year > 1900) | |
| tm.tm_year -= 1900; | |
| else if (tm.tm_year < 70) | |
| tm.tm_year += 100; | |
| if ((tim = timegm(&tm)) == (time_t) -1) | |
| elwix_SetErr(EINVAL, "Invalid date/time format"); | |
| return tim; | |
| } |