* More license declarations
[citadel.git] / citadel / modules / imap / imap_list.c
index 57bb65864dbfbdc3e4b4ba072e7fb0929d8385d5..8e41927127db0d170ff28cc9f27dbcb5ec29eeeb 100644 (file)
@@ -3,9 +3,21 @@
  *
  * Implements the LIST and LSUB commands.
  *
- * Copyright (C) 2000-2007 by Art Cancro and others.
- * This code is released under the terms of the GNU General Public License.
+ * Copyright (c) 2000-2009 by Art Cancro and others.
  *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include "sysdep.h"
@@ -33,6 +45,7 @@
 #include <ctype.h>
 #include <string.h>
 #include <limits.h>
+#include <libcitadel.h>
 #include "citadel.h"
 #include "server.h"
 #include "sysdep_decls.h"
@@ -44,7 +57,6 @@
 #include "policy.h"
 #include "database.h"
 #include "msgbase.h"
-#include "tools.h"
 #include "internet_addressing.h"
 #include "serv_imap.h"
 #include "imap_tools.h"
@@ -54,6 +66,7 @@
 #include "imap_acl.h"
 #include "imap_misc.h"
 #include "imap_list.h"
+#include "ctdl_module.h"
 
 
 /*
@@ -105,9 +118,8 @@ void imap_listroom(struct ctdlroom *qrbuf, void *data)
        int subscribed_rooms_only;
        int num_patterns;
        char **patterns;
-       int return_subscribed;
-       int return_children;
-       int return_metadata;
+       int return_subscribed = 0;
+       int return_children = 0;
        int i = 0;
        int match = 0;
 
@@ -119,7 +131,6 @@ void imap_listroom(struct ctdlroom *qrbuf, void *data)
        patterns = (char **) data_for_callback[3];
        return_subscribed = (int) data_for_callback[4];
        return_children = (int) data_for_callback[5];
-       return_metadata = (int) data_for_callback[6];
 
        /* Only list rooms to which the user has access!! */
        yes_output_this_room = 0;
@@ -139,7 +150,7 @@ void imap_listroom(struct ctdlroom *qrbuf, void *data)
         * We'll fix this later when we have time.
         */
        if (return_children) {
-               if (strlen(return_options) > 0) {
+               if (!IsEmptyStr(return_options)) {
                        strcat(return_options, " ");
                }
                strcat(return_options, "\\HasChildren");
@@ -167,11 +178,6 @@ void imap_listroom(struct ctdlroom *qrbuf, void *data)
                if (match) {
                        cprintf("* %s (%s) \"/\" ", verb, return_options);
                        imap_strout(buf);
-
-                       if (return_metadata) {
-                               cprintf(" (METADATA ())");      /* FIXME */
-                       }
-
                        cprintf("\r\n");
                }
        }
@@ -186,7 +192,7 @@ void imap_list(int num_parms, char *parms[])
        int subscribed_rooms_only = 0;
        char verb[16];
        int i, j, paren_nest;
-       char *data_for_callback[7];
+       char *data_for_callback[6];
        int num_patterns = 1;
        char *patterns[MAX_PATTERNS];
        int selection_left = (-1);
@@ -199,10 +205,6 @@ void imap_list(int num_parms, char *parms[])
        int extended_list_in_use = 0;
        int return_subscribed = 0;
        int return_children = 0;
-       int return_metadata = 0;
-       int select_metadata_left = (-1);
-       int select_metadata_right = (-1);
-       int select_metadata_nest = 0;
 
        if (num_parms < 4) {
                cprintf("%s BAD arguments invalid\r\n", parms[0]);
@@ -223,21 +225,19 @@ void imap_list(int num_parms, char *parms[])
        }
 
        /*
-        * In order to implement draft-ietf-imapext-list-extensions-18
-        * ("LIST Command Extensions") we need to:
+        * Partial implementation of LIST-EXTENDED (which will not get used because
+        * we don't advertise it in our capabilities string).  Several requirements:
         *
-        * 1. Extract "selection options"
-        *                              (Extraction: done
-        *                              SUBSCRIBED option: done
-        *                              RECURSIVEMATCH option: not done yet
-        *                              REMOTE: safe to silently ignore)
+        * Extraction of selection options:
+        *      SUBSCRIBED option: done
+        *      RECURSIVEMATCH option: not done yet
+        *      REMOTE: safe to silently ignore
         *
-        * 2. Extract "return options"
-        *                              (Extraction: done
-        *                              SUBSCRIBED option: done
-        *                              CHILDREN option: done, but needs a non-ugly rewrite)
+        * Extraction of return options:
+        *      SUBSCRIBED option: done
+        *      CHILDREN option: done, but needs a non-ugly rewrite
         *
-        * 3. Determine whether there is more than one match pattern (done)
+        * Multiple match patterns: done
         */
 
        /*
@@ -250,7 +250,7 @@ void imap_list(int num_parms, char *parms[])
                selection_left = 2;
                paren_nest = 0;
                for (i=2; i<num_parms; ++i) {
-                       for (j=0; j<strlen(parms[i]); ++j) {
+                       for (j=0; parms[i][j]; ++j) {
                                if (parms[i][j] == '(') ++paren_nest;
                                if (parms[i][j] == ')') --paren_nest;
                        }
@@ -276,20 +276,7 @@ void imap_list(int num_parms, char *parms[])
 
                for (i=selection_left; i<=selection_right; ++i) {
 
-                       /* are we in the middle of a metadata select block? */
-                       if ((select_metadata_left >= 0) && (select_metadata_right < 0)) {
-                               select_metadata_nest += haschar(parms[i], '(') - haschar(parms[i], ')') ;
-                               if (select_metadata_nest == 0) {
-                                       select_metadata_right = i;
-                               }
-                       }
-
-                       else if (!strcasecmp(parms[i], "METADATA")) {
-                               select_metadata_left = i+1;
-                               select_metadata_nest = 0;
-                       }
-
-                       else if (!strcasecmp(parms[i], "SUBSCRIBED")) {
+                       if (!strcasecmp(parms[i], "SUBSCRIBED")) {
                                subscribed_rooms_only = 1;
                        }
 
@@ -301,9 +288,6 @@ void imap_list(int num_parms, char *parms[])
 
        }
 
-       lprintf(CTDL_DEBUG, "select metadata: %d to %d\n", select_metadata_left, select_metadata_right);
-       /* FIXME blah, we have to do something with this */
-
        /* The folder root appears immediately after the selection options,
         * or in position 2 if no selection options were specified.
         */
@@ -314,7 +298,7 @@ void imap_list(int num_parms, char *parms[])
                extended_list_in_use = 1;
                paren_nest = 0;
                for (i=patterns_left; i<num_parms; ++i) {
-                       for (j=0; j<strlen(parms[i]); ++j) {
+                       for (j=0; &parms[i][j]; ++j) {
                                if (parms[i][j] == '(') ++paren_nest;
                                if (parms[i][j] == ')') --paren_nest;
                        }
@@ -351,7 +335,7 @@ void imap_list(int num_parms, char *parms[])
                extended_list_in_use = 1;
                paren_nest = 0;
                for (i=return_left; i<num_parms; ++i) {
-                       for (j=0; j<strlen(parms[i]); ++j) {
+                       for (j=0; parms[i][j]; ++j) {
                                if (parms[i][j] == '(') ++paren_nest;
                                if (parms[i][j] == ')') --paren_nest;
                        }
@@ -359,7 +343,7 @@ void imap_list(int num_parms, char *parms[])
                        /* Might as well look for these while we're in here... */
                        if (parms[i][0] == '(') strcpy(parms[i], &parms[i][1]);
                        if (parms[i][strlen(parms[i])-1] == ')') parms[i][strlen(parms[i])-1] = 0;
-                       lprintf(9, "evaluating <%s>\n", parms[i]);
+                       CtdlLogPrintf(9, "evaluating <%s>\n", parms[i]);
 
                        if (!strcasecmp(parms[i], "SUBSCRIBED")) {
                                return_subscribed = 1;
@@ -369,10 +353,6 @@ void imap_list(int num_parms, char *parms[])
                                return_children = 1;
                        }
 
-                       else if (!strcasecmp(parms[i], "METADATA")) {
-                               return_metadata = 1;
-                       }
-
                        if (paren_nest == 0) {
                                return_right = i;       /* found end of patterns */
                                i = num_parms + 1;      /* break out of the loop */
@@ -388,14 +368,13 @@ void imap_list(int num_parms, char *parms[])
        data_for_callback[3] = (char *) patterns;
        data_for_callback[4] = (char *) return_subscribed;
        data_for_callback[5] = (char *) return_children;
-       data_for_callback[6] = (char *) return_metadata;
 
        /* The non-extended LIST command is required to treat an empty
         * ("" string) mailbox name argument as a special request to return the
         * hierarchy delimiter and the root name of the name given in the
         * reference parameter.
         */
-       if ( (strlen(patterns[0]) == 0) && (extended_list_in_use == 0) ) {
+       if ( (IsEmptyStr(patterns[0])) && (extended_list_in_use == 0) ) {
                cprintf("* %s (\\Noselect) \"/\" \"\"\r\n", verb);
        }