diff options
| -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)  	{ | 
