3dc10539414c10ee76af78635e3286b447a7e137
[dvdrip] / dvdrip
1 #! /bin/bash -e
2
3 prog=${0##*/}
4 dev=${DVDRIP_DEVICE-/dev/dvd}
5 tmp=${DVDRIP_TMPDIR-${HOME?}/tmp/dvdrip}
6 archive=${DVDRIP_ARCHIVE-jem.distorted.org.uk:/mnt/dvd/archive}
7 : ${DVD_SECTOR_COPY=dvd-sector-copy}
8 : ${DVDRIP_UPLOAD=dvdrip-upload}
9 backup=nil eject=nil force=nil retry=nil verbose=nil bogus=nil
10 usage () {
11 cat <<EOF
12 usage: $prog [-efrv] [-D DEV] [-a ARCH] [-t TMP] TITLE
13 EOF
14 }
15 while getopts "hD:a:efrt:v" opt; do
16 case $opt in
17 h) usage; exit 0 ;;
18 D) dev=$OPTARG ;;
19 a) archive=$OPTARG ;;
20 e) eject=t ;;
21 f) force=t ;;
22 r) retry=t ;;
23 t) tmp=$OPTARG ;;
24 v) verbose=t ;;
25 *) bogus=t ;;
26 esac
27 done
28 shift $(( $OPTIND - 1 ))
29 case $# in 1) title=$1 ;; *) bogus=t ;; esac
30 case $bogus in t) usage >&2; exit 2 ;; esac
31 case $verbose in t) set -x ;; esac
32 case $archive in
33 *:*) archhost=${archive%%:*} archpath=${archive#*:} ;;
34 *) unset archhost; archpath=$archive ;;
35 esac
36
37 notify () {
38 colour=$1 message=$2
39 echo "$(tput bold; tput setaf $colour)$message$(tput sgr0; tput op)"
40 }
41 fail () { notify 1 "!!! $*"; exit 2; }
42 warn () { notify 5 "??? $*"; }
43 info () { notify 6 "--- $*"; }
44 run_setrc () {
45 notify 2 "+++ $*";
46 set +e; nice "$@"; rc=$?; set -e
47 }
48 run () { run_setrc "$@"; case $rc in 0) ;; *) fail "$1: exit $rc" ;; esac; }
49
50 archdo () {
51 op=$1; shift
52 case ${archhost+t} in
53 t)
54 qq=
55 for a in "$@"; do
56 qq="${qq:+$qq }'${a//\'/"'\\''"}'" #" # emacs is confused
57 done
58 "$op" ssh "$archhost" "$qq"
59 ;;
60 *)
61 "$op" "$@"
62 ;;
63 esac
64 }
65 archrun () { archdo run "$@"; }
66
67 tag=${title//\//_}
68
69 archdo run_setrc test -f "$archpath/$title.iso"
70 case $rc,$force in
71 0,nil) fail "output file already exists" ;;
72 0,t) warn "output file already exists; will overwrite" ;;
73 esac
74
75 accumulate_badblocks () {
76 if [ -f "$tmp/$tag/badblocks.new" ]; then
77 if [ ! -f "$tmp/$tag/badblocks" ]; then
78 { echo "## bad-blocks region map"; echo; } >"$tmp/$tag/badblocks"
79 fi
80 sed -n "/^[^#]/p" "$tmp/$tag/badblocks.new" >>"$tmp/$tag/badblocks"
81 rm "$tmp/$tag/badblocks.new"
82 fi
83 }
84
85 set --
86 mkdir -p "$tmp/$tag"
87 any=nil
88 for i in "$tmp/$tag/dest.new" "$tmp/$tag/dest" "$tmp/$tag/dest.seen"; do
89 if [ -f "$tmp/$tag/dest.new" ]; then any=t; fi
90 done
91 case $any in
92 nil) printf "%s\n" "$title.iso" >"$tmp/$tag/dest.new" ;;
93 esac
94
95 accumulate_badblocks
96 case $retry in
97 t)
98 if [ -f "$tmp/$tag/badblocks.retry" ]; then
99 :
100 elif [ -f "$tmp/$tag/badblocks" ]; then
101 run mv "$tmp/$tag/badblocks" "$tmp/$tag/badblocks.retry"
102 else
103 fail "no blocks to retry"
104 fi
105 set -- "$@" -R"$tmp/$tag/badblocks.retry"
106 if [ -f "$tmp/$tag/iso" ]; then
107 mv "$tmp/$tag/iso" "$tmp/$tag/iso.new"
108 fi
109 ;;
110 esac
111 if [ ! -f "$tmp/$tag/iso" ]; then
112 run "$DVD_SECTOR_COPY" -cs -b"$tmp/$tag/badblocks.new" "$@" \
113 "$dev" "$tmp/$tag/iso.new"
114 run mv "$tmp/$tag/iso.new" "$tmp/$tag/iso"
115 accumulate_badblocks
116 case $retry in t) rm -f "$tmp/$tag/badblocks.retry" ;; esac
117 if [ -f "$tmp/$tag/badblocks" ]; then
118 fail "bad sectors found: check \`$tmp/$tag/iso', run again if ok"
119 fi
120 fi
121
122 run mv "$tmp/$tag/dest.new" "$tmp/$tag/dest"
123 run "$DVDRIP_UPLOAD"
124 case $eject in t) run eject "$dev" ;; esac
125 printf "\a"