In the course of doing some modifications to util_date.c, I got irked by the
horrible formatting of util_date.c. Somewhere along the line, someone added
tabs to the file. Since I follow the Apache Coding Style Guide (as a good
Apache wannabe developer), I'm a bit put off when trying to read this file.
Therefore, this patch restores the Apache Coding Style to util_date.c. I've
made no changes except for those affecting human readibility.
I also modified test_date.c to work with the new 64-bit apr_time_t semantics
(which is how I know the first patch didn't break anything). That patch
is also included. It is a bit more traumatic than the change for util_date.c,
but I believe it is valid. I abhor the cast to long, but I'm not sure what
the proper mechanism is to give it to the system time calls. I believe
that the three failures from test_date.c are expected failures as these values
lie outside the range of valid dates. Someone please correct me if I am wrong.
HTH,
Justin Erenkrantz
[EMAIL PROTECTED]
P.S. If anyone is interested, I've also added RFC 822 date support to
util_date.c (not included in this patch). My current thought is that RFC 822
support is probably not required in the "official" CVS repository as Apache
would only normally require RFC 2616 date parsing support. Adding RFC 822
support is quite trivial actually - a few lines here and a few lines there.
Nothing major and very useful for what I'm working on...
Index: server/util_date.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/util_date.c,v
retrieving revision 1.18
diff -u -r1.18 util_date.c
--- server/util_date.c 2001/02/16 04:26:47 1.18
+++ server/util_date.c 2001/02/23 06:31:25
@@ -99,43 +99,41 @@
char d;
for (i = 0; i < 256; i++) {
- d = data[i];
- switch (mask[i]) {
- case '\0':
- return (d == '\0');
-
- case '*':
- return 1;
-
- case '@':
- if (!apr_isupper(d))
- return 0;
- break;
- case '$':
- if (!apr_islower(d))
- return 0;
- break;
- case '#':
- if (!apr_isdigit(d))
- return 0;
- break;
- case '&':
- if (!apr_isxdigit(d))
- return 0;
- break;
- case '~':
- if ((d != ' ') && !apr_isdigit(d))
- return 0;
- break;
- default:
- if (mask[i] != d)
- return 0;
- break;
- }
+ d = data[i];
+ switch (mask[i]) {
+ case '\0':
+ return (d == '\0');
+ case '*':
+ return 1;
+ case '@':
+ if (!apr_isupper(d))
+ return 0;
+ break;
+ case '$':
+ if (!apr_islower(d))
+ return 0;
+ break;
+ case '#':
+ if (!apr_isdigit(d))
+ return 0;
+ break;
+ case '&':
+ if (!apr_isxdigit(d))
+ return 0;
+ break;
+ case '~':
+ if ((d != ' ') && !apr_isdigit(d))
+ return 0;
+ break;
+ default:
+ if (mask[i] != d)
+ return 0;
+ break;
+ }
}
- return 0; /* We only get here if mask is corrupted (exceeds 256)
*/
-}
+ return 0; /* We only get here if mask is corrupted (exceeds 256) */
+}
/*
* Parses an HTTP date in one of three standard forms:
@@ -192,99 +190,102 @@
const char *monstr, *timstr;
static const int months[12] =
{
- ('J' << 16) | ('a' << 8) | 'n', ('F' << 16) | ('e' << 8) | 'b',
- ('M' << 16) | ('a' << 8) | 'r', ('A' << 16) | ('p' << 8) | 'r',
- ('M' << 16) | ('a' << 8) | 'y', ('J' << 16) | ('u' << 8) | 'n',
- ('J' << 16) | ('u' << 8) | 'l', ('A' << 16) | ('u' << 8) | 'g',
- ('S' << 16) | ('e' << 8) | 'p', ('O' << 16) | ('c' << 8) | 't',
- ('N' << 16) | ('o' << 8) | 'v', ('D' << 16) | ('e' << 8) | 'c'};
+ ('J' << 16) | ('a' << 8) | 'n', ('F' << 16) | ('e' << 8) | 'b',
+ ('M' << 16) | ('a' << 8) | 'r', ('A' << 16) | ('p' << 8) | 'r',
+ ('M' << 16) | ('a' << 8) | 'y', ('J' << 16) | ('u' << 8) | 'n',
+ ('J' << 16) | ('u' << 8) | 'l', ('A' << 16) | ('u' << 8) | 'g',
+ ('S' << 16) | ('e' << 8) | 'p', ('O' << 16) | ('c' << 8) | 't',
+ ('N' << 16) | ('o' << 8) | 'v', ('D' << 16) | ('e' << 8) | 'c' };
if (!date)
- return BAD_DATE;
+ return BAD_DATE;
- while (*date && apr_isspace(*date)) /* Find first non-whitespace char */
- ++date;
+ while (*date && apr_isspace(*date)) /* Find first non-whitespace char */
+ ++date;
if (*date == '\0')
- return BAD_DATE;
+ return BAD_DATE;
+
+ if ((date = strchr(date, ' ')) == NULL) /* Find space after weekday */
+ return BAD_DATE;
- if ((date = strchr(date, ' ')) == NULL) /* Find space after weekday */
- return BAD_DATE;
+ ++date; /* Now pointing to first char after space, which should be */
- ++date; /* Now pointing to first char after space, which
should be */
/* start of the actual date information for all 3 formats. */
+ if (ap_checkmask(date, "## @$$ #### ##:##:## *")) { /* RFC 1123 format */
+ ds.tm_year = ((date[7] - '0') * 10 + (date[8] - '0') - 19) * 100;
- if (ap_checkmask(date, "## @$$ #### ##:##:## *")) { /* RFC 1123 format */
- ds.tm_year = ((date[7] - '0') * 10 + (date[8] - '0') - 19) * 100;
- if (ds.tm_year < 0)
- return BAD_DATE;
+ if (ds.tm_year < 0)
+ return BAD_DATE;
- ds.tm_year += ((date[9] - '0') * 10) + (date[10] - '0');
+ ds.tm_year += ((date[9] - '0') * 10) + (date[10] - '0');
- ds.tm_mday = ((date[0] - '0') * 10) + (date[1] - '0');
+ ds.tm_mday = ((date[0] - '0') * 10) + (date[1] - '0');
- monstr = date + 3;
- timstr = date + 12;
+ monstr = date + 3;
+ timstr = date + 12;
}
- else if (ap_checkmask(date, "##-@$$-## ##:##:## *")) { /* RFC 850
format */
- ds.tm_year = ((date[7] - '0') * 10) + (date[8] - '0');
- if (ds.tm_year < 70)
- ds.tm_year += 100;
+ else if (ap_checkmask(date, "##-@$$-## ##:##:## *")) { /* RFC 850 format */
+ ds.tm_year = ((date[7] - '0') * 10) + (date[8] - '0');
- ds.tm_mday = ((date[0] - '0') * 10) + (date[1] - '0');
+ if (ds.tm_year < 70)
+ ds.tm_year += 100;
- monstr = date + 3;
- timstr = date + 10;
+ ds.tm_mday = ((date[0] - '0') * 10) + (date[1] - '0');
+
+ monstr = date + 3;
+ timstr = date + 10;
}
- else if (ap_checkmask(date, "@$$ ~# ##:##:## ####*")) { /* asctime format */
- ds.tm_year = ((date[16] - '0') * 10 + (date[17] - '0') - 19) * 100;
- if (ds.tm_year < 0)
- return BAD_DATE;
-
- ds.tm_year += ((date[18] - '0') * 10) + (date[19] - '0');
-
- if (date[4] == ' ')
- ds.tm_mday = 0;
- else
- ds.tm_mday = (date[4] - '0') * 10;
+ else if (ap_checkmask(date, "@$$ ~# ##:##:## ####*")) {/* asctime format */
+ ds.tm_year = ((date[16] - '0') * 10 + (date[17] - '0') - 19) * 100;
+ if (ds.tm_year < 0)
+ return BAD_DATE;
+
+ ds.tm_year += ((date[18] - '0') * 10) + (date[19] - '0');
+
+ if (date[4] == ' ')
+ ds.tm_mday = 0;
+ else
+ ds.tm_mday = (date[4] - '0') * 10;
- ds.tm_mday += (date[5] - '0');
+ ds.tm_mday += (date[5] - '0');
- monstr = date;
- timstr = date + 7;
+ monstr = date;
+ timstr = date + 7;
}
else
- return BAD_DATE;
+ return BAD_DATE;
if (ds.tm_mday <= 0 || ds.tm_mday > 31)
- return BAD_DATE;
+ return BAD_DATE;
ds.tm_hour = ((timstr[0] - '0') * 10) + (timstr[1] - '0');
ds.tm_min = ((timstr[3] - '0') * 10) + (timstr[4] - '0');
ds.tm_sec = ((timstr[6] - '0') * 10) + (timstr[7] - '0');
if ((ds.tm_hour > 23) || (ds.tm_min > 59) || (ds.tm_sec > 61))
- return BAD_DATE;
+ return BAD_DATE;
mint = (monstr[0] << 16) | (monstr[1] << 8) | monstr[2];
for (mon = 0; mon < 12; mon++)
- if (mint == months[mon])
- break;
+ if (mint == months[mon])
+ break;
+
if (mon == 12)
- return BAD_DATE;
+ return BAD_DATE;
if ((ds.tm_mday == 31) && (mon == 3 || mon == 5 || mon == 8 || mon == 10))
- return BAD_DATE;
+ return BAD_DATE;
/* February gets special check for leapyear */
if ((mon == 1) &&
- ((ds.tm_mday > 29)
- || ((ds.tm_mday == 29)
- && ((ds.tm_year & 3)
- || (((ds.tm_year % 100) == 0)
- && (((ds.tm_year % 400) != 100)))))))
- return BAD_DATE;
+ ((ds.tm_mday > 29)
+ || ((ds.tm_mday == 29)
+ && ((ds.tm_year & 3)
+ || (((ds.tm_year % 100) == 0)
+ && (((ds.tm_year % 400) != 100)))))))
+ return BAD_DATE;
ds.tm_mon = mon;
@@ -300,7 +301,7 @@
ds.tm_usec = 0;
ds.tm_gmtoff = 0;
if (apr_implode_time(&result, &ds) != APR_SUCCESS)
- return BAD_DATE;
+ return BAD_DATE;
return result;
}
Index: test/test_date.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/test/test_date.c,v
retrieving revision 1.2
diff -u -r1.2 test_date.c
--- test/test_date.c 2000/10/16 06:05:15 1.2
+++ test/test_date.c 2001/02/23 06:31:25
@@ -14,105 +14,108 @@
#include <stdio.h>
#include <stdlib.h>
+#include <time.h>
#include "util_date.h"
-static const long year2secs[] = {
- 0L, /* 1970 */
- 31536000L, /* 1971 */
- 63072000L, /* 1972 */
- 94694400L, /* 1973 */
- 126230400L, /* 1974 */
- 157766400L, /* 1975 */
- 189302400L, /* 1976 */
- 220924800L, /* 1977 */
- 252460800L, /* 1978 */
- 283996800L, /* 1979 */
- 315532800L, /* 1980 */
- 347155200L, /* 1981 */
- 378691200L, /* 1982 */
- 410227200L, /* 1983 */
- 441763200L, /* 1984 */
- 473385600L, /* 1985 */
- 504921600L, /* 1986 */
- 536457600L, /* 1987 */
- 567993600L, /* 1988 */
- 599616000L, /* 1989 */
- 631152000L, /* 1990 */
- 662688000L, /* 1991 */
- 694224000L, /* 1992 */
- 725846400L, /* 1993 */
- 757382400L, /* 1994 */
- 788918400L, /* 1995 */
- 820454400L, /* 1996 */
- 852076800L, /* 1997 */
- 883612800L, /* 1998 */
- 915148800L, /* 1999 */
- 946684800L, /* 2000 */
- 978307200L, /* 2001 */
- 1009843200L, /* 2002 */
- 1041379200L, /* 2003 */
- 1072915200L, /* 2004 */
- 1104537600L, /* 2005 */
- 1136073600L, /* 2006 */
- 1167609600L, /* 2007 */
- 1199145600L, /* 2008 */
- 1230768000L, /* 2009 */
- 1262304000L, /* 2010 */
- 1293840000L, /* 2011 */
- 1325376000L, /* 2012 */
- 1356998400L, /* 2013 */
- 1388534400L, /* 2014 */
- 1420070400L, /* 2015 */
- 1451606400L, /* 2016 */
- 1483228800L, /* 2017 */
- 1514764800L, /* 2018 */
- 1546300800L, /* 2019 */
- 1577836800L, /* 2020 */
- 1609459200L, /* 2021 */
- 1640995200L, /* 2022 */
- 1672531200L, /* 2023 */
- 1704067200L, /* 2024 */
- 1735689600L, /* 2025 */
- 1767225600L, /* 2026 */
- 1798761600L, /* 2027 */
- 1830297600L, /* 2028 */
- 1861920000L, /* 2029 */
- 1893456000L, /* 2030 */
- 1924992000L, /* 2031 */
- 1956528000L, /* 2032 */
- 1988150400L, /* 2033 */
- 2019686400L, /* 2034 */
- 2051222400L, /* 2035 */
- 2082758400L, /* 2036 */
- 2114380800L, /* 2037 */
- 2145916800L /* 2038 */
+static const apr_time_t year2secs[] = {
+ 0LL, /* 1970 */
+ 31536000LL, /* 1971 */
+ 63072000LL, /* 1972 */
+ 94694400LL, /* 1973 */
+ 126230400LL, /* 1974 */
+ 157766400LL, /* 1975 */
+ 189302400LL, /* 1976 */
+ 220924800LL, /* 1977 */
+ 252460800LL, /* 1978 */
+ 283996800LL, /* 1979 */
+ 315532800LL, /* 1980 */
+ 347155200LL, /* 1981 */
+ 378691200LL, /* 1982 */
+ 410227200LL, /* 1983 */
+ 441763200LL, /* 1984 */
+ 473385600LL, /* 1985 */
+ 504921600LL, /* 1986 */
+ 536457600LL, /* 1987 */
+ 567993600LL, /* 1988 */
+ 599616000LL, /* 1989 */
+ 631152000LL, /* 1990 */
+ 662688000LL, /* 1991 */
+ 694224000LL, /* 1992 */
+ 725846400LL, /* 1993 */
+ 757382400LL, /* 1994 */
+ 788918400LL, /* 1995 */
+ 820454400LL, /* 1996 */
+ 852076800LL, /* 1997 */
+ 883612800LL, /* 1998 */
+ 915148800LL, /* 1999 */
+ 946684800LL, /* 2000 */
+ 978307200LL, /* 2001 */
+ 1009843200LL, /* 2002 */
+ 1041379200LL, /* 2003 */
+ 1072915200LL, /* 2004 */
+ 1104537600LL, /* 2005 */
+ 1136073600LL, /* 2006 */
+ 1167609600LL, /* 2007 */
+ 1199145600LL, /* 2008 */
+ 1230768000LL, /* 2009 */
+ 1262304000LL, /* 2010 */
+ 1293840000LL, /* 2011 */
+ 1325376000LL, /* 2012 */
+ 1356998400LL, /* 2013 */
+ 1388534400LL, /* 2014 */
+ 1420070400LL, /* 2015 */
+ 1451606400LL, /* 2016 */
+ 1483228800LL, /* 2017 */
+ 1514764800LL, /* 2018 */
+ 1546300800LL, /* 2019 */
+ 1577836800LL, /* 2020 */
+ 1609459200LL, /* 2021 */
+ 1640995200LL, /* 2022 */
+ 1672531200LL, /* 2023 */
+ 1704067200LL, /* 2024 */
+ 1735689600LL, /* 2025 */
+ 1767225600LL, /* 2026 */
+ 1798761600LL, /* 2027 */
+ 1830297600LL, /* 2028 */
+ 1861920000LL, /* 2029 */
+ 1893456000LL, /* 2030 */
+ 1924992000LL, /* 2031 */
+ 1956528000LL, /* 2032 */
+ 1988150400LL, /* 2033 */
+ 2019686400LL, /* 2034 */
+ 2051222400LL, /* 2035 */
+ 2082758400LL, /* 2036 */
+ 2114380800LL, /* 2037 */
+ 2145916800LL /* 2038 */
};
const char month_snames[12][4] = {
"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"
};
-void gm_timestr_822(char *ts, time_t sec)
+void gm_timestr_822(char *ts, apr_time_t sec)
{
static const char *const days[7]=
{"Sun","Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
struct tm *tms;
-
- tms = gmtime(&sec);
+ long ls = (long)sec;
+
+ tms = gmtime(&ls);
sprintf(ts, "%s, %.2d %s %d %.2d:%.2d:%.2d GMT", days[tms->tm_wday],
tms->tm_mday, month_snames[tms->tm_mon], tms->tm_year + 1900,
tms->tm_hour, tms->tm_min, tms->tm_sec);
}
-void gm_timestr_850(char *ts, time_t sec)
+void gm_timestr_850(char *ts, apr_time_t sec)
{
static const char *const days[7]=
{"Sunday","Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
struct tm *tms;
int year;
+ long ls = (long)sec;
- tms = gmtime(&sec);
+ tms = gmtime(&ls);
year = tms->tm_year;
if (year >= 100) year -= 100;
@@ -122,13 +125,14 @@
tms->tm_hour, tms->tm_min, tms->tm_sec);
}
-void gm_timestr_ccc(char *ts, time_t sec)
+void gm_timestr_ccc(char *ts, apr_time_t sec)
{
static const char *const days[7]=
{"Sun","Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
struct tm *tms;
+ long ls = (long)sec;
- tms = gmtime(&sec);
+ tms = gmtime(&ls);
sprintf(ts, "%s %s %2d %.2d:%.2d:%.2d %d", days[tms->tm_wday],
month_snames[tms->tm_mon], tms->tm_mday,
@@ -138,25 +142,26 @@
int main (void)
{
int year, i;
- time_t guess;
- time_t offset = 0;
- /* time_t offset = 0; */
- /* time_t offset = ((31 + 28) * 24 * 3600) - 1; */
- time_t secstodate, newsecs;
+ apr_time_t guess;
+ apr_time_t offset = 0;
+ /* apr_time_t offset = 0; */
+ /* apr_time_t offset = ((31 + 28) * 24 * 3600) - 1; */
+ apr_time_t secstodate, newsecs;
char datestr[50];
for (year = 1970; year < 2038; ++year) {
- secstodate = (time_t)year2secs[year - 1970] + offset;
+ secstodate = year2secs[year - 1970] + offset;
gm_timestr_822(datestr, secstodate);
- newsecs = parseHTTPdate(datestr);
+ secstodate *= APR_USEC_PER_SEC;
+ newsecs = ap_parseHTTPdate(datestr);
if (secstodate == newsecs)
- printf("Yes %4d %11ld %s\n", year, (long)secstodate, datestr);
+ printf("Yes %4d %19lld %s\n", year, secstodate, datestr);
else if (newsecs == BAD_DATE)
- printf("No %4d %11ld %11ld %s\n", year, (long)secstodate,
- (long)newsecs, datestr);
+ printf("No %4d %19lld %19lld %s\n", year, secstodate,
+ newsecs, datestr);
else
- printf("No* %4d %11ld %11ld %s\n", year, (long)secstodate,
- (long)newsecs, datestr);
+ printf("No* %4d %19lld %19lld %s\n", year, secstodate,
+ newsecs, datestr);
}
srand48(978245L);
@@ -166,15 +171,14 @@
if (guess < 0) guess *= -1;
secstodate = guess + offset;
gm_timestr_822(datestr, secstodate);
- newsecs = parseHTTPdate(datestr);
+ secstodate *= APR_USEC_PER_SEC;
+ newsecs = ap_parseHTTPdate(datestr);
if (secstodate == newsecs)
- printf("Yes %11ld %s\n", (long)secstodate, datestr);
+ printf("Yes %19lld %s\n", secstodate, datestr);
else if (newsecs == BAD_DATE)
- printf("No %11ld %11ld %s\n", (long)secstodate,
- (long)newsecs, datestr);
+ printf("No %19lld %19lld %s\n", secstodate, newsecs, datestr);
else
- printf("No* %11ld %11ld %s\n", (long)secstodate,
- (long)newsecs, datestr);
+ printf("No* %19lld %19lld %s\n", secstodate, newsecs, datestr);
}
exit(0);
}