summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Varshavchik2015-03-04 20:10:05 -0500
committerSam Varshavchik2015-03-04 20:10:05 -0500
commit070a5986a3ada0cd6cbb74c77f4e41ed3c4eb48c (patch)
tree96f6fe07a4a3be2812f20feb5611d6efdf820e95
parent0feb9a21453515e53fbf024fd09455af42d01bf1 (diff)
downloadcourier-libs-070a5986a3ada0cd6cbb74c77f4e41ed3c4eb48c.tar.bz2
imap: handle 01-Jan-1970 as a valid search date.
-rw-r--r--imap/ChangeLog4
-rw-r--r--imap/imapd.c41
-rw-r--r--imap/search.c48
-rw-r--r--imap/smap.c11
-rw-r--r--imap/thread.c9
-rw-r--r--rfc2045/rfc2045reply.c8
-rw-r--r--rfc822/ChangeLog5
-rw-r--r--rfc822/imaprefs.c6
-rw-r--r--rfc822/rfc822.h3
-rw-r--r--rfc822/rfc822_parsedt.c37
-rw-r--r--sqwebmail/ChangeLog4
-rw-r--r--sqwebmail/maildir.c18
-rw-r--r--sqwebmail/msg2html.c15
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, &timestamp))
{
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)
{