You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by je...@apache.org on 2001/05/31 06:54:08 UTC

cvs commit: apr-util/misc .cvsignore Makefile.in apr_date.c

jerenkrantz    01/05/30 21:54:07

  Modified:    include  apr_date.h
               .        Makefile.in configure.in
               misc     apr_date.c
  Added:       misc     .cvsignore Makefile.in
  Log:
  APR-utilize the date functions from httpd-2.0.  Add it to the
  build system, etc.  Reformat the apr_date code to follow the style
  guidelines (old, old patch I submitted).
  
  Add the date parsing functions from mod_mbox (apr_parseRFCdate).
  Yes, this takes a char * not a const char * because it could
  potentially modify the incoming char *.  Ugly, but the only way to
  parse some invalid dates is to tweak the string at a particular
  stage.  If someone has time, they can rewrite the apr_parseRFCdate
  function to be better at this and take in a const char *.
  
  Revision  Changes    Path
  1.2       +37 -9     apr-util/include/apr_date.h
  
  Index: apr_date.h
  ===================================================================
  RCS file: /home/cvs/apr-util/include/apr_date.h,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- apr_date.h	2001/05/31 04:30:29	1.1
  +++ apr_date.h	2001/05/31 04:54:00	1.2
  @@ -56,8 +56,8 @@
    * University of Illinois, Urbana-Champaign.
    */
   
  -#ifndef APACHE_UTIL_DATE_H
  -#define APACHE_UTIL_DATE_H
  +#ifndef APR_DATE_H
  +#define APR_DATE_H
   
   #ifdef __cplusplus
   extern "C" {
  @@ -68,12 +68,13 @@
    */
   
   /*
  - * util_date.h: prototypes for date parsing utility routines
  + * apr_date.h: prototypes for date parsing utility routines
    */
   
  +#include "apu.h"
   #include "apr_time.h"
   
  -#define BAD_DATE (apr_time_t)0
  +#define APR_DATE_BAD (apr_time_t)0
   
   /**
    * Compare a string to a mask
  @@ -89,9 +90,9 @@
    *  <x> - exact match for any other character
    * </PRE>
    * @return 1 if the string matches, 0 otherwise
  - * @deffunc int ap_checkmask(const char *data, const char *mask)
  + * @deffunc int apr_checkmask(const char *data, const char *mask)
    */
  -AP_DECLARE(int) ap_checkmask(const char *data, const char *mask);
  +APU_DECLARE(int) apr_checkmask(const char *data, const char *mask);
   
   /**
    * Parses an HTTP date in one of three standard forms:
  @@ -103,12 +104,39 @@
    * @param date The date in one of the three formats above
    * @return the apr_time_t number of microseconds since 1 Jan 1970 GMT, or
    *         0 if this would be out of range or if the date is invalid.
  - * @deffunc apr_time_t ap_parseHTTPdate(const char *date)
  + * @deffunc apr_time_t apr_parseHTTPdate(const char *date)
    */
  -AP_DECLARE(apr_time_t) ap_parseHTTPdate(const char *date);
  +APU_DECLARE(apr_time_t) apr_parseHTTPdate(const char *date);
   
  +/**
  + * Parses a string resembling an RFC 822 date.  This is meant to be
  + * leinent in its parsing of dates.  Hence, this will parse a wider 
  + * range of dates than apr_parseHTTPdate.
  + *
  + * The prominent mailer (or poster, if mailer is unknown) that has
  + * been seen in the wild is included for the unknown formats.
  + * <PRE>
  + *     Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
  + *     Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
  + *     Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format
  + *     Sun, 6 Nov 1994 08:49:37 GMT   ; RFC 822, updated by RFC 1123
  + *     Sun, 06 Nov 94 08:49:37 GMT    ; RFC 822
  + *     Sun, 6 Nov 94 08:49:37 GMT     ; RFC 822
  + *     Sun, 06 Nov 94 08:49 GMT       ; Unknown [drtr@ast.cam.ac.uk] 
  + *     Sun, 6 Nov 94 08:49 GMT        ; Unknown [drtr@ast.cam.ac.uk]
  + *     Sun, 06 Nov 94 8:49:37 GMT     ; Unknown [Elm 70.85]
  + *     Sun, 6 Nov 94 8:49:37 GMT      ; Unknown [Elm 70.85] 
  + * </PRE>
  + *
  + * @param date The date in one of the formats above
  + * @return the apr_time_t number of microseconds since 1 Jan 1970 GMT, or
  + *         0 if this would be out of range or if the date is invalid.
  + * @deffunc apr_time_t apr_parseRFCdate(char *date)
  + */
  +APU_DECLARE(apr_time_t) apr_parseRFCdate(char *date);
  +
   #ifdef __cplusplus
   }
   #endif
   
  -#endif	/* !APACHE_UTIL_DATE_H */
  +#endif	/* !APR_DATE_H */
  
  
  
  1.36      +1 -1      apr-util/Makefile.in
  
  Index: Makefile.in
  ===================================================================
  RCS file: /home/cvs/apr-util/Makefile.in,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- Makefile.in	2001/05/20 07:53:48	1.35
  +++ Makefile.in	2001/05/31 04:54:02	1.36
  @@ -10,7 +10,7 @@
   # bring in rules.mk for standard functionality
   @INCLUDE_RULES@
   
  -SUBDIRS = buckets crypto dbm encoding hooks uri xml
  +SUBDIRS = buckets crypto dbm encoding hooks uri xml misc
   CLEAN_SUBDIRS = . test build
   
   CLEAN_TARGETS = $(TARGET_EXPORTS)
  
  
  
  1.24      +1 -0      apr-util/configure.in
  
  Index: configure.in
  ===================================================================
  RCS file: /home/cvs/apr-util/configure.in,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- configure.in	2001/05/12 03:44:17	1.23
  +++ configure.in	2001/05/31 04:54:03	1.24
  @@ -145,5 +145,6 @@
   	hooks/Makefile
   	uri/Makefile
   	xml/Makefile
  +	misc/Makefile
   	$test_Makefile
   	])
  
  
  
  1.2       +354 -99   apr-util/misc/apr_date.c
  
  Index: apr_date.c
  ===================================================================
  RCS file: /home/cvs/apr-util/misc/apr_date.c,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- apr_date.c	2001/05/31 04:30:36	1.1
  +++ apr_date.c	2001/05/31 04:54:06	1.2
  @@ -57,7 +57,7 @@
    */
   
   /*
  - * util_date.c: date parsing utility routines
  + * apr_date.c: date parsing utility routines
    *     These routines are (hopefully) platform independent.
    * 
    * 27 Oct 1996  Roy Fielding
  @@ -77,11 +77,8 @@
   #include <ctype.h>
   #endif
   
  -#define CORE_PRIVATE
  +#include "apr_date.h"
   
  -#include "ap_config.h"
  -#include "util_date.h"
  -
   /*
    * Compare a string to a mask
    * Mask characters (arbitrary maximum is 256 characters, just in case):
  @@ -93,50 +90,49 @@
    *   * - swallow remaining characters 
    *  <x> - exact match for any other character
    */
  -AP_DECLARE(int) ap_checkmask(const char *data, const char *mask)
  +APU_DECLARE(int) apr_checkmask(const char *data, const char *mask)
   {
       int i;
       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:
    *
  @@ -184,7 +180,7 @@
    * but many changes since then.
    *
    */
  -AP_DECLARE(apr_time_t) ap_parseHTTPdate(const char *date)
  +APU_DECLARE(apr_time_t) apr_parseHTTPdate(const char *date)
   {
       apr_exploded_time_t ds;
       apr_time_t result;
  @@ -192,99 +188,114 @@
       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 APR_DATE_BAD;
   
  -    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 APR_DATE_BAD;
   
  -    if ((date = strchr(date, ' ')) == NULL)	/* Find space after weekday */
  -	return BAD_DATE;
  +    if ((date = strchr(date, ' ')) == NULL)       /* Find space after weekday */
  +        return APR_DATE_BAD;
   
  -    ++date;			/* Now pointing to first char after space, which should be */
  -    /* start of the actual date information for all 3 formats. */
  +    ++date;        /* Now pointing to first char after space, which should be */
   
  -    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;
  +    /* start of the actual date information for all 4 formats. */
   
  -	ds.tm_year += ((date[9] - '0') * 10) + (date[10] - '0');
  +    if (apr_checkmask(date, "## @$$ #### ##:##:## *")) {
  +        /* RFC 1123 format with two days */
  +        ds.tm_year = ((date[7] - '0') * 10 + (date[8] - '0') - 19) * 100;
  +        if (ds.tm_year < 0)
  +            return APR_DATE_BAD;
   
  -	ds.tm_mday = ((date[0] - '0') * 10) + (date[1] - '0');
  +        ds.tm_year += ((date[9] - '0') * 10) + (date[10] - '0');
   
  -	monstr = date + 3;
  -	timstr = date + 12;
  +        ds.tm_mday = ((date[0] - '0') * 10) + (date[1] - '0');
  +
  +        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 (apr_checkmask(date, "##-@$$-## ##:##:## *")) { /* RFC 850 format */
  +        ds.tm_year = ((date[7] - '0') * 10) + (date[8] - '0');
  +        if (ds.tm_year < 70)
  +            ds.tm_year += 100;
   
  -	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 + 10;
  +        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;
  +    else if (apr_checkmask(date, "@$$ ~# ##:##:## ####*")) {/* asctime format */
  +        ds.tm_year = ((date[16] - '0') * 10 + (date[17] - '0') - 19) * 100;
  +        if (ds.tm_year < 0) 
  +            return APR_DATE_BAD;
  +
  +        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_year += ((date[18] - '0') * 10) + (date[19] - '0');
  +        ds.tm_mday += (date[5] - '0');
   
  -	if (date[4] == ' ')
  -	    ds.tm_mday = 0;
  -	else
  -	    ds.tm_mday = (date[4] - '0') * 10;
  +        monstr = date;
  +        timstr = date + 7;
  +    }
  +    else if (apr_checkmask(date, "# @$$ #### ##:##:## *")) {
  +        /* RFC 1123 format with one day */
  +        ds.tm_year = ((date[6] - '0') * 10 + (date[7] - '0') - 19) * 100;
  +        if (ds.tm_year < 0)
  +            return APR_DATE_BAD;
   
  -	ds.tm_mday += (date[5] - '0');
  +        ds.tm_year += ((date[8] - '0') * 10) + (date[9] - '0');
   
  -	monstr = date;
  -	timstr = date + 7;
  +        ds.tm_mday = (date[0] - '0');
  +
  +        monstr = date + 2;
  +        timstr = date + 11;
       }
  -    else 
  -	return BAD_DATE;
  +    else
  +        return APR_DATE_BAD;
   
       if (ds.tm_mday <= 0 || ds.tm_mday > 31)
  -	return BAD_DATE;
  +        return APR_DATE_BAD;
   
       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 APR_DATE_BAD;
   
       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 APR_DATE_BAD;
   
       if ((ds.tm_mday == 31) && (mon == 3 || mon == 5 || mon == 8 || mon == 10))
  -	return BAD_DATE;
  +        return APR_DATE_BAD;
   
       /* 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 APR_DATE_BAD;
   
       ds.tm_mon = mon;
   
  @@ -299,8 +310,252 @@
        */
       ds.tm_usec = 0;
       ds.tm_gmtoff = 0;
  +    if (apr_implode_time(&result, &ds) != APR_SUCCESS) 
  +        return APR_DATE_BAD;
  +    
  +    return result;
  +}
  +
  +/*
  + * Parses a string resembling an RFC 822 date.  This is meant to be
  + * leinent in its parsing of dates.  Hence, this will parse a wider 
  + * range of dates than apr_parseHTTPdate.
  + *
  + * The prominent mailer (or poster, if mailer is unknown) that has
  + * been seen in the wild is included for the unknown formats.
  + *
  + *     Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
  + *     Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
  + *     Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format
  + *     Sun, 6 Nov 1994 08:49:37 GMT   ; RFC 822, updated by RFC 1123
  + *     Sun, 06 Nov 94 08:49:37 GMT    ; RFC 822
  + *     Sun, 6 Nov 94 08:49:37 GMT     ; RFC 822
  + *     Sun, 06 Nov 94 08:49 GMT       ; Unknown [drtr@ast.cam.ac.uk] 
  + *     Sun, 6 Nov 94 08:49 GMT        ; Unknown [drtr@ast.cam.ac.uk]
  + *     Sun, 06 Nov 94 8:49:37 GMT     ; Unknown [Elm 70.85]
  + *     Sun, 6 Nov 94 8:49:37 GMT      ; Unknown [Elm 70.85] 
  + *
  + */
  +APU_DECLARE(apr_time_t) apr_parseRFCdate(char *date)
  +{
  +    apr_exploded_time_t ds;
  +    apr_time_t result;
  +    int mint, mon;
  +    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' };
  +
  +    if (!date)
  +        return APR_DATE_BAD;
  +
  +    /* Not all dates have text months at the beginning. */
  +    if (!apr_isdigit(date[0]))
  +    {
  +        while (*date && apr_isspace(*date)) /* Find first non-whitespace char */
  +            ++date;
  +
  +        if (*date == '\0') 
  +            return APR_DATE_BAD;
  +
  +        if ((date = strchr(date, ' ')) == NULL)   /* Find space after weekday */
  +            return APR_DATE_BAD;
  +
  +        ++date;    /* Now pointing to first char after space, which should be */    }
  +
  +    /* start of the actual date information for all 11 formats. */
  +    if (apr_checkmask(date, "## @$$ #### ##:##:## *")) {   /* RFC 1123 format */
  +        ds.tm_year = ((date[7] - '0') * 10 + (date[8] - '0') - 19) * 100;
  +
  +        if (ds.tm_year < 0)
  +            return APR_DATE_BAD;
  +
  +        ds.tm_year += ((date[9] - '0') * 10) + (date[10] - '0');
  +
  +        ds.tm_mday = ((date[0] - '0') * 10) + (date[1] - '0');
  +
  +        monstr = date + 3;
  +        timstr = date + 12;
  +    }
  +    else if (apr_checkmask(date, "##-@$$-## ##:##:## *")) {/* RFC 850 format  */
  +        ds.tm_year = ((date[7] - '0') * 10) + (date[8] - '0');
  +
  +        if (ds.tm_year < 70)
  +            ds.tm_year += 100;
  +
  +        ds.tm_mday = ((date[0] - '0') * 10) + (date[1] - '0');
  +
  +        monstr = date + 3;
  +        timstr = date + 10;
  +    }
  +    else if (apr_checkmask(date, "@$$ ~# ##:##:## ####*")) {/* asctime format */
  +        ds.tm_year = ((date[16] - '0') * 10 + (date[17] - '0') - 19) * 100;
  +        if (ds.tm_year < 0) 
  +            return APR_DATE_BAD;
  +
  +        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');
  +
  +        monstr = date;
  +        timstr = date + 7;
  +    }
  +    else if (apr_checkmask(date, "# @$$ #### ##:##:## *")) {/* RFC 1123 format*/
  +        ds.tm_year = ((date[6] - '0') * 10 + (date[7] - '0') - 19) * 100;
  +
  +        if (ds.tm_year < 0)
  +            return APR_DATE_BAD;
  +
  +        ds.tm_year += ((date[8] - '0') * 10) + (date[9] - '0');
  +        ds.tm_mday = (date[0] - '0');
  +
  +        monstr = date + 2;
  +        timstr = date + 11;
  +    }
  +    else if (apr_checkmask(date, "## @$$ ## ##:##:## *")) {/* RFC 1123 format */
  +        /* This is the old RFC date format - many many years ago, people
  +         * used two-digit years.  Oh, how foolish.  */
  +        ds.tm_year = ((date[7] - '0') * 10) + (date[8] - '0');
  +
  +        if (ds.tm_year < 70)
  +            ds.tm_year += 100;
  +
  +        ds.tm_mday = ((date[0] - '0') * 10) + (date[1] - '0');
  +
  +        monstr = date + 3;
  +        timstr = date + 10;
  +
  +    } 
  +    else if (apr_checkmask(date, "# @$$ ## ##:##:## *")) {/* RFC 1123 format */
  +        /* This is the old RFC date format - many many years ago, people
  +         * used two-digit years.  Oh, how foolish.  */
  +        ds.tm_year = ((date[6] - '0') * 10) + (date[7] - '0');
  +
  +        if (ds.tm_year < 70)
  +            ds.tm_year += 100;
  +
  +        ds.tm_mday = (date[0] - '0');
  +
  +        monstr = date + 2;
  +        timstr = date + 9;
  +
  +    } 
  +    else if (apr_checkmask(date, "## @$$ ## ##:## *")) {      /* Loser format */
  +        /* This is quite bogus.  */
  +        ds.tm_year = ((date[7] - '0') * 10) + (date[8] - '0');
  +
  +        if (ds.tm_year < 70)
  +            ds.tm_year += 100;
  +
  +        ds.tm_mday = ((date[0] - '0') * 10) + (date[1] - '0');
  +
  +        monstr = date + 3;
  +        timstr = date + 10;
  +        timstr[6] = '0';
  +        timstr[7] = '0';
  +    } 
  +    else if (apr_checkmask(date, "# @$$ ## ##:## *")) {       /* Loser format */
  +        /* This is quite bogus.  */
  +        ds.tm_year = ((date[6] - '0') * 10) + (date[7] - '0');
  +
  +        if (ds.tm_year < 70)
  +            ds.tm_year += 100;
  +
  +        ds.tm_mday = (date[0] - '0');
  +
  +        monstr = date + 2;
  +        timstr = date + 9;
  +
  +        timstr[6] = '0';
  +        timstr[7] = '0';
  +    }
  +    else if (apr_checkmask(date, "## @$$ ## #:##:## *")) {    /* Loser format */
  +        /* This is quite bogus.  */
  +        ds.tm_year = ((date[7] - '0') * 10) + (date[8] - '0');
  +
  +        if (ds.tm_year < 70)
  +            ds.tm_year += 100;
  +
  +        ds.tm_mday = ((date[0] - '0') * 10) + (date[1] - '0');
  +
  +        monstr = date + 3;
  +        timstr = date + 9;
  +
  +        timstr[0] = '0';
  +    }
  +    else if (apr_checkmask(date, "# @$$ ## #:##:## *")) {     /* Loser format */
  +        /* This is quite bogus.  */
  +        ds.tm_year = ((date[6] - '0') * 10) + (date[7] - '0');
  +
  +        if (ds.tm_year < 70)
  +            ds.tm_year += 100;
  +
  +        ds.tm_mday = (date[0] - '0');
  +
  +        monstr = date + 2;
  +        timstr = date + 8;
  +
  +        timstr[0] = '0';
  +    }
  +    else
  +        return APR_DATE_BAD;
  +
  +    if (ds.tm_mday <= 0 || ds.tm_mday > 31)
  +        return APR_DATE_BAD;
  +
  +    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 APR_DATE_BAD;
  +
  +    mint = (monstr[0] << 16) | (monstr[1] << 8) | monstr[2];
  +    for (mon = 0; mon < 12; mon++)
  +        if (mint == months[mon])
  +            break;
  +
  +    if (mon == 12)
  +        return APR_DATE_BAD;
  +
  +    if ((ds.tm_mday == 31) && (mon == 3 || mon == 5 || mon == 8 || mon == 10))
  +        return APR_DATE_BAD;
  +
  +    /* 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 APR_DATE_BAD;
  +
  +    ds.tm_mon = mon;
  +
  +    /* apr_mplode_time uses tm_usec and tm_gmtoff fields, but they haven't 
  +     * been set yet. 
  +     * It should be safe to just zero out these values.
  +     * tm_usec is the number of microseconds into the second.  HTTP only
  +     * cares about second granularity.
  +     * tm_gmtoff is the number of seconds off of GMT the time is.  By
  +     * definition all times going through this function are in GMT, so this
  +     * is zero. 
  +     */
  +    ds.tm_usec = 0;
  +    ds.tm_gmtoff = 0;
       if (apr_implode_time(&result, &ds) != APR_SUCCESS) 
  -	return BAD_DATE;
  +        return APR_DATE_BAD;
       
       return result;
   }
  
  
  
  1.1                  apr-util/misc/.cvsignore
  
  Index: .cvsignore
  ===================================================================
  Makefile
  *.lo
  *.la
  .libs
  
  
  
  1.1                  apr-util/misc/Makefile.in
  
  Index: Makefile.in
  ===================================================================
  TARGETS = apr_date.lo
  CLEAN_TARGETS = 
  
  # bring in rules.mk for standard functionality
  @INCLUDE_RULES@