#!/bin/sh # cyrus-deliver --- wrapper for procmail to deliver to cyrus imap server # Author: Noah Friedman # Created: 2005-05-12 # Public domain # $Id: cyrus-deliver,v 1.7 2011/05/04 20:30:20 friedman Exp $ # Commentary: # The cyrus delivery agent requires access to a unix-domain socket which is # only accessible to group `mail'. If the restricted delivery wrapper is # installed and is setgid, then use that. Otherwise, try to use deliver # directly. If that STILL fails, it's up to procmail to deal with that. # Code: libdir=/usr/lib/cyrus-imapd USER=${SUDO_USER-${USER-$LOGNAME}} lockfile=/tmp/cyrus-deliver.$USER.lock # The cyrus-imap `deliver' program does not gracefully handle temporary # errors due to server-side locks while another message is in the process # of being delivered. Therefore, for all instances of this meta-wrapper, # negotiate a client-side exclusive lock for the user before running the # delivery agent. get_lock() { tmplock=$lockfile.$$ echo $$ > $tmplock tmplstat=`stat -c "%i %Y" $tmplock` while : ; do if link $tmplock $lockfile 2> /dev/null ; then unlink $tmplock trap remove_lock 0 1 2 3 15 return 0 fi # Someone else has the lock; see if they're still alive. pid=`cat $lockfile 2> /dev/null` if [ -n "$pid" ] \ && ! kill -0 $pid 2> /dev/null \ && rm -f $lockfile \ && link $tmplock $lockfile 2> /dev/null then lockstat=`stat -c "%i %Y" $lockfile` case $lockstat in $tmplstat ) unlink $tmplock trap remove_lock 0 1 2 3 15 return 0 ;; esac fi logger -i -p mail.notice -t cyrus-deliver \ "waiting 5s for pid $pid to release lock" sleep 5 done } remove_lock() { e=$? rm -f "$lockfile" exit $e } do_delivery() { # Remove envelope from incoming message. # Cyrus' lmtpd bombs if it sees a leading "From ". sed -e '1{/^From /d;}' \ | { if [ -g $libdir/deliver-wrapper ]; then case $# in 0 ) set INBOX ;; esac $libdir/deliver-wrapper "$1" else case $# in 0 ) $libdir/deliver -a "$USER" "$USER" ;; * ) $libdir/deliver -a "$USER" -m "$1" "$USER" ;; esac fi } } main() { if get_lock ; then do_delivery ${1+"$@"} fi remove_lock } main ${1+"$@"} # eof