$Log$
+ Revision 608.10 2003/07/27 21:15:23 ajc
+ * Implemented all IMAP date-based search criteria. Note that Citadel does
+ not record an "internal date" of a message, so the "sent date" and "internal
+ date" searches perform identically.
+ * Date search comparisons available: "before," "on," or "on or after." Yet
+ another example of why Mark Crispin needs to be taken outside and shot.
+
Revision 608.9 2003/07/26 04:49:40 ajc
* Implemented a bunch of the IMAP SEARCH keywords
Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
* Initial CVS import
+
}
else if (!strcasecmp(itemlist[pos], "BEFORE")) {
- /* FIXME */
+ if (msg->cm_fields['T'] != NULL) {
+ if (imap_datecmp(itemlist[pos+1],
+ atol(msg->cm_fields['T'])) < 0) {
+ match = 1;
+ }
+ }
pos += 2;
}
}
else if (!strcasecmp(itemlist[pos], "ON")) {
- /* FIXME */
+ if (msg->cm_fields['T'] != NULL) {
+ if (imap_datecmp(itemlist[pos+1],
+ atol(msg->cm_fields['T'])) == 0) {
+ match = 1;
+ }
+ }
pos += 2;
}
}
else if (!strcasecmp(itemlist[pos], "SENTBEFORE")) {
- /* FIXME */
+ if (msg->cm_fields['T'] != NULL) {
+ if (imap_datecmp(itemlist[pos+1],
+ atol(msg->cm_fields['T'])) < 0) {
+ match = 1;
+ }
+ }
pos += 2;
}
else if (!strcasecmp(itemlist[pos], "SENTON")) {
- /* FIXME */
+ if (msg->cm_fields['T'] != NULL) {
+ if (imap_datecmp(itemlist[pos+1],
+ atol(msg->cm_fields['T'])) == 0) {
+ match = 1;
+ }
+ }
pos += 2;
}
else if (!strcasecmp(itemlist[pos], "SENTSINCE")) {
- /* FIXME */
+ if (msg->cm_fields['T'] != NULL) {
+ if (imap_datecmp(itemlist[pos+1],
+ atol(msg->cm_fields['T'])) >= 0) {
+ match = 1;
+ }
+ }
pos += 2;
}
else if (!strcasecmp(itemlist[pos], "SINCE")) {
- /* FIXME */
+ if (msg->cm_fields['T'] != NULL) {
+ if (imap_datecmp(itemlist[pos+1],
+ atol(msg->cm_fields['T'])) >= 0) {
+ match = 1;
+ }
+ }
pos += 2;
}
}
return (do_imap_match(mailboxname, pattern) == WILDMAT_TRUE);
}
+
+
+
+/*
+ * Compare an IMAP date string (date only, no time) to the date found in
+ * a Unix timestamp.
+ */
+int imap_datecmp(char *datestr, time_t msgtime) {
+ char daystr[SIZ];
+ char monthstr[SIZ];
+ char yearstr[SIZ];
+ int i;
+ int day, month, year;
+ int msgday, msgmonth, msgyear;
+ struct tm msgtm;
+
+ if (datestr == NULL) return(0);
+
+ /* Expecting a date in the form dd-Mmm-yyyy */
+ extract_token(daystr, datestr, 0, '-');
+ extract_token(monthstr, datestr, 1, '-');
+ extract_token(yearstr, datestr, 2, '-');
+
+ day = atoi(daystr);
+ year = atoi(yearstr);
+ month = 0;
+ for (i=0; i<12; ++i) {
+ if (!strcasecmp(monthstr, ascmonths[i])) {
+ month = i;
+ }
+ }
+
+ /* Extract day/month/year from message timestamp */
+ memcpy(&msgtm, localtime(&msgtime), sizeof(struct tm));
+ msgday = msgtm.tm_mday;
+ msgmonth = msgtm.tm_mon;
+ msgyear = msgtm.tm_year + 1900;
+
+ /* Now start comparing */
+
+ if (year < msgyear) return(+1);
+ if (year > msgyear) return(-1);
+
+ if (month < msgmonth) return(+1);
+ if (month > msgmonth) return(-1);
+
+ if (day < msgday) return(+1);
+ if (day > msgday) return(-1);
+
+ return(0);
+}
int imap_roomname(char *buf, int bufsize, char *foldername);
int imap_is_message_set(char *);
int imap_mailbox_matches_pattern(char *pattern, char *mailboxname);
+int imap_datecmp(char *datestr, time_t msgtime);
/*
* Flags that may be returned by imap_roomname()
typedef unsigned char byte; /* Byte type */
static byte dtable[256]; /* base64 encode / decode table */
+/* Month strings for date conversions */
+char *ascmonths[12] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
char *safestrncpy(char *dest, const char *src, size_t n)
{
struct tm *tm;
int hour;
- char *ascmonths[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- };
-
strcpy(buf, "");
tm = localtime(&thetime);
}
return (NULL);
}
-
char *CtdlTempFileName(char *prefix1, int prefix2);
FILE *CtdlTempFile(void);
char *bmstrcasestr(char *text, char *pattern);
+
+char *ascmonths[12];