chiark / gitweb /
@@@ dvdrip-upload: change settings while i'm stealing someone else's internet
[dvdrip] / dvdrip-upload
1 #! /bin/bash -e
2
3 prog=${0##*/}
4 tmp=${DVDRIP_TMPDIR-${HOME?}/tmp/dvdrip}
5 archive=${DVDRIP_ARCHIVE-jem.distorted.org.uk:/mnt/dvd/archive}
6 kill=nil listen=nil verbose=nil bogus=nil opts=; unset dir sub n label
7 usage () {
8   cat <<EOF
9 usage: $prog [-klv]
10 EOF
11 }
12 while getopts "ha:klv" opt; do
13   case $opt in
14     h) usage; exit 0 ;;
15     a) archive=$OPTARG ;;
16     k) kill=t ;;
17     l) listen=t; opts=${opts}l ;;
18     v) verbose=t; opts=${opts}v ;;
19     *) bogus=t ;;
20   esac
21 done
22 shift $(( $OPTIND - 1 ))
23 case $# in
24   0) ;;
25   *) bogus=t ;;
26 esac
27 case $bogus in t) usage >&2; exit 2 ;; esac
28 case $verbose in t) set -x ;; esac
29
30 notify () {
31   colour=$1 message=$2
32   echo "$(tput bold; tput setaf $colour)$message$(tput sgr0; tput op)"
33 }
34 fail () { notify 1 "!!! $*"; exit 2; }
35 warn () { notify 5 "??? $*"; }
36 info () { notify 6 "--- $*"; }
37 run_setrc () {
38   notify 2 "+++ $*";
39   set +e; nice "$@"; rc=$?; set -e
40 }
41 run () { run_setrc "$@"; case $rc in 0) ;; *) fail "$1: exit $rc" ;; esac; }
42
43 case $archive in
44   *:*) archhost=${archive%%:*} archpath=${archive#*:} ;;
45   *) unset archhost; archpath=$archive ;;
46 esac
47
48 archdo () {
49   op=$1; shift
50   case ${archhost+t} in
51     t)
52       qq=
53       for a in "$@"; do
54         qq="${qq:+$qq }'${a//\'/"'\\''"}'" #" # emacs is confused
55       done
56       "$op" ssh "$archhost" "$qq"
57       ;;
58     *)
59       "$op" "$@"
60       ;;
61   esac
62 }
63 archrun () { archdo run "$@"; }
64
65 check () {
66   info "checking for pending uploads"
67   while :; do
68     any=nil
69     for i in "$tmp"/*; do
70       if [ -f "$i/dest" ]; then
71         read dest <"$i/dest"; any=t
72         mv "$i/dest" "$i/dest.seen"
73         (info "copy $i/iso -> $dest"
74          case $dest in
75            */*) dir=${dest%/*} ;;
76            *) dir= ;;
77          esac
78          archrun mkdir -p "$archpath${dir:+/$dir}"
79          run rsync -svP --inplace --bwlimit 728k "$i/iso" "$archive/$dest"
80          run rm -rf "$i") || :
81       fi
82     done
83     case $any in nil) break ;; esac
84   done
85   info "all done"
86 }
87
88 try_kick_daemon () {
89   sig=$1
90
91   if [ -f "$tmp/upload.pid" ]; then
92     daemon=$(cat "$tmp/upload.pid")
93     case $daemon in
94       "" | *[!0-9]*) ;;
95       *) if kill -$sig $daemon >/dev/null 2>&1; then return 0; fi ;;
96     esac
97   fi
98   return 1
99 }
100
101 try_kill () {
102   victim=$1
103
104   case $victim in
105     nil) ;;
106     *) kill $victim >/dev/null 2>&1 || : ;;
107   esac
108 }
109
110 case $kill,$listen in
111   t,t)
112     fail "inconsistent options \`-k' and \`-l'"
113     ;;
114   t,nil)
115     if ! try_kick_daemon TERM; then fail "failed to kill listener"; fi
116     ;;
117   nil,t)
118     if try_kick_daemon 0; then fail "daemon already running (pid $daemon)"; fi
119     trap 'try_kill $sleepy; rm -f "$tmp/upload.pid"' EXIT
120     trap 'info "quitting on user request"; exit 0' INT TERM
121     trap 'try_kill $sleepy' HUP
122     echo $$ >"$tmp/upload.pid.new"
123     mv "$tmp/upload.pid.new" "$tmp/upload.pid"
124     while :; do
125       sleep 3600& sleepy=$!
126       check
127       wait $sleepy || :; sleepy=nil
128     done
129     ;;
130   nil,nil)
131     if ! try_kick_daemon HUP; then check; fi
132     ;;
133 esac