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
< 

Reply via email to