]> granicus.if.org Git - neomutt/commitdiff
delegate mx_path_canon()
authorRichard Russon <rich@flatcap.org>
Fri, 24 Aug 2018 14:39:00 +0000 (15:39 +0100)
committerRichard Russon <rich@flatcap.org>
Sun, 26 Aug 2018 21:11:03 +0000 (22:11 +0100)
compress.c
imap/imap.c
maildir/mh.c
mbox/mbox.c
mx.c
nntp/nntp.c
notmuch/mutt_notmuch.c
pop/pop.c

index 69f02f3dae2e00cefbcc67a73047208d2aa14594..578ceafa79f6996d8c74686b08cf9dda092edd26 100644 (file)
@@ -909,6 +909,27 @@ int comp_path_probe(const char *path, const struct stat *st)
   return MUTT_UNKNOWN;
 }
 
+/**
+ * comp_path_canon - Canonicalise a mailbox path - Implements MxOps::path_canon
+ */
+int comp_path_canon(char *buf, size_t buflen, const char *folder)
+{
+  if (!buf)
+    return -1;
+
+  if ((buf[0] == '+') || (buf[0] == '='))
+  {
+    if (!folder)
+      return -1;
+
+    buf[0] = '/';
+    mutt_str_inline_replace(buf, buflen, 0, folder);
+  }
+
+  mutt_path_canon(buf, buflen, HomeDir);
+  return 0;
+}
+
 // clang-format off
 /**
  * struct mx_comp_ops - Mailbox callback functions for compressed mailboxes
@@ -931,7 +952,7 @@ struct MxOps mx_comp_ops = {
   .tags_edit        = NULL,
   .tags_commit      = NULL,
   .path_probe       = comp_path_probe,
-  .path_canon       = NULL,
+  .path_canon       = comp_path_canon,
   .path_pretty      = NULL,
 };
 // clang-format on
index d0de7dcb9b08e08647b258c26788ad896441f6d6..df1ebd7a512063ce4a8549dfb26526d8486fd9ec 100644 (file)
@@ -2734,6 +2734,34 @@ int imap_path_probe(const char *path, const struct stat *st)
   return MUTT_UNKNOWN;
 }
 
+/**
+ * imap_path_canon - Canonicalise a mailbox path - Implements MxOps::path_canon
+ */
+int imap_path_canon(char *buf, size_t buflen, const char *folder)
+{
+  if (!buf)
+    return -1;
+
+  if ((buf[0] == '+') || (buf[0] == '='))
+  {
+    if (!folder)
+      return -1;
+
+    size_t flen = mutt_str_strlen(folder);
+    if ((flen > 0) && (folder[flen - 1] != '/'))
+    {
+      buf[0] = '/';
+      mutt_str_inline_replace(buf, buflen, 0, folder);
+    }
+    else
+    {
+      mutt_str_inline_replace(buf, buflen, 1, folder);
+    }
+  }
+
+  return imap_expand_path(buf, buflen);
+}
+
 // clang-format off
 /**
  * struct mx_imap_ops - Mailbox callback functions for IMAP mailboxes
@@ -2753,7 +2781,7 @@ struct MxOps mx_imap_ops = {
   .tags_edit        = imap_tags_edit,
   .tags_commit      = imap_tags_commit,
   .path_probe       = imap_path_probe,
-  .path_canon       = NULL,
+  .path_canon       = imap_path_canon,
   .path_pretty      = NULL,
 };
 // clang-format on
index ac2f31dea5242ea0cade36fe98583db5be797a34..db1d2a5cf7462c6a35fc58b97ce75fa9a3cd9fe4 100644 (file)
@@ -2951,6 +2951,27 @@ bool mx_is_mh(const char *path)
   return (mh_path_probe(path, NULL) == MUTT_MH);
 }
 
+/**
+ * maildir_path_canon - Canonicalise a mailbox path - Implements MxOps::path_canon
+ */
+int maildir_path_canon(char *buf, size_t buflen, const char *folder)
+{
+  if (!buf)
+    return -1;
+
+  if ((buf[0] == '+') || (buf[0] == '='))
+  {
+    if (!folder)
+      return -1;
+
+    buf[0] = '/';
+    mutt_str_inline_replace(buf, buflen, 0, folder);
+  }
+
+  mutt_path_canon(buf, buflen, HomeDir);
+  return 0;
+}
+
 // clang-format off
 /**
  * struct mx_maildir_ops - Mailbox callback functions for Maildir mailboxes
@@ -2970,7 +2991,7 @@ struct MxOps mx_maildir_ops = {
   .tags_edit        = NULL,
   .tags_commit      = NULL,
   .path_probe       = maildir_path_probe,
-  .path_canon       = NULL,
+  .path_canon       = maildir_path_canon,
   .path_pretty      = NULL,
 };
 
@@ -2992,7 +3013,7 @@ struct MxOps mx_mh_ops = {
   .tags_edit        = NULL,
   .tags_commit      = NULL,
   .path_probe       = mh_path_probe,
-  .path_canon       = NULL,
+  .path_canon       = maildir_path_canon,
   .path_pretty      = NULL,
 };
 // clang-format on
index c4c5c860e1d8ec31c1f96500534e795dd71b6487..98edca009774f5fd341c5f365c1f4ef04c4f92ab 100644 (file)
@@ -1376,6 +1376,27 @@ int mbox_path_probe(const char *path, const struct stat *st)
   return magic;
 }
 
+/**
+ * mbox_path_canon - Canonicalise a mailbox path - Implements MxOps::path_canon
+ */
+int mbox_path_canon(char *buf, size_t buflen, const char *folder)
+{
+  if (!buf)
+    return -1;
+
+  if ((buf[0] == '+') || (buf[0] == '='))
+  {
+    if (!folder)
+      return -1;
+
+    buf[0] = '/';
+    mutt_str_inline_replace(buf, buflen, 0, folder);
+  }
+
+  mutt_path_canon(buf, buflen, HomeDir);
+  return 0;
+}
+
 // clang-format off
 /**
  * struct mx_mbox_ops - Mailbox callback functions for mbox mailboxes
@@ -1395,7 +1416,7 @@ struct MxOps mx_mbox_ops = {
   .tags_edit        = NULL,
   .tags_commit      = NULL,
   .path_probe       = mbox_path_probe,
-  .path_canon       = NULL,
+  .path_canon       = mbox_path_canon,
   .path_pretty      = NULL,
 };
 
@@ -1417,7 +1438,7 @@ struct MxOps mx_mmdf_ops = {
   .tags_edit        = NULL,
   .tags_commit      = NULL,
   .path_probe       = mbox_path_probe,
-  .path_canon       = NULL,
+  .path_canon       = mbox_path_canon,
   .path_pretty      = NULL,
 };
 // clang-format on
diff --git a/mx.c b/mx.c
index 16f257f546f3ae2ff6986d422c326ee5dcf5092e..c6be439e5d3d1fe06d8365a6c081c107153c626e 100644 (file)
--- a/mx.c
+++ b/mx.c
@@ -30,6 +30,7 @@
 #include "config.h"
 #include <errno.h>
 #include <limits.h>
+#include <pwd.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
@@ -41,6 +42,7 @@
 #include "email/email.h"
 #include "mutt.h"
 #include "mx.h"
+#include "alias.h"
 #include "context.h"
 #include "copy.h"
 #include "globals.h"
@@ -1566,7 +1568,79 @@ int mx_path_probe(const char *path, const struct stat *st)
  */
 int mx_path_canon(char *buf, size_t buflen, const char *folder)
 {
-  return -1;
+  if (!buf)
+    return -1;
+
+  for (size_t i = 0; i < 3; i++)
+  {
+    /* Look for !! ! - < > or ^ followed by / or NUL */
+    if ((buf[0] == '!') && (buf[1] == '!'))
+    {
+      if (((buf[2] == '/') || (buf[2] == '\0')))
+      {
+        mutt_str_inline_replace(buf, buflen, 2, LastFolder);
+      }
+    }
+    else if ((buf[1] == '/') || (buf[1] == '\0'))
+    {
+      if (buf[0] == '!')
+      {
+        mutt_str_inline_replace(buf, buflen, 1, Spoolfile);
+      }
+      else if (buf[0] == '-')
+      {
+        mutt_str_inline_replace(buf, buflen, 1, LastFolder);
+      }
+      else if (buf[0] == '<')
+      {
+        mutt_str_inline_replace(buf, buflen, 1, Record);
+      }
+      else if (buf[0] == '>')
+      {
+        mutt_str_inline_replace(buf, buflen, 1, Mbox);
+      }
+      else if (buf[0] == '^')
+      {
+        mutt_str_inline_replace(buf, buflen, 1, CurrentFolder);
+      }
+    }
+    else if (buf[0] == '@')
+    {
+      /* elm compatibility, @ expands alias to user name */
+      struct Address *alias = mutt_alias_lookup(buf + 1);
+      if (!alias)
+        break;
+
+      struct Header *h = mutt_header_new();
+      h->env = mutt_env_new();
+      h->env->from = alias;
+      h->env->to = alias;
+      mutt_default_save(buf, buflen, h);
+      h->env->from = NULL;
+      h->env->to = NULL;
+      mutt_header_free(&h);
+      break;
+    }
+    else
+    {
+      break;
+    }
+  }
+
+  if (!folder)
+    return -1;
+
+  int magic = mx_path_probe(folder, NULL);
+  const struct MxOps *ops = mx_get_ops(magic);
+  if (!ops || !ops->path_canon)
+    return -1;
+
+  if (ops->path_canon(buf, buflen, folder) < 0)
+  {
+    mutt_path_canon(buf, buflen, HomeDir);
+  }
+
+  return 0;
 }
 
 /**
index 75f879ae4eabb528a93b021c357594e40db36433..a085a68a346a8891955924f48f2c81c592b9d26e 100644 (file)
@@ -2640,6 +2640,34 @@ int nntp_path_probe(const char *path, const struct stat *st)
   return MUTT_UNKNOWN;
 }
 
+/**
+ * nntp_path_canon - Canonicalise a mailbox path - Implements MxOps::path_canon
+ */
+int nntp_path_canon(char *buf, size_t buflen, const char *folder)
+{
+  if (!buf)
+    return -1;
+
+  if ((buf[0] == '+') || (buf[0] == '='))
+  {
+    if (!folder)
+      return -1;
+
+    size_t flen = mutt_str_strlen(folder);
+    if ((flen > 0) && (folder[flen - 1] != '/'))
+    {
+      buf[0] = '/';
+      mutt_str_inline_replace(buf, buflen, 0, folder);
+    }
+    else
+    {
+      mutt_str_inline_replace(buf, buflen, 1, folder);
+    }
+  }
+
+  return 0;
+}
+
 // clang-format off
 /**
  * struct mx_nntp_ops - Mailbox callback functions for NNTP mailboxes
@@ -2659,7 +2687,7 @@ struct MxOps mx_nntp_ops = {
   .tags_edit        = NULL,
   .tags_commit      = NULL,
   .path_probe       = nntp_path_probe,
-  .path_canon       = NULL,
+  .path_canon       = nntp_path_canon,
   .path_pretty      = NULL,
 };
 // clang-format on
index 5b5acf88e3ce4c1ecb56f7a5939368756cc92606..7468becb569d7d5a672fb1b8fa1faad7e76ec0d5 100644 (file)
@@ -2775,6 +2775,34 @@ int nm_path_probe(const char *path, const struct stat *st)
   return MUTT_UNKNOWN;
 }
 
+/**
+ * nm_path_canon - Canonicalise a mailbox path - Implements MxOps::path_canon
+ */
+int nm_path_canon(char *buf, size_t buflen, const char *folder)
+{
+  if (!buf)
+    return -1;
+
+  if ((buf[0] == '+') || (buf[0] == '='))
+  {
+    if (!folder)
+      return -1;
+
+    size_t flen = mutt_str_strlen(folder);
+    if ((flen > 0) && (folder[flen - 1] != '/'))
+    {
+      buf[0] = '/';
+      mutt_str_inline_replace(buf, buflen, 0, folder);
+    }
+    else
+    {
+      mutt_str_inline_replace(buf, buflen, 1, folder);
+    }
+  }
+
+  return 0;
+}
+
 // clang-format off
 /**
  * struct mx_notmuch_ops - Mailbox callback functions for Notmuch mailboxes
@@ -2794,7 +2822,7 @@ struct MxOps mx_notmuch_ops = {
   .tags_edit        = nm_tags_edit,
   .tags_commit      = nm_tags_commit,
   .path_probe       = nm_path_probe,
-  .path_canon       = NULL,
+  .path_canon       = nm_path_canon,
   .path_pretty      = NULL,
 };
 // clang-format on
index 9caf4a76c666bc289af0ffbf25b8f3727e588edb..16b7d0081cd144e5116d9cf5c93221cdaf8c57b1 100644 (file)
--- a/pop/pop.c
+++ b/pop/pop.c
@@ -1071,6 +1071,34 @@ int pop_path_probe(const char *path, const struct stat *st)
   return MUTT_UNKNOWN;
 }
 
+/**
+ * pop_path_canon - Canonicalise a mailbox path - Implements MxOps::path_canon
+ */
+int pop_path_canon(char *buf, size_t buflen, const char *folder)
+{
+  if (!buf)
+    return -1;
+
+  if ((buf[0] == '+') || (buf[0] == '='))
+  {
+    if (!folder)
+      return -1;
+
+    size_t flen = mutt_str_strlen(folder);
+    if ((flen > 0) && (folder[flen - 1] != '/'))
+    {
+      buf[0] = '/';
+      mutt_str_inline_replace(buf, buflen, 0, folder);
+    }
+    else
+    {
+      mutt_str_inline_replace(buf, buflen, 1, folder);
+    }
+  }
+
+  return 0;
+}
+
 // clang-format off
 /**
  * mx_pop_ops - Mailbox callback functions for POP mailboxes
@@ -1090,7 +1118,7 @@ struct MxOps mx_pop_ops = {
   .tags_edit        = NULL,
   .tags_commit      = NULL,
   .path_probe       = pop_path_probe,
-  .path_canon       = NULL,
+  .path_canon       = pop_path_canon,
   .path_pretty      = NULL,
 };
 // clang-format on