* Added a skeleton IMAP "SEARCH" command (based on the FETCH logic)
authorArt Cancro <ajc@citadel.org>
Wed, 27 Dec 2000 05:09:58 +0000 (05:09 +0000)
committerArt Cancro <ajc@citadel.org>
Wed, 27 Dec 2000 05:09:58 +0000 (05:09 +0000)
citadel/ChangeLog
citadel/Makefile.in
citadel/imap_fetch.c
citadel/imap_fetch.h
citadel/imap_search.c [new file with mode: 0644]
citadel/imap_search.h [new file with mode: 0644]
citadel/serv_imap.c

index fcf957f3682947649171d9f368f552d39b933dae..a1f0afc01775c66634f2c84bd954092c7d449e4a 100644 (file)
@@ -1,4 +1,7 @@
  $Log$
+ Revision 573.58  2000/12/27 05:09:58  ajc
+ * Added a skeleton IMAP "SEARCH" command (based on the FETCH logic)
+
  Revision 573.57  2000/12/26 03:46:50  ajc
  * More IMAP tweaks
 
@@ -2245,3 +2248,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 6d6ac0e51efa4ea540e629c55902be4d73d9dd68..c32cd5bdc71a1e5d68cc7d78ee8a8d83a496b405 100644 (file)
@@ -90,7 +90,7 @@ SOURCES=aidepost.c citadel.c citmail.c citserver.c client_chat.c commands.c \
        serv_smtp.c serv_pop3.c internet_addressing.c parsedate.c genstamp.c \
        domain.c clientsocket.c serv_inetcfg.c serv_rwho.c serv_bio.c \
        serv_moderate.c client_passwords.c \
-       serv_imap.c imap_tools.c imap_fetch.c \
+       serv_imap.c imap_tools.c imap_fetch.c imap_search.c \
        serv_network.c serv_pas2.c md5.c
 
 DEP_FILES=$(SOURCES:.c=.d)
@@ -234,9 +234,9 @@ modules/serv_smtp.mo: serv_smtp.mo
 modules/domain.mo: domain.mo
        ln -f domain.mo modules
 
-modules/serv_imap.so: serv_imap.mo imap_tools.mo imap_fetch.mo
+modules/serv_imap.so: serv_imap.mo imap_tools.mo imap_fetch.mo imap_search.mo
        $(LINK_SHARED) -o modules/serv_imap.so imap_tools.mo serv_imap.mo \
-               imap_fetch.mo
+               imap_fetch.mo imap_search.mo
 
 modules/serv_imap.mo: serv_imap.mo
        ln -f serv_imap.mo modules
@@ -247,6 +247,9 @@ modules/imap_tools.mo: imap_tools.mo
 modules/imap_fetch.mo: imap_fetch.mo
        ln -f imap_fetch.mo modules
 
+modules/imap_search.mo: imap_search.mo
+       ln -f imap_search.mo modules
+
 aidepost: aidepost.o config.o $(LIBOBJS)
        $(CC) aidepost.o config.o $(LIBOBJS) $(LDFLAGS) -o aidepost
 
index 5bfc50520eaa31101c884c8d98a108456466a49c..e97704866eba13cc99a811255b931e19295ca73e 100644 (file)
@@ -735,6 +735,10 @@ void imap_pick_range(char *range, int is_uid) {
        int s;
        char setstr[1024], lostr[1024], histr[1024];
        int lo, hi;
+       char *actual_range;
+
+       actual_range = range;
+       if (!strcasecmp(range, "ALL")) actual_range = "1:*";
 
        /*
         * Clear out the IMAP_FETCHED flags for all messages.
@@ -746,9 +750,9 @@ void imap_pick_range(char *range, int is_uid) {
        /*
         * Now set it for all specified messages.
         */
-       num_sets = num_tokens(range, ',');
+       num_sets = num_tokens(actual_range, ',');
        for (s=0; s<num_sets; ++s) {
-               extract_token(setstr, range, s, ',');
+               extract_token(setstr, actual_range, s, ',');
 
                extract_token(lostr, setstr, 0, ':');
                if (num_tokens(setstr, ':') >= 2) {
index 31c2dd9ef397f2685415be63e1693e466ede39f2..b3f80dfc91d7c3eef12993df4177b170229875f7 100644 (file)
@@ -3,5 +3,7 @@
  *
  */
 
+void imap_pick_range(char *range, int is_uid);
 void imap_fetch(int num_parms, char *parms[]);
 void imap_uidfetch(int num_parms, char *parms[]);
+int imap_extract_data_items(char **argv, char *items);
diff --git a/citadel/imap_search.c b/citadel/imap_search.c
new file mode 100644 (file)
index 0000000..065e4ad
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * $Id$
+ *
+ * Implements the SEARCH command in IMAP.
+ * This command is way too convoluted.  Marc Crispin is a fscking idiot.
+ *
+ */
+
+
+#include "sysdep.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <pwd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <ctype.h>
+#include <string.h>
+#include <limits.h>
+#include "citadel.h"
+#include "server.h"
+#include <time.h>
+#include "sysdep_decls.h"
+#include "citserver.h"
+#include "support.h"
+#include "config.h"
+#include "dynloader.h"
+#include "room_ops.h"
+#include "user_ops.h"
+#include "policy.h"
+#include "database.h"
+#include "msgbase.h"
+#include "tools.h"
+#include "internet_addressing.h"
+#include "mime_parser.h"
+#include "serv_imap.h"
+#include "imap_tools.h"
+#include "imap_fetch.h"
+#include "imap_search.h"
+#include "genstamp.h"
+
+
+
+
+
+
+/*
+ * imap_do_search() calls imap_do_search_msg() to output the deta of an
+ * individual message, once it has been successfully loaded from disk.
+ */
+void imap_do_search_msg(int seq, struct CtdlMessage *msg,
+                       int num_items, char **itemlist, int is_uid) {
+
+       int is_valid = 0;
+
+       is_valid = 1;  /* FIXME ... replace with a real test */
+
+       /*
+        * If the message meets the specified search criteria, output its
+        * sequence number *or* UID, depending on what the client wants.
+        */
+       if (is_valid) {
+               if (is_uid)     cprintf("%ld ", IMAP->msgids[seq-1]);
+               else            cprintf("%d ", seq);
+       }
+
+}
+
+
+
+/*
+ * imap_search() calls imap_do_search() to do its actual work, once it's
+ * validated and boiled down the request a bit.
+ */
+void imap_do_search(int num_items, char **itemlist, int is_uid) {
+       int i;
+       struct CtdlMessage *msg;
+
+       cprintf("* SEARCH ");
+       if (IMAP->num_msgs > 0)
+        for (i = 0; i < IMAP->num_msgs; ++i)
+         if (IMAP->flags[i] && IMAP_FETCHED) {
+               msg = CtdlFetchMessage(IMAP->msgids[i]);
+               if (msg != NULL) {
+                       imap_do_search_msg(i+1, msg, num_items,
+                                       itemlist, is_uid);
+                       CtdlFreeMessage(msg);
+               }
+               else {
+                       lprintf(1, "SEARCH internal error\n");
+               }
+       }
+       cprintf("\r\n");
+}
+
+
+/*
+ * This function is called by the main command loop.
+ */
+void imap_search(int num_parms, char *parms[]) {
+       char items[1024];
+       char *itemlist[256];
+       int num_items;
+       int i;
+
+       if (num_parms < 4) {
+               cprintf("%s BAD invalid parameters\r\n", parms[0]);
+               return;
+       }
+
+       imap_pick_range(parms[2], 0);
+
+       strcpy(items, "");
+       for (i=3; i<num_parms; ++i) {
+               strcat(items, parms[i]);
+               if (i < (num_parms-1)) strcat(items, " ");
+       }
+
+       num_items = imap_extract_data_items(itemlist, items);
+       if (num_items < 1) {
+               cprintf("%s BAD invalid data item list\r\n", parms[0]);
+               return;
+       }
+
+       imap_do_search(num_items, itemlist, 0);
+       cprintf("%s OK SEARCH completed\r\n", parms[0]);
+}
+
+/*
+ * This function is called by the main command loop.
+ */
+void imap_uidsearch(int num_parms, char *parms[]) {
+       char items[1024];
+       char *itemlist[256];
+       int num_items;
+       int i;
+
+       if (num_parms < 5) {
+               cprintf("%s BAD invalid parameters\r\n", parms[0]);
+               return;
+       }
+
+       imap_pick_range(parms[3], 1);
+
+       strcpy(items, "");
+       for (i=4; i<num_parms; ++i) {
+               strcat(items, parms[i]);
+               if (i < (num_parms-1)) strcat(items, " ");
+       }
+
+       num_items = imap_extract_data_items(itemlist, items);
+       if (num_items < 1) {
+               cprintf("%s BAD invalid data item list\r\n", parms[0]);
+               return;
+       }
+
+       imap_do_search(num_items, itemlist, 1);
+       cprintf("%s OK UID SEARCH completed\r\n", parms[0]);
+}
+
+
diff --git a/citadel/imap_search.h b/citadel/imap_search.h
new file mode 100644 (file)
index 0000000..dd0195c
--- /dev/null
@@ -0,0 +1,7 @@
+/*
+ * $Id$
+ *
+ */
+
+void imap_search(int num_parms, char *parms[]);
+void imap_uidsearch(int num_parms, char *parms[]);
index 3b544fd29eb883b622132b6a0a48a24b28499513..62a3ba95b186cc3ed0c3052416938a039e0843cc 100644 (file)
@@ -41,6 +41,7 @@
 #include "serv_imap.h"
 #include "imap_tools.h"
 #include "imap_fetch.h"
+#include "imap_search.h"
 
 
 long SYM_IMAP;
@@ -480,6 +481,15 @@ void imap_command_loop(void) {
                imap_uidfetch(num_parms, parms);
        }
 
+       else if (!strcasecmp(parms[1], "SEARCH")) {
+               imap_search(num_parms, parms);
+       }
+
+       else if ( (!strcasecmp(parms[1], "UID"))
+               && (!strcasecmp(parms[2], "SEARCH")) ) {
+               imap_uidsearch(num_parms, parms);
+       }
+
        else if (!strcasecmp(parms[1], "CLOSE")) {
                imap_close(num_parms, parms);
        }