]> granicus.if.org Git - mutt/commitdiff
Start decoupling mailbox operations.
authorDamien Riegel <damien.riegel@gmail.com>
Thu, 12 May 2016 19:41:25 +0000 (12:41 -0700)
committerDamien Riegel <damien.riegel@gmail.com>
Thu, 12 May 2016 19:41:25 +0000 (12:41 -0700)
Introduce a dedicated structure for mailbox operations: struct mx_ops.
Move the open and close operations into that structure.

Assign this structure to the context in mx_open_mailbox.  This is
currently based on the "magic" for the mailbox type, but may be
refactored in the future.

Add a stub mbox_close_mailbox function.  This function does nothing,
the main purpose is to introduce a mx_ops structure for mbox, so its
usage is similar to mh/imap/pop.  We reuse the name that was made
available by the previous commmit.  Note that the actual closing of
the descriptor is done in mx.c.

To be more consistent with other mailboxes, introduce functions
mh_open_mailbox and maildir_open_mailbox, and create a dedicated
structure for mmdf.

imap/imap.c
imap/imap.h
mbox.c
mh.c
mutt.h
mx.c
mx.h
pop.c
pop.h

index 228b3b29f97a72ea759bad92beb8635c2a1fd8b4..e9e84191d27f8861ad1733a85cb71a8e6df73789 100644 (file)
@@ -554,7 +554,7 @@ static char* imap_get_flags (LIST** hflags, char* s)
   return s;
 }
 
-int imap_open_mailbox (CONTEXT* ctx)
+static int imap_open_mailbox (CONTEXT* ctx)
 {
   IMAP_DATA *idata;
   IMAP_STATUS* status;
@@ -578,7 +578,6 @@ int imap_open_mailbox (CONTEXT* ctx)
 
   /* once again the context is new */
   ctx->data = idata;
-  ctx->mx_close = imap_close_mailbox;
 
   /* Clean up path and replace the one in the ctx */
   imap_fix_path (idata, mx.mbox, buf, sizeof (buf));
@@ -2038,3 +2037,8 @@ int imap_complete(char* dest, size_t dlen, char* path) {
 
   return -1;
 }
+
+struct mx_ops mx_imap_ops = {
+  .open = imap_open_mailbox,
+  .close = imap_close_mailbox,
+};
index a914b404a3607465df360f5d1575166da8971ef5..132ae2b9ba342ef2141284f7d0cc71caffd75c53 100644 (file)
@@ -35,7 +35,6 @@ typedef struct
 int imap_access (const char*, int);
 int imap_check_mailbox (CONTEXT *ctx, int *index_hint, int force);
 int imap_delete_mailbox (CONTEXT* idata, IMAP_MBOX mx);
-int imap_open_mailbox (CONTEXT *ctx);
 int imap_open_mailbox_append (CONTEXT *ctx);
 int imap_sync_mailbox (CONTEXT *ctx, int expunge, int *index_hint);
 int imap_close_mailbox (CONTEXT *ctx);
@@ -48,6 +47,8 @@ int imap_complete (char* dest, size_t dlen, char* path);
 void imap_allow_reopen (CONTEXT *ctx);
 void imap_disallow_reopen (CONTEXT *ctx);
 
+extern struct mx_ops mx_imap_ops;
+
 /* browse.c */
 int imap_browse (char* path, struct browser_state* state);
 int imap_mailbox_state (const char* path, struct mailbox_state* state);
diff --git a/mbox.c b/mbox.c
index 83c9cd87478ae061aaabcb40a7e10b5234448d4b..b7dda14492ad2b807075a569ed7fb5cb219f4631 100644 (file)
--- a/mbox.c
+++ b/mbox.c
@@ -412,7 +412,7 @@ int mbox_parse_mailbox (CONTEXT *ctx)
 #undef PREV
 
 /* open a mbox or mmdf style mailbox */
-int mbox_open_mailbox (CONTEXT *ctx)
+static int mbox_open_mailbox (CONTEXT *ctx)
 {
   int rc;
 
@@ -440,6 +440,11 @@ int mbox_open_mailbox (CONTEXT *ctx)
   return (rc);
 }
 
+static int mbox_close_mailbox (CONTEXT *ctx)
+{
+  return 0;
+}
+
 /* return 1 if address lists are strictly identical */
 static int strict_addrcmp (const ADDRESS *a, const ADDRESS *b)
 {
@@ -1257,3 +1262,13 @@ int mbox_check_empty (const char *path)
 
   return ((st.st_size == 0));
 }
+
+struct mx_ops mx_mbox_ops = {
+  .open = mbox_open_mailbox,
+  .close = mbox_close_mailbox,
+};
+
+struct mx_ops mx_mmdf_ops = {
+  .open = mbox_open_mailbox,
+  .close = mbox_close_mailbox,
+};
diff --git a/mh.c b/mh.c
index 33fc712adb30519d639a3faeb0de993cea4b07b8..c156a10c2778c5540b23a23f9c4b8146bede8a46 100644 (file)
--- a/mh.c
+++ b/mh.c
@@ -1168,7 +1168,7 @@ static int mh_close_mailbox (CONTEXT *ctx)
  *     subdir [IN]     NULL for MH mailboxes, otherwise the subdir of the
  *                     maildir mailbox to read from
  */
-int mh_read_dir (CONTEXT * ctx, const char *subdir)
+static int mh_read_dir (CONTEXT * ctx, const char *subdir)
 {
   struct maildir *md;
   struct mh_sequences mhs;
@@ -1188,7 +1188,6 @@ int mh_read_dir (CONTEXT * ctx, const char *subdir)
   if (!ctx->data)
   {
     ctx->data = safe_calloc(sizeof (struct mh_data), 1);
-    ctx->mx_close = mh_close_mailbox;
   }
   data = mh_data (ctx);
 
@@ -1224,7 +1223,7 @@ int mh_read_dir (CONTEXT * ctx, const char *subdir)
 }
 
 /* read a maildir style mailbox */
-int maildir_read_dir (CONTEXT * ctx)
+static int maildir_read_dir (CONTEXT * ctx)
 {
   /* maildir looks sort of like MH, except that there are two subdirectories
    * of the main folder path from which to read messages
@@ -1235,6 +1234,16 @@ int maildir_read_dir (CONTEXT * ctx)
   return 0;
 }
 
+static int maildir_open_mailbox (CONTEXT *ctx)
+{
+  return maildir_read_dir (ctx);
+}
+
+static int mh_open_mailbox (CONTEXT *ctx)
+{
+  return mh_read_dir (ctx, NULL);
+}
+
 /*
  * Open a new (temporary) message in an MH folder.
  */
@@ -2348,3 +2357,13 @@ int mx_is_mh (const char *path)
 
   return 0;
 }
+
+struct mx_ops mx_maildir_ops = {
+  .open = maildir_open_mailbox,
+  .close = mh_close_mailbox,
+};
+
+struct mx_ops mx_mh_ops = {
+  .open = mh_open_mailbox,
+  .close = mh_close_mailbox,
+};
diff --git a/mutt.h b/mutt.h
index c06054f037fd25cccbac5904aa1c8a242e5f4b5b..582904192d86a318ff7f8348d3f65d928ddd3f56 100644 (file)
--- a/mutt.h
+++ b/mutt.h
@@ -868,6 +868,14 @@ enum
   RIGHTSMAX
 };
 
+struct _context;
+
+struct mx_ops
+{
+  int (*open)(struct _context *);
+  int (*close)(struct _context *);
+};
+
 typedef struct _context
 {
   char *path;
@@ -909,7 +917,7 @@ typedef struct _context
 
   /* driver hooks */
   void *data;                  /* driver specific data */
-  int (*mx_close)(struct _context *);
+  struct mx_ops *mx_ops;
 } CONTEXT;
 
 typedef struct
diff --git a/mx.c b/mx.c
index 3f47932d3d67c32144bb2613c3872415d9eb43d9..256248c13e8dbadfd3942af84b12ebc5a52cd2d8 100644 (file)
--- a/mx.c
+++ b/mx.c
 #include <ctype.h>
 #include <utime.h>
 
+static struct mx_ops* mx_get_ops (int magic)
+{
+  switch (magic)
+  {
+#ifdef USE_IMAP
+    case MUTT_IMAP:
+      return &mx_imap_ops;
+#endif
+    case MUTT_MAILDIR:
+      return &mx_maildir_ops;
+    case MUTT_MBOX:
+      return &mx_mbox_ops;
+    case MUTT_MH:
+      return &mx_mh_ops;
+    case MUTT_MMDF:
+      return &mx_mmdf_ops;
+#ifdef USE_POP
+    case MUTT_POP:
+      return &mx_pop_ops;
+#endif
+    default:
+      return NULL;
+  }
+}
 
 #define mutt_is_spool(s)  (mutt_strcmp (Spoolfile, s) == 0)
 
@@ -625,15 +649,15 @@ CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT *pctx)
   }
 
   ctx->magic = mx_get_magic (path);
-  
-  if(ctx->magic == 0)
-    mutt_error (_("%s is not a mailbox."), path);
+  ctx->mx_ops = mx_get_ops (ctx->magic);
 
-  if(ctx->magic == -1)
-    mutt_perror(path);
-  
-  if(ctx->magic <= 0)
+  if (ctx->magic <= 0 || !ctx->mx_ops)
   {
+    if (ctx->magic == 0 || !ctx->mx_ops)
+      mutt_error (_("%s is not a mailbox."), path);
+    else if (ctx->magic == -1)
+      mutt_perror(path);
+
     mx_fastclose_mailbox (ctx);
     if (!pctx)
       FREE (&ctx);
@@ -650,37 +674,7 @@ CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT *pctx)
   if (!ctx->quiet)
     mutt_message (_("Reading %s..."), ctx->path);
 
-  switch (ctx->magic)
-  {
-    case MUTT_MH:
-      rc = mh_read_dir (ctx, NULL);
-      break;
-
-    case MUTT_MAILDIR:
-      rc = maildir_read_dir (ctx);
-      break;
-
-    case MUTT_MMDF:
-    case MUTT_MBOX:
-      rc = mbox_open_mailbox (ctx);
-      break;
-
-#ifdef USE_IMAP
-    case MUTT_IMAP:
-      rc = imap_open_mailbox (ctx);
-      break;
-#endif /* USE_IMAP */
-
-#ifdef USE_POP
-    case MUTT_POP:
-      rc = pop_open_mailbox (ctx);
-      break;
-#endif /* USE_POP */
-
-    default:
-      rc = -1;
-      break;
-  }
+  rc = ctx->mx_ops->open(ctx);
 
   if (rc == 0)
   {
@@ -718,8 +712,8 @@ void mx_fastclose_mailbox (CONTEXT *ctx)
    * XXX: really belongs in mx_close_mailbox, but this is a nice hook point */
   mutt_buffy_setnotified(ctx->path);
 
-  if (ctx->mx_close)
-    ctx->mx_close (ctx);
+  if (ctx->mx_ops)
+    ctx->mx_ops->close (ctx);
 
   if (ctx->subj_hash)
     hash_destroy (&ctx->subj_hash, NULL);
diff --git a/mx.h b/mx.h
index 18562df47d13478d8af9a581c75c23ab92ea4603..dfc549e0445daee123fc691a402075aa1b45ea5a 100644 (file)
--- a/mx.h
+++ b/mx.h
@@ -44,7 +44,6 @@ WHERE short DefaultMagic INITVAL (MUTT_MBOX);
 #define MAXLOCKATTEMPT 5
 
 int mbox_sync_mailbox (CONTEXT *, int *);
-int mbox_open_mailbox (CONTEXT *);
 int mbox_check_mailbox (CONTEXT *, int *);
 int mbox_lock_mailbox (CONTEXT *, int, int);
 int mbox_parse_mailbox (CONTEXT *);
@@ -53,12 +52,10 @@ void mbox_unlock_mailbox (CONTEXT *);
 int mbox_check_empty (const char *);
 void mbox_reset_atime (CONTEXT *, struct stat *);
 
-int mh_read_dir (CONTEXT *, const char *);
 int mh_sync_mailbox (CONTEXT *, int *);
 int mh_check_mailbox (CONTEXT *, int *);
 int mh_check_empty (const char *);
 
-int maildir_read_dir (CONTEXT *);
 int maildir_check_mailbox (CONTEXT *, int *);
 int maildir_check_empty (const char *);
 
@@ -81,5 +78,9 @@ void mx_update_tables (CONTEXT *, int);
 int mx_lock_file (const char *, int, int, int, int);
 int mx_unlock_file (const char *path, int fd, int dot);
 
+extern struct mx_ops mx_maildir_ops;
+extern struct mx_ops mx_mbox_ops;
+extern struct mx_ops mx_mh_ops;
+extern struct mx_ops mx_mmdf_ops;
 
 #endif
diff --git a/pop.c b/pop.c
index e2977967e7d252bd41505551c2afed047cc7bbe1..f45c2fec0f27a857c9d7dd476359b63add0b1608 100644 (file)
--- a/pop.c
+++ b/pop.c
@@ -397,7 +397,7 @@ static int pop_fetch_headers (CONTEXT *ctx)
 }
 
 /* open POP mailbox - fetch only headers */
-int pop_open_mailbox (CONTEXT *ctx)
+static int pop_open_mailbox (CONTEXT *ctx)
 {
   int ret;
   char buf[LONG_STRING];
@@ -426,7 +426,6 @@ int pop_open_mailbox (CONTEXT *ctx)
   pop_data = safe_calloc (1, sizeof (POP_DATA));
   pop_data->conn = conn;
   ctx->data = pop_data;
-  ctx->mx_close = pop_close_mailbox;
 
   if (pop_open_connection (pop_data) < 0)
     return -1;
@@ -928,3 +927,8 @@ fail:
   mutt_socket_close (conn);
   FREE (&pop_data);
 }
+
+struct mx_ops mx_pop_ops = {
+  .open = pop_open_mailbox,
+  .close = pop_close_mailbox,
+};
diff --git a/pop.h b/pop.h
index efa6d9e3bcfb9e687e2109272b9189ae2a308b8f..88671890933fe973f53d1b114027fea2aa7e486a 100644 (file)
--- a/pop.h
+++ b/pop.h
@@ -106,10 +106,11 @@ void pop_error (POP_DATA *, char *);
 
 /* pop.c */
 int pop_check_mailbox (CONTEXT *, int *);
-int pop_open_mailbox (CONTEXT *);
 int pop_sync_mailbox (CONTEXT *, int *);
 int pop_fetch_message (MESSAGE *, CONTEXT *, int);
 int pop_close_mailbox (CONTEXT *);
 void pop_fetch_mail (void);
 
+extern struct mx_ops mx_pop_ops;
+
 #endif