00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00053 #include <stdio.h>
00054 #include <string.h>
00055 #include <ctype.h>
00056
00057 #include <pro/rfctime.h>
00058
00059 static char rfc1123_buf[32];
00060 static char *wkdays[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
00061 static char *months[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
00062
00070 static char *skip_spaces(CONST char *str)
00071 {
00072 while (*str == ' ' || *str == '\t')
00073 str++;
00074 return (char *)str;
00075 }
00076
00087 static char *parse_digits(CONST char *str, int *val)
00088 {
00089 *val = 0;
00090 while (isdigit((unsigned char)*str)) {
00091 *val *= 10;
00092 *val += *str++ - '0';
00093 }
00094 return (char *)str;
00095 }
00096
00109 char *TimeParseYear(CONST char *str, int *year)
00110 {
00111 str = parse_digits(str, year);
00112 if (*year < 70) {
00113 *year += 100;
00114 }
00115 else if (*year > 1900) {
00116 *year -= 1900;
00117 }
00118 return (char *)str;
00119 }
00120
00135 char *TimeParseMonth(CONST char *str, int *month)
00136 {
00137 if (*str == 'A') {
00138 if (*++str == 'p' || *str == 'P') {
00139
00140 *month = 3;
00141 }
00142 else {
00143
00144 *month = 7;
00145 }
00146 }
00147 else if (*str == 'D') {
00148
00149 *month = 11;
00150 }
00151 else if (*str == 'F') {
00152
00153 *month = 1;
00154 }
00155 else if (*str == 'J') {
00156 if (*++str == 'a' || *str == 'A') {
00157
00158 *month = 0;
00159 }
00160 else if (*str && (*++str == 'l' || *str == 'L')) {
00161
00162 *month = 6;
00163 }
00164 else {
00165
00166 *month = 5;
00167 }
00168 }
00169 else if (*str == 'M') {
00170 if (*++str == 'a' && (*++str == 'r' || *str == 'R')) {
00171
00172 *month = 2;
00173 }
00174 else {
00175
00176 *month = 4;
00177 }
00178 }
00179 else if (*str == 'N') {
00180
00181 *month = 10;
00182 }
00183 else if (*str == 'O') {
00184
00185 *month = 9;
00186 }
00187 else {
00188
00189 *month = 8;
00190 }
00191 while (isalpha((unsigned char)*str)) {
00192 str++;
00193 }
00194 return (char *)str;
00195 }
00196
00210 char *TimeParseDmy(CONST char *str, int *mday, int *mon, int *year)
00211 {
00212 str = parse_digits(str, mday);
00213 while (*str && !isalpha((unsigned char)*str)) {
00214 str++;
00215 }
00216 str = TimeParseMonth(str, mon);
00217 while (*str && !isdigit((unsigned char)*str)) {
00218 str++;
00219 }
00220 str = TimeParseYear(str, year);
00221
00222 return (char *)str;
00223 }
00224
00237 char *TimeParseHms(CONST char *str, int *hour, int *min, int *sec)
00238 {
00239 str = parse_digits(str, hour);
00240 if (*str == ':') {
00241 str = parse_digits(str + 1, min);
00242 if (*str == ':') {
00243 str = parse_digits(str + 1, sec);
00244 }
00245 else {
00246 *sec = 0;
00247 }
00248 }
00249 else {
00250 *min = 0;
00251 }
00252 return (char *)str;
00253 }
00254
00264 time_t RfcTimeParse(CONST char *str)
00265 {
00266 struct _tm dts = { 0, 0, 0, 1, 0, 0, 0, 0, 0 };
00267
00268
00269 str = skip_spaces(str);
00270
00271
00272 if (isalpha((unsigned char)*str)) {
00273 while (*str && *str != ' ' && *str != '\t')
00274 str++;
00275 str = skip_spaces(str);
00276 }
00277
00278 if (isalpha((unsigned char)*str)) {
00279
00280 str = TimeParseMonth(str, &dts.tm_mon);
00281 str = skip_spaces(str);
00282 str = parse_digits(str, &dts.tm_mday);
00283 str = skip_spaces(str);
00284 str = TimeParseYear(str, &dts.tm_year);
00285 str = skip_spaces(str);
00286 str = TimeParseHms(str, &dts.tm_hour, &dts.tm_min, &dts.tm_sec);
00287 }
00288 else if (*str) {
00289
00290
00291 str = TimeParseDmy(str, &dts.tm_mday, &dts.tm_mon, &dts.tm_year);
00292 str = skip_spaces(str);
00293 str = TimeParseHms(str, &dts.tm_hour, &dts.tm_min, &dts.tm_sec);
00294 }
00295 str = skip_spaces(str);
00296 if (strcmp(str, "GMT") == 0) {
00297 return mktime(&dts);
00298 }
00299 return _mkgmtime(&dts);
00300 }
00301
00309 char *Rfc1123TimeString(struct _tm *tm)
00310 {
00311 sprintf(rfc1123_buf, "%s, %02d %s %04d %02d:%02d:%02d",
00312 wkdays[tm->tm_wday],
00313 tm->tm_mday, months[tm->tm_mon], tm->tm_year + 1900,
00314 tm->tm_hour, tm->tm_min, tm->tm_sec);
00315
00316 return rfc1123_buf;
00317 }