summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Makefile2
-rw-r--r--offlineimap-exit.sh10
-rw-r--r--offlineimap-killer.sh31
-rw-r--r--offlineimap-runner.sh71
5 files changed, 38 insertions, 78 deletions
diff --git a/.gitignore b/.gitignore
index 5854bc4..1347fbf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,8 +6,8 @@ chardiff_post
daemon
hangman-helper
maildups
+offlineimap-killer
offlineimap-runner
-offlineimap-exit
ord
roll
tempmon
diff --git a/Makefile b/Makefile
index cf50e18..aafce7c 100644
--- a/Makefile
+++ b/Makefile
@@ -12,8 +12,8 @@ BINFILES = \
daemon \
hangman-helper \
maildups \
+ offlineimap-killer \
offlineimap-runner \
- offlineimap-exit \
ord \
roll \
tempmon \
diff --git a/offlineimap-exit.sh b/offlineimap-exit.sh
deleted file mode 100644
index 7838cd7..0000000
--- a/offlineimap-exit.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-
-offlineimap='offlineimap'
-
-output_file="$(mktemp --tmpdir "${0##*/}.XXXXXXXXXX")"
-trap "rm -f $(printf '%q' "$output_file")" EXIT
-
-"$offlineimap" "$@" |& tee "$output_file"
-
-! grep 'ERROR:' "$output_file"
diff --git a/offlineimap-killer.sh b/offlineimap-killer.sh
new file mode 100644
index 0000000..91f9509
--- /dev/null
+++ b/offlineimap-killer.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# Usage: offlineimap-killer LIMIT
+#
+# Kills any instance of offlineimap that has been running longer than
+# LIMIT seconds.
+
+pid_uptime() {
+ local pid=$1
+ local sec_uptime=$(cut -d ' ' -f1 /proc/uptime)
+ local tic_started_at
+ tic_started_at=$(cut -d ' ' -f 22 /proc/${pid}/stat 2>/dev/null) ||
+ { echo 0; return 0; }
+ local tic_per_sec=$(getconf CLK_TCK)
+
+ bc <<<"${sec_uptime} - (${tic_started_at}/${tic_per_sec})"
+}
+
+main() {
+ declare -i limit=$1
+ local pids=($(pgrep -x offlineimap))
+ local pid
+ for pid in "${pids[@]}"; do
+ declare -i uptime=$(pid_uptime $pid)
+ if [[ "$uptime" -gt "$pid" ]]; then
+ printf 'Killing %d which has been running for %d seconds' "$pid" "$uptime"
+ kill -9 "$pid"
+ fi
+ done
+}
+
+main "$@"
diff --git a/offlineimap-runner.sh b/offlineimap-runner.sh
index ae8bf10..440b2bf 100644
--- a/offlineimap-runner.sh
+++ b/offlineimap-runner.sh
@@ -1,70 +1,9 @@
#!/bin/bash
+# Run offline imap, but "parse" the output to generate a sane exit status
-# offlineimap is pretty nifty, and generally does the right thing, and is
-# remarkably fault-tolerant, even of it's own code.
-#
-# One nifty thing it doesn is to check if an instance of it is already running,
-# and to exit and let the original insance do it's thing. That lets us do
-# things like put it in a crontab. We wouldn't want to do this if it didn't have
-# that feature, because then
-# * If the previous run hadn't finished, things would break
-# I have it run every at m="*/5". 5 minutes is usually plenty of time, but
-# for large attachments, it might not be enough.
-# * If I wanted to run it manually, at say m="*/5+4", if it takes more than a
-# minute to run, then the instance invoked by cron would bork everything.
+output_file="$(mktemp --tmpdir "${0##*/}.XXXXXXXXXX")"
+trap "rm -f $(printf '%q' "$output_file")" EXIT
-# As awesome as this is, it has one fatal flaw: an instance hanging.
-# This only happens rarely, but I've had an instance of offlineimap invoked by
-# cron decided to hang up. After 2 days of recieving suspiciously little email,
-# I decided to check if offlineimap was running ok. That instance had hung up,
-# not recieving any mail, but preventing cron from starting another instance.
-#
-# So, here is my workaround: keep track of how many times in a row that we've
-# tried to start offlineimap, and it failed. If that number exceeds a specified
-# number, then assume the running instance hung, and kill it.
+offlineimap "$@" |& tee "$output_file"
-if [ "$1" = '-v' ]; then
- shift;
- msg() { echo "$@"; }
-else
- msg() { :; }
-fi
-
-# A note on notation:
-# the number/limit is the number of failures allowed *before* anything is killed.
-# So, if the limit is "1", the first time, it will just pass by. The second
-# time, it will see that we've already failed once, so if it's still running,
-# kill it.
-default_limit=2
-limit=${1-$default_limit}
-shift
-
-cookie_file="$HOME/.offlineimap.cookie"
-offlineimap='offlineimap-exit'
-
-# Try running offlineimap
-if $offlineimap "$@"; then
- # Everything went smoothly, remove any record of failures
- msg 'Successfully ran offlineimap'
- msg 'Clearing cookie file'
- echo '0' > "$cookie_file"
-else
- # oh noez!
- msg 'offlineimap had an error'
- # we interupt your regularly scheduled panic for a sanity check
- if [ ! -f "$cookie_file" ]; then
- echo '0' > "$cookie_file"
- fi
- # you may now resume panicing
- number=`cat "$cookie_file"`
- echo $(($number+1)) > "$cookie_file"
-
- msg " has failed $number times (with a limit of $limit)"
- if [ "$number" -ge "$limit" ]; then # kill it!
- killall -9 offlineimap
- # We invoke offlineimap directly, instead of recursing on
- # ourself because if something else is causing it to fail, then
- # we'll fork-bomb
- $offlineimap "$@"
- fi
-fi
+! grep -q '^ERROR:' -- "$output_file"