BDB suck hard. in a GNU env, we will at least have gdbm.
[apps/madmutt.git] / lib-mx / compress.c
index e89d438..6e988ca 100644 (file)
@@ -45,7 +45,7 @@ static int mbox_lock_compressed (CONTEXT * ctx, FILE * fp, int excl, int retry)
     return 0;
   }
 
-  return (r);
+  return r;
 }
 
 static void mbox_unlock_compressed (CONTEXT * ctx, FILE * fp)
@@ -60,7 +60,7 @@ static void mbox_unlock_compressed (CONTEXT * ctx, FILE * fp)
 
 static int is_new (const char *path)
 {
-  return (access (path, W_OK) != 0 && errno == ENOENT) ? 1 : 0;
+  return (access (path, W_OK) && errno == ENOENT);
 }
 
 static const char *find_compress_hook (int type, const char *path)
@@ -113,38 +113,26 @@ static compress_info *set_compress_info (CONTEXT * ctx)
   return (ctx->cinfo = ci);
 }
 
-static void set_path (CONTEXT * ctx)
-{
-  char tmppath[_POSIX_PATH_MAX];
-
-  /* Setup the right paths */
-  ctx->realpath = ctx->path;
-
-  /* Uncompress to /tmp */
-  mutt_mktemp (tmppath);
-  ctx->path = p_dupstr(tmppath, m_strlen(tmppath));
-}
-
 static int get_size (const char *path)
 {
   struct stat sb;
 
   if (stat (path, &sb) != 0)
     return 0;
-  return (sb.st_size);
+  return sb.st_size;
 }
 
-static const char *compresshook_format_str (char *dest, ssize_t destlen,
-                                            char op, const char *src,
-                                            const char *fmt,
-                                            const char *ifstring __attribute__ ((unused)),
-                                            const char *elsestring __attribute__ ((unused)),
-                                            unsigned long data,
-                                            format_flag flags __attribute__ ((unused)))
+static const char *
+compresshook_format_str(char *dest, ssize_t destlen,
+                        char op, const char *src, const char *fmt,
+                        const char *ifstr __attribute__ ((unused)),
+                        const char *elstr __attribute__ ((unused)),
+                        anytype data,
+                        format_flag flags __attribute__ ((unused)))
 {
-  char tmp[SHORT_STRING];
+  char tmp[STRING];
 
-  CONTEXT *ctx = (CONTEXT *) data;
+  CONTEXT *ctx = data.ptr;
 
   switch (op) {
   case 'f':
@@ -156,7 +144,7 @@ static const char *compresshook_format_str (char *dest, ssize_t destlen,
     snprintf (dest, destlen, tmp, ctx->path);
     break;
   }
-  return (src);
+  return src;
 }
 
 /* check that the command has both %f and %t
@@ -167,13 +155,11 @@ int mutt_test_compress_command (const char *cmd)
   return (strstr (cmd, "%f") && strstr (cmd, "%t")) ? 0 : -1;
 }
 
-static char *get_compression_cmd (const char *cmd, const CONTEXT * ctx)
+static char *get_compression_cmd(const char *cmd, const CONTEXT *ctx)
 {
-  char expanded[_POSIX_PATH_MAX];
-
-  mutt_FormatString (expanded, sizeof (expanded), cmd,
-                     compresshook_format_str, (unsigned long) ctx, 0);
-  return m_strdup(expanded);
+    char buf[_POSIX_PATH_MAX];
+    m_strformat(buf, sizeof(buf), 0, cmd, compresshook_format_str, (void*)ctx, 0);
+    return m_strdup(buf);
 }
 
 int mutt_check_mailbox_compressed (CONTEXT * ctx)
@@ -183,28 +169,43 @@ int mutt_check_mailbox_compressed (CONTEXT * ctx)
     p_delete(&ctx->realpath);
     mutt_error _("Mailbox was corrupted!");
 
-    return (-1);
+    return -1;
   }
-  return (0);
+  return 0;
 }
 
-int mutt_open_read_compressed (CONTEXT * ctx)
+int mutt_open_read_compressed(CONTEXT * ctx)
 {
   char *cmd;
   FILE *fp;
   int rc;
+  char tmppath[_POSIX_PATH_MAX];
+  int tmpfd;
 
   compress_info *ci = set_compress_info (ctx);
 
   if (!ci->open) {
     ctx->magic = 0;
     p_delete(&ctx->cinfo);
-    return (-1);
+    return -1;
   }
   if (!ci->close || access (ctx->path, W_OK) != 0)
     ctx->readonly = 1;
 
-  set_path (ctx);
+  /* Setup the right paths */
+  ctx->realpath = ctx->path;
+
+  /* Uncompress to /tmp */
+  tmpfd = m_tempfd(tmppath, sizeof(tmppath), NONULL(MCore.tmpdir), NULL);
+  /* If we cannot open tempfile, that means the file already exists (!?)
+   * or we are following a symlink, which is bad and insecure.
+   */
+  if(tmpfd < 0) {
+      return -1;
+  }
+  close(tmpfd);
+
+  ctx->path = p_dupstr(tmppath, m_strlen(tmppath));
   ctx->cinfo->size = get_size(ctx->realpath);
 
   if (!ctx->quiet)
@@ -212,12 +213,12 @@ int mutt_open_read_compressed (CONTEXT * ctx)
 
   cmd = get_compression_cmd (ci->open, ctx);
   if (cmd == NULL)
-    return (-1);
+    return -1;
 
   if ((fp = fopen (ctx->realpath, "r")) == NULL) {
     mutt_perror (ctx->realpath);
     p_delete(&cmd);
-    return (-1);
+    return -1;
   }
   mutt_block_signals ();
   if (mbox_lock_compressed (ctx, fp, 0, 1) == -1) {
@@ -226,7 +227,7 @@ int mutt_open_read_compressed (CONTEXT * ctx)
     mutt_error _("Unable to lock mailbox!");
 
     p_delete(&cmd);
-    return (-1);
+    return -1;
   }
 
   endwin ();
@@ -246,14 +247,14 @@ int mutt_open_read_compressed (CONTEXT * ctx)
   }
   p_delete(&cmd);
   if (rc)
-    return (-1);
+    return -1;
 
   if (mutt_check_mailbox_compressed (ctx))
-    return (-1);
+    return -1;
 
   ctx->magic = mx_get_magic (ctx->path);
 
-  return (0);
+  return 0;
 }
 
 static void restore_path (CONTEXT * ctx)
@@ -273,27 +274,36 @@ int mutt_open_append_compressed (CONTEXT * ctx)
 {
   FILE *fh;
   compress_info *ci = set_compress_info (ctx);
+  char tmppath[_POSIX_PATH_MAX];
 
   if (!get_append_command (ctx->path, ctx)) {
     if (ci->open && ci->close)
-      return (mutt_open_read_compressed (ctx));
+      return mutt_open_read_compressed(ctx);
 
     ctx->magic = 0;
     p_delete(&ctx->cinfo);
-    return (-1);
+    return -1;
   }
 
-  set_path (ctx);
+  /* Setup the right paths */
+  ctx->realpath = ctx->path;
+
+  /* Uncompress to /tmp */
+  fh = m_tempfile(tmppath, sizeof(tmppath), NONULL(MCore.tmpdir), NULL);
+  m_fclose(&fh);
+
+  ctx->path = p_dupstr(tmppath, m_strlen(tmppath));
 
   ctx->magic = DefaultMagic;
 
-  if (!is_new (ctx->realpath))
-    if (ctx->magic == M_MBOX || ctx->magic == M_MMDF)
-      if ((fh = safe_fopen (ctx->path, "w")))
-        m_fclose(&fh);
+  if (is_new (ctx->realpath) || 
+      (ctx->magic != M_MBOX &&
+       ctx->magic != M_MMDF))
+      unlink(tmppath);
+
   /* No error checking - the parent function will catch it */
 
-  return (0);
+  return 0;
 }
 
 /* close a compressed mailbox */
@@ -325,12 +335,12 @@ int mutt_sync_compressed (CONTEXT * ctx)
 
   cmd = get_compression_cmd (ctx->cinfo->close, ctx);
   if (cmd == NULL)
-    return (-1);
+    return -1;
 
   if ((fp = fopen (ctx->realpath, "a")) == NULL) {
     mutt_perror (ctx->realpath);
     p_delete(&cmd);
-    return (-1);
+    return -1;
   }
   mutt_block_signals ();
   if (mbox_lock_compressed (ctx, fp, 1, 1) == -1) {
@@ -341,7 +351,7 @@ int mutt_sync_compressed (CONTEXT * ctx)
     ctx->cinfo->size = get_size(ctx->realpath);
 
     p_delete(&cmd);
-    return (-1);
+    return -1;
   }
 
   endwin ();
@@ -364,7 +374,7 @@ int mutt_sync_compressed (CONTEXT * ctx)
 
   ctx->cinfo->size = get_size(ctx->realpath);
 
-  return (rc);
+  return rc;
 }
 
 int mutt_slow_close_compressed (CONTEXT * ctx)
@@ -379,7 +389,7 @@ int mutt_slow_close_compressed (CONTEXT * ctx)
       /* if we can not or should not append, we only have to remove the
          compressed info, because sync was already called */
     mutt_fast_close_compressed (ctx);
-    return (0);
+    return 0;
   }
 
   m_fclose(&ctx->fp);
@@ -393,12 +403,12 @@ int mutt_slow_close_compressed (CONTEXT * ctx)
 
   cmd = get_compression_cmd (append, ctx);
   if (cmd == NULL)
-    return (-1);
+    return -1;
 
   if ((fp = fopen (ctx->realpath, "a")) == NULL) {
     mutt_perror (ctx->realpath);
     p_delete(&cmd);
-    return (-1);
+    return -1;
   }
   mutt_block_signals ();
   if (mbox_lock_compressed (ctx, fp, 1, 1) == -1) {
@@ -407,7 +417,7 @@ int mutt_slow_close_compressed (CONTEXT * ctx)
     mutt_error _("Unable to lock mailbox!");
 
     p_delete(&cmd);
-    return (-1);
+    return -1;
   }
 
   endwin ();
@@ -428,7 +438,7 @@ int mutt_slow_close_compressed (CONTEXT * ctx)
     mbox_unlock_compressed (ctx, fp);
     mutt_unblock_signals ();
     m_fclose(&fp);
-    return (-1);
+    return -1;
   }
 
   mbox_unlock_compressed (ctx, fp);
@@ -439,7 +449,7 @@ int mutt_slow_close_compressed (CONTEXT * ctx)
   p_delete(&cmd);
   p_delete(&ctx->cinfo);
 
-  return (0);
+  return 0;
 }
 
 mx_t const compress_mx = {