Simplify sidebar code
[apps/madmutt.git] / mx.c
diff --git a/mx.c b/mx.c
index 5764a51..fde597c 100644 (file)
--- a/mx.c
+++ b/mx.c
@@ -8,70 +8,49 @@
  * please see the file GPL in the top level source directory.
  */
 
-#if HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include <lib-lib/lib-lib.h>
+
+#include <utime.h>
+
+#include <lib-sys/unix.h>
+#include <lib-mime/mime.h>
+#include <lib-ui/sidebar.h>
 
 #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 <imap/imap.h>
+#include <imap/mx_imap.h>
 
-#ifdef USE_POP
-#include "pop/pop.h"
-#include "pop/mx_pop.h"
-#endif
+#include <pop/pop.h>
+#include <pop/mx_pop.h>
 
 #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 <lib-crypt/crypt.h>
 
-#include "lib/mem.h"
-#include "lib/intl.h"
-#include "lib/str.h"
 #include "lib/list.h"
 
-#include <dirent.h>
-#include <fcntl.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <utime.h>
-
 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: 
@@ -79,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];
@@ -105,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;
@@ -120,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];
 
@@ -140,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);
 }
 
@@ -176,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;
@@ -191,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);
@@ -214,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);
@@ -248,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;
@@ -265,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) {
@@ -289,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);
@@ -303,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;
 
@@ -326,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);
@@ -340,7 +311,7 @@ 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));
@@ -388,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);
 
@@ -485,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:
@@ -516,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;
@@ -534,7 +499,7 @@ CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT * pctx)
     if (mx_open_mailbox_append (ctx, flags) != 0) {
       mx_fastclose_mailbox (ctx);
       if (!pctx)
-        FREE (&ctx);
+        p_delete(&ctx);
       return NULL;
     }
     return ctx;
@@ -543,10 +508,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);
@@ -557,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);
   }
 
@@ -587,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);
@@ -610,19 +573,19 @@ void mx_fastclose_mailbox (CONTEXT * ctx)
     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 */
@@ -637,10 +600,8 @@ static int sync_mailbox (CONTEXT * ctx, int *index_hint)
     /* the 1 is only of interest for IMAP and means EXPUNGE */
     rc = MX_COMMAND(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;
 }
@@ -692,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;
@@ -741,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));
@@ -772,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)
@@ -786,7 +745,6 @@ 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;
 
@@ -809,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;
@@ -850,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) {
@@ -859,7 +815,6 @@ int mx_close_mailbox (CONTEXT * ctx, int *index_hint)
     }
   }
   else
-#endif
   {
     if (!purge) {
       for (i = 0; i < ctx->msgcount; i++)
@@ -887,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. */
 
@@ -967,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);
 }
 
 
@@ -981,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;
@@ -994,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;
@@ -1023,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;
@@ -1047,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);
@@ -1080,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 */
@@ -1094,6 +1049,12 @@ int mx_sync_mailbox (CONTEXT * ctx, int *index_hint)
   return (rc);
 }
 
+int mx_sync_mailbox (CONTEXT* ctx, int* index_hint) {
+  int ret = _mx_sync_mailbox (ctx, index_hint);
+  sidebar_set_buffystats (ctx);
+  return (ret);
+}
+
 /* args:
  *     dest    destintation mailbox
  *     hdr     message being copied (required for maildir support, because
@@ -1102,15 +1063,13 @@ int mx_sync_mailbox (CONTEXT * ctx, int *index_hint)
 MESSAGE *mx_open_new_message (CONTEXT * dest, HEADER * hdr, int flags)
 {
   MESSAGE *msg;
-  ADDRESS *p = NULL;
+  address_t *p = NULL;
 
   if (!MX_IDX(dest->magic-1)) {
-    dprint (1, (debugfile, "mx_open_new_message(): function "
-                "unimplemented for mailbox type %d.\n", dest->magic));
     return (NULL);
   }
 
-  msg = safe_calloc (1, sizeof (MESSAGE));
+  msg = p_new(MESSAGE, 1);
   msg->magic = dest->magic;
   msg->write = 1;
 
@@ -1143,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);
 }
 
@@ -1215,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:
@@ -1236,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);
@@ -1283,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 */
@@ -1348,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
@@ -1364,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);
 }
 
@@ -1387,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;
@@ -1411,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;
@@ -1432,7 +1276,7 @@ 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 (!ctx->counting && option (OPTSCORE))
@@ -1463,6 +1307,8 @@ void mx_update_context (CONTEXT * ctx, int new_messages)
         ctx->new++;
     }
   }
+  /* update sidebar count */
+  sidebar_set_buffystats (ctx);
 }
 
 /*
@@ -1490,34 +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");
-/*    if (!MX_COMMAND(i,mx_sync_mailbox)) EXITWITHERR("mx_sync_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);
 }