Dovecot disable zlib compression and decompress existing messages

After upgrading dovecot to 2.1.7 (wheezy) the mailbox index files seems to be broken. Normaly dovecot should repairs them automatically but due to zlib compression it is not able to determine the correct message size.

Error: Corrupted index cache file ...
Input/output error (FETCH for mailbox INBOX UID ...
Maildir filename has wrong S value ...

Now I'd like to disable the zlib plugin completely and decompress the existing messages. Trials with dsync where unsuccessful, because dsync does not decompress them at all.

Any suggestions how to deal with it?


Solution 1:

As far as I'm concerned, the message size is determined by the ",S=12345" attribute in the filename. They provide a Perl script which can recursively scan one or multiple maildirs with the option to extract zlib-compressed files, determine the actual message size, and write it in the filename.

I'm referring to information found here: https://www.dovecot.org/list/dovecot/2013-January/087953.html

The script is available at https://www.dovecot.org/tools/maildir-size-fix.pl

(edit: mirrored v1.1 here in case this link goes offline: https://tubemail.de/maildir-size-fix.pl.txt)

You might have to change some of the configuration variables in the script or determine which parameters are available - at least I myself found no documentation on the script's usage, but the configuration at the beginning of the script is pretty well understandable.

For me, it worked like a charm, no flaws experienced so far.

Edit: The command line usage parameters are in the comments behind the config variables. So to scan through maildir /home/myuser/.maildir/ and correct all message sizes, you'd have to run ./maildir-size-fix.pl -a -f -c -r /home/myuser/.maildir/ where

  • -a adds the size if it's missing
  • -f corrects the size if it's wrong
  • -c checks if the file is compressed, and if it is, extracts it to determine the correct size
  • -r tells the script to run recursively through all subfolders

You need to have the gunzipand bunzip2 binaries installed for the latter to work; also, cat, wc and awk need to be installed, which should be the case on all major Linux distros.

Solution 2:

#!/bin/bash 
IFS=$'\n'

for i in $(find /var/vmail -type f); do

    if file "$i" |grep gzip >/dev/null; then
#       echo "Extracting GZIP:" "$i" 
        mv "$i" "$i".gz
        gunzip "$i".gz

    elif file "$i" |grep bzip2 >/dev/null; then
#       echo "Extracting BZIP2:" "$i"
        bunzip2 -q "$i"
        mv "$i".out "$(echo $i |sed 's/.out//')"
     fi

done