]> git.llucax.com Git - software/mutt-debian.git/blobdiff - imap/util.c
staging the nntp patch which is not applying cleanly at the moment
[software/mutt-debian.git] / imap / util.c
index 785d8f3b097e8c950fab7d3ca53c37e79464e341..5fa71b9097175edf0098d0399084600eac4210a6 100644 (file)
@@ -1,22 +1,22 @@
 /*
  * Copyright (C) 1996-8 Michael R. Elkins <me@mutt.org>
  * Copyright (C) 1996-9 Brandon Long <blong@fiction.net>
- * Copyright (C) 1999-2005 Brendan Cully <brendan@kublai.com>
- * 
+ * Copyright (C) 1999-2009 Brendan Cully <brendan@kublai.com>
+ *
  *     This program is free software; you can redistribute it and/or modify
  *     it under the terms of the GNU General Public License as published by
  *     the Free Software Foundation; either version 2 of the License, or
  *     (at your option) any later version.
- * 
+ *
  *     This program is distributed in the hope that it will be useful,
  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *     GNU General Public License for more details.
- * 
+ *
  *     You should have received a copy of the GNU General Public License
  *     along with this program; if not, write to the Free Software
  *     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */ 
+ */
 
 /* general IMAP utility functions */
 
@@ -26,7 +26,6 @@
 #include "mx.h"        /* for M_IMAP */
 #include "url.h"
 #include "imap_private.h"
-#include "mutt_ssl.h"
 #ifdef USE_HCACHE
 #include "message.h"
 #include "hcache.h"
 int imap_expand_path (char* path, size_t len)
 {
   IMAP_MBOX mx;
+  IMAP_DATA* idata;
   ciss_url_t url;
+  char fixedpath[LONG_STRING];
   int rc;
 
   if (imap_parse_path (path, &mx) < 0)
     return -1;
 
+  idata = imap_conn_find (&mx.account, M_IMAP_CONN_NONEW);
   mutt_account_tourl (&mx.account, &url);
-  url.path = mx.mbox;
+  imap_fix_path (idata, mx.mbox, fixedpath, sizeof (fixedpath));
+  url.path = fixedpath;
 
   rc = url_ciss_tostring (&url, path, len, U_DECODE_PASSWD);
   FREE (&mx.mbox);
@@ -189,7 +192,7 @@ int imap_parse_path (const char* path, IMAP_MBOX* mx)
   }
 
   /* Defaults */
-  mx->account.flags = 0;
+  memset(&mx->account, 0, sizeof(mx->account));
   mx->account.port = ImapPort;
   mx->account.type = M_ACCT_TYPE_IMAP;
 
@@ -223,7 +226,7 @@ int imap_parse_path (const char* path, IMAP_MBOX* mx)
     else
       /* walk past closing '}' */
       mx->mbox = safe_strdup (c+1);
-  
+
     if ((c = strrchr (tmp, '@')))
     {
       *c = '\0';
@@ -231,14 +234,14 @@ int imap_parse_path (const char* path, IMAP_MBOX* mx)
       strfcpy (tmp, c+1, sizeof (tmp));
       mx->account.flags |= M_ACCT_USER;
     }
-  
+
     if ((n = sscanf (tmp, "%127[^:/]%127s", mx->account.host, tmp)) < 1)
     {
       dprint (1, (debugfile, "imap_parse_path: NULL host in %s\n", path));
       FREE (&mx->mbox);
       return -1;
     }
-  
+
     if (n > 1) {
       if (sscanf (tmp, ":%hu%127s", &(mx->account.port), tmp) >= 1)
        mx->account.flags |= M_ACCT_PORT;
@@ -265,10 +268,28 @@ int imap_parse_path (const char* path, IMAP_MBOX* mx)
 /* silly helper for mailbox name string comparisons, because of INBOX */
 int imap_mxcmp (const char* mx1, const char* mx2)
 {
+  char* b1;
+  char* b2;
+  int rc;
+
+  if (!mx1 || !*mx1)
+    mx1 = "INBOX";
+  if (!mx2 || !*mx2)
+    mx2 = "INBOX";
   if (!ascii_strcasecmp (mx1, "INBOX") && !ascii_strcasecmp (mx2, "INBOX"))
     return 0;
-  
-  return mutt_strcmp (mx1, mx2);
+
+  b1 = safe_malloc (strlen (mx1) + 1);
+  b2 = safe_malloc (strlen (mx2) + 1);
+
+  imap_fix_path (NULL, mx1, b1, strlen (mx1) + 1);
+  imap_fix_path (NULL, mx2, b2, strlen (mx2) + 1);
+
+  rc = mutt_strcmp (b1, b2);
+  FREE (&b1);
+  FREE (&b2);
+
+  return rc;
 }
 
 /* imap_pretty_mailbox: called by mutt_pretty_mailbox to make IMAP paths
@@ -354,6 +375,13 @@ IMAP_DATA* imap_new_idata (void)
   if (!(idata->cmdbuf = mutt_buffer_init (NULL)))
     FREE (&idata);
 
+  idata->cmdslots = ImapPipelineDepth + 2;
+  if (!(idata->cmds = safe_calloc(idata->cmdslots, sizeof(*idata->cmds))))
+  {
+    mutt_buffer_free(&idata->cmdbuf);
+    FREE (&idata);
+  }
+
   return idata;
 }
 
@@ -369,6 +397,7 @@ void imap_free_idata (IMAP_DATA** idata)
   mutt_buffer_free(&(*idata)->cmdbuf);
   FREE (&(*idata)->buf);
   mutt_bcache_close (&(*idata)->bcache);
+  FREE (&(*idata)->cmds);
   FREE (idata);                /* __FREE_CHECKED__ */
 }
 
@@ -380,31 +409,39 @@ void imap_free_idata (IMAP_DATA** idata)
  * are not required to do this.
  * Moreover, IMAP servers may dislike the path ending with the delimiter.
  */
-char *imap_fix_path (IMAP_DATA *idata, char *mailbox, char *path, 
+char *imap_fix_path (IMAP_DATA *idata, const char *mailbox, char *path,
     size_t plen)
 {
-  int x = 0;
+  int i = 0;
+  char delim = '\0';
 
-  while (mailbox && *mailbox && (x < (plen - 1)))
+  if (idata)
+    delim = idata->delim;
+
+  while (mailbox && *mailbox && i < plen - 1)
   {
-    if ((*mailbox == '/') || (*mailbox == idata->delim))
+    if ((ImapDelimChars && strchr(ImapDelimChars, *mailbox))
+        || *mailbox == delim)
     {
-      while ((*mailbox == '/') || (*mailbox == idata->delim)) mailbox++;
-      path[x] = idata->delim;
+      /* use connection delimiter if known. Otherwise use user delimiter */
+      if (!idata)
+        delim = *mailbox;
+
+      while (*mailbox &&
+            (strchr(ImapDelimChars, *mailbox) || *mailbox == delim))
+        mailbox++;
+      path[i] = delim;
     }
     else
     {
-      path[x] = *mailbox;
+      path[i] = *mailbox;
       mailbox++;
     }
-    x++;
+    i++;
   }
-  if (x && path[--x] != idata->delim)
-    x++;
-  path[x] = '\0';
-
-  if (!path[0])
-    strfcpy (path, "INBOX", plen);
+  if (i && path[--i] != delim)
+    i++;
+  path[i] = '\0';
 
   return path;
 }
@@ -498,7 +535,7 @@ time_t imap_parse_date (char *s)
   struct tm t;
   time_t tz;
 
-  t.tm_mday = (s[0] == ' '? s[1] - '0' : (s[0] - '0') * 10 + (s[1] - '0'));  
+  t.tm_mday = (s[0] == ' '? s[1] - '0' : (s[0] - '0') * 10 + (s[1] - '0'));
   s += 2;
   if (*s != '-')
     return 0;
@@ -566,7 +603,7 @@ void imap_quote_string (char *dest, size_t dlen, const char *src)
   *pt++ = '"';
   /* save room for trailing quote-char */
   dlen -= 2;
-  
+
   for (; *s && dlen; s++)
   {
     if (strchr (quote, *s))
@@ -646,7 +683,7 @@ void imap_unmunge_mbox_name (char *s)
     imap_utf7_decode (&buf);
     strncpy (s, buf, strlen (s));
   }
-  
+
   FREE (&buf);
 }
 
@@ -672,10 +709,10 @@ int imap_wordcasecmp(const char *a, const char *b)
   return ascii_strcasecmp(a, tmp);
 }
 
-/* 
+/*
  * Imap keepalive: poll the current folder to keep the
  * connection alive.
- * 
+ *
  */
 
 static RETSIGTYPE alrm_handler (int sig)
@@ -724,7 +761,7 @@ int imap_wait_keepalive (pid_t pid)
   int rc;
 
   short imap_passive = option (OPTIMAPPASSIVE);
-  
+
   set_option (OPTIMAPPASSIVE);
   set_option (OPTKEEPQUIET);
 
@@ -749,7 +786,7 @@ int imap_wait_keepalive (pid_t pid)
   }
 
   alarm (0);   /* cancel a possibly pending alarm */
-  
+
   sigaction (SIGALRM, &oldalrm, NULL);
   sigprocmask (SIG_SETMASK, &oldmask, NULL);
 
@@ -773,3 +810,13 @@ void imap_disallow_reopen (CONTEXT *ctx)
   if (ctx && ctx->magic == M_IMAP && CTX_DATA->ctx == ctx)
     CTX_DATA->reopen &= ~IMAP_REOPEN_ALLOW;
 }
+
+int imap_account_match (const ACCOUNT* a1, const ACCOUNT* a2)
+{
+  IMAP_DATA* a1_idata = imap_conn_find (a1, M_IMAP_CONN_NONEW);
+  IMAP_DATA* a2_idata = imap_conn_find (a2, M_IMAP_CONN_NONEW);
+  const ACCOUNT* a1_canon = a1_idata == NULL ? a1 : &a1_idata->conn->account;
+  const ACCOUNT* a2_canon = a2_idata == NULL ? a2 : &a2_idata->conn->account;
+
+  return mutt_account_match (a1_canon, a2_canon);
+}