* rework imap tokenizer, we no longer copy the stuff around, we keep a reference...
authorWilfried Göesgens <willi@citadel.org>
Thu, 25 Feb 2010 22:43:57 +0000 (22:43 +0000)
committerWilfried Göesgens <willi@citadel.org>
Thu, 25 Feb 2010 22:43:57 +0000 (22:43 +0000)
* we may have "unlimited" numbers of tokens
* spread the change of ConstStr all over the imap server
* lots of consts all over the whole place

35 files changed:
citadel/imap_tools.h
citadel/include/ctdl_module.h
citadel/internet_addressing.c
citadel/internet_addressing.h
citadel/modules/fulltext/ft_wordbreaker.c
citadel/modules/fulltext/ft_wordbreaker.h
citadel/modules/fulltext/serv_fulltext.c
citadel/modules/fulltext/serv_fulltext.h
citadel/modules/imap/imap_acl.c
citadel/modules/imap/imap_acl.h
citadel/modules/imap/imap_fetch.c
citadel/modules/imap/imap_fetch.h
citadel/modules/imap/imap_list.c
citadel/modules/imap/imap_list.h
citadel/modules/imap/imap_metadata.c
citadel/modules/imap/imap_metadata.h
citadel/modules/imap/imap_misc.c
citadel/modules/imap/imap_misc.h
citadel/modules/imap/imap_search.c
citadel/modules/imap/imap_search.h
citadel/modules/imap/imap_store.c
citadel/modules/imap/imap_store.h
citadel/modules/imap/imap_tools.c
citadel/modules/imap/serv_imap.c
citadel/modules/imap/serv_imap.h
citadel/modules/managesieve/serv_managesieve.c
citadel/modules/openid/serv_openid_rp.c
citadel/modules/pop3/serv_pop3.c
citadel/modules/smtp/serv_smtp.c
citadel/modules/wiki/serv_wiki.c
citadel/msgbase.c
citadel/msgbase.h
citadel/serv_extensions.c
citadel/serv_extensions.h
citadel/threads.c

index 75aff407b4cf24fd300b2728038d5a0bf44a7590..c0c322e94ce4739b1eacd13edc83606805102a91 100644 (file)
  */
 #define FDELIM '\\'
 
-void imap_strout(char *buf);
-int imap_parameterize(char **args, char *buf);
+typedef struct __citimap_command {
+       StrBuf *CmdBuf;                 /* our current commandline; gets chopped into: */
+       ConstStr *Params;               /* Commandline tokens */
+       int num_parms;                  /* Number of Commandline tokens available */
+       int avail_parms;                /* Number of ConstStr args is big */
+} citimap_command;
+
+/* 
+ * since we work with shifted pointers to ConstStrs in some places, 
+ * we can't just say we want to cut the n'th of Cmd, we have to pass it in
+ * and rely on that CutMe references Cmd->CmdBuf; else peek won't work out
+ * and len will differ.
+ */
+void TokenCutRight(citimap_command *Cmd, 
+                  ConstStr *CutMe,
+                  int n);
+/*
+ * since we just move Key around here, Cmd is just here so the syntax is identical.
+ */
+void TokenCutLeft(citimap_command *Cmd, 
+                 ConstStr *CutMe,
+                 int n);
+
+
+void imap_strout(ConstStr *args);
+void plain_imap_strout(char *buf);
+int imap_parameterize(citimap_command *Cmd);
+int old_imap_parameterize(char** args, char *n);
 void imap_mailboxname(char *buf, int bufsize, struct ctdlroom *qrbuf);
 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_roomname(char *buf, int bufsize, const char *foldername);
+int imap_is_message_set(const char *);
 int imap_mailbox_matches_pattern(char *pattern, char *mailboxname);
-int imap_datecmp(char *datestr, time_t msgtime);
+int imap_datecmp(const char *datestr, time_t msgtime);
 
 /*
  * Flags that may be returned by imap_roomname()
index 83a51c2a9d0908497b8f0053d96af0a415d54172..8f3d3f7417a7d8b7aaff11378d65ca7ca3ccb4aa 100644 (file)
@@ -134,7 +134,7 @@ void CtdlUnRegisterFixedOutputHook(char *content_type);
 
 void CtdlRegisterMaintenanceThread(char *name, void *(*thread_proc) (void *arg));
 
-void CtdlRegisterSearchFuncHook(void (*fcn_ptr)(int *, long **, char *), char *name);
+void CtdlRegisterSearchFuncHook(void (*fcn_ptr)(int *, long **, const char *), char *name);
 
 
 /*
@@ -285,7 +285,7 @@ enum {
 /*
  * API declarations from serv_extensions.h
  */
-void CtdlModuleDoSearch(int *num_msgs, long **search_msgs, char *search_string, char *func_name);
+void CtdlModuleDoSearch(int *num_msgs, long **search_msgs, const char *search_string, const char *func_name);
 /* 
  * Global system configuration.  Don't change anything here.  It's all in dtds/config-defs.h now.
  */
index 23c08d4bf8ae6777b7b5f3a6dec3bc6093b61b23..14439a6abce4d3b8fa8a922c6b216406492a4a1a 100644 (file)
@@ -837,11 +837,11 @@ struct CtdlMessage *convert_internet_message_buf(StrBuf **rfc822)
  * The caller is responsible for freeing the returned buffer.  If the requested
  * field is not present, or anything else goes wrong, it returns NULL.
  */
-char *rfc822_fetch_field(char *rfc822, char *fieldname) {
+char *rfc822_fetch_field(char *rfc822, const char *fieldname) {
        char *fieldbuf = NULL;
-       char *end_of_headers;
-       char *field_start;
-       char *ptr;
+       const char *end_of_headers;
+       const char *field_start;
+       const char *ptr;
        char *cont;
        char fieldhdr[SIZ];
 
index 0a31c2662f9868773aedbd85d02e758365191c85..ca4c2da6e1e7afb3b080604fa5e81e14fdda65b4 100644 (file)
@@ -15,7 +15,7 @@ struct internet_address_list {
 
 int fuzzy_match(struct ctdluser *us, char *matchstring);
 void process_rfc822_addr(const char *rfc822, char *user, char *node, char *name);
-char *rfc822_fetch_field(char *rfc822, char *fieldname);
+char *rfc822_fetch_field(char *rfc822, const char *fieldname);
 
 int IsDirectory(char *addr, int allow_masq_domains);
 void CtdlDirectoryInit(void);
index 0e8dade3bc9747b103bbb3f12100ea4cd3a70f43..5308e87576bcecc2f9efafe92fdede33af35461e 100644 (file)
@@ -191,15 +191,15 @@ int intcmp(const void *rec1, const void *rec2) {
 }
 
 
-void wordbreaker(char *text, int *num_tokens, int **tokens) {
+void wordbreaker(const char *text, int *num_tokens, int **tokens) {
 
        int wb_num_tokens = 0;
        int wb_num_alloc = 0;
        int *wb_tokens = NULL;
 
-       char *ptr;
-       char *word_start;
-       char *word_end;
+       const char *ptr;
+       const char *word_start;
+       const char *word_end;
        char ch;
        int word_len;
        char word[256];
index 5ba67fa24327bd721357182f9e65ace3e099dd51..001dda815b3d49324273074984a9f41317bbc56e 100644 (file)
@@ -33,7 +33,7 @@
 #define WB_MIN                 4       // nothing with 3 or less chars
 #define WB_MAX                 40
 
-void wordbreaker(char *text, int *num_tokens, int **tokens);
+void wordbreaker(const char *text, int *num_tokens, int **tokens);
 
 void initialize_noise_words(void);
 void noise_word_cleanup(void);
index c76671d8ef6e0fe55ec9ae70bf560b84de29a07c..0c2786d0da66159a34dd8b75b7a112e3d6d86c7f 100644 (file)
@@ -397,7 +397,7 @@ void *indexer_thread(void *arg) {
  * (This one does the "all of these words" search.)
  * Caller is responsible for freeing the message list.
  */
-void ft_search(int *fts_num_msgs, long **fts_msgs, char *search_string) {
+void ft_search(int *fts_num_msgs, long **fts_msgs, const char *search_string) {
        int num_tokens = 0;
        int *tokens = NULL;
        int i, j;
index b061256cb35f022d72f2e93fa6fe2078aa06b053..6793f47903c5231831ce681e6258619a2574598c 100644 (file)
@@ -20,5 +20,5 @@
  */
 
 void ft_index_message(long msgnum, int op);
-void ft_search(int *fts_num_msgs, long **fts_msgs, char *search_string);
+void ft_search(int *fts_num_msgs, long **fts_msgs, const char *search_string);
 void *indexer_thread(void *arg);
index 3aff977122cad4a5fcd54e5bed883530816d43df..f8e706988bc946ef6520e4e4b43d26fe0b84e2f4 100644 (file)
@@ -58,8 +58,8 @@
 #include "database.h"
 #include "msgbase.h"
 #include "internet_addressing.h"
-#include "serv_imap.h"
 #include "imap_tools.h"
+#include "serv_imap.h"
 #include "imap_fetch.h"
 #include "imap_misc.h"
 #include "genstamp.h"
@@ -69,9 +69,9 @@
 /*
  * Implements the SETACL command.
  */
-void imap_setacl(int num_parms, char *parms[]) {
+void imap_setacl(int num_parms, ConstStr *Params) {
 
-       cprintf("%s BAD not yet implemented FIXME\r\n", parms[0]);
+       cprintf("%s BAD not yet implemented FIXME\r\n", Params[0].Key);
        return;
 }
 
@@ -79,9 +79,9 @@ void imap_setacl(int num_parms, char *parms[]) {
 /*
  * Implements the DELETEACL command.
  */
-void imap_deleteacl(int num_parms, char *parms[]) {
+void imap_deleteacl(int num_parms, ConstStr *Params) {
 
-       cprintf("%s BAD not yet implemented FIXME\r\n", parms[0]);
+       cprintf("%s BAD not yet implemented FIXME\r\n", Params[0].Key);
        return;
 }
 
@@ -143,7 +143,7 @@ void imap_acl_flags(char *rights, int ra)
 /*
  * Implements the GETACL command.
  */
-void imap_getacl(int num_parms, char *parms[]) {
+void imap_getacl(int num_parms, ConstStr *Params) {
        char roomname[ROOMNAMELEN];
        char savedroom[ROOMNAMELEN];
        int msgs, new;
@@ -154,16 +154,16 @@ void imap_getacl(int num_parms, char *parms[]) {
        char rights[32];
 
        if (num_parms != 3) {
-               cprintf("%s BAD usage error\r\n", parms[0]);
+               cprintf("%s BAD usage error\r\n", Params[0].Key);
                return;
        }
 
        /*
         * Search for the specified room or folder
         */
-       ret = imap_grabroom(roomname, parms[2], 1);
+       ret = imap_grabroom(roomname, Params[2].Key, 1);
        if (ret != 0) {
-               cprintf("%s NO Invalid mailbox name or access denied\r\n", parms[0]);
+               cprintf("%s NO Invalid mailbox name or access denied\r\n", Params[0].Key);
                return;
        }
 
@@ -178,7 +178,7 @@ void imap_getacl(int num_parms, char *parms[]) {
 
        cprintf("* ACL");
        cprintf(" ");
-       imap_strout(parms[2]);
+       imap_strout(&Params[2]);
 
        /*
         * Traverse the userlist
@@ -194,7 +194,7 @@ void imap_getacl(int num_parms, char *parms[]) {
                        imap_acl_flags(rights, ra);
                        if (!IsEmptyStr(rights)) {
                                cprintf(" ");
-                               imap_strout(temp.fullname);
+                               plain_imap_strout(temp.fullname);
                                cprintf(" %s", rights);
                        }
                }
@@ -210,14 +210,14 @@ void imap_getacl(int num_parms, char *parms[]) {
                CtdlUserGoto(savedroom, 0, 0, &msgs, &new);
        }
 
-       cprintf("%s OK GETACL completed\r\n", parms[0]);
+       cprintf("%s OK GETACL completed\r\n", Params[0].Key);
 }
 
 
 /*
  * Implements the LISTRIGHTS command.
  */
-void imap_listrights(int num_parms, char *parms[]) {
+void imap_listrights(int num_parms, ConstStr *Params) {
        char roomname[ROOMNAMELEN];
        char savedroom[ROOMNAMELEN];
        int msgs, new;
@@ -226,16 +226,16 @@ void imap_listrights(int num_parms, char *parms[]) {
        struct ctdluser temp;
 
        if (num_parms != 4) {
-               cprintf("%s BAD usage error\r\n", parms[0]);
+               cprintf("%s BAD usage error\r\n", Params[0].Key);
                return;
        }
 
        /*
         * Search for the specified room/folder
         */
-       ret = imap_grabroom(roomname, parms[2], 1);
+       ret = imap_grabroom(roomname, Params[2].Key, 1);
        if (ret != 0) {
-               cprintf("%s NO Invalid mailbox name or access denied\r\n", parms[0]);
+               cprintf("%s NO Invalid mailbox name or access denied\r\n", Params[0].Key);
                return;
        }
 
@@ -243,7 +243,7 @@ void imap_listrights(int num_parms, char *parms[]) {
         * Search for the specified user
         */
        ret = (-1);
-       valid = validate_recipients(parms[3], NULL, 0);
+       valid = validate_recipients(Params[3].Key, NULL, 0);
        if (valid != NULL) {
                if (valid->num_local == 1) {
                        ret = CtdlGetUser(&temp, valid->recp_local);
@@ -251,7 +251,7 @@ void imap_listrights(int num_parms, char *parms[]) {
                free_recipients(valid);
        }
        if (ret != 0) {
-               cprintf("%s NO Invalid user name or access denied\r\n", parms[0]);
+               cprintf("%s NO Invalid user name or access denied\r\n", Params[0].Key);
                return;
        }
 
@@ -268,11 +268,11 @@ void imap_listrights(int num_parms, char *parms[]) {
         * Now output the list of rights
         */
        cprintf("* LISTRIGHTS ");
-       imap_strout(parms[2]);
+       imap_strout(&Params[2]);
        cprintf(" ");
-       imap_strout(parms[3]);
+       imap_strout(&Params[3]);
        cprintf(" ");
-       imap_strout("");                /* FIXME ... do something here */
+       plain_imap_strout("");          /* FIXME ... do something here */
        cprintf("\r\n");
 
        /*
@@ -283,7 +283,7 @@ void imap_listrights(int num_parms, char *parms[]) {
                CtdlUserGoto(savedroom, 0, 0, &msgs, &new);
        }
 
-       cprintf("%s OK LISTRIGHTS completed\r\n", parms[0]);
+       cprintf("%s OK LISTRIGHTS completed\r\n", Params[0].Key);
        return;
 }
 
@@ -291,7 +291,7 @@ void imap_listrights(int num_parms, char *parms[]) {
 /*
  * Implements the MYRIGHTS command.
  */
-void imap_myrights(int num_parms, char *parms[]) {
+void imap_myrights(int num_parms, ConstStr *Params) {
        char roomname[ROOMNAMELEN];
        char savedroom[ROOMNAMELEN];
        int msgs, new;
@@ -300,13 +300,13 @@ void imap_myrights(int num_parms, char *parms[]) {
        char rights[32];
 
        if (num_parms != 3) {
-               cprintf("%s BAD usage error\r\n", parms[0]);
+               cprintf("%s BAD usage error\r\n", Params[0].Key);
                return;
        }
 
-       ret = imap_grabroom(roomname, parms[2], 1);
+       ret = imap_grabroom(roomname, Params[2].Key, 1);
        if (ret != 0) {
-               cprintf("%s NO Invalid mailbox name or access denied\r\n", parms[0]);
+               cprintf("%s NO Invalid mailbox name or access denied\r\n", Params[0].Key);
                return;
        }
 
@@ -323,7 +323,7 @@ void imap_myrights(int num_parms, char *parms[]) {
        imap_acl_flags(rights, ra);
 
        cprintf("* MYRIGHTS ");
-       imap_strout(parms[2]);
+       imap_strout(&Params[2]);
        cprintf(" %s\r\n", rights);
 
        /*
@@ -333,6 +333,6 @@ void imap_myrights(int num_parms, char *parms[]) {
                CtdlUserGoto(savedroom, 0, 0, &msgs, &new);
        }
 
-       cprintf("%s OK MYRIGHTS completed\r\n", parms[0]);
+       cprintf("%s OK MYRIGHTS completed\r\n", Params[0].Key);
        return;
 }
index 06f4387058743bd627c792d4bd438557cf83d68b..f4d1f50e0a07f9f41c0fb68ac78fbe97272ba76c 100644 (file)
@@ -19,9 +19,9 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-void imap_setacl(int num_parms, char *parms[]);
-void imap_deleteacl(int num_parms, char *parms[]);
-void imap_getacl(int num_parms, char *parms[]);
-void imap_listrights(int num_parms, char *parms[]);
-void imap_myrights(int num_parms, char *parms[]);
+void imap_setacl(int num_parms, ConstStr *Params);
+void imap_deleteacl(int num_parms, ConstStr *Params);
+void imap_getacl(int num_parms, ConstStr *Params);
+void imap_listrights(int num_parms, ConstStr *Params);
+void imap_myrights(int num_parms, ConstStr *Params);
 
index df317780fd118e00075d5c29c723b94b60a3739d..0f65985b5f0b564e99ee6e5cadd8e948690fe09a 100644 (file)
@@ -59,8 +59,8 @@
 #include "database.h"
 #include "msgbase.h"
 #include "internet_addressing.h"
-#include "serv_imap.h"
 #include "imap_tools.h"
+#include "serv_imap.h"
 #include "imap_fetch.h"
 #include "genstamp.h"
 #include "ctdl_module.h"
@@ -130,7 +130,7 @@ void imap_fetch_internaldate(struct CtdlMessage *msg) {
  */
 void imap_fetch_rfc822(long msgnum, char *whichfmt) {
        char buf[SIZ];
-       char *ptr = NULL;
+       const char *ptr = NULL;
        size_t headers_size, text_size, total_size;
        size_t bytes_to_send = 0;
        struct MetaData smi;
@@ -336,25 +336,25 @@ void imap_output_envelope_from(struct CtdlMessage *msg) {
 
        /* For everything else, we do stuff. */
        cprintf("((");                          /* open double-parens */
-       imap_strout(msg->cm_fields['A']);       /* personal name */
+       plain_imap_strout(msg->cm_fields['A']); /* personal name */
        cprintf(" NIL ");                       /* source route (not used) */
 
 
        if (msg->cm_fields['F'] != NULL) {
                process_rfc822_addr(msg->cm_fields['F'], user, node, name);
-               imap_strout(user);              /* mailbox name (user id) */
+               plain_imap_strout(user);                /* mailbox name (user id) */
                cprintf(" ");
                if (!strcasecmp(node, config.c_nodename)) {
-                       imap_strout(config.c_fqdn);
+                       plain_imap_strout(config.c_fqdn);
                }
                else {
-                       imap_strout(node);              /* host name */
+                       plain_imap_strout(node);                /* host name */
                }
        }
        else {
-               imap_strout(msg->cm_fields['A']); /* mailbox name (user id) */
+               plain_imap_strout(msg->cm_fields['A']); /* mailbox name (user id) */
                cprintf(" ");
-               imap_strout(msg->cm_fields['N']);       /* host name */
+               plain_imap_strout(msg->cm_fields['N']); /* host name */
        }
        
        cprintf(")) ");                         /* close double-parens */
@@ -397,11 +397,11 @@ void imap_output_envelope_addr(char *addr) {
                striplt(individual_addr);
                process_rfc822_addr(individual_addr, user, node, name);
                cprintf("(");
-               imap_strout(name);
+               plain_imap_strout(name);
                cprintf(" NIL ");
-               imap_strout(user);
+               plain_imap_strout(user);
                cprintf(" ");
-               imap_strout(node);
+               plain_imap_strout(node);
                cprintf(")");
                if (i < (num_addrs-1)) cprintf(" ");
        }
@@ -441,11 +441,11 @@ void imap_fetch_envelope(struct CtdlMessage *msg) {
        cprintf("ENVELOPE (");
 
        /* Date */
-       imap_strout(datestringbuf);
+       plain_imap_strout(datestringbuf);
        cprintf(" ");
 
        /* Subject */
-       imap_strout(msg->cm_fields['U']);
+       plain_imap_strout(msg->cm_fields['U']);
        cprintf(" ");
 
        /* From */
@@ -492,12 +492,12 @@ void imap_fetch_envelope(struct CtdlMessage *msg) {
 
        /* In-reply-to */
        fieldptr = rfc822_fetch_field(msg->cm_fields['M'], "In-reply-to");
-       imap_strout(fieldptr);
+       plain_imap_strout(fieldptr);
        cprintf(" ");
        if (fieldptr != NULL) free(fieldptr);
 
        /* message ID */
-       imap_strout(msg->cm_fields['I']);
+       plain_imap_strout(msg->cm_fields['I']);
 
        cprintf(")");
 }
@@ -518,7 +518,7 @@ void imap_strip_headers(char *section) {
        char *boiled_headers = NULL;
        int ok = 0;
        int done_headers = 0;
-       char *ptr = NULL;
+       const char *ptr = NULL;
 
        if (CC->redirect_buffer == NULL) return;
 
@@ -539,7 +539,7 @@ void imap_strip_headers(char *section) {
                        break;
                }
        }
-       num_parms = imap_parameterize(parms, which_fields);
+       num_parms = old_imap_parameterize(parms, which_fields);
 
        boiled_headers = malloc(CC->redirect_alloc);
        strcpy(boiled_headers, "");
@@ -761,7 +761,7 @@ void imap_fetch_bodystructure_post(
 
        /* disposition */
        extract_token(subtype, cbtype, 1, '/', sizeof subtype);
-       imap_strout(subtype);
+       plain_imap_strout(subtype);
 
        /* body language */
        /* cprintf(" NIL"); We thought we needed this at one point, but maybe we don't... */
@@ -799,9 +799,9 @@ void imap_fetch_bodystructure_part(
        }
 
        cprintf("(");
-       imap_strout(cbmaintype);                                        /* body type */
+       plain_imap_strout(cbmaintype);                                  /* body type */
        cprintf(" ");
-       imap_strout(cbsubtype);                                         /* body subtype */
+       plain_imap_strout(cbsubtype);                                           /* body subtype */
        cprintf(" ");
 
        cprintf("(");                                                   /* begin body parameter list */
@@ -812,19 +812,19 @@ void imap_fetch_bodystructure_part(
         */
        if (name != NULL) if (!IsEmptyStr(name)) {
                cprintf("\"NAME\" ");
-               imap_strout(name);
+               plain_imap_strout(name);
                cprintf(" ");
        }
 
        cprintf("\"CHARSET\" ");
        if (cbcharset == NULL) {
-               imap_strout("US-ASCII");
+               plain_imap_strout("US-ASCII");
        }
        else if (cbcharset[0] == 0) {
-               imap_strout("US-ASCII");
+               plain_imap_strout("US-ASCII");
        }
        else {
-               imap_strout(cbcharset);
+               plain_imap_strout(cbcharset);
        }
        cprintf(") ");                                                  /* end body parameter list */
 
@@ -833,10 +833,10 @@ void imap_fetch_bodystructure_part(
 
        if (encoding != NULL) if (encoding[0] != 0)  have_encoding = 1;
        if (have_encoding) {
-               imap_strout(encoding);
+               plain_imap_strout(encoding);
        }
        else {
-               imap_strout("7BIT");
+               plain_imap_strout("7BIT");
        }
        cprintf(" ");
 
@@ -875,10 +875,10 @@ void imap_fetch_bodystructure_part(
        }
        else {
                cprintf("(");
-               imap_strout(disp);
+               plain_imap_strout(disp);
                if (filename != NULL) if (!IsEmptyStr(filename)) {
                        cprintf(" (\"FILENAME\" ");
-                       imap_strout(filename);
+                       plain_imap_strout(filename);
                        cprintf(")");
                }
                cprintf(")");
@@ -896,12 +896,13 @@ void imap_fetch_bodystructure_part(
  */
 void imap_fetch_bodystructure (long msgnum, char *item,
                struct CtdlMessage *msg) {
-       char *rfc822 = NULL;
-       char *rfc822_body = NULL;
+       const char *rfc822 = NULL;
+       const char *rfc822_body = NULL;
        size_t rfc822_len;
        size_t rfc822_headers_len;
        size_t rfc822_body_len;
-       char *ptr = NULL;
+       const char *ptr = NULL;
+       char *pch;
        char buf[SIZ];
        int lines = 0;
 
@@ -926,7 +927,7 @@ void imap_fetch_bodystructure (long msgnum, char *item,
                CC->redirect_len = 0;
                CC->redirect_alloc = SIZ;
                CtdlOutputPreLoadedMsg(msg, MT_RFC822, 0, 0, 1, SUPPRESS_ENV_TO);
-               rfc822 = CC->redirect_buffer;
+               rfc822 = pch = CC->redirect_buffer;
                rfc822_len = CC->redirect_len;
                CC->redirect_buffer = NULL;
                CC->redirect_len = 0;
@@ -943,7 +944,7 @@ void imap_fetch_bodystructure (long msgnum, char *item,
 
                rfc822_headers_len = rfc822_body - rfc822;
                rfc822_body_len = rfc822_len - rfc822_headers_len;
-               free(rfc822);
+               free(pch);
 
                cprintf("BODYSTRUCTURE (\"TEXT\" \"PLAIN\" "
                        "(\"CHARSET\" \"US-ASCII\") NIL NIL "
@@ -1225,14 +1226,14 @@ int imap_extract_data_items(char **argv, char *items) {
  *
  * Set is_uid to 1 to fetch by UID instead of sequence number.
  */
-void imap_pick_range(char *supplied_range, int is_uid) {
+void imap_pick_range(const char *supplied_range, int is_uid) {
        int i;
        int num_sets;
        int s;
        char setstr[SIZ], lostr[SIZ], histr[SIZ];
        long lo, hi;
        char actual_range[SIZ];
-       struct citimap *Imap;
+       citimap *Imap;
 
        /* 
         * Handle the "ALL" macro
@@ -1292,39 +1293,39 @@ void imap_pick_range(char *supplied_range, int is_uid) {
 /*
  * This function is called by the main command loop.
  */
-void imap_fetch(int num_parms, char *parms[]) {
+void imap_fetch(int num_parms, ConstStr *Params) {
        char items[SIZ];
        char *itemlist[512];
        int num_items;
        int i;
 
        if (num_parms < 4) {
-               cprintf("%s BAD invalid parameters\r\n", parms[0]);
+               cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
                return;
        }
 
-       imap_pick_range(parms[2], 0);
+       imap_pick_range(Params[2].Key, 0);
 
        strcpy(items, "");
        for (i=3; i<num_parms; ++i) {
-               strcat(items, parms[i]);
+               strcat(items, Params[i].Key);
                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]);
+               cprintf("%s BAD invalid data item list\r\n", Params[0].Key);
                return;
        }
 
        imap_do_fetch(num_items, itemlist);
-       cprintf("%s OK FETCH completed\r\n", parms[0]);
+       cprintf("%s OK FETCH completed\r\n", Params[0].Key);
 }
 
 /*
  * This function is called by the main command loop.
  */
-void imap_uidfetch(int num_parms, char *parms[]) {
+void imap_uidfetch(int num_parms, ConstStr *Params) {
        char items[SIZ];
        char *itemlist[512];
        int num_items;
@@ -1332,21 +1333,21 @@ void imap_uidfetch(int num_parms, char *parms[]) {
        int have_uid_item = 0;
 
        if (num_parms < 5) {
-               cprintf("%s BAD invalid parameters\r\n", parms[0]);
+               cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
                return;
        }
 
-       imap_pick_range(parms[3], 1);
+       imap_pick_range(Params[3].Key, 1);
 
        strcpy(items, "");
        for (i=4; i<num_parms; ++i) {
-               strcat(items, parms[i]);
+               strcat(items, Params[i].Key);
                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]);
+               cprintf("%s BAD invalid data item list\r\n", Params[0].Key);
                return;
        }
 
@@ -1363,7 +1364,7 @@ void imap_uidfetch(int num_parms, char *parms[]) {
        }
 
        imap_do_fetch(num_items, itemlist);
-       cprintf("%s OK UID FETCH completed\r\n", parms[0]);
+       cprintf("%s OK UID FETCH completed\r\n", Params[0].Key);
 }
 
 
index 362ed9d9fc0f33ce11d909c35347edbe6cf4ba3f..aefaa112a8a29f10678edba6406e9c276fc97794 100644 (file)
@@ -19,8 +19,8 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-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[]);
+void imap_pick_range(const char *range, int is_uid);
+void imap_fetch(int num_parms, ConstStr *Params);
+void imap_uidfetch(int num_parms, ConstStr *Params);
 void imap_fetch_flags(int seq);
 int imap_extract_data_items(char **argv, char *items);
index e6f6c19d46760ad5696284d4a1bc9b3d216fd36a..235acfdf48b3f76e50a56c30158e280018ee3136 100644 (file)
@@ -57,8 +57,8 @@
 #include "database.h"
 #include "msgbase.h"
 #include "internet_addressing.h"
-#include "serv_imap.h"
 #include "imap_tools.h"
+#include "serv_imap.h"
 #include "imap_fetch.h"
 #include "imap_search.h"
 #include "imap_store.h"
@@ -89,7 +89,7 @@ void imap_list_floors(char *verb, int num_patterns, char **patterns)
                        }
                        if (match) {
                                cprintf("* %s (\\NoSelect \\HasChildren) \"/\" ", verb);
-                               imap_strout(fl->f_name);
+                               plain_imap_strout(fl->f_name);
                                cprintf("\r\n");
                        }
                }
@@ -176,7 +176,7 @@ void imap_listroom(struct ctdlroom *qrbuf, void *data)
                }
                if (match) {
                        cprintf("* %s (%s) \"/\" ", verb, return_options);
-                       imap_strout(buf);
+                       plain_imap_strout(buf);
                        cprintf("\r\n");
                }
        }
@@ -186,7 +186,7 @@ void imap_listroom(struct ctdlroom *qrbuf, void *data)
 /*
  * Implements the LIST and LSUB commands
  */
-void imap_list(int num_parms, char *parms[])
+void imap_list(int num_parms, ConstStr *Params)
 {
        int subscribed_rooms_only = 0;
        char verb[16];
@@ -206,15 +206,15 @@ void imap_list(int num_parms, char *parms[])
        int return_children = 0;
 
        if (num_parms < 4) {
-               cprintf("%s BAD arguments invalid\r\n", parms[0]);
+               cprintf("%s BAD arguments invalid\r\n", Params[0].Key);
                return;
        }
 
        /* parms[1] is the IMAP verb being used (e.g. LIST or LSUB)
         * This tells us how to behave, and what verb to return back to the caller
         */
-       safestrncpy(verb, parms[1], sizeof verb);
-       j = strlen(verb);
+       safestrncpy(verb, Params[1].Key, sizeof verb);
+       j = Params[1].len;
        for (i=0; i<j; ++i) {
                verb[i] = toupper(verb[i]);
        }
@@ -244,14 +244,14 @@ void imap_list(int num_parms, char *parms[])
         * selection options.  Extract their exact position, and then modify our
         * expectation of where the root folder will be specified.
         */
-       if (parms[2][0] == '(') {
+       if (Params[2].Key[0] == '(') {
                extended_list_in_use = 1;
                selection_left = 2;
                paren_nest = 0;
                for (i=2; i<num_parms; ++i) {
-                       for (j=0; parms[i][j]; ++j) {
-                               if (parms[i][j] == '(') ++paren_nest;
-                               if (parms[i][j] == ')') --paren_nest;
+                       for (j=0; Params[i].Key[j]; ++j) {
+                               if (Params[i].Key[j] == '(') ++paren_nest;
+                               if (Params[i].Key[j] == ')') --paren_nest;
                        }
                        if (paren_nest == 0) {
                                selection_right = i;    /* found end of selection options */
@@ -266,20 +266,24 @@ void imap_list(int num_parms, char *parms[])
        if ((selection_left > 0) && (selection_right >= selection_left)) {
 
                /* Strip off the outer parentheses */
-               if (parms[selection_left][0] == '(') {
-                       strcpy(parms[selection_left], &parms[selection_left][1]);
+               if (Params[selection_left].Key[0] == '(') {
+                       TokenCutLeft(&IMAP->Cmd, 
+                                    &Params[selection_left], 
+                                    1);
                }
-               if (parms[selection_right][strlen(parms[selection_right])-1] == ')') {
-                       parms[selection_right][strlen(parms[selection_right])-1] = 0;
+               if (Params[selection_right].Key[Params[selection_right].len-1] == ')') {
+                       TokenCutRight(&IMAP->Cmd, 
+                                     &Params[selection_right], 
+                                     1);
                }
 
                for (i=selection_left; i<=selection_right; ++i) {
 
-                       if (!strcasecmp(parms[i], "SUBSCRIBED")) {
+                       if (!strcasecmp(Params[i].Key, "SUBSCRIBED")) {
                                subscribed_rooms_only = 1;
                        }
 
-                       else if (!strcasecmp(parms[i], "RECURSIVEMATCH")) {
+                       else if (!strcasecmp(Params[i].Key, "RECURSIVEMATCH")) {
                                /* FIXME - do this! */
                        }
 
@@ -293,13 +297,13 @@ void imap_list(int num_parms, char *parms[])
        patterns_left = root_pos + 1;
        patterns_right = root_pos + 1;
 
-       if (parms[patterns_left][0] == '(') {
+       if (Params[patterns_left].Key[0] == '(') {
                extended_list_in_use = 1;
                paren_nest = 0;
                for (i=patterns_left; i<num_parms; ++i) {
-                       for (j=0; &parms[i][j]; ++j) {
-                               if (parms[i][j] == '(') ++paren_nest;
-                               if (parms[i][j] == ')') --paren_nest;
+                       for (j=0; &Params[i].Key[j]; ++j) {
+                               if (Params[i].Key[j] == '(') ++paren_nest;
+                               if (Params[i].Key[j] == ')') --paren_nest;
                        }
                        if (paren_nest == 0) {
                                patterns_right = i;     /* found end of patterns */
@@ -310,7 +314,7 @@ void imap_list(int num_parms, char *parms[])
                for (i=0; i<num_patterns; ++i) {
                        if (i < MAX_PATTERNS) {
                                patterns[i] = malloc(512);
-                               snprintf(patterns[i], 512, "%s%s", parms[root_pos], parms[patterns_left+i]);
+                               snprintf(patterns[i], 512, "%s%s", Params[root_pos].Key, Params[patterns_left+i].Key);
                                if (i == 0) {
                                        strcpy(patterns[i], &patterns[i][1]);
                                }
@@ -323,32 +327,41 @@ void imap_list(int num_parms, char *parms[])
        else {
                num_patterns = 1;
                patterns[0] = malloc(512);
-               snprintf(patterns[0], 512, "%s%s", parms[root_pos], parms[patterns_left]);
+               snprintf(patterns[0], 512, "%s%s", 
+                        Params[root_pos].Key, 
+                        Params[patterns_left].Key);
        }
 
        /* If the word "RETURN" appears after the folder pattern list, then the client
         * is specifying return options.
         */
-       if (num_parms - patterns_right > 2) if (!strcasecmp(parms[patterns_right+1], "RETURN")) {
+       if (num_parms - patterns_right > 2) if (!strcasecmp(Params[patterns_right+1].Key, "RETURN")) {
                return_left = patterns_right + 2;
                extended_list_in_use = 1;
                paren_nest = 0;
                for (i=return_left; i<num_parms; ++i) {
-                       for (j=0; parms[i][j]; ++j) {
-                               if (parms[i][j] == '(') ++paren_nest;
-                               if (parms[i][j] == ')') --paren_nest;
+                       for (j=0;   Params[i].Key[j]; ++j) {
+                               if (Params[i].Key[j] == '(') ++paren_nest;
+                               if (Params[i].Key[j] == ')') --paren_nest;
                        }
 
                        /* 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;
-                       CtdlLogPrintf(9, "evaluating <%s>\n", parms[i]);
-
-                       if (!strcasecmp(parms[i], "SUBSCRIBED")) {
+                       if (Params[i].Key[0] == '(') 
+                               TokenCutLeft(&IMAP->Cmd, 
+                                            &Params[i], 
+                                            1);
+                       if (Params[i].Key[Params[i].len-1] == ')')
+                           TokenCutRight(&IMAP->Cmd, 
+                                         &Params[i], 
+                                         1);
+
+                       CtdlLogPrintf(9, "evaluating <%s>\n", Params[i].Key);
+
+                       if (!strcasecmp(Params[i].Key, "SUBSCRIBED")) {
                                return_subscribed = 1;
                        }
 
-                       else if (!strcasecmp(parms[i], "CHILDREN")) {
+                       else if (!strcasecmp(Params[i].Key, "CHILDREN")) {
                                return_children = 1;
                        }
 
@@ -392,5 +405,5 @@ void imap_list(int num_parms, char *parms[])
                free(patterns[i]);
        }
 
-       cprintf("%s OK %s completed\r\n", parms[0], verb);
+       cprintf("%s OK %s completed\r\n", Params[0].Key, verb);
 }
index e65d855dee7f9882ea174b2a20e855b80f597ef4..b780c7e0f1580a252e6c199011a19d360b402d42 100644 (file)
@@ -8,4 +8,4 @@
  */
 #define MAX_PATTERNS 20
 
-void imap_list(int num_parms, char *parms[]);
+void imap_list(int num_parms, ConstStr *Params);
index 8e173a0f396a64ec3d08b24fc9e2f9e96cbd0470..b8a8979676476cbc3f631e2190800bca45c0a7a7 100644 (file)
@@ -60,8 +60,8 @@
 #include "database.h"
 #include "msgbase.h"
 #include "internet_addressing.h"
-#include "serv_imap.h"
 #include "imap_tools.h"
+#include "serv_imap.h"
 #include "imap_fetch.h"
 #include "imap_misc.h"
 #include "genstamp.h"
@@ -76,7 +76,7 @@
  * Attempting to set anything else calls a stub which fools the client into
  * thinking that there is no remaining space available to store annotations.
  */
-void imap_setmetadata(int num_parms, char *parms[]) {
+void imap_setmetadata(int num_parms, ConstStr *Params) {
        char roomname[ROOMNAMELEN];
        char savedroom[ROOMNAMELEN];
        int msgs, new;
@@ -87,26 +87,26 @@ void imap_setmetadata(int num_parms, char *parms[]) {
        struct visit vbuf;
 
        if (num_parms != 6) {
-               cprintf("%s BAD usage error\r\n", parms[0]);
+               cprintf("%s BAD usage error\r\n", Params[0].Key);
                return;
        }
 
        /*
         * Don't allow other types of metadata to be set
         */
-       if (strcasecmp(parms[3], "/vendor/kolab/folder-type")) {
-               cprintf("%s NO [METADATA TOOMANY] SETMETADATA failed\r\n", parms[0]);
+       if (strcasecmp(Params[3].Key, "/vendor/kolab/folder-type")) {
+               cprintf("%s NO [METADATA TOOMANY] SETMETADATA failed\r\n", Params[0].Key);
                return;
        }
 
-       if (!strcasecmp(parms[4], "(value.shared")) {
+       if (!strcasecmp(Params[4].Key, "(value.shared")) {
                setting_user_value = 0;                         /* global view */
        }
-       else if (!strcasecmp(parms[4], "(value.priv")) {
+       else if (!strcasecmp(Params[4].Key, "(value.priv")) {
                setting_user_value = 1;                         /* per-user view */
        }
        else {
-               cprintf("%s NO [METADATA TOOMANY] SETMETADATA failed\r\n", parms[0]);
+               cprintf("%s NO [METADATA TOOMANY] SETMETADATA failed\r\n", Params[0].Key);
                return;
        }
 
@@ -114,7 +114,7 @@ void imap_setmetadata(int num_parms, char *parms[]) {
         * Extract the folder type without any parentheses.  Then learn
         * the Citadel view type based on the supplied folder type.
         */
-       extract_token(set_value, parms[5], 0, ')', sizeof set_value);
+       extract_token(set_value, Params[5].Key, 0, ')', sizeof set_value);
        if (!strncasecmp(set_value, "mail", 4)) {
                set_view = VIEW_MAILBOX;
        }
@@ -137,10 +137,10 @@ void imap_setmetadata(int num_parms, char *parms[]) {
                set_view = VIEW_MAILBOX;
        }
 
-       ret = imap_grabroom(roomname, parms[2], 1);
+       ret = imap_grabroom(roomname, Params[2].Key, 1);
        if (ret != 0) {
                cprintf("%s NO Invalid mailbox name or access denied\r\n",
-                       parms[0]);
+                       Params[0].Key);
                return;
        }
 
@@ -164,7 +164,7 @@ void imap_setmetadata(int num_parms, char *parms[]) {
 
        if (setting_user_value)
        {
-               cprintf("%s OK SETANNOTATION complete\r\n", parms[0]);
+               cprintf("%s OK SETANNOTATION complete\r\n", Params[0].Key);
        }
 
        /* If this is a "value.shared" set operation, we are allowed to perform it
@@ -179,12 +179,12 @@ void imap_setmetadata(int num_parms, char *parms[]) {
                CtdlGetRoomLock(&CC->room, CC->room.QRname);
                CC->room.QRdefaultview = set_view;
                CtdlPutRoomLock(&CC->room);
-               cprintf("%s OK SETANNOTATION complete\r\n", parms[0]);
+               cprintf("%s OK SETANNOTATION complete\r\n", Params[0].Key);
        }
 
        /* If we got to this point, we don't have permission to set the default view. */
        else {
-               cprintf("%s NO [METADATA TOOMANY] SETMETADATA failed\r\n", parms[0]);
+               cprintf("%s NO [METADATA TOOMANY] SETMETADATA failed\r\n", Params[0].Key);
        }
 
        /*
@@ -203,21 +203,21 @@ void imap_setmetadata(int num_parms, char *parms[]) {
  * Regardless of what the client asked for, we are going to supply them with
  * the folder type.  It's the only metadata we have anyway.
  */
-void imap_getmetadata(int num_parms, char *parms[]) {
+void imap_getmetadata(int num_parms, ConstStr *Params) {
        char roomname[ROOMNAMELEN];
        char savedroom[ROOMNAMELEN];
        int msgs, new;
        int ret;
 
        if (num_parms > 5) {
-               cprintf("%s BAD usage error\r\n", parms[0]);
+               cprintf("%s BAD usage error\r\n", Params[0].Key);
                return;
        }
 
-       ret = imap_grabroom(roomname, parms[2], 1);
+       ret = imap_grabroom(roomname, Params[2].Key, 1);
        if (ret != 0) {
                cprintf("%s NO Invalid mailbox name or access denied\r\n",
-                       parms[0]);
+                       Params[0].Key);
                return;
        }
 
@@ -231,7 +231,7 @@ void imap_getmetadata(int num_parms, char *parms[]) {
        CtdlUserGoto(roomname, 0, 0, &msgs, &new);
 
        cprintf("* METADATA ");
-       imap_strout(parms[2]);
+       imap_strout(&Params[2]);
        cprintf(" \"/vendor/kolab/folder-type\" (\"value.shared\" \"");
 
        /* If it's one of our hard-coded default rooms, we know what to do... */
@@ -297,7 +297,7 @@ void imap_getmetadata(int num_parms, char *parms[]) {
                CtdlUserGoto(savedroom, 0, 0, &msgs, &new);
        }
 
-       cprintf("%s OK GETMETADATA complete\r\n", parms[0]);
+       cprintf("%s OK GETMETADATA complete\r\n", Params[0].Key);
        return;
 }
 
index 0508cf66435daa512b83f0f22a9f84851797d301..d014a581edbe31c30897502e342b576d5af182ea 100644 (file)
@@ -19,5 +19,5 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-void imap_getmetadata(int num_parms, char *parms[]);
-void imap_setmetadata(int num_parms, char *parms[]);
+void imap_getmetadata(int num_parms, ConstStr *Params);
+void imap_setmetadata(int num_parms, ConstStr *Params);
index ef7f48b26675d7587adb86069aca5264fd46e443..496174a42b7ad9d083a17aac8a1368c26c260f01 100644 (file)
@@ -58,8 +58,8 @@
 #include "database.h"
 #include "msgbase.h"
 #include "internet_addressing.h"
-#include "serv_imap.h"
 #include "imap_tools.h"
+#include "serv_imap.h"
 #include "imap_fetch.h"
 #include "imap_misc.h"
 #include "genstamp.h"
@@ -73,7 +73,7 @@
  * imap_copy() calls imap_do_copy() to do its actual work, once it's
  * validated and boiled down the request a bit.  (returns 0 on success)
  */
-int imap_do_copy(char *destination_folder) {
+int imap_do_copy(const char *destination_folder) {
        int i;
        char roomname[ROOMNAMELEN];
        struct ctdlroom qrbuf;
@@ -192,58 +192,58 @@ void imap_output_copyuid_response(void) {
 /*
  * This function is called by the main command loop.
  */
-void imap_copy(int num_parms, char *parms[]) {
+void imap_copy(int num_parms, ConstStr *Params) {
        int ret;
 
        if (num_parms != 4) {
-               cprintf("%s BAD invalid parameters\r\n", parms[0]);
+               cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
                return;
        }
 
-       if (imap_is_message_set(parms[2])) {
-               imap_pick_range(parms[2], 0);
+       if (imap_is_message_set(Params[2].Key)) {
+               imap_pick_range(Params[2].Key, 0);
        }
        else {
-               cprintf("%s BAD invalid parameters\r\n", parms[0]);
+               cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
                return;
        }
 
-       ret = imap_do_copy(parms[3]);
+       ret = imap_do_copy(Params[3].Key);
        if (!ret) {
-               cprintf("%s OK ", parms[0]);
+               cprintf("%s OK ", Params[0].Key);
                imap_output_copyuid_response();
                cprintf("COPY completed\r\n");
        }
        else {
-               cprintf("%s NO COPY failed (error %d)\r\n", parms[0], ret);
+               cprintf("%s NO COPY failed (error %d)\r\n", Params[0].Key, ret);
        }
 }
 
 /*
  * This function is called by the main command loop.
  */
-void imap_uidcopy(int num_parms, char *parms[]) {
+void imap_uidcopy(int num_parms, ConstStr *Params) {
 
        if (num_parms != 5) {
-               cprintf("%s BAD invalid parameters\r\n", parms[0]);
+               cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
                return;
        }
 
-       if (imap_is_message_set(parms[3])) {
-               imap_pick_range(parms[3], 1);
+       if (imap_is_message_set(Params[3].Key)) {
+               imap_pick_range(Params[3].Key, 1);
        }
        else {
-               cprintf("%s BAD invalid parameters\r\n", parms[0]);
+               cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
                return;
        }
 
-       if (imap_do_copy(parms[4]) == 0) {
-               cprintf("%s OK ", parms[0]);
+       if (imap_do_copy(Params[4].Key) == 0) {
+               cprintf("%s OK ", Params[0].Key);
                imap_output_copyuid_response();
                cprintf("UID COPY completed\r\n");
        }
        else {
-               cprintf("%s NO UID COPY failed\r\n", parms[0]);
+               cprintf("%s NO UID COPY failed\r\n", Params[0].Key);
        }
 }
 
@@ -282,7 +282,7 @@ void imap_do_append_flags(long new_msgnum, char *new_message_flags) {
 /*
  * This function is called by the main command loop.
  */
-void imap_append(int num_parms, char *parms[]) {
+void imap_append(int num_parms, ConstStr *Params) {
        long literal_length;
        long bytes_transferred;
        struct CtdlMessage *msg = NULL;
@@ -294,23 +294,23 @@ void imap_append(int num_parms, char *parms[]) {
        int msgs, new;
        int i;
        char new_message_flags[SIZ];
-       struct citimap *Imap;
+       citimap *Imap;
 
        if (num_parms < 4) {
-               cprintf("%s BAD usage error\r\n", parms[0]);
+               cprintf("%s BAD usage error\r\n", Params[0].Key);
                return;
        }
 
-       if ( (parms[num_parms-1][0] != '{')
-          || (parms[num_parms-1][strlen(parms[num_parms-1])-1] != '}') )  {
-               cprintf("%s BAD no message literal supplied\r\n", parms[0]);
+       if ( (Params[num_parms-1].Key[0] != '{')
+          || (Params[num_parms-1].Key[Params[num_parms-1].len-1] != '}') )  {
+               cprintf("%s BAD no message literal supplied\r\n", Params[0].Key);
                return;
        }
 
        strcpy(new_message_flags, "");
        if (num_parms >= 5) {
                for (i=3; i<num_parms; ++i) {
-                       strcat(new_message_flags, parms[i]);
+                       strcat(new_message_flags, Params[i].Key);
                        strcat(new_message_flags, " ");
                }
                stripallbut(new_message_flags, '(', ')');
@@ -322,10 +322,10 @@ void imap_append(int num_parms, char *parms[]) {
         * }
         */
 
-       literal_length = atol(&parms[num_parms-1][1]);
+       literal_length = atol(&Params[num_parms-1].Key[1]);
        if (literal_length < 1) {
                cprintf("%s BAD Message length must be at least 1.\r\n",
-                       parms[0]);
+                       Params[0].Key);
                return;
        }
 
@@ -335,7 +335,7 @@ void imap_append(int num_parms, char *parms[]) {
        Imap->TransmittedMessage = NewStrBufPlain(NULL, literal_length);
 
        if (Imap->TransmittedMessage == NULL) {
-               cprintf("%s NO Cannot allocate memory.\r\n", parms[0]);
+               cprintf("%s NO Cannot allocate memory.\r\n", Params[0].Key);
                return;
        }
        
@@ -345,7 +345,7 @@ void imap_append(int num_parms, char *parms[]) {
        client_read_blob(Imap->TransmittedMessage, literal_length, config.c_sleeping);
 
        if ((ret < 0) || (StrLength(Imap->TransmittedMessage) < literal_length)) {
-               cprintf("%s NO Read failed.\r\n", parms[0]);
+               cprintf("%s NO Read failed.\r\n", Params[0].Key);
                return;
        }
 
@@ -362,10 +362,10 @@ void imap_append(int num_parms, char *parms[]) {
        CtdlLogPrintf(CTDL_DEBUG, "Converting message format\n");
        msg = convert_internet_message_buf(&Imap->TransmittedMessage);
 
-       ret = imap_grabroom(roomname, parms[2], 1);
+       ret = imap_grabroom(roomname, Params[2].Key, 1);
        if (ret != 0) {
                cprintf("%s NO Invalid mailbox name or access denied\r\n",
-                       parms[0]);
+                       Params[0].Key);
                return;
        }
 
@@ -403,7 +403,7 @@ void imap_append(int num_parms, char *parms[]) {
 
        if (ret) {
                /* Nope ... print an error message */
-               cprintf("%s NO %s\r\n", parms[0], buf);
+               cprintf("%s NO %s\r\n", Params[0].Key, buf);
        }
 
        else {
@@ -413,11 +413,11 @@ void imap_append(int num_parms, char *parms[]) {
                }
                if (new_msgnum >= 0L) {
                        cprintf("%s OK [APPENDUID %ld %ld] APPEND completed\r\n",
-                               parms[0], GLOBAL_UIDVALIDITY_VALUE, new_msgnum);
+                               Params[0].Key, GLOBAL_UIDVALIDITY_VALUE, new_msgnum);
                }
                else {
                        cprintf("%s BAD Error %ld saving message to disk.\r\n",
-                               parms[0], new_msgnum);
+                               Params[0].Key, new_msgnum);
                }
        }
 
index 3cddb76051d08c3a3a00ec06449d48f84083f094..8847aec9e38bbd179621c8ddd3acdb384e77dec9 100644 (file)
@@ -19,6 +19,6 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-void imap_copy(int num_parms, char *parms[]);
-void imap_uidcopy(int num_parms, char *parms[]);
-void imap_append(int num_parms, char *parms[]);
+void imap_copy(int num_parms, ConstStr *Params);
+void imap_uidcopy(int num_parms, ConstStr *Params);
+void imap_append(int num_parms, ConstStr *Params);
index 5241318168c4243997c1a082da58c0003884e9ea..9fe72051355b526dbaa665e32af5228631ee1a17 100644 (file)
@@ -61,8 +61,8 @@
 #include "database.h"
 #include "msgbase.h"
 #include "internet_addressing.h"
-#include "serv_imap.h"
 #include "imap_tools.h"
+#include "serv_imap.h"
 #include "imap_fetch.h"
 #include "imap_search.h"
 #include "genstamp.h"
@@ -78,7 +78,7 @@
  * be loaded only if one or more search criteria require it.
  */
 int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
-                       int num_items, char **itemlist, int is_uid) {
+                       int num_items, ConstStr *itemlist, int is_uid) {
 
        int match = 0;
        int is_not = 0;
@@ -98,31 +98,31 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
        pos = 0;
 
        /* Check for the dreaded NOT criterion. */
-       if (!strcasecmp(itemlist[0], "NOT")) {
+       if (!strcasecmp(itemlist[0].Key, "NOT")) {
                is_not = 1;
                pos = 1;
        }
 
        /* Check for the dreaded OR criterion. */
-       if (!strcasecmp(itemlist[0], "OR")) {
+       if (!strcasecmp(itemlist[0].Key, "OR")) {
                is_or = 1;
                pos = 1;
        }
 
        /* Now look for criteria. */
-       if (!strcasecmp(itemlist[pos], "ALL")) {
+       if (!strcasecmp(itemlist[pos].Key, "ALL")) {
                match = 1;
                ++pos;
        }
        
-       else if (!strcasecmp(itemlist[pos], "ANSWERED")) {
+       else if (!strcasecmp(itemlist[pos].Key, "ANSWERED")) {
                if (IMAP->flags[seq-1] & IMAP_ANSWERED) {
                        match = 1;
                }
                ++pos;
        }
 
-       else if (!strcasecmp(itemlist[pos], "BCC")) {
+       else if (!strcasecmp(itemlist[pos].Key, "BCC")) {
                if (msg == NULL) {
                        msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
                        need_to_free_msg = 1;
@@ -130,7 +130,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                if (msg != NULL) {
                        fieldptr = rfc822_fetch_field(msg->cm_fields['M'], "Bcc");
                        if (fieldptr != NULL) {
-                               if (bmstrcasestr(fieldptr, itemlist[pos+1])) {
+                               if (bmstrcasestr(fieldptr, itemlist[pos+1].Key)) {
                                        match = 1;
                                }
                                free(fieldptr);
@@ -139,14 +139,14 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                pos += 2;
        }
 
-       else if (!strcasecmp(itemlist[pos], "BEFORE")) {
+       else if (!strcasecmp(itemlist[pos].Key, "BEFORE")) {
                if (msg == NULL) {
                        msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
                        if (msg->cm_fields['T'] != NULL) {
-                               if (imap_datecmp(itemlist[pos+1],
+                               if (imap_datecmp(itemlist[pos+1].Key,
                                                atol(msg->cm_fields['T'])) < 0) {
                                        match = 1;
                                }
@@ -155,7 +155,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                pos += 2;
        }
 
-       else if (!strcasecmp(itemlist[pos], "BODY")) {
+       else if (!strcasecmp(itemlist[pos].Key, "BODY")) {
 
                /* If fulltext indexing is active, on this server,
                 *  all messages have already been qualified.
@@ -171,7 +171,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                                need_to_free_msg = 1;
                        }
                        if (msg != NULL) {
-                               if (bmstrcasestr(msg->cm_fields['M'], itemlist[pos+1])) {
+                               if (bmstrcasestr(msg->cm_fields['M'], itemlist[pos+1].Key)) {
                                        match = 1;
                                }
                        }
@@ -180,7 +180,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                pos += 2;
        }
 
-       else if (!strcasecmp(itemlist[pos], "CC")) {
+       else if (!strcasecmp(itemlist[pos].Key, "CC")) {
                if (msg == NULL) {
                        msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
                        need_to_free_msg = 1;
@@ -188,14 +188,14 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                if (msg != NULL) {
                        fieldptr = msg->cm_fields['Y'];
                        if (fieldptr != NULL) {
-                               if (bmstrcasestr(fieldptr, itemlist[pos+1])) {
+                               if (bmstrcasestr(fieldptr, itemlist[pos+1].Key)) {
                                        match = 1;
                                }
                        }
                        else {
                                fieldptr = rfc822_fetch_field(msg->cm_fields['M'], "Cc");
                                if (fieldptr != NULL) {
-                                       if (bmstrcasestr(fieldptr, itemlist[pos+1])) {
+                                       if (bmstrcasestr(fieldptr, itemlist[pos+1].Key)) {
                                                match = 1;
                                        }
                                        free(fieldptr);
@@ -205,44 +205,44 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                pos += 2;
        }
 
-       else if (!strcasecmp(itemlist[pos], "DELETED")) {
+       else if (!strcasecmp(itemlist[pos].Key, "DELETED")) {
                if (IMAP->flags[seq-1] & IMAP_DELETED) {
                        match = 1;
                }
                ++pos;
        }
 
-       else if (!strcasecmp(itemlist[pos], "DRAFT")) {
+       else if (!strcasecmp(itemlist[pos].Key, "DRAFT")) {
                if (IMAP->flags[seq-1] & IMAP_DRAFT) {
                        match = 1;
                }
                ++pos;
        }
 
-       else if (!strcasecmp(itemlist[pos], "FLAGGED")) {
+       else if (!strcasecmp(itemlist[pos].Key, "FLAGGED")) {
                if (IMAP->flags[seq-1] & IMAP_FLAGGED) {
                        match = 1;
                }
                ++pos;
        }
 
-       else if (!strcasecmp(itemlist[pos], "FROM")) {
+       else if (!strcasecmp(itemlist[pos].Key, "FROM")) {
                if (msg == NULL) {
                        msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
-                       if (bmstrcasestr(msg->cm_fields['A'], itemlist[pos+1])) {
+                       if (bmstrcasestr(msg->cm_fields['A'], itemlist[pos+1].Key)) {
                                match = 1;
                        }
-                       if (bmstrcasestr(msg->cm_fields['F'], itemlist[pos+1])) {
+                       if (bmstrcasestr(msg->cm_fields['F'], itemlist[pos+1].Key)) {
                                match = 1;
                        }
                }
                pos += 2;
        }
 
-       else if (!strcasecmp(itemlist[pos], "HEADER")) {
+       else if (!strcasecmp(itemlist[pos].Key, "HEADER")) {
 
                /* We've got to do a slow search for this because the client
                 * might be asking for an RFC822 header field that has not been
@@ -261,9 +261,9 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                        CC->redirect_alloc = SIZ;
                        CtdlOutputPreLoadedMsg(msg, MT_RFC822, HEADERS_FAST, 0, 1, 0);
        
-                       fieldptr = rfc822_fetch_field(CC->redirect_buffer, itemlist[pos+1]);
+                       fieldptr = rfc822_fetch_field(CC->redirect_buffer, itemlist[pos+1].Key);
                        if (fieldptr != NULL) {
-                               if (bmstrcasestr(fieldptr, itemlist[pos+2])) {
+                               if (bmstrcasestr(fieldptr, itemlist[pos+2].Key)) {
                                        match = 1;
                                }
                                free(fieldptr);
@@ -278,46 +278,46 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                pos += 3;       /* Yes, three */
        }
 
-       else if (!strcasecmp(itemlist[pos], "KEYWORD")) {
+       else if (!strcasecmp(itemlist[pos].Key, "KEYWORD")) {
                /* not implemented */
                pos += 2;
        }
 
-       else if (!strcasecmp(itemlist[pos], "LARGER")) {
+       else if (!strcasecmp(itemlist[pos].Key, "LARGER")) {
                if (msg == NULL) {
                        msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
-                       if (strlen(msg->cm_fields['M']) > atoi(itemlist[pos+1])) {
+                       if (strlen(msg->cm_fields['M']) > atoi(itemlist[pos+1].Key)) {
                                match = 1;
                        }
                }
                pos += 2;
        }
 
-       else if (!strcasecmp(itemlist[pos], "NEW")) {
+       else if (!strcasecmp(itemlist[pos].Key, "NEW")) {
                if ( (IMAP->flags[seq-1] & IMAP_RECENT) && (!(IMAP->flags[seq-1] & IMAP_SEEN))) {
                        match = 1;
                }
                ++pos;
        }
 
-       else if (!strcasecmp(itemlist[pos], "OLD")) {
+       else if (!strcasecmp(itemlist[pos].Key, "OLD")) {
                if (!(IMAP->flags[seq-1] & IMAP_RECENT)) {
                        match = 1;
                }
                ++pos;
        }
 
-       else if (!strcasecmp(itemlist[pos], "ON")) {
+       else if (!strcasecmp(itemlist[pos].Key, "ON")) {
                if (msg == NULL) {
                        msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
                        if (msg->cm_fields['T'] != NULL) {
-                               if (imap_datecmp(itemlist[pos+1],
+                               if (imap_datecmp(itemlist[pos+1].Key,
                                                atol(msg->cm_fields['T'])) == 0) {
                                        match = 1;
                                }
@@ -326,28 +326,28 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                pos += 2;
        }
 
-       else if (!strcasecmp(itemlist[pos], "RECENT")) {
+       else if (!strcasecmp(itemlist[pos].Key, "RECENT")) {
                if (IMAP->flags[seq-1] & IMAP_RECENT) {
                        match = 1;
                }
                ++pos;
        }
 
-       else if (!strcasecmp(itemlist[pos], "SEEN")) {
+       else if (!strcasecmp(itemlist[pos].Key, "SEEN")) {
                if (IMAP->flags[seq-1] & IMAP_SEEN) {
                        match = 1;
                }
                ++pos;
        }
 
-       else if (!strcasecmp(itemlist[pos], "SENTBEFORE")) {
+       else if (!strcasecmp(itemlist[pos].Key, "SENTBEFORE")) {
                if (msg == NULL) {
                        msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
                        if (msg->cm_fields['T'] != NULL) {
-                               if (imap_datecmp(itemlist[pos+1],
+                               if (imap_datecmp(itemlist[pos+1].Key,
                                                atol(msg->cm_fields['T'])) < 0) {
                                        match = 1;
                                }
@@ -356,14 +356,14 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                pos += 2;
        }
 
-       else if (!strcasecmp(itemlist[pos], "SENTON")) {
+       else if (!strcasecmp(itemlist[pos].Key, "SENTON")) {
                if (msg == NULL) {
                        msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
                        if (msg->cm_fields['T'] != NULL) {
-                               if (imap_datecmp(itemlist[pos+1],
+                               if (imap_datecmp(itemlist[pos+1].Key,
                                                atol(msg->cm_fields['T'])) == 0) {
                                        match = 1;
                                }
@@ -372,14 +372,14 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                pos += 2;
        }
 
-       else if (!strcasecmp(itemlist[pos], "SENTSINCE")) {
+       else if (!strcasecmp(itemlist[pos].Key, "SENTSINCE")) {
                if (msg == NULL) {
                        msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
                        if (msg->cm_fields['T'] != NULL) {
-                               if (imap_datecmp(itemlist[pos+1],
+                               if (imap_datecmp(itemlist[pos+1].Key,
                                                atol(msg->cm_fields['T'])) >= 0) {
                                        match = 1;
                                }
@@ -388,14 +388,14 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                pos += 2;
        }
 
-       else if (!strcasecmp(itemlist[pos], "SINCE")) {
+       else if (!strcasecmp(itemlist[pos].Key, "SINCE")) {
                if (msg == NULL) {
                        msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
                        if (msg->cm_fields['T'] != NULL) {
-                               if (imap_datecmp(itemlist[pos+1],
+                               if (imap_datecmp(itemlist[pos+1].Key,
                                                atol(msg->cm_fields['T'])) >= 0) {
                                        match = 1;
                                }
@@ -404,40 +404,40 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                pos += 2;
        }
 
-       else if (!strcasecmp(itemlist[pos], "SMALLER")) {
+       else if (!strcasecmp(itemlist[pos].Key, "SMALLER")) {
                if (msg == NULL) {
                        msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
-                       if (strlen(msg->cm_fields['M']) < atoi(itemlist[pos+1])) {
+                       if (strlen(msg->cm_fields['M']) < atoi(itemlist[pos+1].Key)) {
                                match = 1;
                        }
                }
                pos += 2;
        }
 
-       else if (!strcasecmp(itemlist[pos], "SUBJECT")) {
+       else if (!strcasecmp(itemlist[pos].Key, "SUBJECT")) {
                if (msg == NULL) {
                        msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
-                       if (bmstrcasestr(msg->cm_fields['U'], itemlist[pos+1])) {
+                       if (bmstrcasestr(msg->cm_fields['U'], itemlist[pos+1].Key)) {
                                match = 1;
                        }
                }
                pos += 2;
        }
 
-       else if (!strcasecmp(itemlist[pos], "TEXT")) {
+       else if (!strcasecmp(itemlist[pos].Key, "TEXT")) {
                if (msg == NULL) {
                        msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
                        for (i='A'; i<='Z'; ++i) {
-                               if (bmstrcasestr(msg->cm_fields[i], itemlist[pos+1])) {
+                               if (bmstrcasestr(msg->cm_fields[i], itemlist[pos+1].Key)) {
                                        match = 1;
                                }
                        }
@@ -445,13 +445,13 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
                pos += 2;
        }
 
-       else if (!strcasecmp(itemlist[pos], "TO")) {
+       else if (!strcasecmp(itemlist[pos].Key, "TO")) {
                if (msg == NULL) {
                        msg = CtdlFetchMessage(IMAP->msgids[seq-1], 1);
                        need_to_free_msg = 1;
                }
                if (msg != NULL) {
-                       if (bmstrcasestr(msg->cm_fields['R'], itemlist[pos+1])) {
+                       if (bmstrcasestr(msg->cm_fields['R'], itemlist[pos+1].Key)) {
                                match = 1;
                        }
                }
@@ -459,16 +459,16 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
        }
 
        /* FIXME this is b0rken.  fix it. */
-       else if (imap_is_message_set(itemlist[pos])) {
-               if (is_msg_in_sequence_set(itemlist[pos], seq)) {
+       else if (imap_is_message_set(itemlist[pos].Key)) {
+               if (is_msg_in_sequence_set(itemlist[pos].Key, seq)) {
                        match = 1;
                }
                pos += 1;
        }
 
        /* FIXME this is b0rken.  fix it. */
-       else if (!strcasecmp(itemlist[pos], "UID")) {
-               if (is_msg_in_sequence_set(itemlist[pos+1], IMAP->msgids[seq-1])) {
+       else if (!strcasecmp(itemlist[pos].Key, "UID")) {
+               if (is_msg_in_sequence_set(itemlist[pos+1].Key, IMAP->msgids[seq-1])) {
                        match = 1;
                }
                pos += 2;
@@ -479,40 +479,40 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
         * can't there be *one* way to do things?  More gratuitous complexity.
         */
 
-       else if (!strcasecmp(itemlist[pos], "UNANSWERED")) {
+       else if (!strcasecmp(itemlist[pos].Key, "UNANSWERED")) {
                if ((IMAP->flags[seq-1] & IMAP_ANSWERED) == 0) {
                        match = 1;
                }
                ++pos;
        }
 
-       else if (!strcasecmp(itemlist[pos], "UNDELETED")) {
+       else if (!strcasecmp(itemlist[pos].Key, "UNDELETED")) {
                if ((IMAP->flags[seq-1] & IMAP_DELETED) == 0) {
                        match = 1;
                }
                ++pos;
        }
 
-       else if (!strcasecmp(itemlist[pos], "UNDRAFT")) {
+       else if (!strcasecmp(itemlist[pos].Key, "UNDRAFT")) {
                if ((IMAP->flags[seq-1] & IMAP_DRAFT) == 0) {
                        match = 1;
                }
                ++pos;
        }
 
-       else if (!strcasecmp(itemlist[pos], "UNFLAGGED")) {
+       else if (!strcasecmp(itemlist[pos].Key, "UNFLAGGED")) {
                if ((IMAP->flags[seq-1] & IMAP_FLAGGED) == 0) {
                        match = 1;
                }
                ++pos;
        }
 
-       else if (!strcasecmp(itemlist[pos], "UNKEYWORD")) {
+       else if (!strcasecmp(itemlist[pos].Key, "UNKEYWORD")) {
                /* FIXME */
                pos += 2;
        }
 
-       else if (!strcasecmp(itemlist[pos], "UNSEEN")) {
+       else if (!strcasecmp(itemlist[pos].Key, "UNSEEN")) {
                if ((IMAP->flags[seq-1] & IMAP_SEEN) == 0) {
                        match = 1;
                }
@@ -549,7 +549,7 @@ int imap_do_search_msg(int seq, struct CtdlMessage *supplied_msg,
  * 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) {
+void imap_do_search(int num_items, ConstStr *itemlist, int is_uid) {
        int i, j, k;
        int fts_num_msgs = 0;
        long *fts_msgs = NULL;
@@ -561,11 +561,16 @@ void imap_do_search(int num_items, char **itemlist, int is_uid) {
         * client software.  Revisit later...
         */
        for (i=0; i<num_items; ++i) {
-               if (itemlist[i][0] == '(') {
-                       strcpy(&itemlist[i][0], &itemlist[i][1]);
+               if (itemlist[i].Key[0] == '(') {
+                       
+                       TokenCutLeft(&IMAP->Cmd, 
+                                    &itemlist[i], 
+                                    1);
                }
-               if (itemlist[i][strlen(itemlist[i])-1] == ')') {
-                       itemlist[i][strlen(itemlist[i])-1] = 0;
+               if (itemlist[i].Key[itemlist[i].len-1] == ')') {
+                       TokenCutRight(&IMAP->Cmd, 
+                                     &itemlist[i], 
+                                     1);
                }
        }
 
@@ -574,8 +579,8 @@ void imap_do_search(int num_items, char **itemlist, int is_uid) {
         * matching.  (Only do this if the index is enabled!!)
         */
        if (config.c_enable_fulltext) for (i=0; i<(num_items-1); ++i) {
-               if (!strcasecmp(itemlist[i], "BODY")) {
-                       CtdlModuleDoSearch(&fts_num_msgs, &fts_msgs, itemlist[i+1], "fulltext");
+               if (!strcasecmp(itemlist[i].Key, "BODY")) {
+                       CtdlModuleDoSearch(&fts_num_msgs, &fts_msgs, itemlist[i+1].Key, "fulltext");
                        if (fts_num_msgs > 0) {
                                for (j=0; j < IMAP->num_msgs; ++j) {
                                        if (IMAP->flags[j] & IMAP_SELECTED) {
@@ -629,11 +634,11 @@ void imap_do_search(int num_items, char **itemlist, int is_uid) {
 /*
  * This function is called by the main command loop.
  */
-void imap_search(int num_parms, char *parms[]) {
+void imap_search(int num_parms, ConstStr *Params) {
        int i;
 
        if (num_parms < 3) {
-               cprintf("%s BAD invalid parameters\r\n", parms[0]);
+               cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
                return;
        }
 
@@ -641,18 +646,18 @@ void imap_search(int num_parms, char *parms[]) {
                IMAP->flags[i] |= IMAP_SELECTED;
        }
 
-       imap_do_search(num_parms-2, &parms[2], 0);
-       cprintf("%s OK SEARCH completed\r\n", parms[0]);
+       imap_do_search(num_parms-2, &Params[2], 0);
+       cprintf("%s OK SEARCH completed\r\n", Params[0].Key);
 }
 
 /*
  * This function is called by the main command loop.
  */
-void imap_uidsearch(int num_parms, char *parms[]) {
+void imap_uidsearch(int num_parms, ConstStr *Params) {
        int i;
 
        if (num_parms < 4) {
-               cprintf("%s BAD invalid parameters\r\n", parms[0]);
+               cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
                return;
        }
 
@@ -660,8 +665,8 @@ void imap_uidsearch(int num_parms, char *parms[]) {
                IMAP->flags[i] |= IMAP_SELECTED;
        }
 
-       imap_do_search(num_parms-3, &parms[3], 1);
-       cprintf("%s OK UID SEARCH completed\r\n", parms[0]);
+       imap_do_search(num_parms-3, &Params[3], 1);
+       cprintf("%s OK UID SEARCH completed\r\n", Params[0].Key);
 }
 
 
index d504fdf040561751fe49ed450251f7d22a809721..fe90308a96e1d82b73040d2215299d5200687006 100644 (file)
@@ -19,5 +19,5 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-void imap_search(int num_parms, char *parms[]);
-void imap_uidsearch(int num_parms, char *parms[]);
+void imap_search(int num_parms, ConstStr *Params);
+void imap_uidsearch(int num_parms, ConstStr *Params);
index 40f1a5c50d1300c4c2f6db4c1ef34f7b9d0e71f3..a7558ba1641f46b41ed5e92be465fc024d47ba7a 100644 (file)
@@ -58,8 +58,8 @@
 #include "database.h"
 #include "msgbase.h"
 #include "internet_addressing.h"
-#include "serv_imap.h"
 #include "imap_tools.h"
+#include "serv_imap.h"
 #include "imap_fetch.h"
 #include "imap_store.h"
 #include "genstamp.h"
@@ -212,77 +212,77 @@ void imap_do_store(int num_items, char **itemlist) {
 /*
  * This function is called by the main command loop.
  */
-void imap_store(int num_parms, char *parms[]) {
+void imap_store(int num_parms, ConstStr *Params) {
        char items[1024];
        char *itemlist[256];
        int num_items;
        int i;
 
        if (num_parms < 3) {
-               cprintf("%s BAD invalid parameters\r\n", parms[0]);
+               cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
                return;
        }
 
-       if (imap_is_message_set(parms[2])) {
-               imap_pick_range(parms[2], 0);
+       if (imap_is_message_set(Params[2].Key)) {
+               imap_pick_range(Params[2].Key, 0);
        }
        else {
-               cprintf("%s BAD invalid parameters\r\n", parms[0]);
+               cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
                return;
        }
 
        strcpy(items, "");
        for (i=3; i<num_parms; ++i) {
-               strcat(items, parms[i]);
+               strcat(items, Params[i].Key);
                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]);
+               cprintf("%s BAD invalid data item list\r\n", Params[0].Key);
                return;
        }
 
        imap_do_store(num_items, itemlist);
-       cprintf("%s OK STORE completed\r\n", parms[0]);
+       cprintf("%s OK STORE completed\r\n", Params[0].Key);
 }
 
 /*
  * This function is called by the main command loop.
  */
-void imap_uidstore(int num_parms, char *parms[]) {
+void imap_uidstore(int num_parms, ConstStr *Params) {
        char items[1024];
        char *itemlist[256];
        int num_items;
        int i;
 
        if (num_parms < 4) {
-               cprintf("%s BAD invalid parameters\r\n", parms[0]);
+               cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
                return;
        }
 
-       if (imap_is_message_set(parms[3])) {
-               imap_pick_range(parms[3], 1);
+       if (imap_is_message_set(Params[3].Key)) {
+               imap_pick_range(Params[3].Key, 1);
        }
        else {
-               cprintf("%s BAD invalid parameters\r\n", parms[0]);
+               cprintf("%s BAD invalid parameters\r\n", Params[0].Key);
                return;
        }
 
        strcpy(items, "");
        for (i=4; i<num_parms; ++i) {
-               strcat(items, parms[i]);
+               strcat(items, Params[i].Key);
                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]);
+               cprintf("%s BAD invalid data item list\r\n", Params[0].Key);
                return;
        }
 
        imap_do_store(num_items, itemlist);
-       cprintf("%s OK UID STORE completed\r\n", parms[0]);
+       cprintf("%s OK UID STORE completed\r\n", Params[0].Key);
 }
 
 
index 60181911025a3af36a5f63ec3557575ff221799d..ce6a7a4251c2537c213f34e6cb4e99a15e79cdd4 100644 (file)
@@ -19,5 +19,5 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-void imap_store(int num_parms, char *parms[]);
-void imap_uidstore(int num_parms, char *parms[]);
+void imap_store(int num_parms, ConstStr *Params);
+void imap_uidstore(int num_parms, ConstStr *Params);
index 5d1e68ea110b1a825d87f197f3805245c38d05e7..3805b47244412487868f8a355b9386ee78b107e9 100644 (file)
@@ -31,6 +31,7 @@
 #include "sysdep_decls.h"
 #include "internet_addressing.h"
 #include "imap_tools.h"
+#include "serv_imap.h"
 #include "ctdl_module.h"
 
 #ifndef HAVE_SNPRINTF
@@ -297,10 +298,10 @@ static char* toimap(char* destp, char* destend, char* src)
 /* Convert from an IMAP-safe name back into a Citadel name. Returns the end of the destination. */
 
 static int cfrommap(int c);
-static char* fromimap(char* destp, char* destend, char* src)
+static char* fromimap(char* destp, char* destend, const char* src)
 {
        struct string dest;
-       unsigned char *p = (unsigned char*) src;
+       unsigned const char *p = (unsigned const char*) src;
        int v = 0;
        int i = 0;
        int state = 0;
@@ -385,7 +386,7 @@ static int cfrommap(int c)
 /* Output a string to the IMAP client, either as a literal or quoted.
  * (We do a literal if it has any double-quotes or backslashes.) */
 
-void imap_strout(char *buf)
+void plain_imap_strout(char *buf)
 {
        int i;
        int is_literal = 0;
@@ -409,9 +410,186 @@ void imap_strout(char *buf)
        }
 }
 
+/* Output a string to the IMAP client, either as a literal or quoted.
+ * (We do a literal if it has any double-quotes or backslashes.) */
+
+void imap_strout(ConstStr *args)
+{
+       int i;
+       int is_literal = 0;
+       
+       if ((args == NULL) || (args->len == 0))
+       {       /* yeah, we handle this */
+               cprintf("NIL");
+               return;
+       }
+
+       for (i = 0; i < args->len; ++i) {
+               if ((args->Key[i] == '\"') || (args->Key[i] == '\\'))
+                       is_literal = 1;
+       }
+
+       if (is_literal) {
+               cprintf("{%ld}\r\n%s", args->len, args->Key);
+       } else {
+               cprintf("\"%s\"", args->Key);
+       }
+}
+
 /* Break a command down into tokens, unquoting any escaped characters. */
 
-int imap_parameterize(char** args, char* in)
+
+void TokenCutRight(citimap_command *Cmd, 
+                  ConstStr *CutMe,
+                  int n)
+{
+       const char *CutAt;
+
+       if (CutMe->len < n) {
+               CutAt = CutMe->Key;
+               CutMe->len = 0;
+       }
+       else {
+               CutAt = CutMe->Key + CutMe->len - n;
+               CutMe->len -= n;
+       }
+       StrBufPeek(Cmd->CmdBuf, CutAt, -1, '\0');
+}
+
+void TokenCutLeft(citimap_command *Cmd, 
+                 ConstStr *CutMe,
+                 int n)
+{
+       if (CutMe->len < n) {
+               CutMe->Key += CutMe->len;
+               CutMe->len = 0;
+       }
+       else {
+               CutMe->Key += n;
+               CutMe->len -= n;
+       }
+}
+
+
+
+int CmdAdjust(citimap_command *Cmd, 
+             int nArgs,
+             int Realloc)
+{
+       ConstStr *Params;
+       if (nArgs > Cmd->avail_parms) {
+               Params = (ConstStr*) malloc(sizeof(ConstStr) * nArgs);
+               if (Realloc) {
+                       memcpy(Params, 
+                              Cmd->Params, 
+                              sizeof(ConstStr) * Cmd->avail_parms);
+
+                       memset(Cmd->Params + 
+                              sizeof(ConstStr) * Cmd->avail_parms,
+                              0, 
+                              sizeof(ConstStr) * nArgs - 
+                              sizeof(ConstStr) * Cmd->avail_parms 
+                               );
+               }
+               else 
+                       Cmd->num_parms = 0;
+               Cmd->avail_parms = nArgs;
+               if (Cmd->Params != NULL)
+                       free (Cmd->Params);
+               Cmd->Params = Params;
+       }
+       else {
+               if (!Realloc) {
+                       memset(Cmd->Params, 
+                              0,
+                              sizeof(ConstStr) * Cmd->avail_parms);
+                       Cmd->num_parms = 0;
+               }
+       }
+       return Cmd->num_parms;
+}
+
+int imap_parameterize(citimap_command *Cmd)
+{
+       int nArgs;
+       const char *In, *End;
+
+       In = ChrPtr(Cmd->CmdBuf);
+       End = In + StrLength(Cmd->CmdBuf);
+
+       /* we start with 10 chars per arg, maybe we need to realloc later. */
+       nArgs = StrLength(Cmd->CmdBuf) / 10 + 10;
+       nArgs = CmdAdjust(Cmd, nArgs, 0);
+       while (In < End)
+       {
+               /* Skip whitespace. */
+               while (isspace(*In))
+                       In++;
+               if (*In == '\0')
+                       break;
+
+               /* Found the start of a token. */
+               
+               Cmd->Params[Cmd->num_parms].Key = In;
+
+               /* Read in the token. */
+
+               for (;;)
+               {
+                       if (isspace(*In))
+                               break;
+                       
+                       if (*In == '\"')
+                       {
+                               /* Found a quoted section. */
+
+                               Cmd->Params[Cmd->num_parms].Key++; 
+                               //In++;
+                               for (;;)
+                               {
+                                       In++;
+                                       if (*In == '\"') {
+                                               StrBufPeek(Cmd->CmdBuf, In, -1, '\0');
+                                               break;
+                                       }
+                                       else if (*In == '\\')
+                                               In++;
+
+                                       if (*In == '\0') {
+                                               Cmd->Params[Cmd->num_parms].len = 
+                                                       In - Cmd->Params[Cmd->num_parms].Key;
+                                               Cmd->num_parms++;
+                                               return Cmd->num_parms;
+                                       }
+                               }
+                               break;
+                       }
+                       else if (*In == '\\')
+                       {
+                               In++;
+                       }
+
+                       if (*In == '\0') {
+                               Cmd->Params[Cmd->num_parms].len = 
+                                       In - Cmd->Params[Cmd->num_parms].Key;
+                               Cmd->num_parms++;
+                               return Cmd->num_parms;
+                       }
+                       In++;
+               }
+               StrBufPeek(Cmd->CmdBuf, In, -1, '\0');
+               Cmd->Params[Cmd->num_parms].len = 
+                       In - Cmd->Params[Cmd->num_parms].Key;
+               Cmd->num_parms ++;
+               if (Cmd->num_parms >= Cmd->avail_parms) {
+                       nArgs = CmdAdjust(Cmd, nArgs * 2, 1);
+               }
+               In++;
+       }
+       return Cmd->num_parms;
+}
+
+int old_imap_parameterize(char** args, char *in)
 {
        char* out = in;
        int num = 0;
@@ -519,7 +697,7 @@ void imap_mailboxname(char *buf, int bufsize, struct ctdlroom *qrbuf)
  *
  */
 
-int imap_roomname(char *rbuf, int bufsize, char *foldername)
+int imap_roomname(char *rbuf, int bufsize, const char *foldername)
 {
        int levels;
        char floorname[256];
@@ -614,11 +792,11 @@ void imap_ial_out(struct internet_address_list *ialist)
 
        for (iptr = ialist; iptr != NULL; iptr = iptr->next) {
                cprintf("(");
-               imap_strout(iptr->ial_name);
+               plain_imap_strout(iptr->ial_name);
                cprintf(" NIL ");
-               imap_strout(iptr->ial_user);
+               plain_imap_strout(iptr->ial_user);
                cprintf(" ");
-               imap_strout(iptr->ial_node);
+               plain_imap_strout(iptr->ial_node);
                cprintf(")");
        }
 
@@ -633,7 +811,7 @@ void imap_ial_out(struct internet_address_list *ialist)
  * return 1 for a valid message set.  If any other character is found, 
  * return 0.
  */
-int imap_is_message_set(char *buf)
+int imap_is_message_set(const char *buf)
 {
        int i;
 
@@ -679,13 +857,16 @@ static int do_imap_match(const char *supplied_text, const char *supplied_p)
        char lcase_text[SIZ], lcase_p[SIZ];
        char *text = lcase_text;
        char *p = lcase_p;
+       long len;
 
        /* Copy both strings and lowercase them, in order to
         * make this entire operation case-insensitive.
         */
-       for (i=0; i<=strlen(supplied_text); ++i)
+       len = strlen(supplied_text);
+       for (i=0; i<=len; ++i)
                lcase_text[i] = tolower(supplied_text[i]);
-       for (i=0; i<=strlen(supplied_p); ++i)
+       len = strlen(supplied_p);
+       for (i=0; i<=len; ++i)
                p[i] = tolower(supplied_p[i]);
 
        /* Start matching */
@@ -776,7 +957,7 @@ int imap_mailbox_matches_pattern(char *pattern, char *mailboxname)
  * 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) {
+int imap_datecmp(const char *datestr, time_t msgtime) {
        char daystr[256];
        char monthstr[256];
        char yearstr[256];
index de11077be0af8dcc469db8ab320e537929a13b64..533ac82117a16baf66ba78b8c7f65d72effbaa37 100644 (file)
@@ -60,8 +60,8 @@
 #include "database.h"
 #include "msgbase.h"
 #include "internet_addressing.h"
-#include "serv_imap.h"
 #include "imap_tools.h"
+#include "serv_imap.h"
 #include "imap_list.h"
 #include "imap_fetch.h"
 #include "imap_search.h"
@@ -469,12 +469,12 @@ void imap_output_capability_string(void) {
 /*
  * implements the CAPABILITY command
  */
-void imap_capability(int num_parms, char *parms[])
+void imap_capability(int num_parms, ConstStr *Params)
 {
        cprintf("* ");
        imap_output_capability_string();
        cprintf("\r\n");
-       cprintf("%s OK CAPABILITY completed\r\n", parms[0]);
+       cprintf("%s OK CAPABILITY completed\r\n", Params[0].Key);
 }
 
 
@@ -487,10 +487,10 @@ void imap_capability(int num_parms, char *parms[])
  * making use of this extension.
  * 
  */
-void imap_id(int num_parms, char *parms[])
+void imap_id(int num_parms, ConstStr *Params)
 {
        cprintf("* ID NIL\r\n");
-       cprintf("%s OK ID completed\r\n", parms[0]);
+       cprintf("%s OK ID completed\r\n", Params[0].Key);
 }
 
 
@@ -501,8 +501,8 @@ void imap_greeting(void)
 {
 
        strcpy(CC->cs_clientname, "IMAP session");
-       CC->session_specific_data = malloc(sizeof(struct citimap));
-       memset(IMAP, 0, sizeof(struct citimap));
+       CC->session_specific_data = malloc(sizeof(citimap));
+       memset(IMAP, 0, sizeof(citimap));
        IMAP->authstate = imap_as_normal;
        IMAP->cached_rfc822_data = NULL;
        IMAP->cached_rfc822_msgnum = (-1);
@@ -535,34 +535,34 @@ void imaps_greeting(void) {
 /*
  * implements the LOGIN command (ordinary username/password login)
  */
-void imap_login(int num_parms, char *parms[])
+void imap_login(int num_parms, ConstStr *Params)
 {
 
        switch (num_parms) {
        case 3:
-               if (parms[2][0] == '{') {
+               if (Params[2].Key[0] == '{') {
                        cprintf("+ go ahead\r\n");
                        IMAP->authstate = imap_as_expecting_multilineusername;
-                       strcpy(IMAP->authseq, parms[0]);
+                       strcpy(IMAP->authseq, Params[0].Key);
                        return;
                }
                else {
-                       cprintf("%s BAD incorrect number of parameters\r\n", parms[0]);
+                       cprintf("%s BAD incorrect number of parameters\r\n", Params[0].Key);
                        return;
                }
        case 4:
-               if (CtdlLoginExistingUser(NULL, parms[2]) == login_ok) {
-                       if (CtdlTryPassword(parms[3]) == pass_ok) {
-                               cprintf("%s OK [", parms[0]);
+               if (CtdlLoginExistingUser(NULL, Params[2].Key) == login_ok) {
+                       if (CtdlTryPassword(Params[3].Key) == pass_ok) {
+                               cprintf("%s OK [", Params[0].Key);
                                imap_output_capability_string();
                                cprintf("] Hello, %s\r\n", CC->user.fullname);
                                return;
                        }
                }
 
-               cprintf("%s BAD Login incorrect\r\n", parms[0]);
+               cprintf("%s BAD Login incorrect\r\n", Params[0].Key);
        default:
-               cprintf("%s BAD incorrect number of parameters\r\n", parms[0]);
+               cprintf("%s BAD incorrect number of parameters\r\n", Params[0].Key);
                return;
        }
 
@@ -572,55 +572,57 @@ void imap_login(int num_parms, char *parms[])
 /*
  * Implements the AUTHENTICATE command
  */
-void imap_authenticate(int num_parms, char *parms[])
+void imap_authenticate(int num_parms, ConstStr *Params)
 {
        char buf[SIZ];
 
        if (num_parms != 3) {
                cprintf("%s BAD incorrect number of parameters\r\n",
-                       parms[0]);
+                       Params[0].Key);
                return;
        }
 
        if (CC->logged_in) {
-               cprintf("%s BAD Already logged in.\r\n", parms[0]);
+               cprintf("%s BAD Already logged in.\r\n", Params[0].Key);
                return;
        }
 
-       if (!strcasecmp(parms[2], "LOGIN")) {
+       if (!strcasecmp(Params[2].Key, "LOGIN")) {
                CtdlEncodeBase64(buf, "Username:", 9, 0);
                cprintf("+ %s\r\n", buf);
                IMAP->authstate = imap_as_expecting_username;
-               strcpy(IMAP->authseq, parms[0]);
+               strcpy(IMAP->authseq, Params[0].Key);
                return;
        }
 
-       if (!strcasecmp(parms[2], "PLAIN")) {
+       if (!strcasecmp(Params[2].Key, "PLAIN")) {
                // CtdlEncodeBase64(buf, "Username:", 9, 0);
                // cprintf("+ %s\r\n", buf);
                cprintf("+ \r\n");
                IMAP->authstate = imap_as_expecting_plainauth;
-               strcpy(IMAP->authseq, parms[0]);
+               strcpy(IMAP->authseq, Params[0].Key);
                return;
        }
 
        else {
                cprintf("%s NO AUTHENTICATE %s failed\r\n",
-                       parms[0], parms[1]);
+                       Params[0].Key, Params[1].Key);
        }
 }
 
 
-void imap_auth_plain(char *cmd)
+void imap_auth_plain(void)
 {
-       char decoded_authstring[1024];
+       const char *decoded_authstring;
        char ident[256];
        char user[256];
        char pass[256];
        int result;
 
        memset(pass, 0, sizeof(pass));
-       CtdlDecodeBase64(decoded_authstring, cmd, strlen(cmd));
+       StrBufDecodeBase64(IMAP->Cmd.CmdBuf);
+
+       decoded_authstring = ChrPtr(IMAP->Cmd.CmdBuf);
        safestrncpy(ident, decoded_authstring, sizeof ident);
        safestrncpy(user, &decoded_authstring[strlen(ident) + 1], sizeof user);
        safestrncpy(pass, &decoded_authstring[strlen(ident) + strlen(user) + 2], sizeof pass);
@@ -644,22 +646,23 @@ void imap_auth_plain(char *cmd)
 }
 
 
-void imap_auth_login_user(char *cmd, long state)
+void imap_auth_login_user(long state)
 {
        char buf[SIZ];
+       citimap *Imap = IMAP;
 
        switch (state){
        case imap_as_expecting_username:
-               CtdlDecodeBase64(buf, cmd, SIZ);
-               CtdlLoginExistingUser(NULL, buf);
+               StrBufDecodeBase64(Imap->Cmd.CmdBuf);
+               CtdlLoginExistingUser(NULL, ChrPtr(Imap->Cmd.CmdBuf));
                CtdlEncodeBase64(buf, "Password:", 9, 0);
                cprintf("+ %s\r\n", buf);
                
-               IMAP->authstate = imap_as_expecting_password;
+               Imap->authstate = imap_as_expecting_password;
                return;
        case imap_as_expecting_multilineusername:
-               extract_token(buf, cmd, 1, ' ', sizeof(buf));
-               CtdlLoginExistingUser(NULL, cmd);
+               extract_token(buf, ChrPtr(Imap->Cmd.CmdBuf), 1, ' ', sizeof(buf));
+               CtdlLoginExistingUser(NULL, ChrPtr(Imap->Cmd.CmdBuf));
                cprintf("+ go ahead\r\n");
                IMAP->authstate = imap_as_expecting_multilinepassword;
                return;
@@ -667,20 +670,20 @@ void imap_auth_login_user(char *cmd, long state)
 }
 
 
-void imap_auth_login_pass(char *cmd, long state)
+void imap_auth_login_pass(long state)
 {
-       char *pass = NULL;
+       citimap *Imap = IMAP;
+       const char *pass = NULL;
        char buf[SIZ];
 
        switch (state) {
        default:
        case imap_as_expecting_password:
-               memset(buf, 0, sizeof(buf));
-               CtdlDecodeBase64(buf, cmd, SIZ);
+               StrBufDecodeBase64(Imap->Cmd.CmdBuf);
                pass = buf;
                break;
        case imap_as_expecting_multilinepassword:
-               pass = cmd;
+               pass = ChrPtr(Imap->Cmd.CmdBuf);
                break;
        }
        if (CtdlTryPassword(pass) == pass_ok) {
@@ -696,15 +699,15 @@ void imap_auth_login_pass(char *cmd, long state)
 /*
  * implements the STARTTLS command (Citadel API version)
  */
-void imap_starttls(int num_parms, char *parms[])
+void imap_starttls(int num_parms, ConstStr *Params)
 {
        char ok_response[SIZ];
        char nosup_response[SIZ];
        char error_response[SIZ];
 
-       sprintf(ok_response,    "%s OK begin TLS negotiation now\r\n",  parms[0]);
-       sprintf(nosup_response, "%s NO TLS not supported here\r\n",     parms[0]);
-       sprintf(error_response, "%s BAD Internal error\r\n",            parms[0]);
+       sprintf(ok_response,    "%s OK begin TLS negotiation now\r\n",  Params[0].Key);
+       sprintf(nosup_response, "%s NO TLS not supported here\r\n",     Params[0].Key);
+       sprintf(error_response, "%s BAD Internal error\r\n",            Params[0].Key);
        CtdlModuleStartCryptoMsgs(ok_response, nosup_response, error_response);
 }
 
@@ -712,7 +715,7 @@ void imap_starttls(int num_parms, char *parms[])
 /*
  * implements the SELECT command
  */
-void imap_select(int num_parms, char *parms[])
+void imap_select(int num_parms, ConstStr *Params)
 {
        char towhere[SIZ];
        char augmented_roomname[ROOMNAMELEN];
@@ -726,9 +729,9 @@ void imap_select(int num_parms, char *parms[])
        int i;
 
        /* Convert the supplied folder name to a roomname */
-       i = imap_roomname(towhere, sizeof towhere, parms[2]);
+       i = imap_roomname(towhere, sizeof towhere, Params[2].Key);
        if (i < 0) {
-               cprintf("%s NO Invalid mailbox name.\r\n", parms[0]);
+               cprintf("%s NO Invalid mailbox name.\r\n", Params[0].Key);
                IMAP->selected = 0;
                return;
        }
@@ -760,7 +763,7 @@ void imap_select(int num_parms, char *parms[])
 
        /* Fail here if no such room */
        if (!ok) {
-               cprintf("%s NO ... no such room, or access denied\r\n", parms[0]);
+               cprintf("%s NO ... no such room, or access denied\r\n", Params[0].Key);
                return;
        }
 
@@ -775,7 +778,7 @@ void imap_select(int num_parms, char *parms[])
        CtdlUserGoto(NULL, 0, 0, &msgs, &new);
        IMAP->selected = 1;
 
-       if (!strcasecmp(parms[1], "EXAMINE")) {
+       if (!strcasecmp(Params[1].Key, "EXAMINE")) {
                IMAP->readonly = 1;
        } else {
                IMAP->readonly = 0;
@@ -803,8 +806,8 @@ void imap_select(int num_parms, char *parms[])
        cprintf("* OK [PERMANENTFLAGS (\\Deleted \\Seen \\Answered)] permanent flags\r\n");
 
        cprintf("%s OK [%s] %s completed\r\n",
-               parms[0],
-               (IMAP->readonly ? "READ-ONLY" : "READ-WRITE"), parms[1]
+               Params[0].Key,
+               (IMAP->readonly ? "READ-ONLY" : "READ-WRITE"), Params[1].Key
        );
 }
 
@@ -850,19 +853,19 @@ int imap_do_expunge(void)
 /*
  * implements the EXPUNGE command syntax
  */
-void imap_expunge(int num_parms, char *parms[])
+void imap_expunge(int num_parms, ConstStr *Params)
 {
        int num_expunged = 0;
 
        num_expunged = imap_do_expunge();
-       cprintf("%s OK expunged %d messages.\r\n", parms[0], num_expunged);
+       cprintf("%s OK expunged %d messages.\r\n", Params[0].Key, num_expunged);
 }
 
 
 /*
  * implements the CLOSE command
  */
-void imap_close(int num_parms, char *parms[])
+void imap_close(int num_parms, ConstStr *Params)
 {
 
        /* Yes, we always expunge on close. */
@@ -873,14 +876,14 @@ void imap_close(int num_parms, char *parms[])
        IMAP->selected = 0;
        IMAP->readonly = 0;
        imap_free_msgids();
-       cprintf("%s OK CLOSE completed\r\n", parms[0]);
+       cprintf("%s OK CLOSE completed\r\n", Params[0].Key);
 }
 
 
 /*
  * Implements the NAMESPACE command.
  */
-void imap_namespace(int num_parms, char *parms[])
+void imap_namespace(int num_parms, ConstStr *Params)
 {
        int i;
        struct floor *fl;
@@ -903,7 +906,7 @@ void imap_namespace(int num_parms, char *parms[])
                        if (floors > 0) cprintf(" ");
                        cprintf("(");
                        sprintf(buf, "%s/", fl->f_name);
-                       imap_strout(buf);
+                       plain_imap_strout(buf);
                        cprintf(" \"/\")");
                        ++floors;
                }
@@ -912,7 +915,7 @@ void imap_namespace(int num_parms, char *parms[])
 
        /* Wind it up with a newline and a completion message. */
        cprintf("\r\n");
-       cprintf("%s OK NAMESPACE completed\r\n", parms[0]);
+       cprintf("%s OK NAMESPACE completed\r\n", Params[0].Key);
 }
 
 
@@ -920,7 +923,7 @@ void imap_namespace(int num_parms, char *parms[])
  * Implements the CREATE command
  *
  */
-void imap_create(int num_parms, char *parms[])
+void imap_create(int num_parms, ConstStr *Params)
 {
        int ret;
        char roomname[ROOMNAMELEN];
@@ -931,20 +934,20 @@ void imap_create(int num_parms, char *parms[])
        char *notification_message = NULL;
 
        if (num_parms < 3) {
-               cprintf("%s NO A foder name must be specified\r\n", parms[0]);
+               cprintf("%s NO A foder name must be specified\r\n", Params[0].Key);
                return;
        }
 
-       if (strchr(parms[2], '\\') != NULL) {
-               cprintf("%s NO Invalid character in folder name\r\n", parms[0]);
+       if (strchr(Params[2].Key, '\\') != NULL) {
+               cprintf("%s NO Invalid character in folder name\r\n", Params[0].Key);
                CtdlLogPrintf(CTDL_DEBUG, "invalid character in folder name\n");
                return;
        }
 
-       ret = imap_roomname(roomname, sizeof roomname, parms[2]);
+       ret = imap_roomname(roomname, sizeof roomname, Params[2].Key);
        if (ret < 0) {
                cprintf("%s NO Invalid mailbox name or location\r\n",
-                       parms[0]);
+                       Params[0].Key);
                CtdlLogPrintf(CTDL_DEBUG, "invalid mailbox name or location\n");
                return;
        }
@@ -952,8 +955,8 @@ void imap_create(int num_parms, char *parms[])
        flags = (ret & 0xff00); /* upper 8 bits = flags        */
 
        if (flags & IR_MAILBOX) {
-               if (strncasecmp(parms[2], "INBOX/", 6)) {
-                       cprintf("%s NO Personal folders must be created under INBOX\r\n", parms[0]);
+               if (strncasecmp(Params[2].Key, "INBOX/", 6)) {
+                       cprintf("%s NO Personal folders must be created under INBOX\r\n", Params[0].Key);
                        CtdlLogPrintf(CTDL_DEBUG, "not subordinate to inbox\n");
                        return;
                }
@@ -973,9 +976,9 @@ void imap_create(int num_parms, char *parms[])
        ret = CtdlCreateRoom(roomname, newroomtype, "", floornum, 1, 0, newroomview);
        if (ret == 0) {
                /*** DO NOT CHANGE THIS ERROR MESSAGE IN ANY WAY!  BYNARI CONNECTOR DEPENDS ON IT! ***/
-               cprintf("%s NO Mailbox already exists, or create failed\r\n", parms[0]);
+               cprintf("%s NO Mailbox already exists, or create failed\r\n", Params[0].Key);
        } else {
-               cprintf("%s OK CREATE completed\r\n", parms[0]);
+               cprintf("%s OK CREATE completed\r\n", Params[0].Key);
                /* post a message in Aide> describing the new room */
                notification_message = malloc(1024);
                snprintf(notification_message, 1024,
@@ -997,7 +1000,7 @@ void imap_create(int num_parms, char *parms[])
  * Locate a room by its IMAP folder name, and check access to it.
  * If zapped_ok is nonzero, we can also look for the room in the zapped list.
  */
-int imap_grabroom(char *returned_roomname, char *foldername, int zapped_ok)
+int imap_grabroom(char *returned_roomname, const char *foldername, int zapped_ok)
 {
        int ret;
        char augmented_roomname[ROOMNAMELEN];
@@ -1053,7 +1056,7 @@ int imap_grabroom(char *returned_roomname, char *foldername, int zapped_ok)
  * Implements the STATUS command (sort of)
  *
  */
-void imap_status(int num_parms, char *parms[])
+void imap_status(int num_parms, ConstStr *Params)
 {
        int ret;
        char roomname[ROOMNAMELEN];
@@ -1061,11 +1064,11 @@ void imap_status(int num_parms, char *parms[])
        char savedroom[ROOMNAMELEN];
        int msgs, new;
 
-       ret = imap_grabroom(roomname, parms[2], 1);
+       ret = imap_grabroom(roomname, Params[2].Key, 1);
        if (ret != 0) {
                cprintf
                    ("%s NO Invalid mailbox name or location, or access denied\r\n",
-                    parms[0]);
+                    Params[0].Key);
                return;
        }
 
@@ -1087,7 +1090,7 @@ void imap_status(int num_parms, char *parms[])
         */
        imap_mailboxname(buf, sizeof buf, &CC->room);
        cprintf("* STATUS ");
-       imap_strout(buf);
+       plain_imap_strout(buf);
        cprintf(" (MESSAGES %d ", msgs);
        cprintf("RECENT %d ", new);     /* Initially, new==recent */
        cprintf("UIDNEXT %ld ", CitControl.MMhighest + 1);
@@ -1104,7 +1107,7 @@ void imap_status(int num_parms, char *parms[])
        /*
         * Oooh, look, we're done!
         */
-       cprintf("%s OK STATUS completed\r\n", parms[0]);
+       cprintf("%s OK STATUS completed\r\n", Params[0].Key);
 }
 
 
@@ -1112,18 +1115,18 @@ void imap_status(int num_parms, char *parms[])
  * Implements the SUBSCRIBE command
  *
  */
-void imap_subscribe(int num_parms, char *parms[])
+void imap_subscribe(int num_parms, ConstStr *Params)
 {
        int ret;
        char roomname[ROOMNAMELEN];
        char savedroom[ROOMNAMELEN];
        int msgs, new;
 
-       ret = imap_grabroom(roomname, parms[2], 1);
+       ret = imap_grabroom(roomname, Params[2].Key, 1);
        if (ret != 0) {
                cprintf(
                        "%s NO Error %d: invalid mailbox name or location, or access denied\r\n",
-                       parms[0],
+                       Params[0].Key,
                        ret
                );
                return;
@@ -1147,7 +1150,7 @@ void imap_subscribe(int num_parms, char *parms[])
                CtdlUserGoto(savedroom, 0, 0, &msgs, &new);
        }
 
-       cprintf("%s OK SUBSCRIBE completed\r\n", parms[0]);
+       cprintf("%s OK SUBSCRIBE completed\r\n", Params[0].Key);
 }
 
 
@@ -1155,18 +1158,18 @@ void imap_subscribe(int num_parms, char *parms[])
  * Implements the UNSUBSCRIBE command
  *
  */
-void imap_unsubscribe(int num_parms, char *parms[])
+void imap_unsubscribe(int num_parms, ConstStr *Params)
 {
        int ret;
        char roomname[ROOMNAMELEN];
        char savedroom[ROOMNAMELEN];
        int msgs, new;
 
-       ret = imap_grabroom(roomname, parms[2], 1);
+       ret = imap_grabroom(roomname, Params[2].Key, 1);
        if (ret != 0) {
                cprintf
                    ("%s NO Invalid mailbox name or location, or access denied\r\n",
-                    parms[0]);
+                    Params[0].Key);
                return;
        }
 
@@ -1182,11 +1185,11 @@ void imap_unsubscribe(int num_parms, char *parms[])
         * Now make the API call to zap the room
         */
        if (CtdlForgetThisRoom() == 0) {
-               cprintf("%s OK UNSUBSCRIBE completed\r\n", parms[0]);
+               cprintf("%s OK UNSUBSCRIBE completed\r\n", Params[0].Key);
        } else {
                cprintf
                    ("%s NO You may not unsubscribe from this folder.\r\n",
-                    parms[0]);
+                    Params[0].Key);
        }
 
        /*
@@ -1203,17 +1206,17 @@ void imap_unsubscribe(int num_parms, char *parms[])
  * Implements the DELETE command
  *
  */
-void imap_delete(int num_parms, char *parms[])
+void imap_delete(int num_parms, ConstStr *Params)
 {
        int ret;
        char roomname[ROOMNAMELEN];
        char savedroom[ROOMNAMELEN];
        int msgs, new;
 
-       ret = imap_grabroom(roomname, parms[2], 1);
+       ret = imap_grabroom(roomname, Params[2].Key, 1);
        if (ret != 0) {
                cprintf("%s NO Invalid mailbox name, or access denied\r\n",
-                       parms[0]);
+                       Params[0].Key);
                return;
        }
 
@@ -1232,9 +1235,9 @@ void imap_delete(int num_parms, char *parms[])
         */
        if (CtdlDoIHavePermissionToDeleteThisRoom(&CC->room)) {
                CtdlScheduleRoomForDeletion(&CC->room);
-               cprintf("%s OK DELETE completed\r\n", parms[0]);
+               cprintf("%s OK DELETE completed\r\n", Params[0].Key);
        } else {
-               cprintf("%s NO Can't delete this folder.\r\n", parms[0]);
+               cprintf("%s NO Can't delete this folder.\r\n", Params[0].Key);
        }
 
        /*
@@ -1290,7 +1293,7 @@ void imap_rename_backend(struct ctdlroom *qrbuf, void *data)
  * Implements the RENAME command
  *
  */
-void imap_rename(int num_parms, char *parms[])
+void imap_rename(int num_parms, ConstStr *Params)
 {
        char old_room[ROOMNAMELEN];
        char new_room[ROOMNAMELEN];
@@ -1302,43 +1305,43 @@ void imap_rename(int num_parms, char *parms[])
        struct irlparms irlparms;
        char buf[1024];
 
-       if (strchr(parms[3], '\\') != NULL) {
+       if (strchr(Params[3].Key, '\\') != NULL) {
                cprintf("%s NO Invalid character in folder name\r\n",
-                       parms[0]);
+                       Params[0].Key);
                return;
        }
 
-       oldr = imap_roomname(old_room, sizeof old_room, parms[2]);
-       newr = imap_roomname(new_room, sizeof new_room, parms[3]);
+       oldr = imap_roomname(old_room, sizeof old_room, Params[2].Key);
+       newr = imap_roomname(new_room, sizeof new_room, Params[3].Key);
        new_floor = (newr & 0xFF);
 
        r = CtdlRenameRoom(old_room, new_room, new_floor);
 
        if (r == crr_room_not_found) {
                cprintf("%s NO Could not locate this folder\r\n",
-                       parms[0]);
+                       Params[0].Key);
                return;
        }
        if (r == crr_already_exists) {
-               cprintf("%s NO '%s' already exists.\r\n", parms[0], parms[2]);
+               cprintf("%s NO '%s' already exists.\r\n", Params[0].Key, Params[2].Key);
                return;
        }
        if (r == crr_noneditable) {
-               cprintf("%s NO This folder is not editable.\r\n", parms[0]);
+               cprintf("%s NO This folder is not editable.\r\n", Params[0].Key);
                return;
        }
        if (r == crr_invalid_floor) {
-               cprintf("%s NO Folder root does not exist.\r\n", parms[0]);
+               cprintf("%s NO Folder root does not exist.\r\n", Params[0].Key);
                return;
        }
        if (r == crr_access_denied) {
                cprintf("%s NO You do not have permission to edit this folder.\r\n",
-                       parms[0]);
+                       Params[0].Key);
                return;
        }
        if (r != crr_ok) {
                cprintf("%s NO Rename failed - undefined error %d\r\n",
-                       parms[0], r);
+                       Params[0].Key, r);
                return;
        }
 
@@ -1346,14 +1349,14 @@ void imap_rename(int num_parms, char *parms[])
         * contents.  In a Citadel environment it's easier to rename the room
         * (already did that) and create a new inbox.
         */
-       if (!strcasecmp(parms[2], "INBOX")) {
+       if (!strcasecmp(Params[2].Key, "INBOX")) {
                CtdlCreateRoom(MAILROOM, 4, "", 0, 1, 0, VIEW_MAILBOX);
        }
 
        /* Otherwise, do the subfolders.  Build a list of rooms to rename... */
        else {
-               irlparms.oldname = parms[2];
-               irlparms.newname = parms[3];
+               irlparms.oldname = Params[2].Key;
+               irlparms.newname = Params[3].Key;
                irlparms.irl = &irl;
                CtdlForEachRoom(imap_rename_backend, (void *) &irlparms);
 
@@ -1373,13 +1376,13 @@ void imap_rename(int num_parms, char *parms[])
        }
 
        snprintf(buf, sizeof buf, "IMAP folder \"%s\" renamed to \"%s\" by %s\n",
-               parms[2],
-               parms[3],
+               Params[2].Key,
+               Params[3].Key,
                CC->curr_user
        );
        CtdlAideMessage(buf, "IMAP folder rename");
 
-       cprintf("%s OK RENAME completed\r\n", parms[0]);
+       cprintf("%s OK RENAME completed\r\n", Params[0].Key);
 }
 
 
@@ -1388,67 +1391,73 @@ void imap_rename(int num_parms, char *parms[])
  */
 void imap_command_loop(void)
 {
-       char cmdbuf[SIZ];
-       char *parms[SIZ];
-       int num_parms;
        struct timeval tv1, tv2;
        suseconds_t total_time = 0;
        int untagged_ok = 1;
+       citimap *Imap;
+       const char *pchs, *pche;
 
        gettimeofday(&tv1, NULL);
        CC->lastcmd = time(NULL);
-       memset(cmdbuf, 0, sizeof cmdbuf);       /* Clear it, just in case */
+       Imap = IMAP;
+
        flush_output();
-       if (client_getln(cmdbuf, sizeof cmdbuf) < 1) {
+       if (Imap->Cmd.CmdBuf == NULL)
+               Imap->Cmd.CmdBuf = NewStrBufPlain(NULL, SIZ);
+       else
+               FlushStrBuf(Imap->Cmd.CmdBuf);
+
+       if (CtdlClientGetLine(Imap->Cmd.CmdBuf) < 1) {
                CtdlLogPrintf(CTDL_ERR, "Client disconnected: ending session.\r\n");
                CC->kill_me = 1;
                return;
        }
 
-       if (IMAP->authstate == imap_as_expecting_password) {
+       if (Imap->authstate == imap_as_expecting_password) {
                CtdlLogPrintf(CTDL_INFO, "IMAP: <password>\n");
        }
-       else if (IMAP->authstate == imap_as_expecting_plainauth) {
+       else if (Imap->authstate == imap_as_expecting_plainauth) {
                CtdlLogPrintf(CTDL_INFO, "IMAP: <plain_auth>\n");
        }
-       else if ((IMAP->authstate == imap_as_expecting_multilineusername) || 
-                bmstrcasestr(cmdbuf, " LOGIN ")) {
+       else if ((Imap->authstate == imap_as_expecting_multilineusername) || 
+                bmstrcasestr(ChrPtr(Imap->Cmd.CmdBuf), " LOGIN ")) {
                CtdlLogPrintf(CTDL_INFO, "IMAP: LOGIN...\n");
        }
        else {
-               CtdlLogPrintf(CTDL_INFO, "IMAP: %s\n", cmdbuf);
+               CtdlLogPrintf(CTDL_INFO, "IMAP: %s\n", ChrPtr(Imap->Cmd.CmdBuf));
        }
 
-       while (strlen(cmdbuf) < 5)
-               strcat(cmdbuf, " ");
+       pchs = ChrPtr(Imap->Cmd.CmdBuf);
+       pche = pchs + StrLength(Imap->Cmd.CmdBuf);
 
-       /* strip off l/t whitespace and CRLF */
-       if (cmdbuf[strlen(cmdbuf) - 1] == '\n')
-               cmdbuf[strlen(cmdbuf) - 1] = 0;
-       if (cmdbuf[strlen(cmdbuf) - 1] == '\r')
-               cmdbuf[strlen(cmdbuf) - 1] = 0;
-       striplt(cmdbuf);
+       while ((pche > pchs) &&
+              ((*pche == '\n') ||
+               (*pche == '\r')))
+       {
+               pche --;
+               StrBufCutRight(Imap->Cmd.CmdBuf, 1);
+       }
+       StrBufTrim(Imap->Cmd.CmdBuf);
 
        /* If we're in the middle of a multi-line command, handle that */
-       if (IMAP->authstate == imap_as_expecting_username) {
-               imap_auth_login_user(cmdbuf, imap_as_expecting_username);
+       switch (Imap->authstate){
+       case imap_as_expecting_username:
+               imap_auth_login_user(imap_as_expecting_username);
                return;
-       }
-       if (IMAP->authstate == imap_as_expecting_multilineusername) {
-               imap_auth_login_user(cmdbuf, imap_as_expecting_multilineusername);
+       case imap_as_expecting_multilineusername:
+               imap_auth_login_user(imap_as_expecting_multilineusername);
                return;
-       }
-       if (IMAP->authstate == imap_as_expecting_plainauth) {
-               imap_auth_plain(cmdbuf);
+       case imap_as_expecting_plainauth:
+               imap_auth_plain();
                return;
-       }
-       if (IMAP->authstate == imap_as_expecting_password) {
-               imap_auth_login_pass(cmdbuf, imap_as_expecting_password);
+       case imap_as_expecting_password:
+               imap_auth_login_pass(imap_as_expecting_password);
                return;
-       }
-       if (IMAP->authstate == imap_as_expecting_multilinepassword) {
-               imap_auth_login_pass(cmdbuf, imap_as_expecting_multilinepassword);
+       case imap_as_expecting_multilinepassword:
+               imap_auth_login_pass(imap_as_expecting_multilinepassword);
                return;
+       default:
+               break;
        }
 
 
@@ -1456,18 +1465,38 @@ void imap_command_loop(void)
         * If the command just submitted does not contain a literal, we
         * might think about delivering some untagged stuff...
         */
-       if (cmdbuf[strlen(cmdbuf)-1] == '}') {
+       if (*(ChrPtr(Imap->Cmd.CmdBuf) + StrLength(Imap->Cmd.CmdBuf) - 1)
+           == '}') {
                untagged_ok = 0;
        }
 
        /* Grab the tag, command, and parameters. */
-       num_parms = imap_parameterize(parms, cmdbuf);
+       imap_parameterize(&Imap->Cmd);
+#if 0 
+/* debug output the parsed vector */
+       {
+               int i;
+               CtdlLogPrintf(CTDL_DEBUG, "----- %ld params \n",
+                             Imap->Cmd.num_parms);
+
+       for (i=0; i < Imap->Cmd.num_parms; i++) {
+               if (Imap->Cmd.Params[i].len != strlen(Imap->Cmd.Params[i].Key))
+                       CtdlLogPrintf(CTDL_DEBUG, "*********** %ld != %ld : %s\n",
+                                     Imap->Cmd.Params[i].len, 
+                                     strlen(Imap->Cmd.Params[i].Key),
+                                     Imap->Cmd.Params[i].Key);
+               else
+                       CtdlLogPrintf(CTDL_DEBUG, "%ld : %s\n",
+                                     Imap->Cmd.Params[i].len, 
+                                     Imap->Cmd.Params[i].Key);
+       }}
 
+#endif
        /* RFC3501 says that we cannot output untagged data during these commands */
-       if (num_parms >= 2) {
-               if (  (!strcasecmp(parms[1], "FETCH"))
-                  || (!strcasecmp(parms[1], "STORE"))
-                  || (!strcasecmp(parms[1], "SEARCH"))
+       if (Imap->Cmd.num_parms >= 2) {
+               if (  (!strcasecmp(Imap->Cmd.Params[1].Key, "FETCH"))
+                  || (!strcasecmp(Imap->Cmd.Params[1].Key, "STORE"))
+                  || (!strcasecmp(Imap->Cmd.Params[1].Key, "SEARCH"))
                ) {
                        untagged_ok = 0;
                }
@@ -1483,190 +1512,190 @@ void imap_command_loop(void)
                 * messages, and for deletions/changes of existing messages.  This
                 * could probably be optimized better with some deep thought...
                 */
-               if (IMAP->selected) {
+               if (Imap->selected) {
                        imap_rescan_msgids();
                }
        }
 
        /* Now for the command set. */
 
-       if (num_parms < 2) {
+       if (Imap->Cmd.num_parms < 2) {
                cprintf("BAD syntax error\r\n");
        }
 
        /* The commands below may be executed in any state */
 
-       else if ((!strcasecmp(parms[1], "NOOP"))
-                || (!strcasecmp(parms[1], "CHECK"))) {
+       else if ((!strcasecmp(Imap->Cmd.Params[1].Key, "NOOP"))
+                || (!strcasecmp(Imap->Cmd.Params[1].Key, "CHECK"))) {
                cprintf("%s OK No operation\r\n",
-                       parms[0]);
+                       Imap->Cmd.Params[0].Key);
        }
 
-       else if (!strcasecmp(parms[1], "ID")) {
-               imap_id(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "ID")) {
+               imap_id(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
 
-       else if (!strcasecmp(parms[1], "LOGOUT")) {
-               if (IMAP->selected) {
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "LOGOUT")) {
+               if (Imap->selected) {
                        imap_do_expunge();      /* yes, we auto-expunge at logout */
                }
                cprintf("* BYE %s logging out\r\n", config.c_fqdn);
                cprintf("%s OK Citadel IMAP session ended.\r\n",
-                       parms[0]);
+                       Imap->Cmd.Params[0].Key);
                CC->kill_me = 1;
                return;
        }
 
-       else if (!strcasecmp(parms[1], "LOGIN")) {
-               imap_login(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "LOGIN")) {
+               imap_login(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "AUTHENTICATE")) {
-               imap_authenticate(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "AUTHENTICATE")) {
+               imap_authenticate(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "CAPABILITY")) {
-               imap_capability(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "CAPABILITY")) {
+               imap_capability(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 #ifdef HAVE_OPENSSL
-       else if (!strcasecmp(parms[1], "STARTTLS")) {
-               imap_starttls(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "STARTTLS")) {
+               imap_starttls(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 #endif
        else if (!CC->logged_in) {
-               cprintf("%s BAD Not logged in.\r\n", parms[0]);
+               cprintf("%s BAD Not logged in.\r\n", Imap->Cmd.Params[0].Key);
        }
 
        /* The commans below require a logged-in state */
 
-       else if (!strcasecmp(parms[1], "SELECT")) {
-               imap_select(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "SELECT")) {
+               imap_select(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "EXAMINE")) {
-               imap_select(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "EXAMINE")) {
+               imap_select(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "LSUB")) {
-               imap_list(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "LSUB")) {
+               imap_list(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "LIST")) {
-               imap_list(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "LIST")) {
+               imap_list(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "CREATE")) {
-               imap_create(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "CREATE")) {
+               imap_create(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "DELETE")) {
-               imap_delete(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "DELETE")) {
+               imap_delete(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "RENAME")) {
-               imap_rename(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "RENAME")) {
+               imap_rename(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "STATUS")) {
-               imap_status(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "STATUS")) {
+               imap_status(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "SUBSCRIBE")) {
-               imap_subscribe(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "SUBSCRIBE")) {
+               imap_subscribe(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "UNSUBSCRIBE")) {
-               imap_unsubscribe(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "UNSUBSCRIBE")) {
+               imap_unsubscribe(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "APPEND")) {
-               imap_append(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "APPEND")) {
+               imap_append(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "NAMESPACE")) {
-               imap_namespace(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "NAMESPACE")) {
+               imap_namespace(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "SETACL")) {
-               imap_setacl(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "SETACL")) {
+               imap_setacl(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "DELETEACL")) {
-               imap_deleteacl(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "DELETEACL")) {
+               imap_deleteacl(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "GETACL")) {
-               imap_getacl(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "GETACL")) {
+               imap_getacl(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "LISTRIGHTS")) {
-               imap_listrights(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "LISTRIGHTS")) {
+               imap_listrights(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "MYRIGHTS")) {
-               imap_myrights(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "MYRIGHTS")) {
+               imap_myrights(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "GETMETADATA")) {
-               imap_getmetadata(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "GETMETADATA")) {
+               imap_getmetadata(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "SETMETADATA")) {
-               imap_setmetadata(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "SETMETADATA")) {
+               imap_setmetadata(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (IMAP->selected == 0) {
-               cprintf("%s BAD no folder selected\r\n", parms[0]);
+       else if (Imap->selected == 0) {
+               cprintf("%s BAD no folder selected\r\n", Imap->Cmd.Params[0].Key);
        }
 
        /* The commands below require the SELECT state on a mailbox */
 
-       else if (!strcasecmp(parms[1], "FETCH")) {
-               imap_fetch(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "FETCH")) {
+               imap_fetch(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if ((!strcasecmp(parms[1], "UID"))
-                && (!strcasecmp(parms[2], "FETCH"))) {
-               imap_uidfetch(num_parms, parms);
+       else if ((!strcasecmp(Imap->Cmd.Params[1].Key, "UID"))
+                && (!strcasecmp(Imap->Cmd.Params[2].Key, "FETCH"))) {
+               imap_uidfetch(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "SEARCH")) {
-               imap_search(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "SEARCH")) {
+               imap_search(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if ((!strcasecmp(parms[1], "UID"))
-                && (!strcasecmp(parms[2], "SEARCH"))) {
-               imap_uidsearch(num_parms, parms);
+       else if ((!strcasecmp(Imap->Cmd.Params[1].Key, "UID"))
+                && (!strcasecmp(Imap->Cmd.Params[2].Key, "SEARCH"))) {
+               imap_uidsearch(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "STORE")) {
-               imap_store(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "STORE")) {
+               imap_store(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if ((!strcasecmp(parms[1], "UID"))
-                && (!strcasecmp(parms[2], "STORE"))) {
-               imap_uidstore(num_parms, parms);
+       else if ((!strcasecmp(Imap->Cmd.Params[1].Key, "UID"))
+                && (!strcasecmp(Imap->Cmd.Params[2].Key, "STORE"))) {
+               imap_uidstore(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "COPY")) {
-               imap_copy(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "COPY")) {
+               imap_copy(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if ((!strcasecmp(parms[1], "UID")) && (!strcasecmp(parms[2], "COPY"))) {
-               imap_uidcopy(num_parms, parms);
+       else if ((!strcasecmp(Imap->Cmd.Params[1].Key, "UID")) && (!strcasecmp(Imap->Cmd.Params[2].Key, "COPY"))) {
+               imap_uidcopy(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "EXPUNGE")) {
-               imap_expunge(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "EXPUNGE")) {
+               imap_expunge(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if ((!strcasecmp(parms[1], "UID")) && (!strcasecmp(parms[2], "EXPUNGE"))) {
-               imap_expunge(num_parms, parms);
+       else if ((!strcasecmp(Imap->Cmd.Params[1].Key, "UID")) && (!strcasecmp(Imap->Cmd.Params[2].Key, "EXPUNGE"))) {
+               imap_expunge(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
-       else if (!strcasecmp(parms[1], "CLOSE")) {
-               imap_close(num_parms, parms);
+       else if (!strcasecmp(Imap->Cmd.Params[1].Key, "CLOSE")) {
+               imap_close(Imap->Cmd.num_parms, Imap->Cmd.Params);
        }
 
        /* End of commands.  If we get here, the command is either invalid
@@ -1674,7 +1703,7 @@ void imap_command_loop(void)
         */
 
        else {
-               cprintf("%s BAD command unrecognized\r\n", parms[0]);
+               cprintf("%s BAD command unrecognized\r\n", Imap->Cmd.Params[0].Key);
        }
 
        /* If the client transmitted a message we can free it now */
index ee7d683084cecfe6ce8988ef7af41db2b07b930d..c7e8686e876f8475fa025c1218cf251f4a106620 100644 (file)
@@ -8,13 +8,14 @@
 void imap_cleanup_function(void);
 void imap_greeting(void);
 void imap_command_loop(void);
-int imap_grabroom(char *returned_roomname, char *foldername, int zapped_ok);
+int imap_grabroom(char *returned_roomname, const char *foldername, int zapped_ok);
 void imap_free_transmitted_message(void);
 int imap_do_expunge(void);
 void imap_rescan_msgids(void);
 
 
-struct citimap {
+
+typedef struct __citimap {
        int authstate;
        char authseq[SIZ];
        int selected;                   /* set to 1 if in the SELECTED state */
@@ -26,6 +27,8 @@ struct citimap {
        unsigned int *flags;
        StrBuf *TransmittedMessage;     /* for APPEND command... */
 
+       citimap_command Cmd;            /* our current commandline */
+
        /* Cache most recent RFC822 FETCH because client might load in pieces */
        char *cached_rfc822_data;
        long cached_rfc822_msgnum;
@@ -38,7 +41,7 @@ struct citimap {
        char cached_bodypart[SIZ];
        long cached_bodymsgnum;
        char cached_body_withbody;      /* 1 = body cached; 0 = only headers cached */
-};
+} citimap;
 
 /*
  * values of 'authstate'
@@ -68,7 +71,7 @@ enum {
 #define IMAP_RECENT            64      /* reportable but not setable */
 
 
-#define IMAP ((struct citimap *)CC->session_specific_data)
+#define IMAP ((citimap *)CC->session_specific_data)
 
 /*
  * When loading arrays of message ID's into memory, increase the buffer to
index 9c81c9093a4f3c7cb97a7230baf2b7586c6c4160..da56429ce73439d5d84cdb56ec4bc8904e389b39 100644 (file)
@@ -523,7 +523,7 @@ void managesieve_command_loop(void) {
        memset(cmdbuf, 0, sizeof cmdbuf); /* Clear it, just in case */
        length = client_getln(cmdbuf, sizeof cmdbuf);
        if (length >= 1) {
-               num_parms = imap_parameterize(parms, cmdbuf);
+               num_parms = old_imap_parameterize(parms, cmdbuf);
                if (num_parms == 0) return;
                length = strlen(parms[0]);
        }
index 955d823c555132a98480b04858de60ea572a28a0..916fc570ec91d9ac6448dbf752deae045de062c2 100644 (file)
@@ -465,7 +465,7 @@ int login_via_openid(char *claimed_id)
  */
 void extract_link(char *target_buf, int target_size, char *rel, char *source_buf)
 {
-       char *ptr = source_buf;
+       const char *ptr = source_buf;
 
        if (!target_buf) return;
        if (!rel) return;
@@ -493,7 +493,7 @@ void extract_link(char *target_buf, int target_size, char *rel, char *source_buf
                        if (len > sizeof work_buffer) len = sizeof work_buffer;
                        memcpy(work_buffer, link_tag_start, len);
                
-                       char *rel_start = NULL;
+                       const char *rel_start = NULL;
                        char *rel_end = NULL;
                        rel_start = bmstrcasestr(work_buffer, "rel=");
                        if (rel_start) {
index 612b1db98c369e67a6ed854e31e23cf6ad0b6060..258193ab5475550632694cdc29dfae0ebde2db2a 100644 (file)
@@ -403,7 +403,7 @@ void pop3_top(char *argbuf) {
        int lines_dumped = 0;
        char buf[1024];
        char *msgtext;
-       char *ptr;
+       const char *ptr;
        int in_body = 0;
        int done = 0;
 
index f0ae5657ee0e1aa3cda8b3d0e14cd60eddf7b5e8..e0253672cae38e79b42e13c4a9d11ca67041f46c 100644 (file)
@@ -975,7 +975,7 @@ void smtp_try(const char *key, const char *addr, int *status,
        char mx_port[256];
        int lp, rp;
        char *msgtext;
-       char *ptr;
+       const char *ptr;
        size_t msg_size;
        int scan_done;
        CitContext *CCC=CC;
index ddd1c32fc32f27199509fe447f924a719807aac6..ac65bb1db417a8acd0df668ed765d40fe3cf61e2 100644 (file)
@@ -96,7 +96,7 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) {
        int nbytes = 0;
        char *diffbuf = NULL;
        size_t diffbuf_len = 0;
-       char *ptr = NULL;
+       const char *ptr = NULL;
 
        if (!CCC->logged_in) return(0); /* Only do this if logged in. */
 
index 9a6dc22b95cc90a6e8ed5e27190e120f2d4b4dbd..87641e3eef8a96e690bc72cd7982525b6f652b1c 100644 (file)
@@ -2778,7 +2778,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg,       /* message to save */
        char content_type[SIZ];                 /* We have to learn this */
        char recipient[SIZ];
        long newmsgid;
-       char *mptr = NULL;
+       const char *mptr = NULL;
        struct ctdluser userbuf;
        int a, i;
        struct MetaData smi;
@@ -3596,7 +3596,7 @@ int CtdlCheckInternetMailPermission(struct ctdluser *who) {
  *
  * Caller needs to free the result using free_recipients()
  */
-struct recptypes *validate_recipients(char *supplied_recipients, 
+struct recptypes *validate_recipients(const char *supplied_recipients, 
                                      const char *RemoteIdentifier, 
                                      int Flags) {
        struct recptypes *ret;
index ffb6da99489735a3d12feaf7ba321d4cacced60b..31a0e520f39b9374198caf07793b8ca4fd2b8807 100644 (file)
@@ -203,7 +203,7 @@ void CtdlSetSeen(long *target_msgnums, int num_target_msgnums,
                struct ctdluser *which_user, struct ctdlroom *which_room);
 void CtdlGetSeen(char *buf, int which_set);
 
-struct recptypes *validate_recipients(char *recipients,
+struct recptypes *validate_recipients(const char *recipients,
                                      const char *RemoteIdentifier, 
                                      int Flags);
 
index 35abfcc0a2c1ec83e4127a76f22c193fa739fb37..dee9b45499a5e46c5b4f77d928b9de7fd643e592 100644 (file)
@@ -836,7 +836,7 @@ void CtdlDestroyServiceHook(void)
        ServiceHookTable = NULL;
 }
 
-void CtdlRegisterSearchFuncHook(void (*fcn_ptr)(int *, long **, char *), char *name)
+void CtdlRegisterSearchFuncHook(void (*fcn_ptr)(int *, long **, const char *), char *name)
 {
        struct SearchFunctionHook *newfcn;
 
@@ -854,7 +854,7 @@ void CtdlRegisterSearchFuncHook(void (*fcn_ptr)(int *, long **, char *), char *n
        CtdlLogPrintf(CTDL_INFO, "Registered a new search function (%s)\n", name);
 }
 
-void CtdlUnregisterSearchFuncHook(void (*fcn_ptr)(int *, long **, char *), char *name)
+void CtdlUnregisterSearchFuncHook(void (*fcn_ptr)(int *, long **, const char *), char *name)
 {
        struct SearchFunctionHook *cur, *p;
        
@@ -871,7 +871,7 @@ void CtdlUnregisterSearchFuncHook(void (*fcn_ptr)(int *, long **, char *), char
        }
 }
 
-void CtdlModuleDoSearch(int *num_msgs, long **search_msgs, char *search_string, char *func_name)
+void CtdlModuleDoSearch(int *num_msgs, long **search_msgs, const char *search_string, const char *func_name)
 {
        struct SearchFunctionHook *fcn = NULL;
 
index becdb675c92da6bea50e2e9322ad7a7f98c46891..a34526badbbe6953d88c8c47ce9135717b9677ac 100644 (file)
@@ -152,7 +152,7 @@ extern struct RoomFunctionHook *RoomHookTable;
 
 struct SearchFunctionHook {
        struct SearchFunctionHook *next;
-       void (*fcn_ptr) (int *, long **, char *);
+       void (*fcn_ptr) (int *, long **, const char *);
        char *name;
 };
 extern struct SearchFunctionHook *SearchFunctionHookTable;
index a678d60a37cfb5be42e2af6e561b78d2262dd8e9..fb854bf575280c9a75b47e6e1b0f38ec0d546fcf 100644 (file)
@@ -594,10 +594,20 @@ static void ctdl_internal_thread_cleanup(void *arg)
         * In here we were called by the current thread because it is exiting
         * NB. WE ARE THE CURRENT THREAD
         */
-       CtdlLogPrintf(CTDL_NOTICE, "Thread \"%s\" (0x%08lx) exited.\n", CT->name, CT->tid);
+       if (CT)
+       {
+               const char *name = CT->name;
+               const pid_t tid = CT->tid;
+
+               CtdlLogPrintf(CTDL_NOTICE, "Thread \"%s\" (0x%08lx) exited.\n", name, tid);
+       }
+       else 
+       {
+               CtdlLogPrintf(CTDL_NOTICE, "some ((unknown ? ? ?) Thread exited.\n");
+       }
        
        #ifdef HAVE_BACKTRACE
-       eCrash_UnregisterThread();
+///    eCrash_UnregisterThread();
        #endif
        
        citthread_mutex_lock(&CT->ThreadMutex);
@@ -825,7 +835,7 @@ static void *ctdl_internal_thread_func (void *arg)
        
        // Register for tracing
        #ifdef HAVE_BACKTRACE
-       eCrash_RegisterThread(this_thread->name, 0);
+///    eCrash_RegisterThread(this_thread->name, 0);
        #endif
        
        // Tell the world we are here