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