upload http
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / srclib / apr / time / win32 / timestr.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "win32/apr_arch_atime.h"
18 #include "apr_portable.h"
19 #include "apr_strings.h"
20
21 APR_DECLARE_DATA const char apr_month_snames[12][4] =
22 {
23     "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
24 };
25 APR_DECLARE_DATA const char apr_day_snames[7][4] =
26 {
27     "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
28 };
29
30 APR_DECLARE(apr_status_t) apr_rfc822_date(char *date_str, apr_time_t t)
31 {
32     apr_time_exp_t xt;
33     const char *s;
34     int real_year;
35
36     apr_time_exp_gmt(&xt, t);
37
38     /* example: "Sat, 08 Jan 2000 18:31:41 GMT" */
39     /*           12345678901234567890123456789  */
40
41     s = &apr_day_snames[xt.tm_wday][0];
42     *date_str++ = *s++;
43     *date_str++ = *s++;
44     *date_str++ = *s++;
45     *date_str++ = ',';
46     *date_str++ = ' ';
47     *date_str++ = xt.tm_mday / 10 + '0';
48     *date_str++ = xt.tm_mday % 10 + '0';
49     *date_str++ = ' ';
50     s = &apr_month_snames[xt.tm_mon][0];
51     *date_str++ = *s++;
52     *date_str++ = *s++;
53     *date_str++ = *s++;
54     *date_str++ = ' ';
55     real_year = 1900 + xt.tm_year;
56     /* This routine isn't y10k ready. */
57     *date_str++ = real_year / 1000 + '0';
58     *date_str++ = real_year % 1000 / 100 + '0';
59     *date_str++ = real_year % 100 / 10 + '0';
60     *date_str++ = real_year % 10 + '0';
61     *date_str++ = ' ';
62     *date_str++ = xt.tm_hour / 10 + '0';
63     *date_str++ = xt.tm_hour % 10 + '0';
64     *date_str++ = ':';
65     *date_str++ = xt.tm_min / 10 + '0';
66     *date_str++ = xt.tm_min % 10 + '0';
67     *date_str++ = ':';
68     *date_str++ = xt.tm_sec / 10 + '0';
69     *date_str++ = xt.tm_sec % 10 + '0';
70     *date_str++ = ' ';
71     *date_str++ = 'G';
72     *date_str++ = 'M';
73     *date_str++ = 'T';
74     *date_str++ = 0;
75     return APR_SUCCESS;
76 }
77
78 APR_DECLARE(apr_status_t) apr_ctime(char *date_str, apr_time_t t)
79 {
80     apr_time_exp_t xt;
81     const char *s;
82     int real_year;
83
84     /* example: "Wed Jun 30 21:49:08 1993" */
85     /*           123456789012345678901234  */
86
87     apr_time_exp_lt(&xt, t);
88     s = &apr_day_snames[xt.tm_wday][0];
89     *date_str++ = *s++;
90     *date_str++ = *s++;
91     *date_str++ = *s++;
92     *date_str++ = ' ';
93     s = &apr_month_snames[xt.tm_mon][0];
94     *date_str++ = *s++;
95     *date_str++ = *s++;
96     *date_str++ = *s++;
97     *date_str++ = ' ';
98     *date_str++ = xt.tm_mday / 10 + '0';
99     *date_str++ = xt.tm_mday % 10 + '0';
100     *date_str++ = ' ';
101     *date_str++ = xt.tm_hour / 10 + '0';
102     *date_str++ = xt.tm_hour % 10 + '0';
103     *date_str++ = ':';
104     *date_str++ = xt.tm_min / 10 + '0';
105     *date_str++ = xt.tm_min % 10 + '0';
106     *date_str++ = ':';
107     *date_str++ = xt.tm_sec / 10 + '0';
108     *date_str++ = xt.tm_sec % 10 + '0';
109     *date_str++ = ' ';
110     real_year = 1900 + xt.tm_year;
111     *date_str++ = real_year / 1000 + '0';
112     *date_str++ = real_year % 1000 / 100 + '0';
113     *date_str++ = real_year % 100 / 10 + '0';
114     *date_str++ = real_year % 10 + '0';
115     *date_str++ = 0;
116
117     return APR_SUCCESS;
118 }
119
120
121 #ifndef _WIN32_WCE
122
123 int win32_strftime_extra(char *s, size_t max, const char *format,
124                          const struct tm *tm) 
125 {
126    /* If the new format string is bigger than max, the result string won't fit
127     * anyway. If format strings are added, made sure the padding below is
128     * enough */
129     char *new_format = (char *) malloc(max + 11);
130     size_t i, j, format_length = strlen(format);
131     int return_value;
132     int length_written;
133
134     for (i = 0, j = 0; (i < format_length && j < max);) {
135         if (format[i] != '%') {
136             new_format[j++] = format[i++];
137             continue;
138         }
139         switch (format[i+1]) {
140             case 'C':
141                 length_written = apr_snprintf(new_format + j, max - j, "%2d",
142                     (tm->tm_year + 1970)/100);
143                 j = (length_written == -1) ? max : (j + length_written);
144                 i += 2;
145                 break;
146             case 'D':
147                 /* Is this locale dependent? Shouldn't be...
148                    Also note the year 2000 exposure here */
149                 memcpy(new_format + j, "%m/%d/%y", 8);
150                 i += 2;
151                 j += 8;
152                 break;
153             case 'r':
154                 memcpy(new_format + j, "%I:%M:%S %p", 11);
155                 i += 2;
156                 j += 11;
157                 break;
158             case 'R':
159                 memcpy(new_format + j, "%H:%M", 5);
160                 i += 2;
161                 j += 5;
162                 break;
163             case 'T':
164                 memcpy(new_format + j, "%H:%M:%S", 8);
165                 i += 2;
166                 j += 8;
167                 break;
168             case 'e':
169                 length_written = apr_snprintf(new_format + j, max - j, "%2d",
170                     tm->tm_mday);
171                 j = (length_written == -1) ? max : (j + length_written);
172                 i += 2;
173                 break;
174             default:
175                 /* We know we can advance two characters forward here. Also
176                  * makes sure that %% is preserved. */
177                 new_format[j++] = format[i++];
178                 new_format[j++] = format[i++];
179         }
180     }
181     if (j >= max) {
182         *s = '\0';  /* Defensive programming, okay since output is undefined*/
183         return_value = 0;
184     } else {
185         new_format[j] = '\0';
186         return_value = strftime(s, max, new_format, tm);
187     }
188     free(new_format);
189     return return_value;
190 }
191
192 #endif
193
194
195 APR_DECLARE(apr_status_t) apr_strftime(char *s, apr_size_t *retsize,
196                                        apr_size_t max, const char *format,
197                                        apr_time_exp_t *xt)
198 {
199 #ifdef _WIN32_WCE
200     return APR_ENOTIMPL;
201 #else
202     struct tm tm;
203     memset(&tm, 0, sizeof tm);
204     tm.tm_sec  = xt->tm_sec;
205     tm.tm_min  = xt->tm_min;
206     tm.tm_hour = xt->tm_hour;
207     tm.tm_mday = xt->tm_mday;
208     tm.tm_mon  = xt->tm_mon;
209     tm.tm_year = xt->tm_year;
210     tm.tm_wday = xt->tm_wday;
211     tm.tm_yday = xt->tm_yday;
212     tm.tm_isdst = xt->tm_isdst;
213     (*retsize) = win32_strftime_extra(s, max, format, &tm);
214     return APR_SUCCESS;
215 #endif
216 }