remove mx_{pop,nntp,imap}.[hc]
[apps/madmutt.git] / mx.c
diff --git a/mx.c b/mx.c
index 5f18ac1..6ee2be7 100644 (file)
--- a/mx.c
+++ b/mx.c
@@ -8,29 +8,13 @@
  * 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 <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>
 
-#include <lib-lib/mem.h>
-#include <lib-lib/ascii.h>
-#include <lib-lib/str.h>
-#include <lib-lib/macros.h>
-#include <lib-lib/file.h>
-#include <lib-lib/debug.h>
-
+#include <lib-sys/unix.h>
 #include <lib-mime/mime.h>
+#include <lib-ui/sidebar.h>
 
 #include "mutt.h"
 #include "buffy.h"
 #include "thread.h"
 #include "copy.h"
 #include "keymap.h"
-#include "url.h"
-#include "sidebar.h"
 #include "compress.h"
+#include "dotlock.h"
 
 #include <imap/imap.h>
-#include <imap/mx_imap.h>
-
 #include <pop/pop.h>
-#include <pop/mx_pop.h>
 
 #ifdef USE_NNTP
-#include "nntp/nntp.h"
-#include "nntp/mx_nntp.h"
-#endif
-
-#ifdef USE_DOTLOCK
-#include "dotlock.h"
+#include <nntp/nntp.h>
 #endif
 
 #include <lib-crypt/crypt.h>
 
-#include "lib/list.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)
+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?
  */
-
-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];
@@ -100,7 +81,7 @@ static int invoke_dotlock (const char *path, int dummy, int flags, int retry)
   return mutt_system (cmd);
 }
 
-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;
@@ -109,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];
 
@@ -129,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;
@@ -190,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);
@@ -204,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);
@@ -238,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;
@@ -253,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 */
@@ -291,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;
 
@@ -315,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);
@@ -333,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);
 }
 
 /*
@@ -369,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);
 }
 
@@ -553,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) {
@@ -584,8 +549,8 @@ 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)
@@ -617,7 +582,7 @@ 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);
 
   if (rc == 0 && ctx->compressinfo)
     return mutt_sync_compressed (ctx);
@@ -1085,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);
   }
 
@@ -1103,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);
 
@@ -1135,13 +1099,11 @@ int mx_check_mailbox (CONTEXT * ctx, int *index_hint, int lock) {
   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 */
@@ -1170,7 +1132,6 @@ 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);
       }
     }
@@ -1200,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;
   }
@@ -1211,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 */
@@ -1237,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);
   }
@@ -1346,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);
 }
@@ -1356,36 +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 ());
-  list_push_back (&MailboxFormats, (void*) imap_reg_mx ());
-  list_push_back (&MailboxFormats, (void*) pop_reg_mx ());
-#ifdef USE_NNTP
-  list_push_back (&MailboxFormats, (void*) nntp_reg_mx ());
-#endif
-  list_push_back (&MailboxFormats, (void*) compress_reg_mx ());
-#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) {
@@ -1397,18 +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 && 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)
@@ -1418,7 +1349,7 @@ int mx_rebuild_cache (void) {
 
   if (Context && Context->path)
     sidebar_set_current (Context->path);
-  sidebar_draw (CurrentMenu);
+  sidebar_draw ();
 
   return (0);
 #endif