X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=mx.c;h=fde597c67fec215ea0fbbcd11de5680e8c09efda;hp=c577356c918715e7cb5d388baa3e31829234c5dc;hb=98cf5779d8184a74541be1bc61d15c5f35efd310;hpb=41a708d3e526f10bc3aba7c5eac80aaa0b7b6fcd diff --git a/mx.c b/mx.c index c577356..fde597c 100644 --- a/mx.c +++ b/mx.c @@ -8,71 +8,49 @@ * 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 "mutt.h" +#include "buffy.h" #include "mx.h" #include "mbox.h" #include "mh.h" -#include "rfc2047.h" #include "sort.h" +#include "thread.h" #include "copy.h" #include "keymap.h" -#include "url.h" - -#ifdef USE_COMPRESSED #include "compress.h" -#endif -#ifdef USE_IMAP -#include "imap/imap.h" -#include "imap/mx_imap.h" -#endif +#include +#include -#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 BUFFY_SIZE -#include "buffy.h" -#endif - #ifdef USE_DOTLOCK #include "dotlock.h" #endif -#include "mutt_crypt.h" +#include -#include "lib/mem.h" -#include "lib/intl.h" -#include "lib/str.h" #include "lib/list.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef BUFFY_SIZE -#include -#endif - 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) -#define mutt_is_spool(s) (safe_strcmp (Spoolfile, s) == 0) +#define mutt_is_spool(s) (m_strcmp(Spoolfile, s) == 0) #ifdef USE_DOTLOCK /* parameters: @@ -80,9 +58,7 @@ static list2_t* MailboxFormats = NULL; * 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]; @@ -106,13 +82,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; @@ -121,7 +91,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]; @@ -141,9 +111,9 @@ 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); } @@ -152,11 +122,24 @@ static int undotlock_file (const char *path, int fd) /* looks up index of type for path in MailboxFormats */ 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++) { - t = MX_COMMAND(i,mx_is_magic)(path); + if (!MX_COMMAND(i,local)) + t = MX_COMMAND(i,mx_is_magic)(path, NULL); if (t >= 1) - return (t-1); /* use type as index for array */ + 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); + } } return (-1); } @@ -164,9 +147,9 @@ static int mx_get_idx (const char* path) { /* 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; @@ -179,16 +162,16 @@ int mx_lock_file (const char *path, int fd, int excl, int dot, int timeout) struct flock lck; - memset (&lck, 0, sizeof (struct flock)); + p_clear(&lck, 1); lck.l_type = excl ? F_WRLCK : F_RDLCK; lck.l_whence = SEEK_SET; count = 0; attempt = 0; + prev_sb.st_size = 0; while (fcntl (fd, F_SETLK, &lck) == -1) { struct stat sb; - dprint (1, (debugfile, "mx_lock_file(): fcntl errno %d.\n", errno)); if (errno != EAGAIN && errno != EACCES) { mutt_perror ("fcntl"); return (-1); @@ -202,8 +185,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); @@ -236,8 +219,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; @@ -253,7 +236,7 @@ int mx_lock_file (const char *path, int fd, int excl, int dot, int timeout) #ifdef USE_DOTLOCK if (r == 0 && dot) - r = dotlock_file (path, fd, timeout); + r = dotlock_file (path, time_out); #endif /* USE_DOTLOCK */ if (r == -1) { @@ -277,9 +260,9 @@ int mx_lock_file (const char *path, int fd, int excl, int dot, int timeout) int mx_unlock_file (const char *path, int fd, int dot) { #ifdef USE_FCNTL - struct flock unlockit = { F_UNLCK, 0, 0, 0 }; + struct flock unlockit; - memset (&unlockit, 0, sizeof (struct flock)); + p_clear(&unlockit, 1); unlockit.l_type = F_UNLCK; unlockit.l_whence = SEEK_SET; fcntl (fd, F_SETLK, &unlockit); @@ -291,13 +274,13 @@ int mx_unlock_file (const char *path, int fd, int dot) #ifdef USE_DOTLOCK if (dot) - undotlock_file (path, fd); + undotlock_file (path); #endif return 0; } -void mx_unlink_empty (const char *path) +static void mx_unlink_empty (const char *path) { int fd; @@ -314,7 +297,7 @@ void mx_unlink_empty (const char *path) } #ifdef USE_DOTLOCK - invoke_dotlock (path, fd, DL_FL_UNLINK, 1); + invoke_dotlock (path, DL_FL_UNLINK, 1); #else if (fstat (fd, &sb) == 0 && sb.st_size == 0) unlink (path); @@ -328,13 +311,19 @@ void mx_unlink_empty (const char *path) int mx_get_magic (const char *path) { int i = 0; - if (safe_strlen (path) == 0) + if (m_strlen(path) == 0) return (-1); if ((i = mx_get_idx (path)) >= 0) return (MX_COMMAND(i,type)); return (-1); } +int mx_is_local (int m) { + if (!MX_IDX(m)) + return (0); + return (MX_COMMAND(m,local)); +} + /* * set DefaultMagic to the given value */ @@ -370,22 +359,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); @@ -467,7 +450,7 @@ static int mx_open_mailbox_append (CONTEXT * ctx, int flags) } return (-1); } - fseek (ctx->fp, 0, 2); + fseeko (ctx->fp, 0, 2); break; case M_MH: @@ -498,9 +481,9 @@ CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT * pctx) int rc; if (!ctx) - ctx = safe_malloc (sizeof (CONTEXT)); - memset (ctx, 0, sizeof (CONTEXT)); - ctx->path = safe_strdup (path); + ctx = p_new(CONTEXT, 1); + p_clear(ctx, 1); + ctx->path = m_strdup(path); ctx->msgnotreadyet = -1; ctx->collapsed = 0; @@ -509,23 +492,24 @@ CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT * pctx) ctx->quiet = 1; if (flags & M_READONLY) ctx->readonly = 1; + if (flags & M_COUNT) + ctx->counting = 1; if (flags & (M_APPEND | M_NEWFOLDER)) { if (mx_open_mailbox_append (ctx, flags) != 0) { mx_fastclose_mailbox (ctx); if (!pctx) - FREE (&ctx); + p_delete(&ctx); return NULL; } return ctx; } - ctx->magic = mx_get_magic (path); + 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); @@ -536,7 +520,7 @@ CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT * pctx) if (ctx->magic <= 0) { mx_fastclose_mailbox (ctx); if (!pctx) - FREE (&ctx); + p_delete(&ctx); return (NULL); } @@ -566,7 +550,7 @@ CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT * pctx) else { mx_fastclose_mailbox (ctx); if (!pctx) - FREE (&ctx); + p_delete(&ctx); } unset_option (OPTFORCEREFRESH); @@ -581,98 +565,43 @@ void mx_fastclose_mailbox (CONTEXT * ctx) if (!ctx) return; -#ifdef USE_IMAP - if (ctx->magic == M_IMAP) - imap_close_mailbox (ctx); -#endif /* USE_IMAP */ -#ifdef USE_POP - if (ctx->magic == M_POP) - pop_close_mailbox (ctx); -#endif /* USE_POP */ -#ifdef USE_NNTP - if (ctx->magic == M_NNTP) - nntp_fastclose_mailbox (ctx); -#endif /* USE_NNTP */ + if (MX_IDX(ctx->magic-1) && MX_COMMAND(ctx->magic-1,mx_fastclose_mailbox)) + MX_COMMAND(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]); - FREE (&ctx->hdrs); - FREE (&ctx->v2r); -#ifdef USE_COMPRESSED + header_delete(&ctx->hdrs[i]); + p_delete(&ctx->hdrs); + p_delete(&ctx->v2r); + if (ctx->compressinfo) mutt_fast_close_compressed (ctx); -#endif - FREE (&ctx->path); - FREE (&ctx->pattern); + + p_delete(&ctx->path); + p_delete(&ctx->pattern); if (ctx->limit_pattern) mutt_pattern_free (&ctx->limit_pattern); safe_fclose (&ctx->fp); - memset (ctx, 0, sizeof (CONTEXT)); + p_clear(ctx, 1); } /* save changes to disk */ static int sync_mailbox (CONTEXT * ctx, int *index_hint) { -#ifdef BUFFY_SIZE - BUFFY *tmp = NULL; -#endif int rc = -1; if (!ctx->quiet) mutt_message (_("Writing %s..."), ctx->path); - switch (ctx->magic) { - case M_MBOX: - case M_MMDF: - rc = mbox_sync_mailbox (ctx, index_hint); -#ifdef BUFFY_SIZE - tmp = mutt_find_mailbox (ctx->path); -#endif - break; + 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)); - case M_MH: - case M_MAILDIR: - rc = mh_sync_mailbox (ctx, index_hint); - break; - -#ifdef USE_IMAP - case M_IMAP: - /* extra argument means EXPUNGE */ - rc = imap_sync_mailbox (ctx, 1, index_hint); - break; -#endif /* USE_IMAP */ - -#ifdef USE_POP - case M_POP: - rc = pop_sync_mailbox (ctx, index_hint); - break; -#endif /* USE_POP */ - -#ifdef USE_NNTP - case M_NNTP: - rc = nntp_sync_mailbox (ctx); - break; -#endif /* USE_NNTP */ - } - -#if 0 - if (!ctx->quiet && !ctx->shutup && rc == -1) - mutt_error (_("Could not synchronize mailbox %s!"), ctx->path); -#endif - -#ifdef BUFFY_SIZE - if (tmp && tmp->new == 0) - mutt_update_mailbox (tmp); -#endif - -#ifdef USE_COMPRESSED if (rc == 0 && ctx->compressinfo) return mutt_sync_compressed (ctx); -#endif return rc; } @@ -724,7 +653,7 @@ static int trash_append (CONTEXT * ctx) } /* save changes and close mailbox */ -int mx_close_mailbox (CONTEXT * ctx, int *index_hint) +static int _mx_close_mailbox (CONTEXT * ctx, int *index_hint) { int i, move_messages = 0, purge = 1, read_msgs = 0; int check; @@ -773,10 +702,10 @@ int mx_close_mailbox (CONTEXT * ctx, int *index_hint) if ((p = mutt_find_hook (M_MBOXHOOK, ctx->path))) { isSpool = 1; - strfcpy (mbox, p, sizeof (mbox)); + m_strcpy(mbox, sizeof(mbox), p); } else { - strfcpy (mbox, NONULL (Inbox), sizeof (mbox)); + m_strcpy(mbox, sizeof(mbox), NONULL(Inbox)); isSpool = mutt_is_spool (ctx->path) && !mutt_is_spool (mbox); } mutt_expand_path (mbox, sizeof (mbox)); @@ -804,10 +733,8 @@ 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) @@ -818,11 +745,10 @@ 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; - if (ctx->magic == M_IMAP && mx_get_magic (mbox) == M_IMAP) { + if (ctx->magic == M_IMAP && imap_is_magic (mbox, NULL) == M_IMAP) { /* tag messages for moving, and clear old tags, if any */ for (i = 0; i < ctx->msgcount; i++) if (ctx->hdrs[i]->read && !ctx->hdrs[i]->deleted @@ -841,7 +767,6 @@ 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; @@ -882,7 +807,6 @@ 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) { @@ -891,7 +815,6 @@ int mx_close_mailbox (CONTEXT * ctx, int *index_hint) } } else -#endif { if (!purge) { for (i = 0; i < ctx->msgcount; i++) @@ -919,16 +842,22 @@ 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); return 0; } +int mx_close_mailbox (CONTEXT * ctx, int *index_hint) { + int ret = 0; + if (!ctx) + return (0); + ret = _mx_close_mailbox (ctx, index_hint); + sidebar_set_buffystats (ctx); + return (ret); +} /* update a Context structure's internal tables. */ @@ -999,11 +928,14 @@ 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 ctx->msgcount = j; + + /* update sidebar count */ + sidebar_set_buffystats (ctx); } @@ -1013,7 +945,7 @@ void mx_update_tables (CONTEXT * ctx, int committing) * 0 success * -1 error */ -int mx_sync_mailbox (CONTEXT * ctx, int *index_hint) +static int _mx_sync_mailbox (CONTEXT * ctx, int *index_hint) { int rc, i; int purge = 1; @@ -1026,8 +958,7 @@ int mx_sync_mailbox (CONTEXT * ctx, int *index_hint) km_find_func (MENU_MAIN, OP_TOGGLE_WRITE))) snprintf (tmp, sizeof (tmp), _(" Press '%s' to toggle write"), buf); else - strfcpy (tmp, _("Use 'toggle-write' to re-enable write!"), - sizeof (tmp)); + m_strcpy(tmp, sizeof(tmp), _("Use 'toggle-write' to re-enable write!")); mutt_error (_("Mailbox is marked unwritable. %s"), tmp); return -1; @@ -1055,10 +986,8 @@ 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; @@ -1079,19 +1008,15 @@ 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); @@ -1112,10 +1037,8 @@ 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,18 +1049,11 @@ int mx_sync_mailbox (CONTEXT * ctx, int *index_hint) return (rc); } -#ifdef USE_IMAP -int imap_open_new_message (MESSAGE * msg, CONTEXT * dest, HEADER * hdr) -{ - char tmp[_POSIX_PATH_MAX]; - - mutt_mktemp (tmp); - if ((msg->fp = safe_fopen (tmp, "w")) == NULL) - return (-1); - msg->path = safe_strdup (tmp); - return 0; +int mx_sync_mailbox (CONTEXT* ctx, int* index_hint) { + int ret = _mx_sync_mailbox (ctx, index_hint); + sidebar_set_buffystats (ctx); + return (ret); } -#endif /* args: * dest destintation mailbox @@ -1147,34 +1063,13 @@ int imap_open_new_message (MESSAGE * msg, CONTEXT * dest, HEADER * hdr) MESSAGE *mx_open_new_message (CONTEXT * dest, HEADER * hdr, int flags) { MESSAGE *msg; - int (*func) (MESSAGE *, CONTEXT *, HEADER *); - ADDRESS *p = NULL; + address_t *p = NULL; - switch (dest->magic) { - case M_MMDF: - case M_MBOX: - func = mbox_open_new_message; - break; - case M_MAILDIR: - func = maildir_open_new_message; - break; - case M_MH: - func = mh_open_new_message; - break; -#ifdef USE_IMAP - case M_IMAP: - func = imap_open_new_message; - break; -#endif - default: - dprint (1, - (debugfile, - "mx_open_new_message(): function unimplemented for mailbox type %d.\n", - dest->magic)); + if (!MX_IDX(dest->magic-1)) { return (NULL); } - msg = safe_calloc (1, sizeof (MESSAGE)); + msg = p_new(MESSAGE, 1); msg->magic = dest->magic; msg->write = 1; @@ -1188,7 +1083,7 @@ MESSAGE *mx_open_new_message (CONTEXT * dest, HEADER * hdr, int flags) if (msg->received == 0) time (&msg->received); - if (func (msg, dest, hdr) == 0) { + if (MX_COMMAND(dest->magic-1,mx_open_new_message)(msg, dest, hdr) == 0) { if (dest->magic == M_MMDF) fputs (MMDF_SEP, msg->fp); @@ -1207,70 +1102,23 @@ MESSAGE *mx_open_new_message (CONTEXT * dest, HEADER * hdr, int flags) } } else - FREE (&msg); + p_delete(&msg); return msg; } /* check for new mail */ -int mx_check_mailbox (CONTEXT * ctx, int *index_hint, int lock) -{ - int rc; - -#ifdef USE_COMPRESSED +int mx_check_mailbox (CONTEXT * ctx, int *index_hint, int lock) { if (ctx->compressinfo) return mutt_check_mailbox_compressed (ctx); -#endif if (ctx) { if (ctx->locked) lock = 0; - - switch (ctx->magic) { - case M_MBOX: - case M_MMDF: - - if (lock) { - mutt_block_signals (); - if (mbox_lock_mailbox (ctx, 0, 0) == -1) { - mutt_unblock_signals (); - return M_LOCKED; - } - } - - rc = mbox_check_mailbox (ctx, index_hint); - - if (lock) { - mutt_unblock_signals (); - mbox_unlock_mailbox (ctx); - } - - return rc; - - - case M_MH: - return (mh_check_mailbox (ctx, index_hint)); - case M_MAILDIR: - return (maildir_check_mailbox (ctx, index_hint)); - -#ifdef USE_IMAP - case M_IMAP: - return (imap_check_mailbox (ctx, index_hint, 0)); -#endif /* USE_IMAP */ - -#ifdef USE_POP - case M_POP: - return (pop_check_mailbox (ctx, index_hint)); -#endif /* USE_POP */ - -#ifdef USE_NNTP - case M_NNTP: - return (nntp_check_mailbox (ctx)); -#endif /* USE_NNTP */ - } + 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)); } - dprint (1, (debugfile, "mx_check_mailbox: null or invalid context.\n")); return (-1); } @@ -1279,7 +1127,7 @@ MESSAGE *mx_open_message (CONTEXT * ctx, int msgno) { MESSAGE *msg; - msg = safe_calloc (1, sizeof (MESSAGE)); + msg = p_new(MESSAGE, 1); switch (msg->magic = ctx->magic) { case M_MBOX: case M_MMDF: @@ -1300,46 +1148,36 @@ MESSAGE *mx_open_message (CONTEXT * ctx, int msgno) 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); + p_delete(&msg); } } break; -#ifdef USE_IMAP case M_IMAP: { if (imap_fetch_message (msg, ctx, msgno) != 0) - FREE (&msg); + p_delete(&msg); break; } -#endif /* USE_IMAP */ -#ifdef USE_POP case M_POP: { if (pop_fetch_message (msg, ctx, msgno) != 0) - FREE (&msg); + p_delete(&msg); break; } -#endif /* USE_POP */ #ifdef USE_NNTP case M_NNTP: { if (nntp_fetch_message (msg, ctx, msgno) != 0) - FREE (&msg); + p_delete(&msg); break; } #endif /* USE_NNTP */ default: - dprint (1, - (debugfile, - "mx_open_message(): function not implemented for mailbox type %d.\n", - ctx->magic)); - FREE (&msg); + p_delete(&msg); break; } return (msg); @@ -1347,63 +1185,13 @@ MESSAGE *mx_open_message (CONTEXT * ctx, int msgno) /* commit a message to a folder */ -int mx_commit_message (MESSAGE * msg, CONTEXT * ctx) -{ - int r = 0; - +int mx_commit_message (MESSAGE * msg, CONTEXT * ctx) { if (!(msg->write && ctx->append)) { - dprint (1, - (debugfile, - "mx_commit_message(): msg->write = %d, ctx->append = %d\n", - msg->write, ctx->append)); return -1; } - - switch (msg->magic) { - case M_MMDF: - { - if (fputs (MMDF_SEP, msg->fp) == EOF) - r = -1; - break; - } - - case M_MBOX: - { - if (fputc ('\n', msg->fp) == EOF) - r = -1; - break; - } - -#ifdef USE_IMAP - case M_IMAP: - { - if ((r = safe_fclose (&msg->fp)) == 0) - r = imap_append_message (ctx, msg); - break; - } -#endif - - case M_MAILDIR: - { - r = maildir_commit_message (ctx, msg, NULL); - break; - } - - case M_MH: - { - r = mh_commit_message (ctx, msg, NULL); - break; - } - } - - if (r == 0 && (ctx->magic == M_MBOX || ctx->magic == M_MMDF) - && (fflush (msg->fp) == EOF || fsync (fileno (msg->fp)) == -1)) { - mutt_perror (_("Can't write message")); - - r = -1; - } - - return r; + if (!ctx || !MX_IDX(ctx->magic-1) || !MX_COMMAND(ctx->magic-1,mx_commit_message)) + return (-1); + return (MX_COMMAND(ctx->magic-1,mx_commit_message) (msg, ctx)); } /* close a pointer to a message */ @@ -1412,12 +1200,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 @@ -1428,13 +1212,11 @@ int mx_close_message (MESSAGE ** msg) (*msg)->fp = NULL; if ((*msg)->path) { - dprint (1, (debugfile, "mx_close_message (): unlinking %s\n", - (*msg)->path)); unlink ((*msg)->path); - FREE (&(*msg)->path); + p_delete(&(*msg)->path); } - FREE (msg); + p_delete(msg); return (r); } @@ -1451,12 +1233,12 @@ void mx_alloc_memory (CONTEXT * ctx) } if (ctx->hdrs) { - safe_realloc (&ctx->hdrs, sizeof (HEADER *) * (ctx->hdrmax += 25)); - safe_realloc (&ctx->v2r, sizeof (int) * ctx->hdrmax); + p_realloc(&ctx->hdrs, ctx->hdrmax += 25); + p_realloc(&ctx->v2r, ctx->hdrmax); } else { - ctx->hdrs = safe_calloc ((ctx->hdrmax += 25), sizeof (HEADER *)); - ctx->v2r = safe_calloc (ctx->hdrmax, sizeof (int)); + ctx->hdrs = p_new(HEADER *, (ctx->hdrmax += 25)); + ctx->v2r = p_new(int, ctx->hdrmax); } for (i = ctx->msgcount; i < ctx->hdrmax; i++) { ctx->hdrs[i] = NULL; @@ -1475,10 +1257,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; @@ -1496,10 +1276,10 @@ void mx_update_context (CONTEXT * ctx, int new_messages) h2 = hash_find (ctx->id_hash, h->env->supersedes); - /* FREE (&h->env->supersedes); should I ? */ + /* p_delete(&h->env->supersedes); should I ? */ if (h2) { h2->superseded = 1; - if (option (OPTSCORE)) + if (!ctx->counting && option (OPTSCORE)) mutt_score_message (ctx, h2, 1); } } @@ -1507,11 +1287,13 @@ void mx_update_context (CONTEXT * ctx, int new_messages) /* add this message to the hash tables */ if (ctx->id_hash && h->env->message_id) hash_insert (ctx->id_hash, h->env->message_id, h, 0); - if (ctx->subj_hash && h->env->real_subj) - hash_insert (ctx->subj_hash, h->env->real_subj, h, 1); + if (!ctx->counting) { + if (ctx->subj_hash && h->env->real_subj) + hash_insert (ctx->subj_hash, h->env->real_subj, h, 1); - if (option (OPTSCORE)) - mutt_score_message (ctx, h, 0); + if (option (OPTSCORE)) + mutt_score_message (ctx, h, 0); + } if (h->changed) ctx->changed = 1; @@ -1525,6 +1307,8 @@ void mx_update_context (CONTEXT * ctx, int new_messages) ctx->new++; } } + /* update sidebar count */ + sidebar_set_buffystats (ctx); } /* @@ -1543,7 +1327,7 @@ int mx_check_empty (const char *path) } int mx_acl_check (CONTEXT* ctx, int flag) { - if (!ctx || ctx->magic <= 0 || ctx->magic > MailboxFormats->length) + 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)) @@ -1552,33 +1336,74 @@ int mx_acl_check (CONTEXT* ctx, int 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"); +} + +int mx_rebuild_cache (void) { +#ifndef USE_HCACHE + mutt_error (_("Support for header caching was not build in.")); + return (1); +#else + int i = 0, magic = 0; + CONTEXT* ctx = NULL; + BUFFY* b = NULL; + + if (list_empty(Incoming)) { + mutt_error (_("No mailboxes defined.")); + return (1); } -#undef EXITWITHERR -#endif /* DEBUG */ + + for (i = 0; i < Incoming->length; i++) { + b = (BUFFY*) Incoming->data[i]; + magic = mx_get_magic (b->path); + if (magic != M_MAILDIR && magic != M_MH && magic != M_IMAP) + continue; + sidebar_set_current (b->path); + sidebar_draw (); + if ((ctx = mx_open_mailbox (b->path, + M_READONLY | M_NOSORT | M_COUNT, + NULL)) != NULL) + mx_close_mailbox (ctx, 0); + } + mutt_clear_error (); + + if (Context && Context->path) + sidebar_set_current (Context->path); + 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); }