Paul J Stevens wrote:
Simon,
These both look like a valid bugs. Please file a report for both on
the bugtracker and send us your patch for the missing timezone.
String output handling in the imap code is a known issue. I'm working
on a massive cleanup of that code. Could you please send me the actual
IMAP command send by snappermail so I can add that one to my test-suite?
I've created some code to fix the timezone issue. Basically it's a
cleanup of the date_sql2imap() function. I've taken out all the magic,
put a call to strptime() and strftime() in there, and all seems to be
well. :)
It's simpler and returns the datetime + timezone:
example (cut & paste from telnet imap session):
a fetch 1 (INTERNALDATE)
* 1 FETCH (INTERNALDATE "25-Aug-2004 17:08:06 +0100")
a OK FETCH completed
a fetch 2 (INTERNALDATE)
* 2 FETCH (INTERNALDATE "30-Aug-2004 13:44:08 +0100")
a OK FETCH completed
I'm at GMT+1 here, hence the +0100.
I haven't committed the code yet, can people test it? Patch is attached.
Cheers,
Ilja
--
Ilja Booij
IC&S B.V.
Stadhouderslaan 57
3583 JD Utrecht
www.ic-s.nl
T algemeen: 030 6355730
T direct: 030 6355739
F: 030 6355731
E: [EMAIL PROTECTED]
Index: dbmailtypes.h
===================================================================
RCS file: /cvsroot-dbmail/dbmail/dbmailtypes.h,v
retrieving revision 1.20
diff -r1.20 dbmailtypes.h
154a155,159
> /* length of database date string
> YYYY-MM-DD HH:MM:SS
> 1234567890123456789 */
> #define SQL_INTERNALDATE_LEN 19
>
Index: imaputil.c
===================================================================
RCS file: /cvsroot-dbmail/dbmail/imaputil.c,v
retrieving revision 1.74
diff -r1.74 imaputil.c
35a36
> #include <time.h>
68c69,70
< char _imapdate[IMAP_INTERNALDATE_LEN] = "03-Nov-1979 00:00:00";
---
> #define IMAP_STANDARD_DATE "03-Nov-1979 00:00:00 +0000"
> char _imapdate[IMAP_INTERNALDATE_LEN] = IMAP_STANDARD_DATE;
71c73,75
< char _sqldate[] = "1979-11-03 00:00:00";
---
> #define SQL_STANDARD_DATE "1979-11-03 00:00:00"
> char _sqldate[SQL_INTERNALDATE_LEN + 1] = SQL_STANDARD_DATE;
>
199c203
<
---
>
1822,1823c1826
< * NOTE: sqldate is not tested for validity. Behaviour is undefined for
non-sql
< * dates.
---
> * NOTE: if date is not valid, IMAP_STANDARD_DATE is returned
1827,1830c1830,1842
< int mon;
<
< if (strlen(sqldate) != strlen("yyyy-mm-dd hh:mm:ss")) {
< strcpy(_imapdate, "03-Nov-1979 00:00:00");
---
> char *last_char;
> struct tm tm_localtime, tm_sqldate;
> time_t td;
>
> /* we need to get the localtime to get the current timezone */
> tm_localtime = *localtime(&td);
>
> /* parse sqldate */
> last_char = strptime(sqldate, "%Y-%m-%d %T", &tm_sqldate);
> if (*last_char != '\0') {
> trace(TRACE_DEBUG, "%s,%s, error parsing date [%s]",
> __FILE__, __func__, sqldate);
> strcpy(_imapdate, IMAP_STANDARD_DATE);
1833,1855c1845,1847
<
< /* copy day */
< _imapdate[0] = sqldate[8];
< _imapdate[1] = sqldate[9];
<
< /* find out which month */
< mon = strtoul(&sqldate[5], NULL, 10) - 1;
< if (mon < 0 || mon > 11)
< mon = 0;
<
< /* copy month */
< _imapdate[3] = month_desc[mon][0];
< _imapdate[4] = month_desc[mon][1];
< _imapdate[5] = month_desc[mon][2];
<
< /* copy year */
< _imapdate[7] = sqldate[0];
< _imapdate[8] = sqldate[1];
< _imapdate[9] = sqldate[2];
< _imapdate[10] = sqldate[3];
<
< /* copy time */
< strcpy(&_imapdate[11], &sqldate[10]);
---
> tm_sqldate.tm_gmtoff = tm_localtime.tm_gmtoff;
> (void) strftime(_imapdate, IMAP_INTERNALDATE_LEN,
> "%d-%b-%Y %T %z", &tm_sqldate);
1869,1871d1860
< *
< * sqldate is slightly tested for validity. NULL is returned in case of an
erroneous date.
< * however, the tests performed are NOT extensive enough.
1875,1876c1864,1865
< int i, j;
< char sub[4];
---
> struct tm tm;
> char *last_char;
1878,1879c1867,1870
< if (strlen(imapdate) != strlen("dd-mon-yyyy")
< && strlen(imapdate) != strlen("d-mon-yyyy"))
---
> last_char = strptime(imapdate, "%d-%b-%Y", &tm);
> if (*last_char != '\0') {
> trace(TRACE_DEBUG, "%s,%s: error parsing IMAP date %s",
> __FILE__, __func__, imapdate);
1881,1898d1871
<
< j = (strlen(imapdate) == strlen("d-mon-yyyy")) ? 1 : 0;
<
< /* copy year */
< _sqldate[0] = imapdate[7 - j];
< _sqldate[1] = imapdate[8 - j];
< _sqldate[2] = imapdate[9 - j];
< _sqldate[3] = imapdate[10 - j];
<
< _sqldate[4] = '-';
<
< /* copy month */
< strncpy(sub, &imapdate[3 - j], 3);
< sub[3] = 0;
<
< for (i = 0; i < 12; i++) {
< if (strcasecmp(month_desc[i], sub) == 0)
< break;
1900,1914c1873,1874
<
< if (i >= 12)
< return NULL;
<
< i++; /* make i in [1,12] */
< _sqldate[5] = (i < 10) ? '0' : '1';
< _sqldate[6] = (i < 10) ? (i + '0') : ((i - 10) + '0');
<
< _sqldate[7] = '-';
<
< /* copy day */
< _sqldate[8] = j ? '0' : imapdate[0];
< _sqldate[9] = imapdate[1 - j];
<
< _sqldate[10] = 0; /* terminate */
---
> (void) strftime(_sqldate, SQL_INTERNALDATE_LEN,
> "%Y-%m-%d 00:00:00", &tm);
1918d1877
<