diff options
| author | Sam Varshavchik | 2015-03-04 20:10:05 -0500 |
|---|---|---|
| committer | Sam Varshavchik | 2015-03-04 20:10:05 -0500 |
| commit | 070a5986a3ada0cd6cbb74c77f4e41ed3c4eb48c (patch) | |
| tree | 96f6fe07a4a3be2812f20feb5611d6efdf820e95 | |
| parent | 0feb9a21453515e53fbf024fd09455af42d01bf1 (diff) | |
| download | courier-libs-070a5986a3ada0cd6cbb74c77f4e41ed3c4eb48c.tar.bz2 | |
imap: handle 01-Jan-1970 as a valid search date.
| -rw-r--r-- | imap/ChangeLog | 4 | ||||
| -rw-r--r-- | imap/imapd.c | 41 | ||||
| -rw-r--r-- | imap/search.c | 48 | ||||
| -rw-r--r-- | imap/smap.c | 11 | ||||
| -rw-r--r-- | imap/thread.c | 9 | ||||
| -rw-r--r-- | rfc2045/rfc2045reply.c | 8 | ||||
| -rw-r--r-- | rfc822/ChangeLog | 5 | ||||
| -rw-r--r-- | rfc822/imaprefs.c | 6 | ||||
| -rw-r--r-- | rfc822/rfc822.h | 3 | ||||
| -rw-r--r-- | rfc822/rfc822_parsedt.c | 37 | ||||
| -rw-r--r-- | sqwebmail/ChangeLog | 4 | ||||
| -rw-r--r-- | sqwebmail/maildir.c | 18 | ||||
| -rw-r--r-- | sqwebmail/msg2html.c | 15 |
13 files changed, 122 insertions, 87 deletions
diff --git a/imap/ChangeLog b/imap/ChangeLog index 66063b3..f773664 100644 --- a/imap/ChangeLog +++ b/imap/ChangeLog @@ -1,3 +1,7 @@ +2015-03-04 Sam Varshavchik <mrsam@courier-mta.com> + + * Handle 01-Jan-1970 for date-based searches. + 2015-02-28 Sam Varshavchik <mrsam@courier-mta.com> * Update to courier-unicode 1.2. diff --git a/imap/imapd.c b/imap/imapd.c index 1396429..0b00b3c 100644 --- a/imap/imapd.c +++ b/imap/imapd.c @@ -84,6 +84,7 @@ #include "maildir/maildirkeywords.h" #include "maildir/maildirinfo.h" #include "maildir/loginexec.h" +#include "rfc822/rfc822.h" #include <courier-unicode.h> #include "maildir/maildirkeywords.h" @@ -92,7 +93,6 @@ #define KEYWORD_IMAPVERBOTTEN " (){%*\"\\]" #define KEYWORD_SMAPVERBOTTEN "," -extern time_t rfc822_parsedt(const char *); extern void fetchflags(unsigned long); extern unsigned long header_count, body_count; extern time_t start_time; @@ -175,7 +175,7 @@ void quotainfo_out(const char* qroot) char quotabuf[QUOTABUFSIZE]; char qresult[200]=""; char qbuf[200]; - + if ((maildir_getquota(".", quotabuf) == 0) && (strcmp(qroot,"ROOT") == 0)) { struct maildirsize quotainfo; @@ -186,7 +186,7 @@ void quotainfo_out(const char* qroot) quotainfo.quota.nbytes=quotainfo.size.nbytes= quotainfo.quota.nmessages= quotainfo.size.nmessages=0; - + if (quotainfo.quota.nbytes > 0) { sprintf(qbuf,"STORAGE %ld %ld", @@ -403,7 +403,7 @@ char *decode_valid_mailbox(const char *p, int autosubscribe) return (NULL); } -static time_t decode_date_time(char *p) +static int decode_date_time(char *p, time_t *tret) { unsigned i; @@ -414,7 +414,7 @@ unsigned i; if (!p[i]) return (0); if (p[i] == '-') p[i]=' '; } - return (rfc822_parsedt(p)); + return (rfc822_parsedate_chk(p, tret)); } int get_flagname(const char *p, struct imapflags *flags) @@ -716,7 +716,7 @@ int rb; nbytes -= n; if (p[n-1] == '\n') lastnl = 1; else lastnl = 0; - + while (n) { e = memchr(p, '\r', n); @@ -729,7 +729,7 @@ int rb; rb = fwrite(p, 1, e-p, fp); } else - { + { rb = fwrite(p, 1, n, fp); } n -= rb; @@ -759,7 +759,7 @@ int rb; nbytes=ftell(fp); if (nbytes == (unsigned long)-1 || (p=maildir_requota(newname, nbytes)) == 0) - + { fclose(fp); unlink(tmpname); @@ -1162,7 +1162,7 @@ void doNoop(int real_noop) #endif struct noopKeywordUpdateInfo kui; - imapscan_init(&new_maildir_info); + imapscan_init(&new_maildir_info); if (imapscan_maildir(&new_maildir_info, current_mailbox, 0, current_mailbox_ro, NULL)) @@ -1484,7 +1484,7 @@ static int doId() writes("\" \"os-version\" \""); writeqs(uts.release); } - + } } #endif @@ -2782,7 +2782,7 @@ static void writeacl(const char *aclstr) writeqs(p); free(p); } - + static int list_acl_cb(const char *ident, const maildir_aclt *acl, void *cb_arg) @@ -3273,7 +3273,7 @@ void aclminimum(const char *identifier) writes(*identifier == '-' ? "\"\"":ACL_ADMINISTER ACL_LOOKUP); writes(" " ACL_CREATE - " " ACL_EXPUNGE + " " ACL_EXPUNGE " " ACL_INSERT " " ACL_POST " " ACL_READ @@ -3886,8 +3886,7 @@ static int append(const char *tag, const char *mailbox, const char *path) if (curtoken->tokentype == IT_QUOTED_STRING) { - timestamp=decode_date_time(curtoken->tokenbuf); - if (timestamp == 0) + if (decode_date_time(curtoken->tokenbuf, ×tamp)) { libmail_kwmDestroy(keywords); return (-1); @@ -4270,7 +4269,7 @@ int uid=0; rc=mailbox_scan(reference, name, list_flags, list_callback, cmdbuf); - + free(reference); free(name); if (rc == 0) @@ -4324,7 +4323,7 @@ int uid=0; ACL_INSERT); return 0; } - + rc=append(tag, tok->tokenbuf, p); free(p); maildir_info_destroy(&mi); @@ -6122,7 +6121,7 @@ int uid=0; append_rights, ACL_INSERT ACL_DELETEMSGS ACL_SEEN ACL_WRITE); - + if (strchr(append_rights, ACL_INSERT[0]) == NULL) { writes(tag); @@ -6334,7 +6333,7 @@ char *p, *q; *p=0; p=strrchr(q, '/'); } - + if (p) p[1]=0; else *q=0; @@ -6568,14 +6567,14 @@ int main(int argc, char **argv) if (!p) dogethostname(); - if ((p=getenv("IMAP_TRASHFOLDERNAME")) != 0 && *p) + if ((p=getenv("IMAP_TRASHFOLDERNAME")) != 0 && *p) { trash = strdup(p); dot_trash = malloc(strlen(trash) + 2); dot_trash[0] = '.'; - strcpy(&dot_trash[1], trash); + strcpy(&dot_trash[1], trash); } - + #if 0 mdcreate("." DRAFTS); #endif diff --git a/imap/search.c b/imap/search.c index 1aa0007..cc64bbf 100644 --- a/imap/search.c +++ b/imap/search.c @@ -215,12 +215,12 @@ int rc; { /* No, search the headers then */ /* struct rfc2045 *rfcp=rfc2045_fromfp(fp); */ - struct rfc2045 *rfcp=rfc2045header_fromfp(fp); + struct rfc2045 *rfcp=rfc2045header_fromfp(fp); fill_search_header(sihead, charset, rfcp, fp, current_maildir_info.msgs+i); rc=search_evaluate(si); - rfc2045_free(rfcp); + rfc2045_free(rfcp); if (rc < 0) { @@ -302,16 +302,16 @@ unsigned long i, j; ** Use convenient RFC822 functions for that purpose. */ -static time_t decode_date(char *p) +static int decode_date(char *p, time_t *tret) { -char *s=malloc(strlen(p)+sizeof(" 00:00:00")); -unsigned i; -time_t t; + char *s=malloc(strlen(p)+sizeof(" 00:00:00")); + unsigned i; + int ret; if (!s) write_error_exit(0); /* Convert to format rfc822_parsedt likes */ - + for (i=1; p[i] != ' '; i++) { if (!p[i]) break; @@ -324,9 +324,9 @@ time_t t; s[i]=' '; } - t=rfc822_parsedt(s); + ret=rfc822_parsedate_chk(s, tret); free(s); - return (t); + return (ret); } /* Given a time_t that falls on, say, 3-Aug-1999 9:50:43 local time, @@ -345,7 +345,10 @@ char buf1[60], buf2[80]; strcat(buf2, " "); strcat(buf2, strtok(0, " ")); strcat(buf2, " 00:00:00"); - return (rfc822_parsedt(buf2)); + + rfc822_parsedate_chk(buf2, &t); + + return t; } static char *timestamp_for_sorting(time_t t) @@ -474,27 +477,30 @@ static void fill_search_quick(struct searchinfo *p, case search_before: p->value=0; { - time_t t=decode_date(p->as); + time_t t; - if (t && timestamp_to_day(stat_buf->st_mtime) < t) + if (decode_date(p->as, &t) == 0 && + timestamp_to_day(stat_buf->st_mtime) < t) p->value=1; } break; case search_since: p->value=0; { - time_t t=decode_date(p->as); + time_t t; - if (t && timestamp_to_day(stat_buf->st_mtime) >= t) + if (decode_date(p->as, &t) == 0 && + timestamp_to_day(stat_buf->st_mtime) >= t) p->value=1; } break; case search_on: p->value=0; { - time_t t=decode_date(p->as); + time_t t; - if (t && timestamp_to_day(stat_buf->st_mtime) == t) + if (decode_date(p->as, &t) == 0 && + timestamp_to_day(stat_buf->st_mtime) == t) p->value=1; } break; @@ -787,8 +793,9 @@ static int headerfilter_func(const char *name, const char *value, void *arg) if (isdate == 0 && sip->as == 0) { - time_t msg_time=rfc822_parsedt(value); + time_t msg_time; + rfc822_parsedate_chk(value, &msg_time); sip->as=timestamp_for_sorting(msg_time); } break; @@ -802,10 +809,11 @@ static int headerfilter_func(const char *name, const char *value, void *arg) if (isdate == 0) { - time_t given_time=decode_date(sip->as); - time_t msg_time=rfc822_parsedt(value); + time_t given_time; + time_t msg_time; - if (given_time == 0 || msg_time == 0) + if (decode_date(sip->as, &given_time) + || rfc822_parsedate_chk(value, &msg_time)) break; msg_time=timestamp_to_day(msg_time); diff --git a/imap/smap.c b/imap/smap.c index b7669cf..2b528a9 100644 --- a/imap/smap.c +++ b/imap/smap.c @@ -3376,9 +3376,9 @@ void smap() if (strcmp(p, "INTERNALDATE") == 0 && q) { - add_internaldate=rfc822_parsedt(q); - - if (add_internaldate) + if (rfc822_parsedate_chk(q, + &add_internaldate) + == 0) okmsg="INTERNALDATE set"; } @@ -4359,9 +4359,8 @@ void smap() up(p); - t=rfc822_parsedt(p+13); - - if (t && + if (rfc822_parsedate_chk(p+13, &t) + == 0 && (dummy=applymsgset(&setdate, &t)) != 0) break; diff --git a/imap/thread.c b/imap/thread.c index 791a7a8..883ae59 100644 --- a/imap/thread.c +++ b/imap/thread.c @@ -198,11 +198,18 @@ static void thread_os_callback(struct searchinfo *si, void *voidarg) { if (sihead->type == search_orderedsubj) + { /* SHOULD BE ALWAYS TRUE */ + time_t t=0; + + if (sihead->bs) + rfc822_parsedate_chk(sihead->bs, &t); + os_add( (struct os_struct *)voidarg, isuid ? current_maildir_info.msgs[i].uid:i+1, sihead->as ? sihead->as:"", - sihead->bs ? rfc822_parsedt(sihead->bs):0); + t); + } } static void printthread(struct imap_refmsg *, int); diff --git a/rfc2045/rfc2045reply.c b/rfc2045/rfc2045reply.c index 52d7b71..a3b57b5 100644 --- a/rfc2045/rfc2045reply.c +++ b/rfc2045/rfc2045reply.c @@ -38,7 +38,7 @@ static void mksalutation_datefmt(const char *fmt_start, fmt_end=fmt_start + strlen(fmt_start); } - if ((t=rfc822_parsedt(date))) + if (rfc822_parsedate_chk(date, &t) == 0) { struct tm tmbuf; @@ -710,7 +710,7 @@ static int mkforward(struct rfc2045_mkreplyinfo *ri) if (textplain_content) { /* Copy original headers. */ - + hi=rfc2045header_start(ri->src, ri->rfc2045partp); for (;;) { @@ -795,7 +795,7 @@ static int mkforward(struct rfc2045_mkreplyinfo *ri) rfc2045_mimepos(first_attachment, &start_pos, &end_pos, &start_body, &dummy, &dummy); - + if (SRC_SEEK(ri->src, start_pos) == (off_t)-1) { if (subject) free(subject); @@ -819,7 +819,7 @@ static int mkforward(struct rfc2045_mkreplyinfo *ri) &end_pos, &start_body, &dummy, &dummy); - + if (SRC_SEEK(ri->src, start_pos) == (off_t)-1) { if (subject) free(subject); diff --git a/rfc822/ChangeLog b/rfc822/ChangeLog index 0145335..834004e 100644 --- a/rfc822/ChangeLog +++ b/rfc822/ChangeLog @@ -1,3 +1,8 @@ +2015-03-03 Sam Varshavchik <mrsam@courier-mta.com> + + * Replace rfc822_parsedt with rfc822_parsedate_chk(), returning + 0 for ok, -1 for an error parsing the date string. + 2015-02-28 Sam Varshavchik <mrsam@courier-mta.com> * Update to courier-unicode 1.2. diff --git a/rfc822/imaprefs.c b/rfc822/imaprefs.c index dc58869..b5f9a7d 100644 --- a/rfc822/imaprefs.c +++ b/rfc822/imaprefs.c @@ -523,7 +523,9 @@ static struct imap_refmsg *threadmsg_common(struct imap_refmsg *m, return (0); /* Cleanup in rfc822_threadfree() */ if (dateheader) - dateheader_tm=rfc822_parsedt(dateheader); + { + rfc822_parsedate_chk(dateheader, &dateheader_tm); + } m->timestamp=dateheader_tm; @@ -567,7 +569,7 @@ struct imap_refmsg *rfc822_threadgetroot(struct imap_refmsgtable *mt) } /* -** +** ** (3) Prune dummy messages from the thread tree. Traverse each ** thread under the root, and for each message: */ diff --git a/rfc822/rfc822.h b/rfc822/rfc822.h index 3d437e3..09050ad 100644 --- a/rfc822/rfc822.h +++ b/rfc822/rfc822.h @@ -136,7 +136,8 @@ char *rfc822_getaddrs_wrap(const struct rfc822a *, int); void rfc822_mkdate_buf(time_t, char *); const char *rfc822_mkdate(time_t); -time_t rfc822_parsedt(const char *); + +int rfc822_parsedate_chk(const char *, time_t *); #define CORESUBJ_RE 1 #define CORESUBJ_FWD 2 diff --git a/rfc822/rfc822_parsedt.c b/rfc822/rfc822_parsedt.c index 036be34..c3eacff 100644 --- a/rfc822/rfc822_parsedt.c +++ b/rfc822/rfc822_parsedt.c @@ -62,7 +62,7 @@ static const char * const zonenames[] = { "MST","MDT", "PST","PDT", "Z", - "A", "B", "C", "D", "E", "F", "G", "H", "I", "K", "L", "M", + "A", "B", "C", "D", "E", "F", "G", "H", "I", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", NULL}; @@ -122,13 +122,15 @@ static int parsetime(const char **t) return (h * 60 * 60 + m * 60 + s); } -time_t rfc822_parsedt(const char *rfcdt) +int rfc822_parsedate_chk(const char *rfcdt, time_t *tret) { -unsigned day=0, mon=0, year; -int secs; -int offset; -time_t t; -unsigned y; + unsigned day=0, mon=0, year; + int secs; + int offset; + time_t t; + unsigned y; + + *tret=0; /* Ignore day of the week. Tolerate "Tue, 25 Feb 1997 ... " ** without the comma. Tolerate "Feb 25 1997 ...". @@ -136,10 +138,10 @@ unsigned y; while (!day || !mon) { - if (!*rfcdt) return (0); + if (!*rfcdt) return (-1); if (my_isalpha(*rfcdt)) { - if (mon) return (0); + if (mon) return (-1); mon=parsekey(&rfcdt, mnames); if (!mon) while (*rfcdt && my_isalpha(*rfcdt)) @@ -149,9 +151,9 @@ unsigned y; if (my_isdigit(*rfcdt)) { - if (day) return (0); + if (day) return (-1); day=parsedig(&rfcdt); - if (!day) return (0); + if (!day) return (-1); continue; } ++rfcdt; @@ -159,7 +161,7 @@ unsigned y; while (*rfcdt && my_isspace(*rfcdt)) ++rfcdt; - if (!my_isdigit(*rfcdt)) return (0); + if (!my_isdigit(*rfcdt)) return (-1); year=parsedig(&rfcdt); if (year < 70) year += 2000; if (year < 100) year += 1900; @@ -168,10 +170,10 @@ unsigned y; ++rfcdt; if (day == 0 || mon == 0 || mon > 12 || day > mdays(mon,year)) - return (0); + return (-1); secs=parsetime(&rfcdt); - if (secs < 0) return (0); + if (secs < 0) return (-1); offset=0; @@ -210,8 +212,8 @@ unsigned y; } } - if (year < 1970) return (0); - if (year > 9999) return (0); + if (year < 1970) return (-1); + if (year > 9999) return (-1); t=0; for (y=1970; y<year; y++) @@ -232,7 +234,8 @@ unsigned y; for (y=1; y < mon; y++) t += mdays(y, year) * 24 * 60 * 60; - return ( t + (day-1) * 24 * 60 * 60 + secs - offset ); + *tret = ( t + (day-1) * 24 * 60 * 60 + secs - offset ); + return 0; } const char *rfc822_mkdt(time_t t) diff --git a/sqwebmail/ChangeLog b/sqwebmail/ChangeLog index 5769d82..66affb7 100644 --- a/sqwebmail/ChangeLog +++ b/sqwebmail/ChangeLog @@ -1,3 +1,7 @@ +2015-03-03 Sam Varshavchik <mrsam@courier-mta.com> + + * Recognize 01-Jan-1970 as a valid RFC 822 date. + 2015-02-28 Sam Varshavchik <mrsam@courier-mta.com> * Update to courier-unicode 1.2. diff --git a/sqwebmail/maildir.c b/sqwebmail/maildir.c index b822697..79dfbda 100644 --- a/sqwebmail/maildir.c +++ b/sqwebmail/maildir.c @@ -325,7 +325,7 @@ static char datebuf[40]; const char *date_yfmt; const char *date_wfmt; - + date_yfmt = getarg ("DSPFMT_YDATE"); if (*date_yfmt == 0) date_yfmt = "%d %b %Y"; @@ -1224,7 +1224,7 @@ static void maildir_checknew(const char *folder, const char *dir) /* Does The Right Thing if this is a shared ** folder */ - + free(p); } } @@ -1303,7 +1303,7 @@ void maildir_autopurge() unlink(filename); free(filename); - filename=alloc_filename(dire->d_name, "", + filename=alloc_filename(dire->d_name, "", MAILDIRCURCACHE "." DBNAME); if (!filename) enomem(); unlink(filename); @@ -2391,7 +2391,7 @@ static int do_search_utf8(struct searchresults *res) if (res->finished) return 1; - return 0; + return 0; } static int do_search(const char *str, size_t n, void *arg) @@ -2695,7 +2695,7 @@ static void dodirscan(const char *folder, fprintf(fp, "%s", cntbuf); fclose(fp); - + if (rename(createInfo.tmpname, cntfilename) < 0 || stat(cntfilename, &c_stat) < 0) { @@ -2975,9 +2975,9 @@ int fd; if (strcmp(hdr, "date") == 0 && mi->date_s == 0) { - time_t t=rfc822_parsedt(val); + time_t t; - if (t) + if (rfc822_parsedate_chk(val, &t) == 0) { mi->date_n=t; mi->date_s=strdup(displaydate(mi->date_n)); @@ -3784,7 +3784,7 @@ int maildir_closemsg(int n, /* File descriptor */ char *newname; struct stat stat_buf; - + writeflush(n); /* If there's still anything in the buffer */ if (fstat(n, &stat_buf)) { @@ -3849,7 +3849,7 @@ int maildir_closemsg(int n, /* File descriptor */ if (isok) rename(oldname, newname); - + unlink(oldname); if (isok) diff --git a/sqwebmail/msg2html.c b/sqwebmail/msg2html.c index f5b703b..f58df1d 100644 --- a/sqwebmail/msg2html.c +++ b/sqwebmail/msg2html.c @@ -215,7 +215,7 @@ static void show_email_header(const char *h) } static void print_header_uc(struct msg2html_info *info, char *h) -{ +{ header_uc(h); printf("<tr valign=\"baseline\"><th align=\"right\" class=\"message-rfc822-header-name\">"); @@ -588,10 +588,13 @@ off_t pos; if (save_date) { - time_t t=rfc822_parsedt(save_date); - struct tm *tmp=t ? localtime(&t):0; + time_t t; + struct tm *tmp=0; char date_buf[256]; + if (rfc822_parsedate_chk(save_date, &t) == 0) + tmp=localtime(&t); + if (tmp) { char date_header[10]; @@ -780,7 +783,7 @@ int gpg_status; { if (q->isdummy) continue; - + if (nextpart.idnum == 1) { printf("<blockquote class=\"%s\">", @@ -2796,7 +2799,7 @@ msg2html_textplain_start(const char *message_charset, { struct msg2html_textplain_info *tinfo= malloc(sizeof(struct msg2html_textplain_info)); - + memset(tinfo, 0, sizeof(*tinfo)); tinfo->flowed=isflowed; @@ -3018,7 +3021,7 @@ static int download_func(const char *, size_t, void *); static void disposition_attachment(FILE *fp, const char *p, int attachment) { - fprintf(fp, "Content-Disposition: %s; filename=\"", + fprintf(fp, "Content-Disposition: %s; filename=\"", attachment ? "attachment":"inline"); while (*p) { |
