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 const char* days3[] = {
00030 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
00031 };
00032 const char* days[] = {
00033 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
00034 "Saturday", "Sunday"
00035 };
00036 const char* months[] = {
00037 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
00038 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
00039 };
00040
00041 static int month_idx(const char *mon)
00042 {
00043 int i;
00044
00045 dbg_return_if (mon == NULL, -1);
00046
00047 for(i = 0; i < 12; ++i)
00048 if(strcasecmp(months[i], mon) == 0)
00049 return i;
00050
00051 return -1;
00052 }
00053
00066 int u_asctime_to_tt(const char *str, time_t *tp)
00067 {
00068 enum { BUFSZ = 64 };
00069 char wday[BUFSZ], mon[BUFSZ];
00070 unsigned int day, year, hour, min, sec;
00071 struct tm tm;
00072 int i;
00073
00074 dbg_return_if (str == NULL, ~0);
00075 dbg_return_if (tp == NULL, ~0);
00076 dbg_return_if (strlen(str) >= BUFSZ, ~0);
00077
00078 dbg_err_if((i = sscanf(str, "%s %s %u %u:%u:%u %u", wday,
00079 mon, &day, &hour, &min, &sec, &year)) != 7);
00080
00081 memset(&tm, 0, sizeof(struct tm));
00082
00083
00084 tm.tm_sec = sec; tm.tm_min = min; tm.tm_hour = hour;
00085
00086
00087 tm.tm_mday = day;
00088 tm.tm_mon = month_idx(mon);
00089 tm.tm_year = year - 1900;
00090
00091 dbg_err_if(tm.tm_mon < 0);
00092
00093 *tp = timegm(&tm);
00094
00095 return 0;
00096 err:
00097 return ~0;
00098 }
00099
00112 int u_rfc850_to_tt(const char *str, time_t *tp)
00113 {
00114 enum { BUFSZ = 64 };
00115 char wday[BUFSZ], mon[BUFSZ], tzone[BUFSZ];
00116 unsigned int day, year, hour, min, sec;
00117 struct tm tm;
00118 int i;
00119 char c;
00120
00121 dbg_return_if (str == NULL, ~0);
00122 dbg_return_if (tp == NULL, ~0);
00123 dbg_return_if (strlen(str) >= BUFSZ, ~0);
00124
00125 dbg_err_if((i = sscanf(str, "%[^,], %u%c%[^-]%c%u %u:%u:%u %s", wday,
00126 &day, &c, mon, &c, &year, &hour, &min, &sec, tzone)) != 10);
00127
00128 memset(&tm, 0, sizeof(struct tm));
00129
00130
00131 tm.tm_sec = sec; tm.tm_min = min; tm.tm_hour = hour;
00132
00133
00134 tm.tm_mday = day;
00135 tm.tm_mon = month_idx(mon);
00136 tm.tm_year = year - 1900;
00137
00138 dbg_err_if(tm.tm_mon < 0);
00139
00140 #ifdef HAVE_TMZONE
00141
00142 tm.tm_zone = tzone;
00143 #endif
00144
00145 *tp = timegm(&tm);
00146
00147 return 0;
00148 err:
00149 return ~0;
00150 }
00151
00164 int u_rfc822_to_tt(const char *str, time_t *tp)
00165 {
00166 enum { BUFSZ = 64 };
00167 char wday[BUFSZ], mon[BUFSZ], tzone[BUFSZ];
00168 unsigned int day, year, hour, min, sec;
00169 struct tm tm;
00170
00171 dbg_return_if (str == NULL, ~0);
00172 dbg_return_if (tp == NULL, ~0);
00173 dbg_return_if (strlen(str) >= BUFSZ, ~0);
00174
00175 dbg_err_if(sscanf(str, "%[^,], %u %s %u %u:%u:%u %s", wday,
00176 &day, mon, &year, &hour, &min, &sec, tzone) != 8);
00177
00178 memset(&tm, 0, sizeof(struct tm));
00179
00180
00181 tm.tm_sec = sec; tm.tm_min = min; tm.tm_hour = hour;
00182
00183
00184 tm.tm_mday = day;
00185 tm.tm_mon = month_idx(mon);
00186 tm.tm_year = year - 1900;
00187
00188 dbg_err_if(tm.tm_mon < 0);
00189
00190 #ifdef HAVE_TMZONE
00191
00192 tm.tm_zone = tzone;
00193 #endif
00194
00195 *tp = timegm(&tm);
00196
00197 return 0;
00198 err:
00199 return ~0;
00200 }
00201
00214 int u_httpdate_to_tt(const char *str, time_t *tp)
00215 {
00216 dbg_return_if (str == NULL, ~0);
00217 dbg_return_if (tp == NULL, ~0);
00218 dbg_return_if (strlen(str) < 4, ~0);
00219
00220 if(str[3] == ',')
00221 return u_rfc822_to_tt(str, tp);
00222 else if(str[3] == ' ')
00223 return u_asctime_to_tt(str, tp);
00224
00225 return u_rfc850_to_tt(str, tp);
00226 }
00227
00242 int u_tt_to_rfc822(char dst[], time_t ts)
00243 {
00244 enum { RFC822_DATE_BUFSZ = 32 };
00245 char buf[RFC822_DATE_BUFSZ];
00246 struct tm tm;
00247
00248 dbg_return_if (dst == NULL, ~0);
00249
00250 #ifdef OS_WIN
00251 memcpy(&tm, gmtime(&ts), sizeof(tm));
00252 #else
00253 dbg_err_if(gmtime_r(&ts, &tm) == NULL);
00254 #endif
00255
00256 dbg_err_if(tm.tm_wday > 6 || tm.tm_wday < 0);
00257 dbg_err_if(tm.tm_mon > 11 || tm.tm_mon < 0);
00258
00259 dbg_err_if(u_snprintf(buf, RFC822_DATE_BUFSZ,
00260 "%s, %02u %s %02u %02u:%02u:%02u GMT",
00261 days3[tm.tm_wday],
00262 tm.tm_mday, months[tm.tm_mon], tm.tm_year + 1900,
00263 tm.tm_hour, tm.tm_min, tm.tm_sec));
00264
00265
00266 u_sstrncpy(dst, buf, RFC822_DATE_BUFSZ - 1);
00267
00268 return 0;
00269 err:
00270 return ~0;
00271 }
00272