BDB suck hard. in a GNU env, we will at least have gdbm.
[apps/madmutt.git] / lib-mx / compress.c
index 3770fef..6e988ca 100644 (file)
@@ -45,7 +45,7 @@ static int mbox_lock_compressed (CONTEXT * ctx, FILE * fp, int excl, int retry)
     return 0;
   }
 
     return 0;
   }
 
-  return (r);
+  return r;
 }
 
 static void mbox_unlock_compressed (CONTEXT * ctx, FILE * fp)
 }
 
 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)
 {
 
 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)
 }
 
 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);
 }
 
   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;
 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':
 
   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;
   }
     snprintf (dest, destlen, tmp, ctx->path);
     break;
   }
-  return (src);
+  return src;
 }
 
 /* check that the command has both %f and %t
 }
 
 /* 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;
 }
 
   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)
 }
 
 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!");
 
     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 *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);
 
   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;
 
   }
   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)
   ctx->cinfo->size = get_size(ctx->realpath);
 
   if (!ctx->quiet)
@@ -212,21 +213,21 @@ int mutt_open_read_compressed (CONTEXT * ctx)
 
   cmd = get_compression_cmd (ci->open, ctx);
   if (cmd == NULL)
 
   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);
 
   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) {
   }
   mutt_block_signals ();
   if (mbox_lock_compressed (ctx, fp, 0, 1) == -1) {
-    fclose (fp);
+    m_fclose(&fp);
     mutt_unblock_signals ();
     mutt_error _("Unable to lock mailbox!");
 
     p_delete(&cmd);
     mutt_unblock_signals ();
     mutt_error _("Unable to lock mailbox!");
 
     p_delete(&cmd);
-    return (-1);
+    return -1;
   }
 
   endwin ();
   }
 
   endwin ();
@@ -236,7 +237,7 @@ int mutt_open_read_compressed (CONTEXT * ctx)
   rc = mutt_system (cmd);
   mbox_unlock_compressed (ctx, fp);
   mutt_unblock_signals ();
   rc = mutt_system (cmd);
   mbox_unlock_compressed (ctx, fp);
   mutt_unblock_signals ();
-  fclose (fp);
+  m_fclose(&fp);
 
   if (rc) {
     mutt_any_key_to_continue (NULL);
 
   if (rc) {
     mutt_any_key_to_continue (NULL);
@@ -246,14 +247,14 @@ int mutt_open_read_compressed (CONTEXT * ctx)
   }
   p_delete(&cmd);
   if (rc)
   }
   p_delete(&cmd);
   if (rc)
-    return (-1);
+    return -1;
 
   if (mutt_check_mailbox_compressed (ctx))
 
   if (mutt_check_mailbox_compressed (ctx))
-    return (-1);
+    return -1;
 
   ctx->magic = mx_get_magic (ctx->path);
 
 
   ctx->magic = mx_get_magic (ctx->path);
 
-  return (0);
+  return 0;
 }
 
 static void restore_path (CONTEXT * ctx)
 }
 
 static void restore_path (CONTEXT * ctx)
@@ -273,36 +274,44 @@ int mutt_open_append_compressed (CONTEXT * ctx)
 {
   FILE *fh;
   compress_info *ci = set_compress_info (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)
 
   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);
 
     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;
 
 
   ctx->magic = DefaultMagic;
 
-  if (!is_new (ctx->realpath))
-    if (ctx->magic == M_MBOX || ctx->magic == M_MMDF)
-      if ((fh = safe_fopen (ctx->path, "w")))
-        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 */
 
   /* No error checking - the parent function will catch it */
 
-  return (0);
+  return 0;
 }
 
 /* close a compressed mailbox */
 void mutt_fast_close_compressed (CONTEXT * ctx)
 {
   if (ctx->cinfo) {
 }
 
 /* close a compressed mailbox */
 void mutt_fast_close_compressed (CONTEXT * ctx)
 {
   if (ctx->cinfo) {
-    if (ctx->fp)
-      fclose (ctx->fp);
-    ctx->fp = NULL;
+    m_fclose(&ctx->fp);
+
     /* if the folder was removed, remove the gzipped folder too */
     if (access (ctx->path, F_OK) != 0 && !option (OPTSAVEEMPTY))
       remove (ctx->realpath);
     /* if the folder was removed, remove the gzipped folder too */
     if (access (ctx->path, F_OK) != 0 && !option (OPTSAVEEMPTY))
       remove (ctx->realpath);
@@ -326,23 +335,23 @@ int mutt_sync_compressed (CONTEXT * ctx)
 
   cmd = get_compression_cmd (ctx->cinfo->close, ctx);
   if (cmd == NULL)
 
   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);
 
   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) {
   }
   mutt_block_signals ();
   if (mbox_lock_compressed (ctx, fp, 1, 1) == -1) {
-    fclose (fp);
+    m_fclose(&fp);
     mutt_unblock_signals ();
     mutt_error _("Unable to lock mailbox!");
 
     ctx->cinfo->size = get_size(ctx->realpath);
 
     p_delete(&cmd);
     mutt_unblock_signals ();
     mutt_error _("Unable to lock mailbox!");
 
     ctx->cinfo->size = get_size(ctx->realpath);
 
     p_delete(&cmd);
-    return (-1);
+    return -1;
   }
 
   endwin ();
   }
 
   endwin ();
@@ -359,13 +368,13 @@ int mutt_sync_compressed (CONTEXT * ctx)
 
   mbox_unlock_compressed (ctx, fp);
   mutt_unblock_signals ();
 
   mbox_unlock_compressed (ctx, fp);
   mutt_unblock_signals ();
-  fclose (fp);
+  m_fclose(&fp);
 
   p_delete(&cmd);
 
   ctx->cinfo->size = get_size(ctx->realpath);
 
 
   p_delete(&cmd);
 
   ctx->cinfo->size = get_size(ctx->realpath);
 
-  return (rc);
+  return rc;
 }
 
 int mutt_slow_close_compressed (CONTEXT * ctx)
 }
 
 int mutt_slow_close_compressed (CONTEXT * ctx)
@@ -380,12 +389,10 @@ 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);
       /* 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;
   }
 
   }
 
-  if (ctx->fp)
-    fclose (ctx->fp);
-  ctx->fp = NULL;
+  m_fclose(&ctx->fp);
 
   if (!ctx->quiet) {
     if (append == ci->close)
 
   if (!ctx->quiet) {
     if (append == ci->close)
@@ -396,21 +403,21 @@ int mutt_slow_close_compressed (CONTEXT * ctx)
 
   cmd = get_compression_cmd (append, ctx);
   if (cmd == NULL)
 
   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);
 
   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) {
   }
   mutt_block_signals ();
   if (mbox_lock_compressed (ctx, fp, 1, 1) == -1) {
-    fclose (fp);
+    m_fclose(&fp);
     mutt_unblock_signals ();
     mutt_error _("Unable to lock mailbox!");
 
     p_delete(&cmd);
     mutt_unblock_signals ();
     mutt_error _("Unable to lock mailbox!");
 
     p_delete(&cmd);
-    return (-1);
+    return -1;
   }
 
   endwin ();
   }
 
   endwin ();
@@ -430,19 +437,19 @@ int mutt_slow_close_compressed (CONTEXT * ctx)
     p_delete(&cmd);
     mbox_unlock_compressed (ctx, fp);
     mutt_unblock_signals ();
     p_delete(&cmd);
     mbox_unlock_compressed (ctx, fp);
     mutt_unblock_signals ();
-    fclose (fp);
-    return (-1);
+    m_fclose(&fp);
+    return -1;
   }
 
   mbox_unlock_compressed (ctx, fp);
   mutt_unblock_signals ();
   }
 
   mbox_unlock_compressed (ctx, fp);
   mutt_unblock_signals ();
-  fclose (fp);
+  m_fclose(&fp);
   remove_file (ctx);
   restore_path (ctx);
   p_delete(&cmd);
   p_delete(&ctx->cinfo);
 
   remove_file (ctx);
   restore_path (ctx);
   p_delete(&cmd);
   p_delete(&ctx->cinfo);
 
-  return (0);
+  return 0;
 }
 
 mx_t const compress_mx = {
 }
 
 mx_t const compress_mx = {