Rework LuCI build system
[project/luci.git] / libs / luci-lib-nixio / axTLS / httpd / tdate_parse.c
1 /*
2  * Copyright (c) 2007, Cameron Rich
3  * 
4  * All rights reserved.
5  * 
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * * Redistributions of source code must retain the above copyright notice, 
10  *   this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright notice, 
12  *   this list of conditions and the following disclaimer in the documentation 
13  *   and/or other materials provided with the distribution.
14  * * Neither the name of the axTLS project nor the names of its contributors 
15  *   may be used to endorse or promote products derived from this software 
16  *   without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include <sys/types.h>
32 #include <ctype.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <time.h>
37 #include "axhttp.h"
38
39 struct day_mon_map 
40 {
41     const char* s;
42     uint8_t l;
43 };
44
45 static struct day_mon_map wday_tab[] = 
46 {
47     { "Sun", 0 }, { "Mon", 1 }, { "Tue", 2 }, { "Wed", 3 },
48     { "Thu", 4 }, { "Fri", 5 }, { "Sat", 6 }, 
49 };
50
51 static struct day_mon_map mon_tab[] = 
52 {
53     { "Jan", 0 }, { "Feb", 1 }, { "Mar", 2 }, { "Apr", 3 },
54     { "May", 4 }, { "Jun", 5 }, { "Jul", 6 }, { "Aug", 7 },
55     { "Sep", 8 }, { "Oct", 9 }, { "Nov", 10 }, { "Dec", 11 },
56 };
57
58 static int day_mon_map_compare(const char *v1, const char *v2)
59 {
60     return strcmp(((struct day_mon_map*)v1)->s, ((struct day_mon_map*)v2)->s);
61 }
62
63 void tdate_init(void)
64 {
65     qsort(wday_tab, sizeof(wday_tab)/sizeof(struct day_mon_map),
66             sizeof(struct day_mon_map), 
67             (int (*)(const void *, const void *))day_mon_map_compare);
68     qsort(mon_tab, sizeof(mon_tab)/sizeof(struct day_mon_map),
69             sizeof(struct day_mon_map), 
70             (int (*)(const void *, const void *))day_mon_map_compare);
71 }
72
73 static int8_t day_mon_map_search(const char* str, 
74                             const struct day_mon_map* tab, int n)
75 {
76     struct day_mon_map *search = bsearch(&str, tab, n,
77             sizeof(struct day_mon_map), 
78                 (int (*)(const void *, const void *))day_mon_map_compare);
79     return search ? search->l : -1;
80 }
81
82 time_t tdate_parse(const char* str)
83 {
84     struct tm tm;
85     char str_mon[4], str_wday[4];
86     int tm_sec, tm_min, tm_hour, tm_mday, tm_year;
87
88     /* Initialize. */
89     memset(&tm, 0, sizeof(struct tm));
90
91     /* wdy, DD mth YY HH:MM:SS GMT */
92     if ((sscanf(str, "%3[a-zA-Z], %d %3[a-zA-Z] %d %d:%d:%d GMT",
93                 str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
94                     &tm_sec) == 7) ||
95     /* wdy mth DD HH:MM:SS YY */
96         (sscanf(str, "%3[a-zA-Z] %3[a-zA-Z] %d %d:%d:%d %d",
97                 str_wday, str_mon, &tm_mday, &tm_hour, &tm_min, &tm_sec,
98                     &tm_year) == 7))
99     {
100         int8_t tm_wday = day_mon_map_search(str_wday, wday_tab, 
101                         sizeof(wday_tab)/sizeof(struct day_mon_map));
102         int8_t tm_mon = day_mon_map_search(str_mon, mon_tab, 
103                         sizeof(mon_tab)/sizeof(struct day_mon_map));
104
105         if (tm_wday < 0 || tm_mon < 0)
106             return -1;
107
108         tm.tm_wday = tm_wday;
109         tm.tm_mon = tm_mon;
110         tm.tm_mday = tm_mday;
111         tm.tm_hour = tm_hour;
112         tm.tm_min = tm_min;
113         tm.tm_sec = tm_sec;
114         tm.tm_year = tm_year - 1900;
115         return mktime(&tm);
116     }
117
118     return -1;  /* error */
119 }