Index: mailbox/mbx_imap.c =================================================================== RCS file: /cvsroot/mailutils//mailutils/mailbox/mbx_imap.c,v retrieving revision 1.29 diff -u -r1.29 mbx_imap.c --- mailbox/mbx_imap.c 2001/06/01 05:59:29 1.29 +++ mailbox/mbx_imap.c 2001/06/15 03:29:53 @@ -1230,6 +1230,58 @@ return status; } +int +imap_parse_date_time (const char **p, struct tm *tm) +{ + int year, mon, day, hour, min, sec; + char zone[6] = "+0000"; /* ( "+" / "-" ) hhmm */ + char month[5] = ""; + int hh = 0; + int mm = 0; + int sign = 1; + int scanned = 0; + int i; + + day = mon = year = hour = min = sec = 0; + + memset (tm, 0, sizeof (*tm)); + + if (sscanf (*p, + "%2d-%3s-%4d %2d:%2d:%2d %5s%n", + &day, month, &year, &hour, &min, &sec, zone, &scanned) != 7) + { + return -1; + } + + tm->tm_sec = sec; + tm->tm_min = min; + tm->tm_hour = hour; + tm->tm_mday = day; + + for (i = 0; i < 12; i++) + { + if (strncasecmp (month, MONTHS[i], 3) == 0) + { + mon = i; + break; + } + } + tm->tm_mon = mon; + tm->tm_year = (year > 1900) ? year - 1900 : year; + tm->tm_yday = 0; /* unknown. */ + tm->tm_wday = 0; /* unknown. */ + tm->tm_isdst = -1; /* unknown. */ + + hh = (zone[1] - '0') * 10 + (zone[2] - '0'); + mm = (zone[3] - '0') * 10 + (zone[4] - '0'); + sign = (zone[0] == '-') ? -1 : +1; + + tm->tm_gmtoff = sign * (hh * 60 * 60 + mm * 60); + + *p += scanned; + + return 0; +} static int imap_envelope_date (envelope_t envelope, char *buffer, size_t buflen, size_t *plen) @@ -1238,12 +1290,12 @@ msg_imap_t msg_imap = message_get_owner (msg); m_imap_t m_imap = msg_imap->m_imap; f_imap_t f_imap = m_imap->f_imap; - int year, mon, day, hour, min, sec; - int offt; - int i; struct tm tm; time_t now; - char month[5]; + char datebuf[] = "mm-dd-yyyy hh:mm:ss +0000"; + const char* date = datebuf; + const char** datep = &date; + /* reserve as much space as we need for internal-date */ int status; if (f_imap->state == IMAP_NO_STATE) { @@ -1258,47 +1310,47 @@ MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer); f_imap->state = IMAP_FETCH; } - status = message_operation (f_imap, msg_imap, buffer, buflen, plen); + status = message_operation (f_imap, msg_imap, datebuf, sizeof(datebuf), NULL); if (status != 0) return status; - day = mon = year = hour = min = sec = offt = 0; - month[0] = '\0'; - sscanf (buffer, "%2d-%3s-%4d %2d:%2d:%2d %d", &day, month, &year, - &hour, &min, &sec, &offt); - tm.tm_sec = sec; - tm.tm_min = min; - tm.tm_hour = hour; - tm.tm_mday = day; - for (i = 0; i < 12; i++) - { - if (strncasecmp(month, MONTHS[i], 3) == 0) - { - mon = i; - break; - } - } - tm.tm_mon = mon; - tm.tm_year = (year > 1900) ? year - 1900 : year; - tm.tm_yday = 0; /* unknown. */ - tm.tm_wday = 0; /* unknown. */ - tm.tm_isdst = -1; /* unknown. */ - /* What to do the timezone? */ - now = mktime (&tm); - if (now == (time_t)-1) - { - size_t len; - /* Fall back to localtime. */ - now = time (NULL); - snprintf (buffer, buflen, "%s", ctime(&now)); - len = strlen (buffer); - if (len && buffer[len - 1] == '\n') - buffer[len - 1] = '\0'; - } + if(imap_parse_date_time(datep, &tm) != 0) + now = (time_t)-1; else + now = mktime (&tm); + + /* if the time was unparseable, or mktime() didn't like what we + parsed, use the calendar time. */ + if (now == (time_t)-1) { - strftime (buffer, buflen, " %a %b %d %H:%M:%S %Y", &tm); + struct tm* gmt; + + time(&now); + + gmt = gmtime(&now); + + tm = *gmt; } + + { + int len = strftime (buffer, buflen, " %a %b %d %H:%M:%S %Y", &tm); + + /* FIXME: I don't know what strftime does if the buflen is too + short, or it fails. Assuming that it won't fail, this is my guess + as to the right thing. + + I think if the buffer is too short, it will fill it as much + as it can, and nul terminate it. But I'll terminate it anyhow. + */ + if(len == 0) + { + len = buflen - 1; + buffer[len] = 0; + } + + if(plen) + *plen = len; + } return 0; } Index: imap4d/imap4d.h =================================================================== RCS file: /cvsroot/mailutils//mailutils/imap4d/imap4d.h,v retrieving revision 1.19 diff -u -r1.19 imap4d.h --- imap4d/imap4d.h 2001/06/01 19:52:05 1.19 +++ imap4d/imap4d.h 2001/06/15 03:29:54 @@ -68,6 +68,8 @@ # include #endif +#include + #include #include #include @@ -76,6 +78,7 @@ #include #include #include +#include #include #ifndef _PATH_MAILDIR Index: imap4d/search.c =================================================================== RCS file: /cvsroot/mailutils//mailutils/imap4d/search.c,v retrieving revision 1.8 diff -u -r1.8 search.c --- imap4d/search.c 2001/06/01 19:53:37 1.8 +++ imap4d/search.c 2001/06/15 03:29:56 @@ -797,7 +797,7 @@ message_get_envelope (pb->msg, &env); envelope_date (env, buffer, sizeof (buffer), NULL); - util_parse_rfc822_date (buffer, &mesg_time); + util_parse_ctime_date (buffer, &mesg_time); _search_push (pb, mesg_time < t); } @@ -882,7 +882,7 @@ message_get_envelope (pb->msg, &env); envelope_date (env, buffer, sizeof (buffer), NULL); - util_parse_rfc822_date (buffer, &mesg_time); + util_parse_ctime_date (buffer, &mesg_time); _search_push (pb, t <= mesg_time && mesg_time <= t + 86400); } @@ -927,7 +927,7 @@ message_get_envelope (pb->msg, &env); envelope_date (env, buffer, sizeof (buffer), NULL); - util_parse_rfc822_date (buffer, &mesg_time); + util_parse_ctime_date (buffer, &mesg_time); _search_push (pb, mesg_time >= t); } Index: imap4d/util.c =================================================================== RCS file: /cvsroot/mailutils//mailutils/imap4d/util.c,v retrieving revision 1.22 diff -u -r1.22 util.c --- imap4d/util.c 2001/06/12 00:40:58 1.22 +++ imap4d/util.c 2001/06/15 03:29:57 @@ -16,7 +16,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "imap4d.h" -#include static int add2set __P ((size_t **, int *, unsigned long)); static const char *sc2string __P ((int)); @@ -199,7 +198,7 @@ /* Copy stuff */ s = p + 2; p = q; - while (*q++ = *s++) + while ((*q++ = *s++)) ; continue; } @@ -672,90 +671,23 @@ return 0; } -static const char *months[] = -{ - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; - -#define c2d(c) (c-'0') - int util_parse_internal_date0 (char *date, time_t *timep, char **endp) { struct tm tm; - char *save; - int n, i; - int year, day, hour, min, sec; - char mon[4]; - char sign[2]; - char tzs[6]; + const char** datep = &date; time_t time; - int off; - - memset (&tm, 0, sizeof (tm)); - n = sscanf (date, "%2d-%3s-%4d %2d:%2d:%2d %5s%n\n", - &day, mon, &year, - &hour, &min, &sec, &tzs, &off); - - switch (n) - { - case 3: - case 6: - if (endp) - return 1; - /*FALLTHRU*/ - case 7: - break; - default: - return 1; - } - tm.tm_mday = day; - for (i = 0; i < 11; i++) - if (strncmp (months[i], mon, 3) == 0) - break; - if (i == 12) + if(imap_parse_date_time(datep, &tm)) return 1; - tm.tm_mon = i; - tm.tm_year = (year < 1900) ? year : year - 1900; - if (n >= 6) - { - tm.tm_hour = hour; - tm.tm_min = min; - tm.tm_sec = sec; - } - - tm.tm_isdst = -1; /* unknown. */ - time = mktime (&tm); if (time == (time_t) -1) return 2; - if (n == 7) - { - int sign; - int tz; - - if (strlen (tzs) != 5) - return 3; - - for (i = 1; i <= 4; i++) - if (!isdigit (tzs[i])) - return 3; - - tz = (c2d (tzs[1])*10 + c2d (tzs[2]))*60 + - c2d (tzs[3])*10 + c2d (tzs[4]); - if (tzs[0] == '-') - tz = -tz; - else if (tzs[0] != '+') - return 4; - time -= tz*60; - } *timep = time; if (endp) - *endp = date + off; + *endp = *datep; return 0; } @@ -765,79 +697,29 @@ return util_parse_internal_date0 (date, timep, NULL); } - int util_parse_header_date (char *date, time_t *timep) { struct tm tm; - char *save; - int n, i; - int year, day, hour, min, sec; - char wday[5]; - char mon[4]; - char sign[2]; - char tzs[6]; + const char* datep = date; time_t time; memset (&tm, 0, sizeof (tm)); - n = sscanf (date, "%3s, %2d %3s %4d %2d:%2d:%2d %5s", - wday, &day, mon, &year, - &hour, &min, &sec, &tzs); - if (n < 7) - return 1; - - tm.tm_mday = day; - for (i = 0; i < 11; i++) - if (strncmp (months[i], mon, 3) == 0) - break; - if (i == 12) + if(parse822_date_time(&datep, datep + strlen(date), &tm)) return 1; - tm.tm_mon = i; - tm.tm_year = (year < 1900) ? year : year - 1900; - if (n >= 6) - { - tm.tm_hour = hour; - tm.tm_min = min; - tm.tm_sec = sec; - } - - tm.tm_isdst = -1; /* unknown. */ - time = mktime (&tm); + if (time == (time_t) -1) return 2; - /*FIXME: mktime corrects for the timezone. We should fix up the - correction here */ - - if (n == 8) - { - int sign; - int tz; - - if (strlen (tzs) != 5) - return 3; - - for (i = 1; i <= 4; i++) - if (!isdigit (tzs[i])) - return 3; - - tz = (c2d (tzs[1])*10 + c2d (tzs[2]))*60 + - c2d (tzs[3])*10 + c2d (tzs[4]); - if (tzs[0] == '-') - tz = -tz; - else if (tzs[0] != '+') - return 4; - time -= tz*60; - } *timep = time; return 0; } int -util_parse_rfc822_date (char *date, time_t *timep) +util_parse_ctime_date (char *date, time_t *timep) { int year, mon, day, hour, min, sec; int offt; @@ -845,12 +727,15 @@ struct tm tm; char month[5]; char wday[5]; + time_t time; + memset (&tm, 0, sizeof (tm)); + month[0] = '\0'; wday[0] = '\0'; day = mon = year = hour = min = sec = offt = 0; - /* RFC822 Date: format. */ + /* ctime() date format. */ if (sscanf (date, "%3s %3s %2d %2d:%2d:%2d %d\n", wday, month, &day, &hour, &min, &sec, &year) != 7) return 1; @@ -871,8 +756,14 @@ tm.tm_yday = 0; /* unknown. */ tm.tm_wday = 0; /* unknown. */ tm.tm_isdst = -1; /* unknown. */ - /* What to do the timezone? */ - *timep = mktime (&tm); + + time = mktime (&tm); + + if (time == (time_t) -1) + return 1; + + *timep = time; + return 0; } @@ -916,12 +807,12 @@ char *name; int flag; } _imap4d_attrlist[] = { - "\\Answered", MU_ATTRIBUTE_ANSWERED, - "\\Flagged", MU_ATTRIBUTE_FLAGGED, - "\\Deleted", MU_ATTRIBUTE_DELETED, - "\\Draft", MU_ATTRIBUTE_DRAFT, - "\\Seen", MU_ATTRIBUTE_SEEN, - "\\Recent", MU_ATTRIBUTE_RECENT, + { "\\Answered", MU_ATTRIBUTE_ANSWERED }, + { "\\Flagged", MU_ATTRIBUTE_FLAGGED }, + { "\\Deleted", MU_ATTRIBUTE_DELETED }, + { "\\Draft", MU_ATTRIBUTE_DRAFT }, + { "\\Seen", MU_ATTRIBUTE_SEEN }, + { "\\Recent", MU_ATTRIBUTE_RECENT }, }; #define NATTR sizeof(_imap4d_attrlist)/sizeof(_imap4d_attrlist[0])