X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=lib-mx%2Fcompress.c;h=01e4a07c725d5e986eb2dc393b13a2e1af20d9e2;hp=e89d438944d8fb7a8b13c633b9667f67eef7e7e1;hb=2c0e197ef42e4cdff1eff705c8b1b1d07336bf24;hpb=9ed7a487e3a922f2cbb222961c2c9710c3a65f91 diff --git a/lib-mx/compress.c b/lib-mx/compress.c index e89d438..01e4a07 100644 --- a/lib-mx/compress.c +++ b/lib-mx/compress.c @@ -12,7 +12,7 @@ #include #include -#include +#include #include "mutt.h" @@ -38,36 +38,50 @@ static int mbox_lock_compressed (CONTEXT * ctx, FILE * fp, int excl, int retry) { 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) @@ -113,38 +127,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 +158,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 +169,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 +183,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(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) @@ -212,12 +227,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 +241,7 @@ int mutt_open_read_compressed (CONTEXT * ctx) mutt_error _("Unable to lock mailbox!"); p_delete(&cmd); - return (-1); + return -1; } endwin (); @@ -246,14 +261,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) @@ -265,7 +280,7 @@ 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); } @@ -273,27 +288,33 @@ 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(mod_core.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); - /* No error checking - the parent function will catch it */ + if (is_new (ctx->realpath) || ctx->magic != M_MBOX) + unlink(tmppath); - return (0); + /* No error checking - the parent function will catch it */ + return 0; } /* close a compressed mailbox */ @@ -303,11 +324,7 @@ void mutt_fast_close_compressed (CONTEXT * ctx) 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); } @@ -325,12 +342,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 +358,7 @@ int mutt_sync_compressed (CONTEXT * ctx) ctx->cinfo->size = get_size(ctx->realpath); p_delete(&cmd); - return (-1); + return -1; } endwin (); @@ -364,7 +381,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 +396,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 +410,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 +424,7 @@ int mutt_slow_close_compressed (CONTEXT * ctx) mutt_error _("Unable to lock mailbox!"); p_delete(&cmd); - return (-1); + return -1; } endwin (); @@ -428,7 +445,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 +456,7 @@ int mutt_slow_close_compressed (CONTEXT * ctx) p_delete(&cmd); p_delete(&ctx->cinfo); - return (0); + return 0; } mx_t const compress_mx = {