# HG changeset patch
# User Damien Riegel <[email protected]>
# Date 1462472851 14400
#      Thu May 05 14:27:31 2016 -0400
# Node ID 5a9939d77f263a6fae4917734a2121fc2bd740ca
# Parent  c1a4059ef454226bf2cdfdf70ba6d53791170b7e
provide a facility to register mailboxes

To make mailboxes less tighly coupled with the rest of the application,
we need to register them dynamically, and not rely on some kind of magic
enum. For that, a mx_register function is introduced. It will store the
mx_ops in a linked list. It is not intended to be called but in
mx_register_all.

mx_probe takes a path as parameter and returns the first mx_ops for
which mx_ops->probe returned true, or NULL otherwise.

diff -r c1a4059ef454 -r 5a9939d77f26 mx.c
--- a/mx.c      Thu May 05 12:29:44 2016 -0400
+++ b/mx.c      Thu May 05 14:27:31 2016 -0400
@@ -57,6 +57,75 @@
 #include <ctype.h>
 #include <utime.h>
 
+struct mailbox_list {
+  struct mx_ops *mx_ops;
+  struct mailbox_list *next;
+};
+
+static struct mailbox_list *first_mailbox = NULL;
+
+static int mx_register(struct mx_ops *ops)
+{
+  struct mailbox_list **last = &first_mailbox;
+  struct mailbox_list *current;
+
+  if (!ops)
+    return -1;
+
+  while (*last)
+    last = &(*last)->next;
+
+  current = malloc(sizeof(*current));
+  if (!current)
+    return -1;
+
+  current->mx_ops = ops;
+  current->next = NULL;
+  (*last) = current;
+
+  return 0;
+}
+
+#define MX_REGISTER_MAILBOX(_mailbox)             \
+  {                                               \
+    extern struct mx_ops mx_ ## _mailbox ## _ops; \
+    mx_register(&mx_##_mailbox##_ops);            \
+  }
+
+static void mx_register_all(void)
+{
+  static int initialized = 0;
+
+  if (initialized)
+    return;
+
+  initialized = 1;
+
+#ifdef USE_IMAP
+  MX_REGISTER_MAILBOX(imap);
+#endif
+  MX_REGISTER_MAILBOX(maildir);
+  MX_REGISTER_MAILBOX(mbox);
+  MX_REGISTER_MAILBOX(mh);
+  MX_REGISTER_MAILBOX(mmdf);
+#ifdef USE_POP
+  MX_REGISTER_MAILBOX(pop);
+#endif
+}
+
+static struct mx_ops* mx_probe(const char *path)
+{
+  struct mailbox_list *current = first_mailbox;
+
+  while (current) {
+    if (current->mx_ops->probe(path))
+      return current->mx_ops;
+
+    current = current->next;
+  }
+
+  return NULL;
+}
 
 #define mutt_is_spool(s)  (mutt_strcmp (Spoolfile, s) == 0)
 
@@ -623,6 +692,7 @@
     return ctx;
   }
 
+  mx_register_all();
   ctx->magic = mx_get_magic (path);
   
   if(ctx->magic == 0)

Reply via email to