00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "klone_conf.h"
00012 #include <stdlib.h>
00013 #include <stdio.h>
00014 #include <time.h>
00015 #include <ctype.h>
00016 #include <fcntl.h>
00017 #include <unistd.h>
00018 #include <dirent.h>
00019 #include <sys/stat.h>
00020 #include <u/libu.h>
00021 #include <klone/os.h>
00022 #include <klone/utils.h>
00023
00029 static const char* days3[] = {
00030 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
00031 };
00032
00033 static const char* months[] = {
00034 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
00035 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
00036 };
00037
00038 static int month_idx(const char *mon)
00039 {
00040 int i;
00041
00042 dbg_return_if (mon == NULL, -1);
00043
00044 for(i = 0; i < 12; ++i)
00045 if(strcasecmp(months[i], mon) == 0)
00046 return i;
00047
00048 return -1;
00049 }
00050
00063 int u_asctime_to_tt(const char *str, time_t *tp)
00064 {
00065 enum { BUFSZ = 64 };
00066 char wday[BUFSZ], mon[BUFSZ];
00067 unsigned int day, year, hour, min, sec;
00068 struct tm tm;
00069 int i;
00070
00071 dbg_return_if (str == NULL, ~0);
00072 dbg_return_if (tp == NULL, ~0);
00073 dbg_return_if (strlen(str) >= BUFSZ, ~0);
00074
00075 dbg_err_if((i = sscanf(str, "%s %s %u %u:%u:%u %u", wday,
00076 mon, &day, &hour, &min, &sec, &year)) != 7);
00077
00078 memset(&tm, 0, sizeof(struct tm));
00079
00080
00081 tm.tm_sec = sec; tm.tm_min = min; tm.tm_hour = hour;
00082
00083
00084 tm.tm_mday = day;
00085 tm.tm_mon = month_idx(mon);
00086 tm.tm_year = year - 1900;
00087
00088 dbg_err_if(tm.tm_mon < 0);
00089
00090 *tp = timegm(&tm);
00091
00092 return 0;
00093 err:
00094 return ~0;
00095 }
00096
00109 int u_rfc850_to_tt(const char *str, time_t *tp)
00110 {
00111 enum { BUFSZ = 64 };
00112 char wday[BUFSZ], mon[BUFSZ], tzone[BUFSZ];
00113 unsigned int day, year, hour, min, sec;
00114 struct tm tm;
00115 int i;
00116 char c;
00117
00118 dbg_return_if (str == NULL, ~0);
00119 dbg_return_if (tp == NULL, ~0);
00120 dbg_return_if (strlen(str) >= BUFSZ, ~0);
00121
00122 dbg_err_if((i = sscanf(str, "%[^,], %u%c%[^-]%c%u %u:%u:%u %s", wday,
00123 &day, &c, mon, &c, &year, &hour, &min, &sec, tzone)) != 10);
00124
00125 memset(&tm, 0, sizeof(struct tm));
00126
00127
00128 tm.tm_sec = sec; tm.tm_min = min; tm.tm_hour = hour;
00129
00130
00131 tm.tm_mday = day;
00132 tm.tm_mon = month_idx(mon);
00133 tm.tm_year = year - 1900;
00134
00135 dbg_err_if(tm.tm_mon < 0);
00136
00137 #ifdef HAVE_TMZONE
00138
00139 tm.tm_zone = tzone;
00140 #endif
00141
00142 *tp = timegm(&tm);
00143
00144 return 0;
00145 err:
00146 return ~0;
00147 }
00148
00161 int u_rfc822_to_tt(const char *str, time_t *tp)
00162 {
00163 enum { BUFSZ = 64 };
00164 char wday[BUFSZ], mon[BUFSZ], tzone[BUFSZ];
00165 unsigned int day, year, hour, min, sec;
00166 struct tm tm;
00167
00168 dbg_return_if (str == NULL, ~0);
00169 dbg_return_if (tp == NULL, ~0);
00170 dbg_return_if (strlen(str) >= BUFSZ, ~0);
00171
00172 dbg_err_if(sscanf(str, "%[^,], %u %s %u %u:%u:%u %s", wday,
00173 &day, mon, &year, &hour, &min, &sec, tzone) != 8);
00174
00175 memset(&tm, 0, sizeof(struct tm));
00176
00177
00178 tm.tm_sec = sec; tm.tm_min = min; tm.tm_hour = hour;
00179
00180
00181 tm.tm_mday = day;
00182 tm.tm_mon = month_idx(mon);
00183 tm.tm_year = year - 1900;
00184
00185 dbg_err_if(tm.tm_mon < 0);
00186
00187 #ifdef HAVE_TMZONE
00188
00189 tm.tm_zone = tzone;
00190 #endif
00191
00192 *tp = timegm(&tm);
00193
00194 return 0;
00195 err:
00196 return ~0;
00197 }
00198
00211 int u_httpdate_to_tt(const char *str, time_t *tp)
00212 {
00213 dbg_return_if (str == NULL, ~0);
00214 dbg_return_if (tp == NULL, ~0);
00215 dbg_return_if (strlen(str) < 4, ~0);
00216
00217 if(str[3] == ',')
00218 return u_rfc822_to_tt(str, tp);
00219 else if(str[3] == ' ')
00220 return u_asctime_to_tt(str, tp);
00221
00222 return u_rfc850_to_tt(str, tp);
00223 }
00224
00239 int u_tt_to_rfc822(char dst[RFC822_DATE_BUFSZ], time_t ts)
00240 {
00241 char buf[RFC822_DATE_BUFSZ];
00242 struct tm tm;
00243
00244 dbg_return_if (dst == NULL, ~0);
00245
00246 #ifdef OS_WIN
00247 memcpy(&tm, gmtime(&ts), sizeof(tm));
00248 #else
00249 dbg_err_if(gmtime_r(&ts, &tm) == NULL);
00250 #endif
00251
00252 dbg_err_if(tm.tm_wday > 6 || tm.tm_wday < 0);
00253 dbg_err_if(tm.tm_mon > 11 || tm.tm_mon < 0);
00254
00255 dbg_err_if(u_snprintf(buf, sizeof buf,
00256 "%s, %02u %s %02u %02u:%02u:%02u GMT",
00257 days3[tm.tm_wday],
00258 tm.tm_mday, months[tm.tm_mon], tm.tm_year + 1900,
00259 tm.tm_hour, tm.tm_min, tm.tm_sec));
00260
00261
00262 u_strlcpy(dst, buf, RFC822_DATE_BUFSZ);
00263
00264 return 0;
00265 err:
00266 return ~0;
00267 }
00268