fix possible buffer underrun (by 1;-)
[citadel.git] / citadel / modules / imap / imap_tools.c
index 9cbad8b419f96d8fe6d9bea15c73ff01e1c60ee8..e3cc6bffce11a878c15b5f25e8783ae4c51ccd89 100644 (file)
@@ -1,12 +1,10 @@
 /*
- * $Id$
- *
  * Utility functions for the IMAP module.
  *
  * Copyright (c) 2001-2009 by the citadel.org team and others, except for
  * most of the UTF7 and UTF8 handling code which was lifted from Evolution.
  *
- * This program is free software; you can redistribute it and/or modify
+ * This program is open source software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#define SHOW_ME_VAPPEND_PRINTF
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <string.h>
+#include <stdarg.h>
 #include <libcitadel.h>
 #include "citadel.h"
 #include "sysdep_decls.h"
 #include "internet_addressing.h"
-#include "imap_tools.h"
 #include "serv_imap.h"
+#include "imap_tools.h"
 #include "ctdl_module.h"
 
 #ifndef HAVE_SNPRINTF
@@ -225,7 +225,7 @@ static char* toimap(char* destp, char* destend, char* src)
 
        *destp = 0;
        string_init(&dest, destp, destend-destp);
-       /* CtdlLogPrintf(CTDL_DEBUG, "toimap %s\r\n", src); */
+       /* IMAP_syslog(LOG_DEBUG, "toimap %s", src); */
 
        for (;;)
        {
@@ -291,7 +291,7 @@ static char* toimap(char* destp, char* destend, char* src)
 
        if (state == 1)
                utf7_closeb64(&dest, v, i);
-       /* CtdlLogPrintf(CTDL_DEBUG, "    -> %s\r\n", destp); */
+       /* IMAP_syslog(LOG_DEBUG, "    -> %s", destp); */
        return string_end(&dest);
 }
 
@@ -309,7 +309,7 @@ static char* fromimap(char* destp, char* destend, const char* src)
 
        *destp = 0;
        string_init(&dest, destp, destend-destp);
-       /* CtdlLogPrintf(CTDL_DEBUG, "fromimap %s\r\n", src); */
+       /* IMAP_syslog(LOG_DEBUG, "fromimap %s", src); */
 
        do {
                c = *p++;
@@ -367,7 +367,7 @@ static char* fromimap(char* destp, char* destend, const char* src)
                        }
        } while (c != '\0');
 
-       /* CtdlLogPrintf(CTDL_DEBUG, "      -> %s\r\n", destp); */
+       /* IMAP_syslog(LOG_DEBUG, "      -> %s", destp); */
        return string_end(&dest);
 }
 
@@ -383,59 +383,6 @@ static int cfrommap(int c)
        return 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 plain_imap_strout(char *buf)
-{
-       int i;
-       int is_literal = 0;
-       long len;
-
-       if (buf == NULL) {      /* yeah, we handle this */
-               cprintf("NIL");
-               return;
-       }
-
-       len = strlen(buf);
-       for (i = 0; i < len; ++i) {
-               if ((buf[i] == '\"') || (buf[i] == '\\'))
-                       is_literal = 1;
-       }
-
-       if (is_literal) {
-               cprintf("{%ld}\r\n%s", len, buf);
-       } else {
-               cprintf("\"%s\"", 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);
-       }
-}
-
 
 
 
@@ -606,65 +553,6 @@ int imap_parameterize(citimap_command *Cmd)
        return Cmd->num_parms;
 }
 
-int old_imap_parameterize(char** args, char *in)
-{
-       char* out = in;
-       int num = 0;
-
-       for (;;)
-       {
-               /* Skip whitespace. */
-
-               while (isspace(*in))
-                       in++;
-               if (*in == 0)
-                       break;
-
-               /* Found the start of a token. */
-               
-               args[num++] = out;
-
-               /* Read in the token. */
-
-               for (;;)
-               {
-                       int c = *in++;
-                       if (isspace(c))
-                               break;
-                       
-                       if (c == '\"')
-                       {
-                               /* Found a quoted section. */
-
-                               for (;;)
-                               {
-                                       c = *in++;
-                                       if (c == '\"')
-                                               break;
-                                       else if (c == '\\')
-                                               c = *in++;
-
-                                       *out++ = c;
-                                       if (c == 0)
-                                               return num;
-                               }
-                       }
-                       else if (c == '\\')
-                       {
-                               c = *in++;
-                               *out++ = c;
-                       }
-                       else
-                               *out++ = c;
-
-                       if (c == 0)
-                               return num;
-               }
-               *out++ = '\0';
-       }
-
-       return num;
-}
 
 /* Convert a struct ctdlroom to an IMAP-compatible mailbox name. */
 
@@ -681,13 +569,13 @@ void imap_mailboxname(char *buf, int bufsize, struct ctdlroom *qrbuf)
        if (qrbuf->QRflags & QR_MAILBOX)
        {
                if (strcasecmp(qrbuf->QRname+11, MAILROOM) == 0)
-                       p = toimap(p, bufend, "INBOX");
+                       toimap(p, bufend, "INBOX");
                else
                {
                        p = toimap(p, bufend, "INBOX");
                        if (p < bufend)
                                *p++ = '/';
-                       p = toimap(p, bufend, qrbuf->QRname+11);
+                       toimap(p, bufend, qrbuf->QRname+11);
                }
        }
        else
@@ -698,7 +586,7 @@ void imap_mailboxname(char *buf, int bufsize, struct ctdlroom *qrbuf)
                p = toimap(p, bufend, fl->f_name);
                if (p < bufend)
                        *p++ = '/';
-               p = toimap(p, bufend, qrbuf->QRname);
+               toimap(p, bufend, qrbuf->QRname);
        }
 }
 
@@ -716,6 +604,7 @@ void imap_mailboxname(char *buf, int bufsize, struct ctdlroom *qrbuf)
 
 int imap_roomname(char *rbuf, int bufsize, const char *foldername)
 {
+       struct CitContext *CCC = CC;
        int levels;
        char floorname[ROOMNAMELEN*2];
        char roomname[ROOMNAMELEN];
@@ -792,7 +681,7 @@ int imap_roomname(char *rbuf, int bufsize, const char *foldername)
        ret = (0 | IR_MAILBOX);
 
 exit:
-       CtdlLogPrintf(CTDL_DEBUG, "(That translates to \"%s\")\n", rbuf);
+       IMAP_syslog(LOG_DEBUG, "(That translates to \"%s\")", rbuf);
        return(ret);
 }
 
@@ -804,22 +693,22 @@ void imap_ial_out(struct internet_address_list *ialist)
        struct internet_address_list *iptr;
 
        if (ialist == NULL) {
-               cprintf("NIL");
+               IAPuts("NIL");
                return;
        }
-       cprintf("(");
+       IAPuts("(");
 
        for (iptr = ialist; iptr != NULL; iptr = iptr->next) {
-               cprintf("(");
+               IAPuts("(");
                plain_imap_strout(iptr->ial_name);
-               cprintf(" NIL ");
+               IAPuts(" NIL ");
                plain_imap_strout(iptr->ial_user);
-               cprintf(" ");
+               IAPuts(" ");
                plain_imap_strout(iptr->ial_node);
-               cprintf(")");
+               IAPuts(")");
        }
 
-       cprintf(")");
+       IAPuts(")");
 }
 
 
@@ -951,7 +840,10 @@ star:
                                }
                                return WILDMAT_TRUE;
                        }
-                       while (!IsEmptyStr(text) && (*(text - 1) != WILDMAT_DELIM)) {
+                       while (!IsEmptyStr(text) &&
+                              /* make shure texst - 1 isn't before lcase_p */
+                              ((text == lcase_text) || (*(text - 1) != WILDMAT_DELIM)))
+                       {
                                if ((matched = do_imap_match(text++, p))
                                   != WILDMAT_FALSE) {
                                        return matched;
@@ -961,7 +853,8 @@ star:
                }
        }
 
-       return (*text == '\0');
+       if ((*text == '\0') && (*p == '\0')) return WILDMAT_TRUE;
+       else return WILDMAT_FALSE;
 }
 
 
@@ -1034,3 +927,137 @@ int imap_datecmp(const char *datestr, time_t msgtime) {
        return(0);
 }
 
+
+
+
+
+void IAPrintf(const char *Format, ...)
+{
+       va_list arg_ptr;
+       
+       va_start(arg_ptr, Format);
+       StrBufVAppendPrintf(IMAP->Reply, Format, arg_ptr);
+       va_end(arg_ptr);
+}
+
+void iaputs(const char *Str, long Len)
+{
+       StrBufAppendBufPlain(IMAP->Reply, Str, Len, 0);
+}
+
+void ireply(const char *Msg, long len)
+{
+       citimap *Imap = IMAP;
+
+       StrBufAppendBufPlain(Imap->Reply, 
+                            CKEY(Imap->Cmd.Params[0]), 0);
+       StrBufAppendBufPlain(Imap->Reply, 
+                            HKEY(" "), 0);
+       StrBufAppendBufPlain(Imap->Reply, 
+                            Msg, len, 0);
+       
+       StrBufAppendBufPlain(Imap->Reply, 
+                            HKEY("\r\n"), 0);
+       
+}
+
+void IReplyPrintf(const char *Format, ...)
+{
+       citimap *Imap = IMAP;
+       va_list arg_ptr;
+       
+
+       StrBufAppendBufPlain(Imap->Reply, 
+                            CKEY(Imap->Cmd.Params[0]), 0);
+
+       StrBufAppendBufPlain(Imap->Reply, 
+                            HKEY(" "), 0);
+
+       va_start(arg_ptr, Format);
+       StrBufVAppendPrintf(IMAP->Reply, Format, arg_ptr);
+       va_end(arg_ptr);
+       
+       StrBufAppendBufPlain(Imap->Reply, 
+                            HKEY("\r\n"), 0);
+       
+}
+
+
+
+/* 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 plain_imap_strout(char *buf)
+{
+       int i;
+       int is_literal = 0;
+       long Len;
+       citimap *Imap = IMAP;
+
+       if (buf == NULL) {      /* yeah, we handle this */
+               IAPuts("NIL");
+               return;
+       }
+
+       Len = strlen(buf);
+       for (i = 0; i < Len; ++i) {
+               if ((buf[i] == '\"') || (buf[i] == '\\'))
+                       is_literal = 1;
+       }
+
+       if (is_literal) {
+               StrBufAppendPrintf(Imap->Reply, "{%ld}\r\n", Len);
+               StrBufAppendBufPlain(Imap->Reply, buf, Len, 0);
+       } else {
+               StrBufAppendBufPlain(Imap->Reply, 
+                                    HKEY("\""), 0);
+               StrBufAppendBufPlain(Imap->Reply, 
+                                    buf, Len, 0);
+               StrBufAppendBufPlain(Imap->Reply, 
+                                    HKEY("\""), 0);
+       }
+}
+
+
+/* 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 IPutStr(const char *Msg, long Len)
+{
+       int i;
+       int is_literal = 0;
+       citimap *Imap = IMAP;
+
+       
+       if ((Msg == NULL) || (Len == 0))
+       {       /* yeah, we handle this */
+               StrBufAppendBufPlain(Imap->Reply, HKEY("NIL"), 0);
+               return;
+       }
+
+       for (i = 0; i < Len; ++i) {
+               if ((Msg[i] == '\"') || (Msg[i] == '\\'))
+                       is_literal = 1;
+       }
+
+       if (is_literal) {
+               StrBufAppendPrintf(Imap->Reply, "{%ld}\r\n", Len);
+               StrBufAppendBufPlain(Imap->Reply, Msg, Len, 0);
+       } else {
+               StrBufAppendBufPlain(Imap->Reply, 
+                                    HKEY("\""), 0);
+               StrBufAppendBufPlain(Imap->Reply, 
+                                    Msg, Len, 0);
+               StrBufAppendBufPlain(Imap->Reply, 
+                                    HKEY("\""), 0);
+       }
+}
+
+void IUnbuffer (void)
+{
+       citimap *Imap = IMAP;
+
+       cputbuf(Imap->Reply);
+       FlushStrBuf(Imap->Reply);
+}