]> code.citadel.org Git - citadel.git/blobdiff - citadel/modules/imap/imap_tools.c
Fix IMAP-List command
[citadel.git] / citadel / modules / imap / imap_tools.c
index 3805b47244412487868f8a355b9386ee78b107e9..23e27419aa4c35f4a55a98a676e5d723399cb5cb 100644 (file)
@@ -84,7 +84,7 @@ static void string_append_sn(struct string* s, char* p, int len)
 
 static void string_append_c(struct string* s, int c)
 {
-       char buf[5];
+       char UmlChar[5];
        int len = 0;
 
        /* Don't do anything if there's no room. */
@@ -102,27 +102,27 @@ static void string_append_c(struct string* s, int c)
        }
        else if (c <= 0x7FF)
        {
-               buf[0] = 0xC0 | (c >> 6);
-               buf[1] = 0x80 | (c & 0x3F);
+               UmlChar[0] = 0xC0 | (c >> 6);
+               UmlChar[1] = 0x80 | (c & 0x3F);
                len = 2;
        }
        else if (c <= 0xFFFF)
        {
-               buf[0] = 0xE0 | (c >> 12);
-               buf[1] = 0x80 | ((c >> 6) & 0x3f);
-               buf[2] = 0x80 | (c & 0x3f);
+               UmlChar[0] = 0xE0 | (c >> 12);
+               UmlChar[1] = 0x80 | ((c >> 6) & 0x3f);
+               UmlChar[2] = 0x80 | (c & 0x3f);
                len = 3;
        }
        else
        {
-               buf[0] = 0xf0 | c >> 18;
-               buf[1] = 0x80 | ((c >> 12) & 0x3f);
-               buf[2] = 0x80 | ((c >> 6) & 0x3f);
-               buf[3] = 0x80 | (c & 0x3f);
+               UmlChar[0] = 0xf0 | c >> 18;
+               UmlChar[1] = 0x80 | ((c >> 12) & 0x3f);
+               UmlChar[2] = 0x80 | ((c >> 6) & 0x3f);
+               UmlChar[3] = 0x80 | (c & 0x3f);
                len = 4;
        }
 
-       string_append_sn(s, buf, len);
+       string_append_sn(s, UmlChar, len);
 }      
 
 /* Reads a UTF8 character from a char*, advancing the pointer. */
@@ -436,8 +436,22 @@ void imap_strout(ConstStr *args)
        }
 }
 
+
+
+
 /* Break a command down into tokens, unquoting any escaped characters. */
 
+void MakeStringOf(StrBuf *Buf, int skip)
+{
+       int i;
+       citimap_command *Cmd = &IMAP->Cmd;
+
+       for (i=skip; i<Cmd->num_parms; ++i) {
+               StrBufAppendBufPlain(Buf, Cmd->Params[i].Key, Cmd->Params[i].len, 0);
+               if (i < (Cmd->num_parms-1)) StrBufAppendBufPlain(Buf, HKEY(" "), 0);
+       }
+}
+
 
 void TokenCutRight(citimap_command *Cmd, 
                   ConstStr *CutMe,
@@ -491,8 +505,11 @@ int CmdAdjust(citimap_command *Cmd,
                               sizeof(ConstStr) * Cmd->avail_parms 
                                );
                }
-               else 
+               else {
                        Cmd->num_parms = 0;
+                       memset(Params, 0, 
+                              sizeof(ConstStr) * nArgs);
+               }
                Cmd->avail_parms = nArgs;
                if (Cmd->Params != NULL)
                        free (Cmd->Params);
@@ -506,7 +523,7 @@ int CmdAdjust(citimap_command *Cmd,
                        Cmd->num_parms = 0;
                }
        }
-       return Cmd->num_parms;
+       return Cmd->avail_parms;
 }
 
 int imap_parameterize(citimap_command *Cmd)
@@ -580,10 +597,10 @@ int imap_parameterize(citimap_command *Cmd)
                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) {
+               if (Cmd->num_parms + 1 >= Cmd->avail_parms) {
                        nArgs = CmdAdjust(Cmd, nArgs * 2, 1);
                }
+               Cmd->num_parms ++;
                In++;
        }
        return Cmd->num_parms;
@@ -700,7 +717,7 @@ void imap_mailboxname(char *buf, int bufsize, struct ctdlroom *qrbuf)
 int imap_roomname(char *rbuf, int bufsize, const char *foldername)
 {
        int levels;
-       char floorname[256];
+       char floorname[ROOMNAMELEN*2];
        char roomname[ROOMNAMELEN];
        int i;
        struct floor *fl;
@@ -743,10 +760,12 @@ int imap_roomname(char *rbuf, int bufsize, const char *foldername)
        levels = num_tokens(rbuf, FDELIM);
        if (levels > 1)
        {
+               long len;
                /* Extract the main room name. */
                
-               extract_token(floorname, rbuf, 0, FDELIM, sizeof floorname);
-               strcpy(roomname, &rbuf[strlen(floorname)+1]);
+               len = extract_token(floorname, rbuf, 0, FDELIM, sizeof floorname);
+               if (len < 0) len = 0;
+               safestrncpy(roomname, &rbuf[len  + 1], sizeof(roomname));
 
                /* Try and find it on any floor. */
                
@@ -855,22 +874,30 @@ static int do_imap_match(const char *supplied_text, const char *supplied_p)
 {
        int matched, i;
        char lcase_text[SIZ], lcase_p[SIZ];
-       char *text = lcase_text;
-       char *p = lcase_p;
-       long len;
-
+       char *text;
+       char *p;
+       
        /* Copy both strings and lowercase them, in order to
         * make this entire operation case-insensitive.
         */
-       len = strlen(supplied_text);
-       for (i=0; i<=len; ++i)
+       for (i=0; 
+            ((supplied_text[i] != '\0') && 
+             (i < sizeof(lcase_text)));
+            ++i)
                lcase_text[i] = tolower(supplied_text[i]);
-       len = strlen(supplied_p);
-       for (i=0; i<=len; ++i)
-               p[i] = tolower(supplied_p[i]);
+       lcase_text[i] = '\0';
+
+       for (i=0; 
+            ((supplied_p[i] != '\0') && 
+             (i < sizeof(lcase_p))); 
+            ++i)
+               lcase_p[i] = tolower(supplied_p[i]);
+       lcase_p[i] = '\0';
 
        /* Start matching */
-       for (; *p; text++, p++) {
+       for (p = lcase_p, text = lcase_text; 
+            !IsEmptyStr(p) && !IsEmptyStr(text); 
+            text++, p++) {
                if ((*text == '\0') && (*p != '*') && (*p != '%')) {
                        return WILDMAT_ABORT;
                }
@@ -900,7 +927,8 @@ star:
                        }
                        return WILDMAT_ABORT;
                case '%':
-                       while (++p, ((*p == '*') || (*p == '%'))) {
+                       while (++p, (!IsEmptyStr(p) && ((*p == '*') || (*p == '%'))))
+                       {
                                /* Consecutive %'s act just like one, but even
                                 * a single star makes the sequence act like
                                 * one star, instead.
@@ -915,7 +943,7 @@ star:
                                 * Trailing % matches everything
                                 * without a delimiter.
                                 */
-                               while (*text) {
+                               while (!IsEmptyStr(text)) {
                                        if (*text == WILDMAT_DELIM) {
                                                return WILDMAT_FALSE;
                                        }
@@ -923,7 +951,7 @@ star:
                                }
                                return WILDMAT_TRUE;
                        }
-                       while (*text && (*(text - 1) != WILDMAT_DELIM)) {
+                       while (!IsEmptyStr(text) && (*(text - 1) != WILDMAT_DELIM)) {
                                if ((matched = do_imap_match(text++, p))
                                   != WILDMAT_FALSE) {
                                        return matched;
@@ -933,7 +961,8 @@ star:
                }
        }
 
-       return (*text == '\0');
+       if ((*text == '\0') && (*p == '\0')) return WILDMAT_TRUE;
+       else return WILDMAT_FALSE;
 }
 
 
@@ -942,7 +971,7 @@ star:
  * Support function for mailbox pattern name matching in LIST and LSUB
  * Returns nonzero if the supplied mailbox name matches the supplied pattern.
  */
-int imap_mailbox_matches_pattern(char *pattern, char *mailboxname)
+int imap_mailbox_matches_pattern(const char *pattern, char *mailboxname)
 {
        /* handle just-star case quickly */
        if ((pattern[0] == '*') && (pattern[1] == '\0')) {