I'm attaching you an example :) 
#!/bin/sh
#VERSION=0.0.2
# This script is written by Martynas Bendorius and DirectAdmin
# It is used to gzip all emails in Maildir directory
# Official DirectAdmin webpage: http://www.directadmin.com
# Usage:
# ./dovecot_compress.sh </home/user/imap/domains/domain.com/email/Maildir>
MYUID=`/usr/bin/id -u`
if [ "${MYUID}" != 0 ]; then
        echo "You require Root Access to run this script";
        exit 0;
fi

if [ $# -lt 1 ]; then
        echo "Usage:";
        echo "$0 /home/user/imap/domains/domain.com/email/Maildir";
        echo "you gave #$#: $0 $1";
        exit 0;
fi

MAILDIR_PATH="${1}"
if ! echo "${MAILDIR_PATH}" | grep -m1 -q '/Maildir$'; then
        echo "Path does not end with /Maildir: ${MAILDIR_PATH}. Exiting.."
        exit 1
fi

if [ ! -d "${MAILDIR_PATH}/cur" ]; then
        echo "${MAILDIR_PATH}/cur does not exist, exiting..."
        exit 1
fi

cd "${MAILDIR_PATH}"
if [ $? -ne 0 ]; then
        echo "Failed to cd to ${MAILDIR_PATH}. Exiting..."
        exit 1
fi

echo "Checking for directories in ${MAILDIR_PATH}..."

# https://wiki.dovecot.org/Plugins/Zlib
find . -maxdepth 1 -mindepth 1 -type d -print0 | while read -d $'\0' directory; 
do {
        if [ "${directory}" = "tmp" ]; then
                continue
        fi
        cd "${MAILDIR_PATH}/${directory}"
        if [ $? -ne 0 ]; then
                echo "Failed to cd to ${MAILDIR_PATH}/${directory}. Skipping..."
                continue
        fi
        if [ ! -d "${MAILDIR_PATH}/${directory}/tmp" ]; then
                mkdir -p ${MAILDIR_PATH}/${directory}/tmp
                chown --reference=${MAILDIR_PATH}/${directory} 
${MAILDIR_PATH}/${directory}/tmp
        fi
        find ./tmp/ -maxdepth 1 -group mail -type f -delete
        # ignore all files with "*,S=*" (dovecot needs to know the size of the 
email, when it's gzipped) and "*,*:2,*,*Z*" (dovecot recommends adding Z to the 
end of gzipped files just to know which ones are gzipped) in their names, also 
skip files that are also compressed (find skips all other 'exec' after first 
failure)
        # dovecot: Note that if the filename doesn't contain the ',S=<size>' 
before compression, adding it afterwards changes the base filename and thus the 
message UID. The safest thing to do is simply to not compress such files.
        find . -type f -name "*,S=*" ! -name "*,*:2,*,*Z*" ! -exec gzip -t {} 
2>/dev/null \; -exec sh -c 'gzip --best --stdout $1 > ./tmp/$1' x {} \; -exec 
sh -c 'chown --reference=$1 ./tmp/$1' x {} \; -exec sh -c 'chmod --reference=$1 
./tmp/$1' x {} \; -exec sh -c 'touch --reference=$1 ./tmp/$1' x {} \;
        #if there are any compressed files, maildirlock the directory
        if ! find ./tmp -maxdepth 0 -type d -empty | grep -m1 -q '\.'; then
                echo "Size before compression: `du -sh 
\"${MAILDIR_PATH}/${directory}\" | awk '{print $1}'`"
                MAILDIRLOCK=/usr/libexec/dovecot/maildirlock
                if [ ! -x ${MAILDIRLOCK} ]; then
                        MAILDIRLOCK=/usr/lib/dovecot/maildirlock
                fi
                if [ ! -x ${MAILDIRLOCK} ]; then
                        echo "Unable to find ${MAILDIRLOCK}, exiting..."
                        find ./tmp/ -maxdepth 1 -group mail -type f -delete
                        exit 2
                fi
                # If we're able to create the maildirlock, then continue with 
moving compressed emails back
                #MAILDIRLOCK had a bug, which is patched in CB 2.0
                if PIDOFMAILDIRLOCK=`${MAILDIRLOCK} 
"${MAILDIR_PATH}/${directory}" 10`; then
                        # Move email only if it exists in destination folder, 
otherwise it's been removed at the time we converted it
                        find ${MAILDIR_PATH}/${directory}/tmp -maxdepth 1 -type 
f -exec sh -c "if [ -s \"\${1}\" ]; then mv -f \${1} 
${MAILDIR_PATH}/${directory}/; fi" x {} \;
                        kill ${PIDOFMAILDIRLOCK}
                        echo "Compressed ${MAILDIR_PATH}/${directory}..."
                        # Remove dovecot index files to have no issues with 
mails
                        find "${MAILDIR_PATH}" -type f -name dovecot.index\* 
-delete
                        echo "Size after compression: `du -sh 
\"${MAILDIR_PATH}/${directory}\" | awk '{print $1}'`"
                else
                        echo "Failed to lock: ${MAILDIR_PATH}/${directory}" >&2
                        find ./tmp/ -maxdepth 1 -group mail -type f -delete
                fi
    fi
};
done
exit 0

--
Best regards,
Martynas Bendorius


> On 2019-12-08, at 15:21, @lbutlr via dovecot <dovecot@dovecot.org> wrote:
> 
> On 08 Dec 2019, at 05:58, @lbutlr <krem...@kreme.com> wrote:
>> On 06 Dec 2019, at 16:28, Martynas Bendorius <marty...@martynas.it> wrote:
>>> when zlib compression is enabled in dovecot, old emails remain untouched
>> 
>> I’ve been considering doing this, or at least looking into how much space 
>> we’d save (answer so far, less than you might think), but I am hesitant to 
>> “alter” the user’s mail stores without a bit more guidance.
>> 
>> Has anyone found a good walkthrough/guide on setting this up and also on 
>> compressing the old mail?
>> 
>> Are there any common issues to watch out for? Is it entirely transparent to 
>> the user?
>> 
>> https://wiki2.dovecot.org/Plugins/Zlib says it has moved to 
>> https://doc.dovecot.org/plugin-settings/zlib_plugin/ which does not exist.
>> 
>> "Not Found
>> The requested URL /plugin-settings/zlib_plugin/ was not found on this 
>> server."
> 
> The ULR on that page has the _ character instead of a - in the URL.
> 
> <https://doc.dovecot.org/plugin-settings/zlib-plugin/> loads and leads to
> 
> <https://doc.dovecot.org/configuration_manual/zlib_plugin/#zlib-plugin>
> 
> Which, sadly, does not have example code on actually compressing the existing 
> mail, but does say to use maildirlock.
> 
> 
> 
> 
> -- 
> Wife: Who are you talking to? Husb: [on phone] Jon Wife: Aren't you
>       going to talk to me? Husb: I talked to you at dinner, do I need
>       to talk to you again?

Reply via email to