]> code.citadel.org Git - citadel.git/commitdiff
* Implemented all IMAP date-based search criteria. Note that Citadel does
authorArt Cancro <ajc@citadel.org>
Sun, 27 Jul 2003 21:15:23 +0000 (21:15 +0000)
committerArt Cancro <ajc@citadel.org>
Sun, 27 Jul 2003 21:15:23 +0000 (21:15 +0000)
  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.

citadel/ChangeLog
citadel/imap_search.c
citadel/imap_tools.c
citadel/imap_tools.h
citadel/tools.c
citadel/tools.h

index b751c12957d9e10a393931bb04308108e0872a20..d69f52bd5b562fd7ce3390ee6a7cb0315705dd36 100644 (file)
@@ -1,4 +1,11 @@
  $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
 
@@ -4904,3 +4911,4 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant <bryant@cs.usm.maine.edu>
 
 Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
        * Initial CVS import
+
index 70abccf65fc2674f221ac980fb882d9dd1857d1d..bac0f83b27fadf81e2bb956a4773593b8dcac255 100644 (file)
@@ -106,7 +106,12 @@ int imap_do_search_msg(int seq, struct CtdlMessage *msg,
        }
 
        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;
        }
 
@@ -178,7 +183,12 @@ int imap_do_search_msg(int seq, struct CtdlMessage *msg,
        }
 
        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;
        }
 
@@ -195,22 +205,42 @@ int imap_do_search_msg(int seq, struct CtdlMessage *msg,
        }
 
        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;
        }
 
index 87f145f4745ba3758a3e5dedf95d57aad340e88d..47941d117102755e3306c3759a6b8449ee9c1b7b 100644 (file)
@@ -373,3 +373,54 @@ int imap_mailbox_matches_pattern(char *pattern, char *mailboxname)
        }
        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);
+}
index 872adffcab4a681b66e13b9ce2ce05e349279685..75aff407b4cf24fd300b2728038d5a0bf44a7590 100644 (file)
@@ -20,6 +20,7 @@ void imap_ial_out(struct internet_address_list *ialist);
 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()
index 748be69d6e2078c3025776041fe20a88179b83f1..d3610212a04b040053802ae28a2cfd22e738692a 100644 (file)
 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)
 {
@@ -364,11 +369,6 @@ void fmt_date(char *buf, size_t n, time_t thetime, int seconds) {
        struct tm *tm;
        int hour;
 
-       char *ascmonths[] = {
-               "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-               "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-       };
-
        strcpy(buf, "");
        tm = localtime(&thetime);
 
@@ -634,4 +634,3 @@ char *bmstrcasestr(char *text, char *pattern)
        }
        return (NULL);
 }
-
index bd084e92bee52eb4099d14f007be7c06b4a597be..053e42e2571af0543c0990abaa98329f96b650fe 100644 (file)
@@ -31,3 +31,5 @@ void urlesc(char *outbuf, char *strbuf);
 char *CtdlTempFileName(char *prefix1, int prefix2);
 FILE *CtdlTempFile(void);
 char *bmstrcasestr(char *text, char *pattern);
+
+char *ascmonths[12];