]>
git.ipfire.org Git - thirdparty/squid.git/blob - lib/rfc1123.c
3 * $Id: rfc1123.c,v 1.26 2000/11/07 23:37:35 wessels Exp $
6 * AUTHOR: Harvest Derived
8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
9 * ----------------------------------------------------------
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
13 * National Laboratory for Applied Network Research and funded by the
14 * National Science Foundation. Squid is Copyrighted (C) 1998 by
15 * the Regents of the University of California. Please see the
16 * COPYRIGHT file for full details. Squid incorporates software
17 * developed and/or copyrighted by other sources. Please see the
18 * CREDITS file for full details.
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
40 * Adapted from HTSUtils.c in CERN httpd 3.0 (http://info.cern.ch/httpd/)
41 * by Darren Hardy <hardy@cs.colorado.edu>, November 1994.
56 #include <sys/types.h>
69 #define RFC850_STRFTIME "%A, %d-%b-%y %H:%M:%S GMT"
70 #define RFC1123_STRFTIME "%a, %d %b %Y %H:%M:%S GMT"
72 static const char *const w_space
= " \t\r\n";
74 static int make_month(const char *s
);
75 static int make_num(const char *s
);
77 static char *month_names
[12] =
79 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
80 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
85 make_num(const char *s
)
87 if (*s
>= '0' && *s
<= '9')
88 return 10 * (*s
- '0') + *(s
+ 1) - '0';
90 return *(s
+ 1) - '0';
94 make_month(const char *s
)
99 month
[0] = xtoupper(*s
);
100 month
[1] = xtolower(*(s
+ 1));
101 month
[2] = xtolower(*(s
+ 2));
103 for (i
= 0; i
< 12; i
++)
104 if (!strncmp(month_names
[i
], month
, 3))
110 tmSaneValues(struct tm
*tm
)
112 if (tm
->tm_sec
< 0 || tm
->tm_sec
> 59)
114 if (tm
->tm_min
< 0 || tm
->tm_min
> 59)
116 if (tm
->tm_hour
< 0 || tm
->tm_hour
> 23)
118 if (tm
->tm_mday
< 1 || tm
->tm_mday
> 31)
120 if (tm
->tm_mon
< 0 || tm
->tm_mon
> 11)
122 if (tm
->tm_year
< 70 || tm
->tm_year
> 120)
128 parse_date1(const char *str
)
130 /* Thursday, 10-Jun-93 01:29:59 GMT */
134 memset(&tm
, '\0', sizeof(struct tm
));
135 s
= strchr(str
, ',');
140 /* backup if month is only one digit */
141 if (xisdigit(*s
) && !xisdigit(*(s
+ 1)))
145 if ((int) strlen(s
) < 18)
147 memset(&tm
, '\0', sizeof(tm
));
148 tm
.tm_mday
= make_num(s
);
149 tm
.tm_mon
= make_month(s
+ 3);
150 tm
.tm_year
= make_num(s
+ 7);
152 * Y2K: Arjan de Vet <Arjan.deVet@adv.IAEhv.nl>
153 * if tm.tm_year < 70, assume it's after the year 2000.
157 tm
.tm_hour
= make_num(s
+ 10);
158 tm
.tm_min
= make_num(s
+ 13);
159 tm
.tm_sec
= make_num(s
+ 16);
160 return tmSaneValues(&tm
) ? &tm
: NULL
;
164 parse_date2(const char *str
)
166 /* Thu, 10 Jan 1993 01:29:59 GMT */
170 memset(&tm
, '\0', sizeof(struct tm
));
171 s
= strchr(str
, ',');
176 /* backup if month is only one digit */
177 if (xisdigit(*s
) && !xisdigit(*(s
+ 1)))
181 if ((int) strlen(s
) < 20)
183 memset(&tm
, '\0', sizeof(tm
));
184 tm
.tm_mday
= make_num(s
);
185 tm
.tm_mon
= make_month(s
+ 3);
186 tm
.tm_year
= (100 * make_num(s
+ 7) - 1900) + make_num(s
+ 9);
187 tm
.tm_hour
= make_num(s
+ 12);
188 tm
.tm_min
= make_num(s
+ 15);
189 tm
.tm_sec
= make_num(s
+ 18);
190 return tmSaneValues(&tm
) ? &tm
: NULL
;
194 parse_date3(const char *str
)
196 /* Wed Jun 9 01:29:59 1993 GMT */
199 static char buf
[128];
200 while (*str
&& *str
== ' ')
202 xstrncpy(buf
, str
, 128);
203 if (NULL
== (s
= strtok(buf
, w_space
)))
205 if (NULL
== (s
= strtok(NULL
, w_space
)))
207 tm
.tm_mon
= make_month(s
);
208 if (NULL
== (s
= strtok(NULL
, w_space
)))
210 tm
.tm_mday
= atoi(s
);
211 if (NULL
== (s
= strtok(NULL
, ":")))
213 tm
.tm_hour
= atoi(s
);
214 if (NULL
== (s
= strtok(NULL
, ":")))
217 if (NULL
== (s
= strtok(NULL
, w_space
)))
220 if (NULL
== (s
= strtok(NULL
, w_space
)))
222 /* Y2K fix, richard.kettlewell@kewill.com */
223 tm
.tm_year
= atoi(s
) - 1900;
224 return tmSaneValues(&tm
) ? &tm
: NULL
;
228 parse_rfc1123(const char *str
)
234 tm
= parse_date1(str
);
236 tm
= parse_date2(str
);
238 tm
= parse_date3(str
);
249 struct tm
*local
= localtime(&t
);
250 t
+= local
->tm_gmtoff
;
253 /* some systems do not have tm_gmtoff so we fake it */
257 #if defined (_TIMEZONE)
258 #elif defined (_timezone)
259 #elif defined(_SQUID_AIX_)
260 #elif defined(_SQUID_CYGWIN_)
262 extern time_t timezone
;
265 * The following assumes a fixed DST offset of 1 hour,
266 * which is probably wrong.
268 if (tm
->tm_isdst
> 0)
270 #if defined ( _timezone) || defined(_SQUID_CYGWIN_)
271 t
-= (_timezone
+ dst
);
273 t
-= (timezone
+ dst
);
283 static char buf
[128];
285 struct tm
*gmt
= gmtime(&t
);
288 strftime(buf
, 127, RFC1123_STRFTIME
, gmt
);
293 mkhttpdlogtime(const time_t * t
)
295 static char buf
[128];
297 struct tm
*gmt
= gmtime(t
);
300 int gmt_min
, gmt_hour
, gmt_yday
, day_offset
;
305 /* localtime & gmtime may use the same static data */
306 gmt_min
= gmt
->tm_min
;
307 gmt_hour
= gmt
->tm_hour
;
308 gmt_yday
= gmt
->tm_yday
;
312 day_offset
= lt
->tm_yday
- gmt_yday
;
313 /* wrap round on end of year */
316 else if (day_offset
< -1)
319 min_offset
= day_offset
* 1440 + (lt
->tm_hour
- gmt_hour
) * 60
320 + (lt
->tm_min
- gmt_min
);
322 len
= strftime(buf
, 127 - 5, "%d/%b/%Y:%H:%M:%S ", lt
);
323 snprintf(buf
+ len
, 128 - len
, "%+03d%02d",
324 (min_offset
/ 60) % 24,
328 strftime(buf
, 127, "%d/%b/%Y:%H:%M:%S -000", gmt
);
343 printf("HTTP Time: %s\n", x
);
345 pt
= parse_rfc1123(x
);
346 printf("Parsed: %d vs. %d\n", pt
, t
);