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