Add the callback to open an existing message to struct mx_ops. For mbox, mmdf, maildir, and mh, the code was implemented directly into mx_open_message, so it is moved in their respective source files. For imap and pop, there were already <mailbox>_fetch_message functions, but their argument order has been changed to pass the context as a first argument. --- Changes in v2: - Restore missing perror and debug messages - Change mx_open_message to improve readability
imap/imap.c | 1 + imap/imap.h | 1 - imap/imap_private.h | 2 ++ imap/message.c | 2 +- mbox.c | 9 ++++++++ mh.c | 34 +++++++++++++++++++++++++++++ mutt.h | 1 + mx.c | 62 +++++++++-------------------------------------------- pop.c | 3 ++- pop.h | 1 - 10 files changed, 60 insertions(+), 56 deletions(-) diff --git a/imap/imap.c b/imap/imap.c index 8a73ec9..ce802b1 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -2070,6 +2070,7 @@ int imap_complete(char* dest, size_t dlen, char* path) { struct mx_ops mx_imap_ops = { .open = imap_open_mailbox, .close = imap_close_mailbox, + .open_msg = imap_fetch_message, .open_new_msg = imap_open_new_message, .check = imap_check_mailbox_reopen, }; diff --git a/imap/imap.h b/imap/imap.h index 132ae2b..dbbaf92 100644 --- a/imap/imap.h +++ b/imap/imap.h @@ -58,7 +58,6 @@ int imap_mailbox_rename (const char* mailbox); /* message.c */ int imap_append_message (CONTEXT* ctx, MESSAGE* msg); int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete); -int imap_fetch_message (MESSAGE* msg, CONTEXT* ctx, int msgno); /* socket.c */ void imap_logout_all (void); diff --git a/imap/imap_private.h b/imap/imap_private.h index b557974..f5dd83f 100644 --- a/imap/imap_private.h +++ b/imap/imap_private.h @@ -268,6 +268,8 @@ char* imap_set_flags (IMAP_DATA* idata, HEADER* h, char* s); int imap_cache_del (IMAP_DATA* idata, HEADER* h); int imap_cache_clean (IMAP_DATA* idata); +int imap_fetch_message (CONTEXT *ctx, MESSAGE *msg, int msgno); + /* util.c */ #ifdef USE_HCACHE header_cache_t* imap_hcache_open (IMAP_DATA* idata, const char* path); diff --git a/imap/message.c b/imap/message.c index 5e66b1d..f631617 100644 --- a/imap/message.c +++ b/imap/message.c @@ -391,7 +391,7 @@ error_out_0: return retval; } -int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno) +int imap_fetch_message (CONTEXT *ctx, MESSAGE *msg, int msgno) { IMAP_DATA* idata; HEADER* h; diff --git a/mbox.c b/mbox.c index 3d071dc..fb3f5b5 100644 --- a/mbox.c +++ b/mbox.c @@ -451,6 +451,13 @@ static int mbox_close_mailbox (CONTEXT *ctx) return 0; } +static int mbox_open_message (CONTEXT *ctx, MESSAGE *msg, int msgno) +{ + msg->fp = ctx->fp; + + return 0; +} + static int mbox_open_new_message (MESSAGE *msg, CONTEXT *dest, HEADER *hdr) { msg->fp = dest->fp; @@ -1278,6 +1285,7 @@ int mbox_check_empty (const char *path) struct mx_ops mx_mbox_ops = { .open = mbox_open_mailbox, .close = mbox_close_mailbox, + .open_msg = mbox_open_message, .open_new_msg = mbox_open_new_message, .check = mbox_check_mailbox, }; @@ -1285,6 +1293,7 @@ struct mx_ops mx_mbox_ops = { struct mx_ops mx_mmdf_ops = { .open = mbox_open_mailbox, .close = mbox_close_mailbox, + .open_msg = mbox_open_message, .open_new_msg = mbox_open_new_message, .check = mbox_check_mailbox, }; diff --git a/mh.c b/mh.c index 7b04305..c88d216 100644 --- a/mh.c +++ b/mh.c @@ -1330,6 +1330,38 @@ static void maildir_flags (char *dest, size_t destlen, HEADER * hdr) } } +static int maildir_mh_open_message (CONTEXT *ctx, MESSAGE *msg, int msgno, + int is_maildir) +{ + HEADER *cur = ctx->hdrs[msgno]; + char path[_POSIX_PATH_MAX]; + + snprintf (path, sizeof (path), "%s/%s", ctx->path, cur->path); + + msg->fp = fopen (path, "r"); + if (msg->fp == NULL && errno == ENOENT && is_maildir) + msg->fp = maildir_open_find_message (ctx->path, cur->path); + + if (!msg->fp) + { + mutt_perror (path); + dprint (1, (debugfile, "maildir_mh_open_message: fopen: %s: %s (errno %d).\n", + path, strerror (errno), errno)); + return -1; + } + + return 0; +} + +static int maildir_open_message (CONTEXT *ctx, MESSAGE *msg, int msgno) +{ + return maildir_mh_open_message (ctx, msg, msgno, 1); +} + +static int mh_open_message (CONTEXT *ctx, MESSAGE *msg, int msgno) +{ + return maildir_mh_open_message (ctx, msg, msgno, 0); +} /* * Open a new (temporary) message in a maildir folder. @@ -2406,6 +2438,7 @@ int mx_is_mh (const char *path) struct mx_ops mx_maildir_ops = { .open = maildir_open_mailbox, .close = mh_close_mailbox, + .open_msg = maildir_open_message, .open_new_msg = maildir_open_new_message, .check = maildir_check_mailbox, }; @@ -2413,6 +2446,7 @@ struct mx_ops mx_maildir_ops = { struct mx_ops mx_mh_ops = { .open = mh_open_mailbox, .close = mh_close_mailbox, + .open_msg = mh_open_message, .open_new_msg = mh_open_new_message, .check = mh_check_mailbox, }; diff --git a/mutt.h b/mutt.h index cb386fb..9e728b2 100644 --- a/mutt.h +++ b/mutt.h @@ -893,6 +893,7 @@ struct mx_ops int (*open)(struct _context *); int (*close)(struct _context *); int (*check) (struct _context *ctx, int *index_hint); + int (*open_msg) (struct _context *, struct _message *, int msgno); int (*open_new_msg) (struct _message *, struct _context *, HEADER *); }; diff --git a/mx.c b/mx.c index e051421..f5920d2 100644 --- a/mx.c +++ b/mx.c @@ -1314,62 +1314,20 @@ int mx_check_mailbox (CONTEXT *ctx, int *index_hint) /* return a stream pointer for a message */ MESSAGE *mx_open_message (CONTEXT *ctx, int msgno) { + struct mx_ops *ops = mx_get_ops (ctx->magic); MESSAGE *msg; - - msg = safe_calloc (1, sizeof (MESSAGE)); - switch (msg->magic = ctx->magic) - { - case MUTT_MBOX: - case MUTT_MMDF: - msg->fp = ctx->fp; - break; + int ret; - case MUTT_MH: - case MUTT_MAILDIR: - { - HEADER *cur = ctx->hdrs[msgno]; - char path[_POSIX_PATH_MAX]; - - snprintf (path, sizeof (path), "%s/%s", ctx->path, cur->path); - - if ((msg->fp = fopen (path, "r")) == NULL && errno == ENOENT && - ctx->magic == MUTT_MAILDIR) - msg->fp = maildir_open_find_message (ctx->path, cur->path); - - if (msg->fp == NULL) - { - mutt_perror (path); - dprint (1, (debugfile, "mx_open_message: fopen: %s: %s (errno %d).\n", - path, strerror (errno), errno)); - FREE (&msg); - } - } - break; - -#ifdef USE_IMAP - case MUTT_IMAP: - { - if (imap_fetch_message (msg, ctx, msgno) != 0) - FREE (&msg); - break; - } -#endif /* USE_IMAP */ + if (!ops || !ops->open_msg) + dprint (1, (debugfile, "mx_open_message(): function not implemented for mailbox type %d.\n", ctx->magic)); -#ifdef USE_POP - case MUTT_POP: - { - if (pop_fetch_message (msg, ctx, msgno) != 0) - FREE (&msg); - break; - } -#endif /* USE_POP */ + msg = safe_calloc (1, sizeof (MESSAGE)); + msg->magic = ctx->magic; + ret = ops->open_msg (ctx, msg, msgno); + if (ret) + FREE (&msg); - default: - dprint (1, (debugfile, "mx_open_message(): function not implemented for mailbox type %d.\n", ctx->magic)); - FREE (&msg); - break; - } - return (msg); + return msg; } /* commit a message to a folder */ diff --git a/pop.c b/pop.c index 4f0124a..15c9979 100644 --- a/pop.c +++ b/pop.c @@ -512,7 +512,7 @@ int pop_close_mailbox (CONTEXT *ctx) } /* fetch message from POP server */ -int pop_fetch_message (MESSAGE* msg, CONTEXT* ctx, int msgno) +static int pop_fetch_message (CONTEXT* ctx, MESSAGE* msg, int msgno) { int ret; void *uidl; @@ -931,5 +931,6 @@ fail: struct mx_ops mx_pop_ops = { .open = pop_open_mailbox, .close = pop_close_mailbox, + .open_msg = pop_fetch_message, .check = pop_check_mailbox, }; diff --git a/pop.h b/pop.h index edc1ed1..53454c6 100644 --- a/pop.h +++ b/pop.h @@ -106,7 +106,6 @@ void pop_error (POP_DATA *, char *); /* pop.c */ int pop_sync_mailbox (CONTEXT *, int *); -int pop_fetch_message (MESSAGE *, CONTEXT *, int); int pop_close_mailbox (CONTEXT *); void pop_fetch_mail (void); -- 2.8.3