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.

I'm trying to run some smartsieve rules on a IMAP mailbox, I can certainly do this for mails that are delivered to that mailbox, but for emails that are already in that mailbox, or ones that a moved to it (via thunderbird/outlook) the rules are not processed. Are there any applications / methods of having a rule(s) run on the mailbox ever X secconds / minutes?

share|improve this question

2 Answers 2

By design, sieve processes mail on arrival in the user's mailbox from the outside. There is no built-in way to process folders afterwards.

It would be possible, though, to collect messages from a cyrus folder ("hotfolder"), and re-send them through the regular MTA to a special mailbox ("specialmailbox") which in turn has the sieve rules you need.

For this purpose, you could use something like this, for example, via cron:

#!/bin/sh
for msg in /var/spool/cyrus/mail/hotfolder; do
    sendmail speicalmailbox <$msg && rm $msg
done

The messages in the "hot" folder are removed from the file system without removing them from the cyrus index, this is not optimal. You could use iprune (part of the cyrus distribution, it will delete messages from folders depending on their age) to fix that. Removal from the file system is needed so we do not process each message multiple times.

I Hope this helps.

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.