Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

For my mailserver I have a dovecot, postfix and sieve setup.

I have several hundred mails in my maildir and have recently created some sieve rules for sorting them. Unfortunatelly the sieve rules are by design only applied to incoming messages. Therefore my question:

How can I run sieve against messages in an already existing maildir?

Thanks

--- edit:

Thanks larsks

With the link you provided I ended up using:

mkdir todo
mkdir done
mv cur/* todo
for  i  in todo/*; do
    echo "Delivering message $i ..."
    /usr/lib/dovecot/deliver -d mail@example.de < $i && mv $i done/
done

which works like I charm. I can rerun this script for every new filter I create.

share|improve this question
1  

2 Answers 2

up vote 6 down vote accepted

There's not an easy way to do this, but according to this message you can write a shell script to re-deliver messages using Dovecot's deliver program...so something like this:

produce_message_list |
while read msg; do
  /usr/libexec/dovecot/deliver -d user < $msg && rm -f $msg
done

You'll have to replace produce_message_list with something that produces a list of messages for processing; possibly find will do what you need.

share|improve this answer

Newer versions of dovecot and pidgeonhole now come with a sieve-filter command. So you can write a script to scan all mailboxes for a "INBOX.Refilter" folder, and then run sieve-filter against that folder.

This script assumes that you have structured your mail folder as /var/vmail/domain/user.

#!/bin/bash

FIND=/usr/bin/find
GREP=/bin/grep
RM=/bin/rm
SED=/bin/sed
SORT=/bin/sort

# BASE should point at /var/vmail/ and should have trailing slash
BASE="/var/vmail/"

RESORTFOLDER="INBOX.Refilter"

SEARCHFILE="dovecot-uidlist"

echo ""
echo "Search for messages to resort under ${BASE}"
echo "Started at: " `date`
echo "Looking for mailboxes with ${RESORTFOLDER}"
echo ""

# since RHEL5/CentOS5 don't have "sort -R" option to randomize, use the following example
# echo -e "2\n1\n3\n5\n4" | perl -MList::Util -e 'print List::Util::shuffle <>'

DIRS=`$FIND ${BASE} -maxdepth 3 -name ${SEARCHFILE} | \
    $SED -n "s:^${BASE}::p" | $SED "s:/${SEARCHFILE}$:/:" | \
    perl -MList::Util -e 'print List::Util::shuffle <>'`

# keep track of directories processed so far
DCNT=0

for DIR in ${DIRS}
do
    UD="${BASE}${DIR}.${RESORTFOLDER}"
    D=`echo "$DIR" | tr '/' ' ' | awk '{print $1}'`
    U=`echo "$DIR" | tr '/' ' ' | awk '{print $2}'`

    if [ -d "$UD/cur" ] 
    then
        echo "`date` - $DIR"
        echo " domain: $D"
        echo "   user: $U"
        FILES=`find $UD/cur/ $UD/new/ -type f -name '*' | wc -l`
        echo "  files: $FILES"

        if [[ $FILES -ge 1 ]]; then
            echo "Run $FILES messages back through the sieve filter."
            # -c2 means run at best-effort, -n7 is least priority possible
            ionice -c2 -n7 sieve-filter -e -W -C -u "${U}@${D}" "${BASE}${DIR}.dovecot.sieve" "${RESORTFOLDER}"
        fi

        echo ""
    fi

    # the following is debug code, to stop the script after N directories
    #DCNT=$(($DCNT+1))
    #echo "DCNT: $DCNT"
    #if [[ $DCNT -ge 5 ]]; then exit 0; fi
done

echo ""
echo "Finished at:" `date`
echo ""
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.