Merge branch 'master' of git.distorted.org.uk:~mdw/publish/public-git/dvdrip
[dvdrip] / dvdrip
CommitLineData
7fbe0fb9
MW
1#! /bin/bash -e
2
3prog=${0##*/}
4dev=${DVDRIP_DEVICE-/dev/dvd}
5tmp=${DVDRIP_TMPDIR-${HOME?}/tmp/dvdrip}
6archive=${DVDRIP_ARCHIVE-jem.distorted.org.uk:/mnt/dvd/archive}
f49b5c86 7: ${DVD_SECTOR_COPY=dvd-sector-copy}
32c8d775 8: ${DVD_ID=dvd-id}
f49b5c86 9: ${DVDRIP_UPLOAD=dvdrip-upload}
dc53ebfa
MW
10backup=nil ding=nil eject=nil force=nil retry=nil verbose=nil bogus=nil
11unset params
7fbe0fb9
MW
12usage () {
13 cat <<EOF
dc53ebfa 14usage: $prog [-defrv] [-D DEV] [-a ARCH] [-t TMP] TITLE
7fbe0fb9
MW
15EOF
16}
dc53ebfa 17while getopts "hB:D:a:defrt:v" opt; do
7fbe0fb9
MW
18 case $opt in
19 h) usage; exit 0 ;;
dc53ebfa 20 B) params=${params+$params,}$OPTARG ;;
7fbe0fb9
MW
21 D) dev=$OPTARG ;;
22 a) archive=$OPTARG ;;
dc53ebfa 23 d) ding=t ;;
7fbe0fb9
MW
24 e) eject=t ;;
25 f) force=t ;;
192df729 26 r) retry=t ;;
7fbe0fb9
MW
27 t) tmp=$OPTARG ;;
28 v) verbose=t ;;
29 *) bogus=t ;;
30 esac
31done
32shift $(( $OPTIND - 1 ))
822ac8a8 33case $# in 1) title=$1 ;; *) bogus=t ;; esac
7fbe0fb9
MW
34case $bogus in t) usage >&2; exit 2 ;; esac
35case $verbose in t) set -x ;; esac
36case $archive in
37 *:*) archhost=${archive%%:*} archpath=${archive#*:} ;;
38 *) unset archhost; archpath=$archive ;;
39esac
40
41notify () {
42 colour=$1 message=$2
43 echo "$(tput bold; tput setaf $colour)$message$(tput sgr0; tput op)"
44}
45fail () { notify 1 "!!! $*"; exit 2; }
46warn () { notify 5 "??? $*"; }
47info () { notify 6 "--- $*"; }
48run_setrc () {
49 notify 2 "+++ $*";
50 set +e; nice "$@"; rc=$?; set -e
51}
52run () { run_setrc "$@"; case $rc in 0) ;; *) fail "$1: exit $rc" ;; esac; }
53
54archdo () {
55 op=$1; shift
56 case ${archhost+t} in
57 t)
58 qq=
59 for a in "$@"; do
60 qq="${qq:+$qq }'${a//\'/"'\\''"}'" #" # emacs is confused
61 done
62 "$op" ssh "$archhost" "$qq"
63 ;;
64 *)
65 "$op" "$@"
66 ;;
67 esac
68}
69archrun () { archdo run "$@"; }
70
59f1250f 71tag=${title//\//_}
7fbe0fb9 72
59f1250f 73archdo run_setrc test -f "$archpath/$title.iso"
7fbe0fb9
MW
74case $rc,$force in
75 0,nil) fail "output file already exists" ;;
76 0,t) warn "output file already exists; will overwrite" ;;
77esac
78
dc53ebfa
MW
79mkdir -p "$tmp/$tag"
80
e14e3621 81discid=$("$DVD_ID" -I "$dev")
dc53ebfa
MW
82if [ -f "$tmp/$tag/discid" ]; then
83 read oldid <"$tmp/$tag/discid"
84 case $force,$oldid in
85 t,"$discid" | nil,"$discid")
86 ;;
87 nil,*)
88 fail "discid mismatch: expected \`$oldid' but drive has \`$discid'"
89 ;;
90 t,*)
91 warn "discid mismatch: expected \`$oldid' but drive has \`$discid'; continuing anway"
92 ;;
93 esac
94fi
95info "copying \`$discid'"
96echo "$discid" >"$tmp/$tag/discid.new"
97mv "$tmp/$tag/discid.new" "$tmp/$tag/discid"
98
8d83b9f6
MW
99if [ -b "$dev" ]; then msz=$(blockdev --getsize64 "$dev")
100else msz=nil; fi
101
1ef7b954
MW
102echo "$dev" >"$tmp/$tag/device.new"
103mv "$tmp/$tag/device.new" "$tmp/$tag/device"
104
b1a4618a
MW
105accumulate_badblocks () {
106 if [ -f "$tmp/$tag/badblocks.new" ]; then
107 if [ ! -f "$tmp/$tag/badblocks" ]; then
108 { echo "## bad-blocks region map"; echo; } >"$tmp/$tag/badblocks"
109 fi
110 sed -n "/^[^#]/p" "$tmp/$tag/badblocks.new" >>"$tmp/$tag/badblocks"
111 rm "$tmp/$tag/badblocks.new"
112 fi
113}
114
192df729 115set --
861c3824
MW
116any=nil
117for i in "$tmp/$tag/dest.new" "$tmp/$tag/dest" "$tmp/$tag/dest.seen"; do
118 if [ -f "$tmp/$tag/dest.new" ]; then any=t; fi
119done
120case $any in
59f1250f 121 nil) printf "%s\n" "$title.iso" >"$tmp/$tag/dest.new" ;;
861c3824 122esac
dc53ebfa
MW
123case $eject in
124 t) touch "$tmp/$tag/eject" ;;
125 nil) rm -f "$tmp/$tag/eject" ;;
126esac
127case $ding in
128 t) touch "$tmp/$tag/ding" ;;
129 nil) rm -f "$tmp/$tag/ding" ;;
130esac
59f1250f
MW
131
132accumulate_badblocks
133case $retry in
7fbe0fb9 134 t)
59f1250f
MW
135 if [ -f "$tmp/$tag/badblocks.retry" ]; then
136 :
137 elif [ -f "$tmp/$tag/badblocks" ]; then
138 run mv "$tmp/$tag/badblocks" "$tmp/$tag/badblocks.retry"
139 else
140 fail "no blocks to retry"
7fbe0fb9 141 fi
59f1250f
MW
142 set -- "$@" -R"$tmp/$tag/badblocks.retry"
143 if [ -f "$tmp/$tag/iso" ]; then
144 mv "$tmp/$tag/iso" "$tmp/$tag/iso.new"
7fbe0fb9
MW
145 fi
146 ;;
147esac
59f1250f 148if [ ! -f "$tmp/$tag/iso" ]; then
dc53ebfa
MW
149 run "$DVD_SECTOR_COPY" -cs ${params+"-B$params"} \
150 -b"$tmp/$tag/badblocks.new" "$@" "$dev" "$tmp/$tag/iso.new"
59f1250f
MW
151 run mv "$tmp/$tag/iso.new" "$tmp/$tag/iso"
152 accumulate_badblocks
1ef7b954 153 rm -f "$tmp/$tag/device"
59f1250f
MW
154 case $retry in t) rm -f "$tmp/$tag/badblocks.retry" ;; esac
155 if [ -f "$tmp/$tag/badblocks" ]; then
156 fail "bad sectors found: check \`$tmp/$tag/iso', run again if ok"
157 fi
8d83b9f6
MW
158 case $msz in
159 nil) ;;
160 *)
161 newmsz=$(blockdev --getsize64 "$dev")
162 case $newmsz in
163 $msz) ;;
164 *) fail "medium size changed ($msz -> $newmsz): try again" ;;
165 esac
166 ;;
167 esac
59f1250f
MW
168fi
169
1ef7b954 170rm -f "$tmp/$tag/device"
192df729 171run mv "$tmp/$tag/dest.new" "$tmp/$tag/dest"
dc53ebfa
MW
172if [ -f "$tmp/$tag/eject" ]; then eject=t; else eject=nil; fi
173if [ -f "$tmp/$tag/ding" ]; then ding=t; else ding=nil; fi
7fbe0fb9
MW
174run "$DVDRIP_UPLOAD"
175case $eject in t) run eject "$dev" ;; esac
dc53ebfa
MW
176case $ding in
177 t)
178 if [ -t 1 ]; then exec 3>&1
179 elif [ -t 2 ]; then exec 3>&2
180 else exec 3>/dev/tty
181 fi
182 printf "\a" >&3
183 exec 3>&-
184 ;;
185esac