From d22efaae6e4ec48aad0da1324278a567b5b3326a Mon Sep 17 00:00:00 2001 From: Damien Riegel Date: Thu, 12 May 2016 12:41:25 -0700 Subject: [PATCH] Start decoupling mailbox operations. 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 | 8 ++++-- imap/imap.h | 3 ++- mbox.c | 17 +++++++++++- mh.c | 25 +++++++++++++++--- mutt.h | 10 +++++++- mx.c | 74 ++++++++++++++++++++++++----------------------------- mx.h | 7 ++--- pop.c | 8 ++++-- pop.h | 3 ++- 9 files changed, 101 insertions(+), 54 deletions(-) diff --git a/imap/imap.c b/imap/imap.c index 228b3b29..e9e84191 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -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, +}; diff --git a/imap/imap.h b/imap/imap.h index a914b404..132ae2b9 100644 --- a/imap/imap.h +++ b/imap/imap.h @@ -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 83c9cd87..b7dda144 100644 --- 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 33fc712a..c156a10c 100644 --- 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 c06054f0..58290419 100644 --- 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 3f47932d..256248c1 100644 --- a/mx.c +++ b/mx.c @@ -57,6 +57,30 @@ #include #include +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 18562df4..dfc549e0 100644 --- 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 e2977967..f45c2fec 100644 --- 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 efa6d9e3..88671890 100644 --- 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 -- 2.40.0