#include <lib-sys/mutt_signal.h>
#include <lib-sys/unix.h>
-#include <lib-ui/curses.h>
+#include <lib-ui/lib-ui.h>
#include "mutt.h"
{
int r;
- if ((r = mx_lock_file (ctx->realpath, fileno (fp), excl, 1, retry)) == 0)
+ if ((r = mx_lock_file (ctx->realpath, fileno (fp), excl, retry)) == 0)
ctx->locked = 1;
else if (retry && !excl) {
ctx->readonly = 1;
return 0;
}
- return (r);
+ return r;
}
static void mbox_unlock_compressed (CONTEXT * ctx, FILE * fp)
{
if (ctx->locked) {
fflush (fp);
-
- mx_unlock_file (ctx->realpath, fileno (fp), 1);
+ mx_unlock_file(ctx->realpath, fileno(fp));
ctx->locked = 0;
}
}
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)
{
- const char *c = mutt_find_hook (type, path);
-
- return (!c || !*c) ? NULL : c;
+ int len = strlen(path);
+ if (len > 3 && !strcmp(path + len - 3, ".gz")) {
+ switch (type) {
+ case M_OPENHOOK: return "gzip -cd %f > %t";
+ case M_CLOSEHOOK: return "gzip -cd %t > %f";
+ case M_APPENDHOOK: return "gzip -cd %t >> %f";
+ default: return NULL;
+ }
+ }
+ if (len > 4 && !strcmp(path + len - 4, ".bz2")) {
+ switch (type) {
+ case M_OPENHOOK: return "bzip2 -cd %f > %t";
+ case M_CLOSEHOOK: return "bzip2 -cd %t > %f";
+ case M_APPENDHOOK: return "bzip2 -cd %t >> %f";
+ default: return NULL;
+ }
+ }
+ return NULL;
}
int mutt_can_read_compressed (const char *path)
int magic;
if (is_new (path))
- return (find_compress_hook (M_CLOSEHOOK, path) ? 1 : 0);
+ return find_compress_hook (M_CLOSEHOOK, path) ? 1 : 0;
magic = mx_get_magic (path);
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 *ifstr __attribute__ ((unused)),
- const char *elstr __attribute__ ((unused)),
- anytype 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[STRING];
snprintf (dest, destlen, tmp, ctx->path);
break;
}
- return (src);
+ return src;
}
/* check that the command has both %f and %t
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 buf[_POSIX_PATH_MAX];
- m_strformat(buf, sizeof(buf), cmd, compresshook_format_str, ctx, 0);
+ m_strformat(buf, sizeof(buf), 0, cmd, compresshook_format_str, (void*)ctx, 0);
return m_strdup(buf);
}
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(mod_core.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)
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) {
mutt_error _("Unable to lock mailbox!");
p_delete(&cmd);
- return (-1);
+ return -1;
}
endwin ();
}
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)
/* remove the temporary mailbox */
static void remove_file (CONTEXT * ctx)
{
- if (ctx->magic == M_MBOX || ctx->magic == M_MMDF)
+ if (ctx->magic == M_MBOX)
remove (ctx->path);
}
{
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(mod_core.tmpdir), NULL);
+ m_fclose(&fh);
- ctx->magic = DefaultMagic;
+ ctx->path = p_dupstr(tmppath, m_strlen(tmppath));
+ ctx->magic = M_MBOX;
+ if (is_new (ctx->realpath) || ctx->magic != M_MBOX)
+ unlink(tmppath);
- if (!is_new (ctx->realpath))
- if (ctx->magic == M_MBOX || ctx->magic == M_MMDF)
- if ((fh = safe_fopen (ctx->path, "w")))
- m_fclose(&fh);
/* No error checking - the parent function will catch it */
-
- return (0);
+ return 0;
}
/* close a compressed mailbox */
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);
- else
- remove_file (ctx);
-
+ remove_file (ctx);
restore_path (ctx);
p_delete(&ctx->cinfo);
}
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) {
ctx->cinfo->size = get_size(ctx->realpath);
p_delete(&cmd);
- return (-1);
+ return -1;
}
endwin ();
ctx->cinfo->size = get_size(ctx->realpath);
- return (rc);
+ return rc;
}
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);
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) {
mutt_error _("Unable to lock mailbox!");
p_delete(&cmd);
- return (-1);
+ return -1;
}
endwin ();
mbox_unlock_compressed (ctx, fp);
mutt_unblock_signals ();
m_fclose(&fp);
- return (-1);
+ return -1;
}
mbox_unlock_compressed (ctx, fp);
p_delete(&cmd);
p_delete(&ctx->cinfo);
- return (0);
+ return 0;
}
mx_t const compress_mx = {
NULL,
NULL,
NULL,
+ NULL,
};