1*76404edcSAsim Jamshed /* tdate_parse - parse string dates into internal form, stripped-down version
2*76404edcSAsim Jamshed **
3*76404edcSAsim Jamshed ** Copyright (C) 1995 by Jef Poskanzer <[email protected]>.  All rights reserved.
4*76404edcSAsim Jamshed **
5*76404edcSAsim Jamshed ** Redistribution and use in source and binary forms, with or without
6*76404edcSAsim Jamshed ** modification, are permitted provided that the following conditions
7*76404edcSAsim Jamshed ** are met:
8*76404edcSAsim Jamshed ** 1. Redistributions of source code must retain the above copyright
9*76404edcSAsim Jamshed **    notice, this list of conditions and the following disclaimer.
10*76404edcSAsim Jamshed ** 2. Redistributions in binary form must reproduce the above copyright
11*76404edcSAsim Jamshed **    notice, this list of conditions and the following disclaimer in the
12*76404edcSAsim Jamshed **    documentation and/or other materials provided with the distribution.
13*76404edcSAsim Jamshed **
14*76404edcSAsim Jamshed ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*76404edcSAsim Jamshed ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*76404edcSAsim Jamshed ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*76404edcSAsim Jamshed ** ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*76404edcSAsim Jamshed ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*76404edcSAsim Jamshed ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*76404edcSAsim Jamshed ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*76404edcSAsim Jamshed ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*76404edcSAsim Jamshed ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*76404edcSAsim Jamshed ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*76404edcSAsim Jamshed ** SUCH DAMAGE.
25*76404edcSAsim Jamshed */
26*76404edcSAsim Jamshed 
27*76404edcSAsim Jamshed /* This is a stripped-down version of date_parse.c, available at
28*76404edcSAsim Jamshed ** http://www.acme.com/software/date_parse/
29*76404edcSAsim Jamshed */
30*76404edcSAsim Jamshed 
31*76404edcSAsim Jamshed #include <sys/types.h>
32*76404edcSAsim Jamshed 
33*76404edcSAsim Jamshed #include <ctype.h>
34*76404edcSAsim Jamshed #ifdef HAVE_MEMORY_H
35*76404edcSAsim Jamshed #include <memory.h>
36*76404edcSAsim Jamshed #endif
37*76404edcSAsim Jamshed #include <stdio.h>
38*76404edcSAsim Jamshed #include <stdlib.h>
39*76404edcSAsim Jamshed #include <string.h>
40*76404edcSAsim Jamshed #include <time.h>
41*76404edcSAsim Jamshed 
42*76404edcSAsim Jamshed #include "tdate_parse.h"
43*76404edcSAsim Jamshed 
44*76404edcSAsim Jamshed 
45*76404edcSAsim Jamshed struct strlong {
46*76404edcSAsim Jamshed     char* s;
47*76404edcSAsim Jamshed     long l;
48*76404edcSAsim Jamshed     };
49*76404edcSAsim Jamshed 
50*76404edcSAsim Jamshed 
51*76404edcSAsim Jamshed static void
pound_case(char * str)52*76404edcSAsim Jamshed pound_case( char* str )
53*76404edcSAsim Jamshed     {
54*76404edcSAsim Jamshed     for ( ; *str != '\0'; ++str )
55*76404edcSAsim Jamshed 	{
56*76404edcSAsim Jamshed 	if ( isupper( *str ) )
57*76404edcSAsim Jamshed 	    *str = tolower( *str );
58*76404edcSAsim Jamshed 	}
59*76404edcSAsim Jamshed     }
60*76404edcSAsim Jamshed 
61*76404edcSAsim Jamshed static int
strlong_compare(v1,v2)62*76404edcSAsim Jamshed strlong_compare( v1, v2 )
63*76404edcSAsim Jamshed     char* v1;
64*76404edcSAsim Jamshed     char* v2;
65*76404edcSAsim Jamshed     {
66*76404edcSAsim Jamshed     return strcmp( ((struct strlong*) v1)->s, ((struct strlong*) v2)->s );
67*76404edcSAsim Jamshed     }
68*76404edcSAsim Jamshed 
69*76404edcSAsim Jamshed 
70*76404edcSAsim Jamshed static int
strlong_search(char * str,struct strlong * tab,int n,long * lP)71*76404edcSAsim Jamshed strlong_search( char* str, struct strlong* tab, int n, long* lP )
72*76404edcSAsim Jamshed     {
73*76404edcSAsim Jamshed     int i, h, l, r;
74*76404edcSAsim Jamshed 
75*76404edcSAsim Jamshed     l = 0;
76*76404edcSAsim Jamshed     h = n - 1;
77*76404edcSAsim Jamshed     for (;;)
78*76404edcSAsim Jamshed 	{
79*76404edcSAsim Jamshed 	i = ( h + l ) / 2;
80*76404edcSAsim Jamshed 	r = strcmp( str, tab[i].s );
81*76404edcSAsim Jamshed 	if ( r < 0 )
82*76404edcSAsim Jamshed 	    h = i - 1;
83*76404edcSAsim Jamshed 	else if ( r > 0 )
84*76404edcSAsim Jamshed 	    l = i + 1;
85*76404edcSAsim Jamshed 	else
86*76404edcSAsim Jamshed 	    {
87*76404edcSAsim Jamshed 	    *lP = tab[i].l;
88*76404edcSAsim Jamshed 	    return 1;
89*76404edcSAsim Jamshed 	    }
90*76404edcSAsim Jamshed 	if ( h < l )
91*76404edcSAsim Jamshed 	    return 0;
92*76404edcSAsim Jamshed 	}
93*76404edcSAsim Jamshed     }
94*76404edcSAsim Jamshed 
95*76404edcSAsim Jamshed 
96*76404edcSAsim Jamshed static int
scan_wday(char * str_wday,long * tm_wdayP)97*76404edcSAsim Jamshed scan_wday( char* str_wday, long* tm_wdayP )
98*76404edcSAsim Jamshed     {
99*76404edcSAsim Jamshed     static struct strlong wday_tab[] = {
100*76404edcSAsim Jamshed 	{ "sun", 0 }, { "sunday", 0 },
101*76404edcSAsim Jamshed 	{ "mon", 1 }, { "monday", 1 },
102*76404edcSAsim Jamshed 	{ "tue", 2 }, { "tuesday", 2 },
103*76404edcSAsim Jamshed 	{ "wed", 3 }, { "wednesday", 3 },
104*76404edcSAsim Jamshed 	{ "thu", 4 }, { "thursday", 4 },
105*76404edcSAsim Jamshed 	{ "fri", 5 }, { "friday", 5 },
106*76404edcSAsim Jamshed 	{ "sat", 6 }, { "saturday", 6 },
107*76404edcSAsim Jamshed 	};
108*76404edcSAsim Jamshed     static int sorted = 0;
109*76404edcSAsim Jamshed 
110*76404edcSAsim Jamshed     if ( ! sorted )
111*76404edcSAsim Jamshed 	{
112*76404edcSAsim Jamshed 	(void) qsort(
113*76404edcSAsim Jamshed 	    wday_tab, sizeof(wday_tab)/sizeof(struct strlong),
114*76404edcSAsim Jamshed 	    sizeof(struct strlong), strlong_compare );
115*76404edcSAsim Jamshed 	sorted = 1;
116*76404edcSAsim Jamshed 	}
117*76404edcSAsim Jamshed     pound_case( str_wday );
118*76404edcSAsim Jamshed     return strlong_search(
119*76404edcSAsim Jamshed 	str_wday, wday_tab, sizeof(wday_tab)/sizeof(struct strlong), tm_wdayP );
120*76404edcSAsim Jamshed     }
121*76404edcSAsim Jamshed 
122*76404edcSAsim Jamshed 
123*76404edcSAsim Jamshed static int
scan_mon(char * str_mon,long * tm_monP)124*76404edcSAsim Jamshed scan_mon( char* str_mon, long* tm_monP )
125*76404edcSAsim Jamshed     {
126*76404edcSAsim Jamshed     static struct strlong mon_tab[] = {
127*76404edcSAsim Jamshed 	{ "jan", 0 }, { "january", 0 },
128*76404edcSAsim Jamshed 	{ "feb", 1 }, { "february", 1 },
129*76404edcSAsim Jamshed 	{ "mar", 2 }, { "march", 2 },
130*76404edcSAsim Jamshed 	{ "apr", 3 }, { "april", 3 },
131*76404edcSAsim Jamshed 	{ "may", 4 },
132*76404edcSAsim Jamshed 	{ "jun", 5 }, { "june", 5 },
133*76404edcSAsim Jamshed 	{ "jul", 6 }, { "july", 6 },
134*76404edcSAsim Jamshed 	{ "aug", 7 }, { "august", 7 },
135*76404edcSAsim Jamshed 	{ "sep", 8 }, { "september", 8 },
136*76404edcSAsim Jamshed 	{ "oct", 9 }, { "october", 9 },
137*76404edcSAsim Jamshed 	{ "nov", 10 }, { "november", 10 },
138*76404edcSAsim Jamshed 	{ "dec", 11 }, { "december", 11 },
139*76404edcSAsim Jamshed 	};
140*76404edcSAsim Jamshed     static int sorted = 0;
141*76404edcSAsim Jamshed 
142*76404edcSAsim Jamshed     if ( ! sorted )
143*76404edcSAsim Jamshed 	{
144*76404edcSAsim Jamshed 	(void) qsort(
145*76404edcSAsim Jamshed 	    mon_tab, sizeof(mon_tab)/sizeof(struct strlong),
146*76404edcSAsim Jamshed 	    sizeof(struct strlong), strlong_compare );
147*76404edcSAsim Jamshed 	sorted = 1;
148*76404edcSAsim Jamshed 	}
149*76404edcSAsim Jamshed     pound_case( str_mon );
150*76404edcSAsim Jamshed     return strlong_search(
151*76404edcSAsim Jamshed 	str_mon, mon_tab, sizeof(mon_tab)/sizeof(struct strlong), tm_monP );
152*76404edcSAsim Jamshed     }
153*76404edcSAsim Jamshed 
154*76404edcSAsim Jamshed 
155*76404edcSAsim Jamshed static int
is_leap(int year)156*76404edcSAsim Jamshed is_leap( int year )
157*76404edcSAsim Jamshed     {
158*76404edcSAsim Jamshed     return year % 400? ( year % 100 ? ( year % 4 ? 0 : 1 ) : 0 ) : 1;
159*76404edcSAsim Jamshed     }
160*76404edcSAsim Jamshed 
161*76404edcSAsim Jamshed 
162*76404edcSAsim Jamshed /* Basically the same as mktime(). */
163*76404edcSAsim Jamshed static time_t
tm_to_time(struct tm * tmP)164*76404edcSAsim Jamshed tm_to_time( struct tm* tmP )
165*76404edcSAsim Jamshed     {
166*76404edcSAsim Jamshed     time_t t;
167*76404edcSAsim Jamshed     static int monthtab[12] = {
168*76404edcSAsim Jamshed 	0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
169*76404edcSAsim Jamshed 
170*76404edcSAsim Jamshed     /* Years since epoch, converted to days. */
171*76404edcSAsim Jamshed     t = ( tmP->tm_year - 70 ) * 365;
172*76404edcSAsim Jamshed     /* Leap days for previous years. */
173*76404edcSAsim Jamshed     t += ( tmP->tm_year - 1 - 68 ) / 4; /* -1: don't count this year */
174*76404edcSAsim Jamshed     /* 100-divisible year is not a leap year
175*76404edcSAsim Jamshed        400-divisible year is a leap year */
176*76404edcSAsim Jamshed     if (tmP->tm_year > 200)
177*76404edcSAsim Jamshed       t -= (tmP->tm_year - 1 - 100) / 100;
178*76404edcSAsim Jamshed     if (tmP->tm_year > 500)
179*76404edcSAsim Jamshed       t += (tmP->tm_year - 1 - 100) / 400;
180*76404edcSAsim Jamshed 
181*76404edcSAsim Jamshed     /* Days for the beginning of this month. */
182*76404edcSAsim Jamshed     t += monthtab[tmP->tm_mon];
183*76404edcSAsim Jamshed     /* Leap day for this year. */
184*76404edcSAsim Jamshed     if ( tmP->tm_mon >= 2 && is_leap( tmP->tm_year ) )
185*76404edcSAsim Jamshed 	++t;
186*76404edcSAsim Jamshed     /* Days since the beginning of this month. */
187*76404edcSAsim Jamshed     t += tmP->tm_mday - 1;	/* 1-based field */
188*76404edcSAsim Jamshed     /* Hours, minutes, and seconds. */
189*76404edcSAsim Jamshed     t = t * 24 + tmP->tm_hour;
190*76404edcSAsim Jamshed     t = t * 60 + tmP->tm_min;
191*76404edcSAsim Jamshed     t = t * 60 + tmP->tm_sec;
192*76404edcSAsim Jamshed 
193*76404edcSAsim Jamshed     return t;
194*76404edcSAsim Jamshed     }
195*76404edcSAsim Jamshed 
196*76404edcSAsim Jamshed 
197*76404edcSAsim Jamshed time_t
httpdate_to_timet(const char * str)198*76404edcSAsim Jamshed httpdate_to_timet( const char* str )
199*76404edcSAsim Jamshed     {
200*76404edcSAsim Jamshed     struct tm tm;
201*76404edcSAsim Jamshed     const char* cp;
202*76404edcSAsim Jamshed     char str_mon[500], str_wday[500];
203*76404edcSAsim Jamshed     int tm_sec, tm_min, tm_hour, tm_mday, tm_year;
204*76404edcSAsim Jamshed     long tm_mon, tm_wday;
205*76404edcSAsim Jamshed     time_t t;
206*76404edcSAsim Jamshed 
207*76404edcSAsim Jamshed     /* Initialize. */
208*76404edcSAsim Jamshed     memset( (char*) &tm, 0, sizeof(struct tm) );
209*76404edcSAsim Jamshed 
210*76404edcSAsim Jamshed     /* Skip initial whitespace ourselves - sscanf is clumsy at this. */
211*76404edcSAsim Jamshed     for ( cp = str; *cp == ' ' || *cp == '\t'; ++cp )
212*76404edcSAsim Jamshed 	;
213*76404edcSAsim Jamshed 
214*76404edcSAsim Jamshed     /* And do the sscanfs.  WARNING: you can add more formats here,
215*76404edcSAsim Jamshed     ** but be careful!  You can easily screw up the parsing of existing
216*76404edcSAsim Jamshed     ** formats when you add new ones.  The order is important.
217*76404edcSAsim Jamshed     */
218*76404edcSAsim Jamshed 
219*76404edcSAsim Jamshed     /* DD-mth-YY HH:MM:SS GMT */
220*76404edcSAsim Jamshed     if ( sscanf( cp, "%d-%[a-zA-Z]-%d %d:%d:%d GMT",
221*76404edcSAsim Jamshed 		&tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
222*76404edcSAsim Jamshed 		&tm_sec ) == 6 &&
223*76404edcSAsim Jamshed 	    scan_mon( str_mon, &tm_mon ) )
224*76404edcSAsim Jamshed 	{
225*76404edcSAsim Jamshed 	tm.tm_mday = tm_mday;
226*76404edcSAsim Jamshed 	tm.tm_mon = tm_mon;
227*76404edcSAsim Jamshed 	tm.tm_year = tm_year;
228*76404edcSAsim Jamshed 	tm.tm_hour = tm_hour;
229*76404edcSAsim Jamshed 	tm.tm_min = tm_min;
230*76404edcSAsim Jamshed 	tm.tm_sec = tm_sec;
231*76404edcSAsim Jamshed 	}
232*76404edcSAsim Jamshed 
233*76404edcSAsim Jamshed     /* DD mth YY HH:MM:SS GMT */
234*76404edcSAsim Jamshed     else if ( sscanf( cp, "%d %[a-zA-Z] %d %d:%d:%d GMT",
235*76404edcSAsim Jamshed 		&tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
236*76404edcSAsim Jamshed 		&tm_sec) == 6 &&
237*76404edcSAsim Jamshed 	    scan_mon( str_mon, &tm_mon ) )
238*76404edcSAsim Jamshed 	{
239*76404edcSAsim Jamshed 	tm.tm_mday = tm_mday;
240*76404edcSAsim Jamshed 	tm.tm_mon = tm_mon;
241*76404edcSAsim Jamshed 	tm.tm_year = tm_year;
242*76404edcSAsim Jamshed 	tm.tm_hour = tm_hour;
243*76404edcSAsim Jamshed 	tm.tm_min = tm_min;
244*76404edcSAsim Jamshed 	tm.tm_sec = tm_sec;
245*76404edcSAsim Jamshed 	}
246*76404edcSAsim Jamshed 
247*76404edcSAsim Jamshed     /* HH:MM:SS GMT DD-mth-YY */
248*76404edcSAsim Jamshed     else if ( sscanf( cp, "%d:%d:%d GMT %d-%[a-zA-Z]-%d",
249*76404edcSAsim Jamshed 		&tm_hour, &tm_min, &tm_sec, &tm_mday, str_mon,
250*76404edcSAsim Jamshed 		&tm_year ) == 6 &&
251*76404edcSAsim Jamshed 	    scan_mon( str_mon, &tm_mon ) )
252*76404edcSAsim Jamshed 	{
253*76404edcSAsim Jamshed 	tm.tm_hour = tm_hour;
254*76404edcSAsim Jamshed 	tm.tm_min = tm_min;
255*76404edcSAsim Jamshed 	tm.tm_sec = tm_sec;
256*76404edcSAsim Jamshed 	tm.tm_mday = tm_mday;
257*76404edcSAsim Jamshed 	tm.tm_mon = tm_mon;
258*76404edcSAsim Jamshed 	tm.tm_year = tm_year;
259*76404edcSAsim Jamshed 	}
260*76404edcSAsim Jamshed 
261*76404edcSAsim Jamshed     /* HH:MM:SS GMT DD mth YY */
262*76404edcSAsim Jamshed     else if ( sscanf( cp, "%d:%d:%d GMT %d %[a-zA-Z] %d",
263*76404edcSAsim Jamshed 		&tm_hour, &tm_min, &tm_sec, &tm_mday, str_mon,
264*76404edcSAsim Jamshed 		&tm_year ) == 6 &&
265*76404edcSAsim Jamshed 	    scan_mon( str_mon, &tm_mon ) )
266*76404edcSAsim Jamshed 	{
267*76404edcSAsim Jamshed 	tm.tm_hour = tm_hour;
268*76404edcSAsim Jamshed 	tm.tm_min = tm_min;
269*76404edcSAsim Jamshed 	tm.tm_sec = tm_sec;
270*76404edcSAsim Jamshed 	tm.tm_mday = tm_mday;
271*76404edcSAsim Jamshed 	tm.tm_mon = tm_mon;
272*76404edcSAsim Jamshed 	tm.tm_year = tm_year;
273*76404edcSAsim Jamshed 	}
274*76404edcSAsim Jamshed 
275*76404edcSAsim Jamshed     /* wdy, DD-mth-YY HH:MM:SS GMT */
276*76404edcSAsim Jamshed     else if ( sscanf( cp, "%[a-zA-Z], %d-%[a-zA-Z]-%d %d:%d:%d GMT",
277*76404edcSAsim Jamshed 		str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
278*76404edcSAsim Jamshed 		&tm_sec ) == 7 &&
279*76404edcSAsim Jamshed 	    scan_wday( str_wday, &tm_wday ) &&
280*76404edcSAsim Jamshed 	    scan_mon( str_mon, &tm_mon ) )
281*76404edcSAsim Jamshed 	{
282*76404edcSAsim Jamshed 	tm.tm_wday = tm_wday;
283*76404edcSAsim Jamshed 	tm.tm_mday = tm_mday;
284*76404edcSAsim Jamshed 	tm.tm_mon = tm_mon;
285*76404edcSAsim Jamshed 	tm.tm_year = tm_year;
286*76404edcSAsim Jamshed 	tm.tm_hour = tm_hour;
287*76404edcSAsim Jamshed 	tm.tm_min = tm_min;
288*76404edcSAsim Jamshed 	tm.tm_sec = tm_sec;
289*76404edcSAsim Jamshed 	}
290*76404edcSAsim Jamshed 
291*76404edcSAsim Jamshed     /* wdy, DD mth YY HH:MM:SS GMT */
292*76404edcSAsim Jamshed     else if ( sscanf( cp, "%[a-zA-Z], %d %[a-zA-Z] %d %d:%d:%d GMT",
293*76404edcSAsim Jamshed 		str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
294*76404edcSAsim Jamshed 		&tm_sec ) == 7 &&
295*76404edcSAsim Jamshed 	    scan_wday( str_wday, &tm_wday ) &&
296*76404edcSAsim Jamshed 	    scan_mon( str_mon, &tm_mon ) )
297*76404edcSAsim Jamshed 	{
298*76404edcSAsim Jamshed 	tm.tm_wday = tm_wday;
299*76404edcSAsim Jamshed 	tm.tm_mday = tm_mday;
300*76404edcSAsim Jamshed 	tm.tm_mon = tm_mon;
301*76404edcSAsim Jamshed 	tm.tm_year = tm_year;
302*76404edcSAsim Jamshed 	tm.tm_hour = tm_hour;
303*76404edcSAsim Jamshed 	tm.tm_min = tm_min;
304*76404edcSAsim Jamshed 	tm.tm_sec = tm_sec;
305*76404edcSAsim Jamshed 	}
306*76404edcSAsim Jamshed 
307*76404edcSAsim Jamshed     /* wdy mth DD HH:MM:SS GMT YY */
308*76404edcSAsim Jamshed     else if ( sscanf( cp, "%[a-zA-Z] %[a-zA-Z] %d %d:%d:%d GMT %d",
309*76404edcSAsim Jamshed 		str_wday, str_mon, &tm_mday, &tm_hour, &tm_min, &tm_sec,
310*76404edcSAsim Jamshed 		&tm_year ) == 7 &&
311*76404edcSAsim Jamshed 	    scan_wday( str_wday, &tm_wday ) &&
312*76404edcSAsim Jamshed 	    scan_mon( str_mon, &tm_mon ) )
313*76404edcSAsim Jamshed 	{
314*76404edcSAsim Jamshed 	tm.tm_wday = tm_wday;
315*76404edcSAsim Jamshed 	tm.tm_mon = tm_mon;
316*76404edcSAsim Jamshed 	tm.tm_mday = tm_mday;
317*76404edcSAsim Jamshed 	tm.tm_hour = tm_hour;
318*76404edcSAsim Jamshed 	tm.tm_min = tm_min;
319*76404edcSAsim Jamshed 	tm.tm_sec = tm_sec;
320*76404edcSAsim Jamshed 	tm.tm_year = tm_year;
321*76404edcSAsim Jamshed 	}
322*76404edcSAsim Jamshed     else
323*76404edcSAsim Jamshed 	return (time_t) -1;
324*76404edcSAsim Jamshed 
325*76404edcSAsim Jamshed     if ( tm.tm_year > 1900 )
326*76404edcSAsim Jamshed 	tm.tm_year -= 1900;
327*76404edcSAsim Jamshed     else if ( tm.tm_year < 70 )
328*76404edcSAsim Jamshed 	tm.tm_year += 100;
329*76404edcSAsim Jamshed 
330*76404edcSAsim Jamshed     t = tm_to_time( &tm );
331*76404edcSAsim Jamshed 
332*76404edcSAsim Jamshed     return t;
333*76404edcSAsim Jamshed }
334*76404edcSAsim Jamshed 
335*76404edcSAsim Jamshed /*
336*76404edcSAsim Jamshed    Convert 't' (in time_t format) into the HTTP date format
337*76404edcSAsim Jamshed    <input parameters>
338*76404edcSAsim Jamshed    t:      input (epoch-based time)
339*76404edcSAsim Jamshed    str:    output string that holds the HTTP date strinng
340*76404edcSAsim Jamshed    strlen: the buffer size of str
341*76404edcSAsim Jamshed 
342*76404edcSAsim Jamshed    <return value>
343*76404edcSAsim Jamshed     0 : in case of successful conversion
344*76404edcSAsim Jamshed    -1 : otherwise
345*76404edcSAsim Jamshed                                         by KyoungSoo Park
346*76404edcSAsim Jamshed */
347*76404edcSAsim Jamshed int
timet_to_httpdate(time_t t,char * str,int strlen)348*76404edcSAsim Jamshed timet_to_httpdate(time_t t, char* str, int strlen )
349*76404edcSAsim Jamshed {
350*76404edcSAsim Jamshed   static const char* day_of_week[] = {"Sun", "Mon","Tue",
351*76404edcSAsim Jamshed 									  "Wed", "Thu", "Fri", "Sat"};
352*76404edcSAsim Jamshed 
353*76404edcSAsim Jamshed   static const char* months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
354*76404edcSAsim Jamshed 								 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
355*76404edcSAsim Jamshed   struct tm gm;
356*76404edcSAsim Jamshed 
357*76404edcSAsim Jamshed   if (gmtime_r(&t, &gm) == NULL)
358*76404edcSAsim Jamshed 	return(-1);
359*76404edcSAsim Jamshed 
360*76404edcSAsim Jamshed   /* example date: "Sat, 26 Mar 2011 05:53:57 GMT" */
361*76404edcSAsim Jamshed   if (snprintf(str, strlen,
362*76404edcSAsim Jamshed 			   "%s, %02d %s %4d %02d:%02d:%02d GMT",
363*76404edcSAsim Jamshed 			   day_of_week[gm.tm_wday],
364*76404edcSAsim Jamshed 			   gm.tm_mday,
365*76404edcSAsim Jamshed 			   months[gm.tm_mon],
366*76404edcSAsim Jamshed 			   gm.tm_year + 1900,
367*76404edcSAsim Jamshed 			   gm.tm_hour,
368*76404edcSAsim Jamshed 			   gm.tm_min,
369*76404edcSAsim Jamshed 			   gm.tm_sec) == strlen)
370*76404edcSAsim Jamshed 	/* probably str has an insufficient buffer size */
371*76404edcSAsim Jamshed 	return (-1);
372*76404edcSAsim Jamshed   return(0);
373*76404edcSAsim Jamshed }
374