I've taken code snippets from elsewhere and created a script to compress existing maildir emails (Dovecot would need to be stopped as I don't check for locks).
#!/bin/bash
store=/var/vmail/mydomain.com
find "$store" -type d -name "cur" | while read maildir; do
tmpdir=$(cd "$maildir/../tmp" &>/dev/null && pwd) || exit 1
find=$(find "$maildir" -type f -name "*,S=*" ! -name "*,*:2,*,*Z*" -printf "%f\n")
if [ -z "$find" ]; then
echo continue
continue
fi
echo "$find" | while read filename; do
if file "$maildir/$filename" | grep -q "SMTP mail, "; then
echo 'Uncompressed' "$filename"
flags=$(echo $filename | awk -F:2, '{print $2}')
if echo $flags | grep ','; then
newname=$filename"Z"
else
newname=$filename",Z"
fi
srcfile="$maildir/$filename"
tmpfile="$tmpdir/$filename"
dstfile="$maildir/$newname"
gzip -c "$srcfile" > "$tmpfile" &&
chown --reference="$srcfile" "$tmpfile" &&
chmod --reference="$srcfile" "$tmpfile" &&
touch --reference="$srcfile" "$tmpfile"
if [ -f "$srcfile" ] && [ -f "$tmpfile" ]; then
mv "$tmpfile" "$srcfile" &&
mv "$srcfile" "$dstfile"
else
rm -f "$tmpfile"
fi
elif file "$maildir/$filename" | grep -q "gzip compressed data"; then
echo 'Compressed' "$filename"
else
echo 'Unknown type'
fi
done
done
However I realised that my inbound mail doesn't get found, as not all of the emails meet the find criteria of -name "*,S=*"
Example
find "/var/vmail/mydomain.com" -type d -name "cur" | while read maildir; do find "$maildir" -type f -name "*,S=*" ! -name "*,*:2,*,*Z*" -printf "%f\n"; done
Will find these:
/var/vmail/mydomain.com/Maildir/.Sent/cur
1580000001.M10001P10008.ip-172-1-1-100,S=14037,W=14302:2,Sa
1580000002.M20002P10009.ip-172-1-1-100,S=3784,W=3888:2,S
However not these:
/var/vmail/mydomain.com/Maildir/.INBOX/cur
1580000003.Vca01I80f58M300003.ip-172-1-1-100:2,S
1580000004.Vca01I80de7M400004.ip-172-1-1-100:2,Sa
1580000005.Vca01I85252M400005.ip-172-1-1-100:2,RS
1580000006.Vca01I83ffeM400006.ip-172-1-1-100:2,Sb
1580000007.Vca01I8159aM400007.ip-172-1-1-100:2,RSa
1580000008.Vca01I84015M400008.ip-172-1-1-100:2,Sab
I could easily change the find command to match the inbound mail but as the find criteria came from elsewhere I wondered if there was a reason for the explicit "*,S=*"
?
Ps. Please note that mail is not received through Dovecot, inbound mail is picked up by postfix which saves the mail directly to the relevant directory, postfix variables below for an example.
virtual_mailbox_base: /var/vmail
virtual_mailbox_maps: ldap lookup, %d/%u/Maildir/
You may consider searching for substring :2,
in filenames.
Dovecot: Maildir filename extensions
The standard filename definition is: ":2,". […]
* ,S=: contains the file size. Getting the size from the filename avoids doing a stat(), which may improve the performance. This is especially useful with Maildir++ quota.
* ,W=: contains the file's RFC822.SIZE, ie. the file size with linefeeds being CR+LF characters. […]
Uppercase letters mark "standard flags", lowercase letters mean "local/user flags".