From: Richard Russon Date: Fri, 24 Aug 2018 14:39:00 +0000 (+0100) Subject: delegate mx_path_canon() X-Git-Tag: 2019-10-25~682^2~12 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5f79f7f610cb965d5ea7a97ab9beb226bbfb8262;p=neomutt delegate mx_path_canon() --- diff --git a/compress.c b/compress.c index 69f02f3da..578ceafa7 100644 --- a/compress.c +++ b/compress.c @@ -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 diff --git a/imap/imap.c b/imap/imap.c index d0de7dcb9..df1ebd7a5 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -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 diff --git a/maildir/mh.c b/maildir/mh.c index ac2f31dea..db1d2a5cf 100644 --- a/maildir/mh.c +++ b/maildir/mh.c @@ -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 diff --git a/mbox/mbox.c b/mbox/mbox.c index c4c5c860e..98edca009 100644 --- a/mbox/mbox.c +++ b/mbox/mbox.c @@ -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 16f257f54..c6be439e5 100644 --- a/mx.c +++ b/mx.c @@ -30,6 +30,7 @@ #include "config.h" #include #include +#include #include #include #include @@ -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; } /** diff --git a/nntp/nntp.c b/nntp/nntp.c index 75f879ae4..a085a68a3 100644 --- a/nntp/nntp.c +++ b/nntp/nntp.c @@ -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 diff --git a/notmuch/mutt_notmuch.c b/notmuch/mutt_notmuch.c index 5b5acf88e..7468becb5 100644 --- a/notmuch/mutt_notmuch.c +++ b/notmuch/mutt_notmuch.c @@ -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 diff --git a/pop/pop.c b/pop/pop.c index 9caf4a76c..16b7d0081 100644 --- 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