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
.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
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
.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
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
.tags_edit = NULL,
.tags_commit = NULL,
.path_probe = maildir_path_probe,
- .path_canon = NULL,
+ .path_canon = maildir_path_canon,
.path_pretty = NULL,
};
.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
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
.tags_edit = NULL,
.tags_commit = NULL,
.path_probe = mbox_path_probe,
- .path_canon = NULL,
+ .path_canon = mbox_path_canon,
.path_pretty = NULL,
};
.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
#include "config.h"
#include <errno.h>
#include <limits.h>
+#include <pwd.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "email/email.h"
#include "mutt.h"
#include "mx.h"
+#include "alias.h"
#include "context.h"
#include "copy.h"
#include "globals.h"
*/
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;
}
/**
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
.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
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
.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
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
.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