]>
Commit | Line | Data |
---|---|---|
164f7660 | 1 | |
cf49df4b | 2 | /* |
cbdec147 | 3 | * $Id: rfc1123.c,v 1.19 1998/07/20 17:18:56 wessels Exp $ |
cf49df4b | 4 | * |
5 | * DEBUG: | |
6 | * AUTHOR: Harvest Derived | |
7 | * | |
42c04c16 | 8 | * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ |
cf49df4b | 9 | * -------------------------------------------------------- |
10 | * | |
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 | |
14 | * the National Science Foundation. | |
15 | * | |
16 | * This program is free software; you can redistribute it and/or modify | |
17 | * it under the terms of the GNU General Public License as published by | |
18 | * the Free Software Foundation; either version 2 of the License, or | |
19 | * (at your option) any later version. | |
20 | * | |
21 | * This program is distributed in the hope that it will be useful, | |
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24 | * GNU General Public License for more details. | |
25 | * | |
26 | * You should have received a copy of the GNU General Public License | |
27 | * along with this program; if not, write to the Free Software | |
cbdec147 | 28 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. |
cf49df4b | 29 | * |
30 | */ | |
31 | ||
32 | /* | |
33 | * Copyright (c) 1994, 1995. All rights reserved. | |
34 | * | |
35 | * The Harvest software was developed by the Internet Research Task | |
36 | * Force Research Group on Resource Discovery (IRTF-RD): | |
37 | * | |
38 | * Mic Bowman of Transarc Corporation. | |
39 | * Peter Danzig of the University of Southern California. | |
40 | * Darren R. Hardy of the University of Colorado at Boulder. | |
41 | * Udi Manber of the University of Arizona. | |
42 | * Michael F. Schwartz of the University of Colorado at Boulder. | |
43 | * Duane Wessels of the University of Colorado at Boulder. | |
44 | * | |
45 | * This copyright notice applies to software in the Harvest | |
46 | * ``src/'' directory only. Users should consult the individual | |
47 | * copyright notices in the ``components/'' subdirectories for | |
48 | * copyright information about other software bundled with the | |
49 | * Harvest source code distribution. | |
50 | * | |
51 | * TERMS OF USE | |
52 | * | |
53 | * The Harvest software may be used and re-distributed without | |
54 | * charge, provided that the software origin and research team are | |
55 | * cited in any use of the system. Most commonly this is | |
56 | * accomplished by including a link to the Harvest Home Page | |
57 | * (http://harvest.cs.colorado.edu/) from the query page of any | |
58 | * Broker you deploy, as well as in the query result pages. These | |
59 | * links are generated automatically by the standard Broker | |
60 | * software distribution. | |
61 | * | |
62 | * The Harvest software is provided ``as is'', without express or | |
63 | * implied warranty, and with no support nor obligation to assist | |
64 | * in its use, correction, modification or enhancement. We assume | |
65 | * no liability with respect to the infringement of copyrights, | |
66 | * trade secrets, or any patents, and are not responsible for | |
67 | * consequential damages. Proper use of the Harvest software is | |
68 | * entirely the responsibility of the user. | |
69 | * | |
70 | * DERIVATIVE WORKS | |
71 | * | |
72 | * Users may make derivative works from the Harvest software, subject | |
73 | * to the following constraints: | |
74 | * | |
75 | * - You must include the above copyright notice and these | |
76 | * accompanying paragraphs in all forms of derivative works, | |
77 | * and any documentation and other materials related to such | |
78 | * distribution and use acknowledge that the software was | |
79 | * developed at the above institutions. | |
80 | * | |
81 | * - You must notify IRTF-RD regarding your distribution of | |
82 | * the derivative work. | |
83 | * | |
84 | * - You must clearly notify users that your are distributing | |
85 | * a modified version and not the original Harvest software. | |
86 | * | |
87 | * - Any derivative product is also subject to these copyright | |
88 | * and use restrictions. | |
89 | * | |
90 | * Note that the Harvest software is NOT in the public domain. We | |
91 | * retain copyright, as specified above. | |
92 | * | |
93 | * HISTORY OF FREE SOFTWARE STATUS | |
94 | * | |
95 | * Originally we required sites to license the software in cases | |
96 | * where they were going to build commercial products/services | |
97 | * around Harvest. In June 1995 we changed this policy. We now | |
98 | * allow people to use the core Harvest software (the code found in | |
99 | * the Harvest ``src/'' directory) for free. We made this change | |
100 | * in the interest of encouraging the widest possible deployment of | |
101 | * the technology. The Harvest software is really a reference | |
102 | * implementation of a set of protocols and formats, some of which | |
103 | * we intend to standardize. We encourage commercial | |
104 | * re-implementations of code complying to this set of standards. | |
105 | */ | |
106 | ||
107 | #include "config.h" | |
108 | ||
109 | ||
110 | /* | |
111 | * Adapted from HTSUtils.c in CERN httpd 3.0 (http://info.cern.ch/httpd/) | |
112 | * by Darren Hardy <hardy@cs.colorado.edu>, November 1994. | |
113 | */ | |
114 | #if HAVE_STDIO_H | |
115 | #include <stdio.h> | |
116 | #endif | |
117 | #if HAVE_STRING_H | |
118 | #include <string.h> | |
119 | #endif | |
120 | #if HAVE_CTYPE_H | |
121 | #include <ctype.h> | |
122 | #endif | |
123 | #if HAVE_SYS_TYPES_H | |
124 | #include <sys/types.h> | |
125 | #endif | |
126 | #if HAVE_TIME_H | |
127 | #include <time.h> | |
128 | #endif | |
129 | #if HAVE_SYS_TIME_H | |
130 | #include <sys/time.h> | |
131 | #endif | |
132 | ||
cf49df4b | 133 | #include "util.h" |
5e2e108b | 134 | #include "snprintf.h" |
cf49df4b | 135 | |
2a8a7464 | 136 | #define RFC850_STRFTIME "%A, %d-%b-%y %H:%M:%S GMT" |
137 | #define RFC1123_STRFTIME "%a, %d %b %Y %H:%M:%S GMT" | |
138 | ||
f5b8bbc4 | 139 | static int make_month(const char *s); |
140 | static int make_num(const char *s); | |
cf49df4b | 141 | |
142 | static char *month_names[12] = | |
143 | { | |
144 | "Jan", "Feb", "Mar", "Apr", "May", "Jun", | |
145 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" | |
146 | }; | |
147 | ||
148 | ||
149 | static int | |
0ee4272b | 150 | make_num(const char *s) |
cf49df4b | 151 | { |
152 | if (*s >= '0' && *s <= '9') | |
153 | return 10 * (*s - '0') + *(s + 1) - '0'; | |
154 | else | |
155 | return *(s + 1) - '0'; | |
156 | } | |
157 | ||
158 | static int | |
0ee4272b | 159 | make_month(const char *s) |
cf49df4b | 160 | { |
161 | int i; | |
0ee4272b | 162 | char month[3]; |
cf49df4b | 163 | |
0ee4272b | 164 | month[0] = toupper(*s); |
165 | month[1] = tolower(*(s + 1)); | |
166 | month[2] = tolower(*(s + 2)); | |
cf49df4b | 167 | |
168 | for (i = 0; i < 12; i++) | |
0ee4272b | 169 | if (!strncmp(month_names[i], month, 3)) |
cf49df4b | 170 | return i; |
171 | return 0; | |
172 | } | |
173 | ||
174 | ||
175 | time_t | |
0ee4272b | 176 | parse_rfc1123(const char *str) |
cf49df4b | 177 | { |
0ee4272b | 178 | const char *s; |
cf49df4b | 179 | struct tm tm; |
180 | time_t t; | |
181 | ||
182 | if (!str) | |
183 | return -1; | |
184 | ||
7446ea01 | 185 | memset(&tm, '\0', sizeof(struct tm)); |
cf49df4b | 186 | if ((s = strchr(str, ','))) { /* Thursday, 10-Jun-93 01:29:59 GMT */ |
187 | s++; /* or: Thu, 10 Jan 1993 01:29:59 GMT */ | |
14227516 | 188 | while (*s == ' ') |
cf49df4b | 189 | s++; |
14227516 | 190 | if (isdigit(*s) && !isdigit(*(s+1))) /* backoff if only one digit */ |
191 | s--; | |
cf49df4b | 192 | if (strchr(s, '-')) { /* First format */ |
193 | if ((int) strlen(s) < 18) | |
194 | return -1; | |
195 | tm.tm_mday = make_num(s); | |
196 | tm.tm_mon = make_month(s + 3); | |
197 | tm.tm_year = make_num(s + 7); | |
72367f90 | 198 | /* |
199 | * Y2K: Arjan de Vet <Arjan.deVet@adv.IAEhv.nl> | |
200 | * if tm.tm_year < 70, assume it's after the year 2000. | |
201 | */ | |
202 | if (tm.tm_year < 70) | |
203 | tm.tm_year += 100; | |
cf49df4b | 204 | tm.tm_hour = make_num(s + 10); |
205 | tm.tm_min = make_num(s + 13); | |
206 | tm.tm_sec = make_num(s + 16); | |
207 | } else { /* Second format */ | |
208 | if ((int) strlen(s) < 20) | |
209 | return -1; | |
210 | tm.tm_mday = make_num(s); | |
211 | tm.tm_mon = make_month(s + 3); | |
212 | tm.tm_year = (100 * make_num(s + 7) - 1900) + make_num(s + 9); | |
213 | tm.tm_hour = make_num(s + 12); | |
214 | tm.tm_min = make_num(s + 15); | |
215 | tm.tm_sec = make_num(s + 18); | |
216 | ||
217 | } | |
218 | } else { /* Try the other format: */ | |
219 | s = str; /* Wed Jun 9 01:29:59 1993 GMT */ | |
220 | while (*s && *s == ' ') | |
221 | s++; | |
222 | if ((int) strlen(s) < 24) | |
223 | return -1; | |
224 | tm.tm_mday = make_num(s + 8); | |
225 | tm.tm_mon = make_month(s + 4); | |
226 | tm.tm_year = make_num(s + 22); | |
227 | tm.tm_hour = make_num(s + 11); | |
228 | tm.tm_min = make_num(s + 14); | |
229 | tm.tm_sec = make_num(s + 17); | |
230 | } | |
231 | if (tm.tm_sec < 0 || tm.tm_sec > 59 || | |
232 | tm.tm_min < 0 || tm.tm_min > 59 || | |
233 | tm.tm_hour < 0 || tm.tm_hour > 23 || | |
234 | tm.tm_mday < 1 || tm.tm_mday > 31 || | |
235 | tm.tm_mon < 0 || tm.tm_mon > 11 || | |
236 | tm.tm_year < 70 || tm.tm_year > 120) { | |
237 | return -1; | |
238 | } | |
239 | tm.tm_isdst = -1; | |
240 | ||
241 | #ifdef HAVE_TIMEGM | |
242 | t = timegm(&tm); | |
243 | #elif HAVE_TM_GMTOFF | |
244 | t = mktime(&tm); | |
245 | { | |
f2d03c5f | 246 | struct tm *local = localtime(&t); |
cf49df4b | 247 | t += local->tm_gmtoff; |
248 | } | |
249 | #else | |
250 | /* some systems do not have tm_gmtoff so we fake it */ | |
251 | t = mktime(&tm); | |
252 | { | |
253 | time_t dst = 0; | |
44965270 | 254 | #if defined (_TIMEZONE) |
255 | #elif defined (_timezone) | |
256 | #elif defined(_SQUID_AIX_) | |
257 | #else | |
cf49df4b | 258 | extern time_t timezone; |
9b6dbb2a | 259 | #endif |
cf49df4b | 260 | /* |
261 | * The following assumes a fixed DST offset of 1 hour, | |
262 | * which is probably wrong. | |
263 | */ | |
264 | if (tm.tm_isdst > 0) | |
265 | dst = -3600; | |
9b6dbb2a | 266 | #ifdef _timezone |
267 | t -= (_timezone + dst); | |
268 | #else | |
cf49df4b | 269 | t -= (timezone + dst); |
9b6dbb2a | 270 | #endif |
cf49df4b | 271 | } |
272 | #endif | |
273 | return t; | |
274 | } | |
275 | ||
0ee4272b | 276 | const char * |
cf49df4b | 277 | mkrfc1123(time_t t) |
278 | { | |
279 | static char buf[128]; | |
280 | ||
281 | struct tm *gmt = gmtime(&t); | |
282 | ||
283 | buf[0] = '\0'; | |
2a8a7464 | 284 | strftime(buf, 127, RFC1123_STRFTIME, gmt); |
cf49df4b | 285 | return buf; |
286 | } | |
287 | ||
0ee4272b | 288 | const char * |
38cac3c8 | 289 | mkhttpdlogtime(const time_t * t) |
cf49df4b | 290 | { |
291 | static char buf[128]; | |
292 | ||
293 | struct tm *gmt = gmtime(t); | |
294 | ||
295 | #ifndef USE_GMT | |
296 | int gmt_min, gmt_hour, gmt_yday, day_offset; | |
297 | size_t len; | |
298 | struct tm *lt; | |
299 | int min_offset; | |
300 | ||
301 | /* localtime & gmtime may use the same static data */ | |
302 | gmt_min = gmt->tm_min; | |
303 | gmt_hour = gmt->tm_hour; | |
304 | gmt_yday = gmt->tm_yday; | |
305 | ||
306 | lt = localtime(t); | |
307 | day_offset = lt->tm_yday - gmt_yday; | |
308 | min_offset = day_offset * 1440 + (lt->tm_hour - gmt_hour) * 60 | |
309 | + (lt->tm_min - gmt_min); | |
310 | ||
311 | /* wrap round on end of year */ | |
312 | if (day_offset > 1) | |
313 | day_offset = -1; | |
314 | else if (day_offset < -1) | |
315 | day_offset = 1; | |
316 | ||
317 | len = strftime(buf, 127 - 5, "%d/%b/%Y:%H:%M:%S ", lt); | |
0e473d70 | 318 | snprintf(buf + len, 128 - len, "%+03d%02d", |
cf49df4b | 319 | (min_offset / 60) % 24, |
320 | min_offset % 60); | |
321 | #else /* USE_GMT */ | |
322 | buf[0] = '\0'; | |
2a8a7464 | 323 | strftime(buf, 127, "%d/%b/%Y:%H:%M:%S -000", gmt); |
cf49df4b | 324 | #endif /* USE_GMT */ |
325 | ||
326 | return buf; | |
327 | } | |
328 | ||
329 | #if 0 | |
330 | int | |
331 | main() | |
332 | { | |
333 | char *x; | |
334 | time_t t, pt; | |
335 | ||
336 | t = time(NULL); | |
337 | x = mkrfc1123(t); | |
338 | printf("HTTP Time: %s\n", x); | |
339 | ||
340 | pt = parse_rfc1123(x); | |
341 | printf("Parsed: %d vs. %d\n", pt, t); | |
342 | } | |
343 | ||
344 | #endif |