s3: Wait longer after failure, pick up any failed pieces later.
[clinton/scripts.git] / redeliver-mail
index 0d68870..52fa643 100755 (executable)
@@ -4,7 +4,61 @@
 # /var/mail/$USER, due to temporary AFS glitches.
 #
 # This should be called as root on deleuze.
+#
+# USAGE: redeliver-mail [USER]
+#
+# If USER is specified, redeliver their mail, regardless of whether
+# mail redelivery is stopped for all users.
+
+BLOCKFILE=/tmp/exim4/inhibit-redelivery
 
+# Function to deliver mail for $USER.  If the message still can't be
+# written to $USER/Maildir, Exim will place it in /var/mail/$USER
+# again.
+function deliver_mail() {
+    local USER=$1
+    local TMPMBOX=$2
+
+    mv /var/mail/$USER $TMPMBOX
+    formail -s /etc/exim4/deliver-once $USER < $TMPMBOX
+    rm -f $TMPMBOX
+}
+
+# Check arguments.
+if [ -n "$2" ]; then
+    echo "Incorrect number of arguments"
+    exit 1
+elif [ -n "$1" ]; then
+    # Do redelivery for just one person
+    USER=$1
+    MBOX=/var/mail/$USER
+    TMPMBOX=/tmp/exim4/$USER.mbox.tmp
+
+    if test -f $TMPMBOX; then
+        echo "The temporary file $TMPMBOX still exists."
+        echo "Please wait an hour for it to go away before running this" \
+            "script again."
+        exit 1
+    fi
+
+    if ! test -s $MBOX || ! test -f $MBOX; then
+        echo "$MBOX is empty"
+        exit 1
+    fi
+
+    deliver_mail $USER $TMPMBOX
+    echo Done delivering mail for $USER
+    exit 0
+fi   
+
+# Make sure we didn't get into trouble with an earlier run of this
+# script.  A separate daily cron job should run to check for the
+# existence of this file.
+if test -f $BLOCKFILE; then
+    exit 0
+fi
+
+# Run redelivery for everyone
 for MBOX in /var/mail/*; do
 
     USER=$(basename $MBOX)
@@ -15,9 +69,37 @@ for MBOX in /var/mail/*; do
         continue
     fi
 
+    # Sanity check: If TMPMBOX exists and is 20 minutes old or less,
+    # there is some serious trouble, and we should (1) email
+    # postmaster about it and (2) block future processing of /var/mail
+    # until someone removes BLOCKFILE.
+    #
+    # If TMPMBOX exists and is older than 20 minutes, it's probably
+    # stale, so blow it away.  Note that we will never get to this
+    # point if BLOCKFILE exists, so there is no need to refine the
+    # metric further.
+    if test -f $TMPMBOX; then
+        if test $(stat --format=%Y $TMPMBOX) -le \
+            $(date --date='-20 min' +%s); then
+            # Set block file
+            touch $BLOCKFILE
+            echo -e "/var/mail/$USER contains too much email." \
+                "\nBlocking email redelivery script until this is resolved." \
+                "\n\nTo indicate that this is resolved, do the following" \
+                "\non deleuze." \
+                "\n (1) Wait for $TMPMBOX to go away (should take an hour)" \
+                "\n (2) Run '$0 $USER'" \
+                "\n (3) Remove $BLOCKFILE" | \
+              mail -s "[redeliver-mail] Mail backlog too large on deleuze" \
+                -e -a "From: root@deleuze.hcoop.net" \
+                postmaster@deleuze.hcoop.net
+            exit 0
+        else
+            rm -fr $TMPMBOX
+        fi
+    fi
+
     # Deliver mail.  If the message still can't be written to
     # $USER/Maildir, Exim will place it in /var/mail/$USER again.
-    mv /var/mail/$USER $TMPMBOX
-    formail -s /etc/exim4/deliver-once $USER < $TMPMBOX
-    rm -f $TMPMBOX
+    deliver_mail $USER $TMPMBOX
 done