When a compressed maildir message has a bad S= size in its filename it puts the user in an unrecoverable state, since maildir's do_fix_size function just does a stat() on the maildir file and saves the compressed size in the filename.
This (quick, rough, barely tested) patch addresses this issue, it's inefficient, but we're already in a hopefully rare emergency situation.
--- maildir-mail.c 2014-02-11 22:23:37.000000000 +0000
+++ maildir-mail.c.new 2014-04-24 20:41:25.000000000 +0000
@@ -8,6 +8,7 @@
#include "maildir-filename.h"
#include "maildir-uidlist.h"
#include "maildir-sync.h"
+#include "compression.h"
#include
#include
@@ -640,6 +641,10 @@
{
const char *fname, *newpath, *extra, *info, *dir;
struct stat st;
+ const struct stat * stp;
+ const struct compression_handler * handler;
+ struct istream * fstream;
+ struct istream * cstream;
fname = strrchr(path, '/');
i_assert(fname != NULL);
@@ -650,13 +655,29 @@
info = strchr(fname, MAILDIR_INFO_SEP);
if (info == NULL) info = "";
+ fstream = i_stream_create_file(path, 1024);
+ handler = compression_detect_handler(fstream);
+ if (handler != NULL && handler->create_istream != NULL)
+ {
+ cstream = handler->create_istream(fstream, TRUE);
+ if (i_stream_stat(cstream, TRUE, &stp) < 0)
+ {
+ return -1;
+ }
+ st = *stp; /* dumb copy */
+ i_stream_unref(&cstream);
+ }
+ else
+ {
if (stat(path, &st) < 0) {
if (errno == ENOENT)
return 0;
mail_storage_set_critical(&mbox->storage->storage,
"stat(%s) failed: %m", path);
return -1;
- }
+ }
+ }
+ i_stream_unref(&fstream);
newpath = t_strdup_printf("%s/%s,S=%"PRIuUOFF_T"%s", dir,
t_strdup_until(fname, extra),