X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=mx.c;h=6ee2be7a01f1bf0fe640cc4cbc9558bc66b2ca80;hp=6f6f779dc087eb1a9e06af76a76ef43674aa977d;hb=ac1ea3143e61def7fc9000bee6d0d59d56c5b997;hpb=d0dc8fb657cff90709c15d4b106415b868857f6a diff --git a/mx.c b/mx.c index 6f6f779..6ee2be7 100644 --- a/mx.c +++ b/mx.c @@ -8,17 +8,13 @@ * please see the file GPL in the top level source directory. */ -#if HAVE_CONFIG_H -# include "config.h" -#endif +#include -#include -#include -#include -#include -#include +#include +#include #include +#include #include "mutt.h" #include "buffy.h" @@ -29,63 +25,39 @@ #include "thread.h" #include "copy.h" #include "keymap.h" -#include "url.h" -#include "sidebar.h" - -#ifdef USE_COMPRESSED #include "compress.h" -#endif - -#ifdef USE_IMAP -#include "imap/imap.h" -#include "imap/mx_imap.h" -#endif +#include "dotlock.h" -#ifdef USE_POP -#include "pop/pop.h" -#include "pop/mx_pop.h" -#endif +#include +#include #ifdef USE_NNTP -#include "nntp/nntp.h" -#include "nntp/mx_nntp.h" -#endif - -#ifdef USE_DOTLOCK -#include "dotlock.h" +#include #endif -#include "mutt_crypt.h" - -#include "lib/list.h" -#include "lib/debug.h" +#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static list2_t* MailboxFormats = NULL; -#define MX_COMMAND(idx,cmd) ((mx_t*) MailboxFormats->data[idx])->cmd -#define MX_IDX(idx) (idx >= 0 && idx < MailboxFormats->length) +static mx_t const *mxfmts[] = { + &mbox_mx, + &mmdf_mx, + &mh_mx, + &maildir_mx, + &imap_mx, + &pop_mx, +#ifdef USE_NNTP + &nntp_mx, +#endif + &compress_mx, +}; -#define mutt_is_spool(s) (m_strcmp(Spoolfile, s) == 0) +#define MX_IDX(idx) (idx >= 0 && idx < countof(mxfmts)) +#define mutt_is_spool(s) (m_strcmp(Spoolfile, s) == 0) -#ifdef USE_DOTLOCK /* parameters: * path - file to lock * retry - should retry if unable to lock? */ - -#ifdef DL_STANDALONE - -static int invoke_dotlock (const char *path, int dummy, int flags, int retry) +static int invoke_dotlock (const char *path, int flags, int retry) { char cmd[LONG_STRING + _POSIX_PATH_MAX]; char f[SHORT_STRING + _POSIX_PATH_MAX]; @@ -109,13 +81,7 @@ static int invoke_dotlock (const char *path, int dummy, int flags, int retry) return mutt_system (cmd); } -#else - -#define invoke_dotlock dotlock_invoke - -#endif - -static int dotlock_file (const char *path, int fd, int retry) +static int dotlock_file (const char *path, int retry) { int r; int flags = DL_FL_USEPRIV | DL_FL_RETRY; @@ -124,7 +90,7 @@ static int dotlock_file (const char *path, int fd, int retry) retry = 1; retry_lock: - if ((r = invoke_dotlock (path, fd, flags, retry)) == DL_EX_EXIST) { + if ((r = invoke_dotlock (path, flags, retry)) == DL_EX_EXIST) { if (!option (OPTNOCURSES)) { char msg[LONG_STRING]; @@ -144,45 +110,43 @@ retry_lock: return (r == DL_EX_OK ? 0 : -1); } -static int undotlock_file (const char *path, int fd) +static int undotlock_file (const char *path) { - return (invoke_dotlock (path, fd, DL_FL_USEPRIV | DL_FL_UNLOCK, 0) == + return (invoke_dotlock (path, DL_FL_USEPRIV | DL_FL_UNLOCK, 0) == DL_EX_OK ? 0 : -1); } -#endif /* USE_DOTLOCK */ - -/* looks up index of type for path in MailboxFormats */ +/* looks up index of type for path in mxfmts */ static int mx_get_idx (const char* path) { - int i = 0, t = 0; - struct stat st; - - /* first, test all non-local folders to avoid stat() call */ - for (i = 0; i < MailboxFormats->length; i++) { - if (!MX_COMMAND(i,local)) - t = MX_COMMAND(i,mx_is_magic)(path, NULL); - if (t >= 1) - return (t-1); - } - if (stat (path, &st) == 0) { - /* if stat() succeeded, keep testing until success and - * pass stat() info so that we only need to do it once */ - for (i = 0; i < MailboxFormats->length; i++) { - if (MX_COMMAND(i,local)) - t = MX_COMMAND(i,mx_is_magic)(path, &st); - if (t >= 1) - return (t-1); + int i = 0, t = 0; + struct stat st; + + /* first, test all non-local folders to avoid stat() call */ + for (i = 0; i < countof(mxfmts); i++) { + if (!mxfmts[i]->local) + t = mxfmts[i]->mx_is_magic(path, NULL); + if (t >= 1) + return (t-1); } - } - return (-1); + if (stat (path, &st) == 0) { + /* if stat() succeeded, keep testing until success and + * pass stat() info so that we only need to do it once */ + for (i = 0; i < countof(mxfmts); i++) { + if (mxfmts[i]->local) + t = mxfmts[i]->mx_is_magic(path, &st); + if (t >= 1) + return (t-1); + } + } + return (-1); } /* Args: * excl if excl != 0, request an exclusive lock * dot if dot != 0, try to dotlock the file - * timeout should retry locking? + * time_out should retry locking? */ -int mx_lock_file (const char *path, int fd, int excl, int dot, int timeout) +int mx_lock_file (const char *path, int fd, int excl, int dot, int time_out) { #if defined (USE_FCNTL) || defined (USE_FLOCK) int count; @@ -205,7 +169,6 @@ int mx_lock_file (const char *path, int fd, int excl, int dot, int timeout) while (fcntl (fd, F_SETLK, &lck) == -1) { struct stat sb; - debug_print (1, ("fcntl errno %d.\n", errno)); if (errno != EAGAIN && errno != EACCES) { mutt_perror ("fcntl"); return (-1); @@ -219,8 +182,8 @@ int mx_lock_file (const char *path, int fd, int excl, int dot, int timeout) /* only unlock file if it is unchanged */ if (prev_sb.st_size == sb.st_size - && ++count >= (timeout ? MAXLOCKATTEMPT : 0)) { - if (timeout) + && ++count >= (time_out ? MAXLOCKATTEMPT : 0)) { + if (time_out) mutt_error _("Timeout exceeded while attempting fcntl lock!"); return (-1); @@ -253,8 +216,8 @@ int mx_lock_file (const char *path, int fd, int excl, int dot, int timeout) /* only unlock file if it is unchanged */ if (prev_sb.st_size == sb.st_size - && ++count >= (timeout ? MAXLOCKATTEMPT : 0)) { - if (timeout) + && ++count >= (time_out ? MAXLOCKATTEMPT : 0)) { + if (time_out) mutt_error _("Timeout exceeded while attempting flock lock!"); r = -1; @@ -268,10 +231,8 @@ int mx_lock_file (const char *path, int fd, int excl, int dot, int timeout) } #endif /* USE_FLOCK */ -#ifdef USE_DOTLOCK if (r == 0 && dot) - r = dotlock_file (path, fd, timeout); -#endif /* USE_DOTLOCK */ + r = dotlock_file (path, time_out); if (r == -1) { /* release any other locks obtained in this routine */ @@ -306,22 +267,16 @@ int mx_unlock_file (const char *path, int fd, int dot) flock (fd, LOCK_UN); #endif -#ifdef USE_DOTLOCK if (dot) - undotlock_file (path, fd); -#endif + undotlock_file (path); return 0; } -void mx_unlink_empty (const char *path) +static void mx_unlink_empty (const char *path) { int fd; -#ifndef USE_DOTLOCK - struct stat sb; -#endif - if ((fd = open (path, O_RDWR)) == -1) return; @@ -330,12 +285,7 @@ void mx_unlink_empty (const char *path) return; } -#ifdef USE_DOTLOCK - invoke_dotlock (path, fd, DL_FL_UNLINK, 1); -#else - if (fstat (fd, &sb) == 0 && sb.st_size == 0) - unlink (path); -#endif + invoke_dotlock(path, DL_FL_UNLINK, 1); mx_unlock_file (path, fd, 0); close (fd); @@ -348,14 +298,14 @@ int mx_get_magic (const char *path) { if (m_strlen(path) == 0) return (-1); if ((i = mx_get_idx (path)) >= 0) - return (MX_COMMAND(i,type)); + return (mxfmts[i]->type); return (-1); } int mx_is_local (int m) { if (!MX_IDX(m)) return (0); - return (MX_COMMAND(m,local)); + return (mxfmts[m]->local); } /* @@ -384,8 +334,8 @@ int mx_access (const char *path, int flags) { int i = 0; - if ((i = mx_get_idx (path)) >= 0 && MX_COMMAND(i,mx_access)) - return (MX_COMMAND(i,mx_access)(path,flags)); + if ((i = mx_get_idx (path)) >= 0 && mxfmts[i]->mx_access) + return (mxfmts[i]->mx_access(path,flags)); return (0); } @@ -393,22 +343,16 @@ static int mx_open_mailbox_append (CONTEXT * ctx, int flags) { struct stat sb; -#ifdef USE_COMPRESSED /* special case for appending to compressed folders - * even if we can not open them for reading */ if (mutt_can_append_compressed (ctx->path)) mutt_open_append_compressed (ctx); -#endif ctx->append = 1; -#ifdef USE_IMAP - if (mx_get_magic (ctx->path) == M_IMAP) return imap_open_mailbox_append (ctx); -#endif - if (stat (ctx->path, &sb) == 0) { ctx->magic = mx_get_magic (ctx->path); @@ -548,10 +492,8 @@ CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT * pctx) if (!MX_IDX(ctx->magic-1)) ctx->magic = mx_get_magic (path); -#ifdef USE_COMPRESSED if (ctx->magic == M_COMPRESSED) mutt_open_read_compressed (ctx); -#endif if (ctx->magic == 0) mutt_error (_("%s is not a mailbox."), path); @@ -576,7 +518,7 @@ CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT * pctx) if (!ctx->quiet) mutt_message (_("Reading %s..."), ctx->path); - rc = MX_COMMAND(ctx->magic-1,mx_open_mailbox)(ctx); + rc = mxfmts[ctx->magic-1]->mx_open_mailbox(ctx); if (rc == 0) { if ((flags & M_NOSORT) == 0) { @@ -607,21 +549,21 @@ void mx_fastclose_mailbox (CONTEXT * ctx) if (!ctx) return; - if (MX_IDX(ctx->magic-1) && MX_COMMAND(ctx->magic-1,mx_fastclose_mailbox)) - MX_COMMAND(ctx->magic-1,mx_fastclose_mailbox(ctx)); + if (MX_IDX(ctx->magic-1) && mxfmts[ctx->magic-1]->mx_fastclose_mailbox) + mxfmts[ctx->magic-1]->mx_fastclose_mailbox(ctx); if (ctx->subj_hash) hash_destroy (&ctx->subj_hash, NULL); if (ctx->id_hash) hash_destroy (&ctx->id_hash, NULL); mutt_clear_threads (ctx); for (i = 0; i < ctx->msgcount; i++) - mutt_free_header (&ctx->hdrs[i]); + header_delete(&ctx->hdrs[i]); p_delete(&ctx->hdrs); p_delete(&ctx->v2r); -#ifdef USE_COMPRESSED + if (ctx->compressinfo) mutt_fast_close_compressed (ctx); -#endif + p_delete(&ctx->path); p_delete(&ctx->pattern); if (ctx->limit_pattern) @@ -640,12 +582,10 @@ static int sync_mailbox (CONTEXT * ctx, int *index_hint) if (MX_IDX(ctx->magic-1)) /* the 1 is only of interest for IMAP and means EXPUNGE */ - rc = MX_COMMAND(ctx->magic-1,mx_sync_mailbox(ctx,1,index_hint)); + rc = mxfmts[ctx->magic-1]->mx_sync_mailbox(ctx,1,index_hint); -#ifdef USE_COMPRESSED if (rc == 0 && ctx->compressinfo) return mutt_sync_compressed (ctx); -#endif return rc; } @@ -777,10 +717,8 @@ static int _mx_close_mailbox (CONTEXT * ctx, int *index_hint) } } -#ifdef USE_IMAP /* IMAP servers manage the OLD flag themselves */ if (ctx->magic != M_IMAP) -#endif if (option (OPTMARKOLD)) { for (i = 0; i < ctx->msgcount; i++) { if (!ctx->hdrs[i]->deleted && !ctx->hdrs[i]->old) @@ -791,7 +729,6 @@ static int _mx_close_mailbox (CONTEXT * ctx, int *index_hint) if (move_messages) { mutt_message (_("Moving read messages to %s..."), mbox); -#ifdef USE_IMAP /* try to use server-side copy first */ i = 1; @@ -814,7 +751,6 @@ static int _mx_close_mailbox (CONTEXT * ctx, int *index_hint) return -1; } else /* use regular append-copy mode */ -#endif { if (mx_open_mailbox (mbox, M_APPEND, &f) == NULL) { ctx->closing = 0; @@ -855,7 +791,6 @@ static int _mx_close_mailbox (CONTEXT * ctx, int *index_hint) return -1; } -#ifdef USE_IMAP /* allow IMAP to preserve the deleted flag across sessions */ if (ctx->magic == M_IMAP) { if ((check = imap_sync_mailbox (ctx, purge, index_hint)) != 0) { @@ -864,7 +799,6 @@ static int _mx_close_mailbox (CONTEXT * ctx, int *index_hint) } } else -#endif { if (!purge) { for (i = 0; i < ctx->msgcount; i++) @@ -892,10 +826,8 @@ static int _mx_close_mailbox (CONTEXT * ctx, int *index_hint) !mutt_is_spool (ctx->path) && !option (OPTSAVEEMPTY)) mx_unlink_empty (ctx->path); -#ifdef USE_COMPRESSED if (ctx->compressinfo && mutt_slow_close_compressed (ctx)) return (-1); -#endif mx_fastclose_mailbox (ctx); @@ -980,7 +912,7 @@ void mx_update_tables (CONTEXT * ctx, int committing) if (ctx->id_hash && ctx->hdrs[i]->env->message_id) hash_delete (ctx->id_hash, ctx->hdrs[i]->env->message_id, ctx->hdrs[i], NULL); - mutt_free_header (&ctx->hdrs[i]); + header_delete(&ctx->hdrs[i]); } } #undef this_body @@ -1038,10 +970,8 @@ static int _mx_sync_mailbox (CONTEXT * ctx, int *index_hint) else if (purge == M_NO) { if (!ctx->changed) return 0; /* nothing to do! */ -#ifdef USE_IMAP /* let IMAP servers hold on to D flags */ if (ctx->magic != M_IMAP) -#endif { for (i = 0; i < ctx->msgcount; i++) ctx->hdrs[i]->deleted = 0; @@ -1062,19 +992,15 @@ static int _mx_sync_mailbox (CONTEXT * ctx, int *index_hint) return -1; } -#ifdef USE_IMAP if (ctx->magic == M_IMAP) rc = imap_sync_mailbox (ctx, purge, index_hint); else -#endif rc = sync_mailbox (ctx, index_hint); if (rc == 0) { -#ifdef USE_IMAP if (ctx->magic == M_IMAP && !purge) mutt_message (_("Mailbox checkpointed.")); else -#endif mutt_message (_("%d kept, %d deleted."), msgcount - deleted, deleted); mutt_sleep (0); @@ -1095,10 +1021,8 @@ static int _mx_sync_mailbox (CONTEXT * ctx, int *index_hint) * at least with the new threading code. */ if (purge || (ctx->magic != M_MAILDIR && ctx->magic != M_MH)) { -#ifdef USE_IMAP /* IMAP does this automatically after handling EXPUNGE */ if (ctx->magic != M_IMAP) -#endif { mx_update_tables (ctx, 1); mutt_sort_headers (ctx, 1); /* rethread from scratch */ @@ -1126,7 +1050,6 @@ MESSAGE *mx_open_new_message (CONTEXT * dest, HEADER * hdr, int flags) address_t *p = NULL; if (!MX_IDX(dest->magic-1)) { - debug_print (1, ("function unimplemented for mailbox type %d.\n", dest->magic)); return (NULL); } @@ -1144,7 +1067,7 @@ MESSAGE *mx_open_new_message (CONTEXT * dest, HEADER * hdr, int flags) if (msg->received == 0) time (&msg->received); - if (MX_COMMAND(dest->magic-1,mx_open_new_message)(msg, dest, hdr) == 0) { + if (mxfmts[dest->magic-1]->mx_open_new_message(msg, dest, hdr) == 0) { if (dest->magic == M_MMDF) fputs (MMDF_SEP, msg->fp); @@ -1170,21 +1093,17 @@ MESSAGE *mx_open_new_message (CONTEXT * dest, HEADER * hdr, int flags) /* check for new mail */ int mx_check_mailbox (CONTEXT * ctx, int *index_hint, int lock) { -#ifdef USE_COMPRESSED if (ctx->compressinfo) return mutt_check_mailbox_compressed (ctx); -#endif if (ctx) { if (ctx->locked) lock = 0; - if (MX_IDX(ctx->magic-1) && MX_COMMAND(ctx->magic-1,mx_check_mailbox)) - return (MX_COMMAND(ctx->magic-1,mx_check_mailbox)(ctx, index_hint, lock)); + if (MX_IDX(ctx->magic-1) && mxfmts[ctx->magic-1]->mx_check_mailbox) + return (mxfmts[ctx->magic-1]->mx_check_mailbox(ctx, index_hint, lock)); } - debug_print (1, ("null or invalid context.\n")); return (-1); - } /* return a stream pointer for a message */ @@ -1213,29 +1132,24 @@ MESSAGE *mx_open_message (CONTEXT * ctx, int msgno) if (msg->fp == NULL) { mutt_perror (path); - debug_print (1, ("fopen: %s: %s (errno %d).\n", path, strerror (errno), errno)); p_delete(&msg); } } break; -#ifdef USE_IMAP case M_IMAP: { if (imap_fetch_message (msg, ctx, msgno) != 0) p_delete(&msg); break; } -#endif /* USE_IMAP */ -#ifdef USE_POP case M_POP: { if (pop_fetch_message (msg, ctx, msgno) != 0) p_delete(&msg); break; } -#endif /* USE_POP */ #ifdef USE_NNTP case M_NNTP: @@ -1247,7 +1161,6 @@ MESSAGE *mx_open_message (CONTEXT * ctx, int msgno) #endif /* USE_NNTP */ default: - debug_print (1, ("function not implemented for mailbox type %d.\n", ctx->magic)); p_delete(&msg); break; } @@ -1258,12 +1171,11 @@ MESSAGE *mx_open_message (CONTEXT * ctx, int msgno) int mx_commit_message (MESSAGE * msg, CONTEXT * ctx) { if (!(msg->write && ctx->append)) { - debug_print (1, ("msg->write = %d, ctx->append = %d\n", msg->write, ctx->append)); return -1; } - if (!ctx || !MX_IDX(ctx->magic-1) || !MX_COMMAND(ctx->magic-1,mx_commit_message)) + if (!ctx || !MX_IDX(ctx->magic-1) || !mxfmts[ctx->magic-1]->mx_commit_message) return (-1); - return (MX_COMMAND(ctx->magic-1,mx_commit_message) (msg, ctx)); + return (mxfmts[ctx->magic-1]->mx_commit_message (msg, ctx)); } /* close a pointer to a message */ @@ -1272,12 +1184,8 @@ int mx_close_message (MESSAGE ** msg) int r = 0; if ((*msg)->magic == M_MH || (*msg)->magic == M_MAILDIR -#ifdef USE_IMAP || (*msg)->magic == M_IMAP -#endif -#ifdef USE_POP || (*msg)->magic == M_POP -#endif #ifdef USE_NNTP || (*msg)->magic == M_NNTP #endif @@ -1288,7 +1196,6 @@ int mx_close_message (MESSAGE ** msg) (*msg)->fp = NULL; if ((*msg)->path) { - debug_print (1, ("unlinking %s\n", (*msg)->path)); unlink ((*msg)->path); p_delete(&(*msg)->path); } @@ -1334,10 +1241,8 @@ void mx_update_context (CONTEXT * ctx, int new_messages) for (msgno = ctx->msgcount - new_messages; msgno < ctx->msgcount; msgno++) { h = ctx->hdrs[msgno]; - if (WithCrypto) { - /* NOTE: this _must_ be done before the check for mailcap! */ - h->security = crypt_query (h->content); - } + /* NOTE: this _must_ be done before the check for mailcap! */ + h->security = crypt_query (h->content); if (!ctx->pattern) { ctx->v2r[ctx->vcount] = msgno; @@ -1399,8 +1304,8 @@ void mx_update_context (CONTEXT * ctx, int new_messages) int mx_check_empty (const char *path) { int i = 0; - if ((i = mx_get_idx (path)) >= 0 && MX_COMMAND(i,mx_check_empty)) - return (MX_COMMAND(i,mx_check_empty)(path)); + if ((i = mx_get_idx (path)) >= 0 && mxfmts[i]->mx_check_empty) + return (mxfmts[i]->mx_check_empty(path)); errno = EINVAL; return (-1); } @@ -1409,42 +1314,9 @@ int mx_acl_check (CONTEXT* ctx, int flag) { if (!ctx || !MX_IDX(ctx->magic-1)) return (0); /* if no acl_check defined for module, assume permission is granted */ - if (!MX_COMMAND(ctx->magic-1,mx_acl_check)) + if (!mxfmts[ctx->magic-1]->mx_acl_check) return (1); - return (MX_COMMAND(ctx->magic-1,mx_acl_check)(ctx,flag)); -} - -void mx_init (void) { -#ifdef DEBUG - int i = 0; -#endif - list_push_back (&MailboxFormats, (void*) mbox_reg_mx ()); - list_push_back (&MailboxFormats, (void*) mmdf_reg_mx ()); - list_push_back (&MailboxFormats, (void*) mh_reg_mx ()); - list_push_back (&MailboxFormats, (void*) maildir_reg_mx ()); -#ifdef USE_IMAP - list_push_back (&MailboxFormats, (void*) imap_reg_mx ()); -#endif -#ifdef USE_POP - list_push_back (&MailboxFormats, (void*) pop_reg_mx ()); -#endif -#ifdef USE_NNTP - list_push_back (&MailboxFormats, (void*) nntp_reg_mx ()); -#endif -#ifdef USE_COMPRESSED - list_push_back (&MailboxFormats, (void*) compress_reg_mx ()); -#endif -#ifdef DEBUG - /* check module registration for completeness with debug versions */ -#define EXITWITHERR(m) do { fprintf(stderr, "error: incomplete mx module: %s is missing for type %i\n",m,i);exit(1); } while (0) - for (i = 0; i < MailboxFormats->length; i++) { - if (MX_COMMAND(i,type) < 1) EXITWITHERR("type"); - if (!MX_COMMAND(i,mx_is_magic)) EXITWITHERR("mx_is_magic"); - if (!MX_COMMAND(i,mx_open_mailbox)) EXITWITHERR("mx_open_mailbox"); -/* if (!MX_COMMAND(i,mx_sync_mailbox)) EXITWITHERR("mx_sync_mailbox");*/ - } -#undef EXITWITHERR -#endif /* DEBUG */ + return (mxfmts[ctx->magic-1]->mx_acl_check(ctx,flag)); } int mx_rebuild_cache (void) { @@ -1456,22 +1328,18 @@ int mx_rebuild_cache (void) { CONTEXT* ctx = NULL; BUFFY* b = NULL; - if (list_empty(Incoming)) { + if (!Incoming.len) { mutt_error (_("No mailboxes defined.")); return (1); } - for (i = 0; i < Incoming->length; i++) { - b = (BUFFY*) Incoming->data[i]; + for (i = 0; i < Incoming.len; i++) { + b = Incoming.arr[i]; magic = mx_get_magic (b->path); - if (magic != M_MAILDIR && magic != M_MH -#ifdef USE_IMAP - && magic != M_IMAP -#endif - ) + if (magic != M_MAILDIR && magic != M_MH && magic != M_IMAP) continue; sidebar_set_current (b->path); - sidebar_draw (CurrentMenu); + sidebar_draw (); if ((ctx = mx_open_mailbox (b->path, M_READONLY | M_NOSORT | M_COUNT, NULL)) != NULL) @@ -1481,8 +1349,32 @@ int mx_rebuild_cache (void) { if (Context && Context->path) sidebar_set_current (Context->path); - sidebar_draw (CurrentMenu); + sidebar_draw (); return (0); #endif } + +void mutt_parse_mime_message (CONTEXT * ctx, HEADER * cur) +{ + MESSAGE *msg; + int flags = 0; + + do { + if (cur->content->type != TYPEMESSAGE + && cur->content->type != TYPEMULTIPART) + break; /* nothing to do */ + + if (cur->content->parts) + break; /* The message was parsed earlier. */ + + if ((msg = mx_open_message (ctx, cur->msgno))) { + mutt_parse_part (msg->fp, cur->content); + + cur->security = crypt_query (cur->content); + + mx_close_message (&msg); + } + } while (0); + mutt_count_body_parts (cur, flags | M_PARTS_RECOUNT); +}