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