#! /bin/bash -e prog=${0##*/} dev=${DVDRIP_DEVICE-/dev/dvd} tmp=${DVDRIP_TMPDIR-${HOME?}/tmp/dvdrip} archive=${DVDRIP_ARCHIVE-jem.distorted.org.uk:/mnt/dvd/archive} : ${DVD_SECTOR_COPY=dvd-sector-copy} : ${DVD_ID=dvd-id} : ${DVDRIP_UPLOAD=dvdrip-upload} backup=nil ding=nil eject=nil force=nil retry=nil verbose=nil bogus=nil unset params usage () { cat <&2; exit 2 ;; esac case $verbose in t) set -x ;; esac case $archive in *:*) archhost=${archive%%:*} archpath=${archive#*:} ;; *) unset archhost; archpath=$archive ;; esac notify () { colour=$1 message=$2 echo "$(tput bold; tput setaf $colour)$message$(tput sgr0; tput op)" } fail () { notify 1 "!!! $*"; exit 2; } warn () { notify 5 "??? $*"; } info () { notify 6 "--- $*"; } run_setrc () { notify 2 "+++ $*"; set +e; nice "$@"; rc=$?; set -e } run () { run_setrc "$@"; case $rc in 0) ;; *) fail "$1: exit $rc" ;; esac; } archdo () { op=$1; shift case ${archhost+t} in t) qq= for a in "$@"; do qq="${qq:+$qq }'${a//\'/"'\\''"}'" #" # emacs is confused done "$op" ssh "$archhost" "$qq" ;; *) "$op" "$@" ;; esac } archrun () { archdo run "$@"; } tag=${title//\//_} archdo run_setrc test -f "$archpath/$title.iso" case $rc,$force in 0,nil) fail "output file already exists" ;; 0,t) warn "output file already exists; will overwrite" ;; esac mkdir -p "$tmp/$tag" discid=$("$DVD_ID" -I "$dev") if [ -f "$tmp/$tag/discid" ]; then read oldid <"$tmp/$tag/discid" case $force,$oldid in t,"$discid" | nil,"$discid") ;; nil,*) fail "discid mismatch: expected \`$oldid' but drive has \`$discid'" ;; t,*) warn "discid mismatch: expected \`$oldid' but drive has \`$discid'; continuing anway" ;; esac fi info "copying \`$discid'" echo "$discid" >"$tmp/$tag/discid.new" mv "$tmp/$tag/discid.new" "$tmp/$tag/discid" if [ -b "$dev" ]; then msz=$(blockdev --getsize64 "$dev") else msz=nil; fi echo "$dev" >"$tmp/$tag/device.new" mv "$tmp/$tag/device.new" "$tmp/$tag/device" accumulate_badblocks () { if [ -f "$tmp/$tag/badblocks.new" ]; then if [ ! -f "$tmp/$tag/badblocks" ]; then { echo "## bad-blocks region map"; echo; } >"$tmp/$tag/badblocks" fi sed -n "/^[^#]/p" "$tmp/$tag/badblocks.new" >>"$tmp/$tag/badblocks" rm "$tmp/$tag/badblocks.new" fi } set -- any=nil for i in "$tmp/$tag/dest.new" "$tmp/$tag/dest" "$tmp/$tag/dest.seen"; do if [ -f "$tmp/$tag/dest.new" ]; then any=t; fi done case $any in nil) printf "%s\n" "$title.iso" >"$tmp/$tag/dest.new" ;; esac case $eject in t) touch "$tmp/$tag/eject" ;; nil) rm -f "$tmp/$tag/eject" ;; esac case $ding in t) touch "$tmp/$tag/ding" ;; nil) rm -f "$tmp/$tag/ding" ;; esac accumulate_badblocks case $retry in t) if [ -f "$tmp/$tag/badblocks.retry" ]; then : elif [ -f "$tmp/$tag/badblocks" ]; then run mv "$tmp/$tag/badblocks" "$tmp/$tag/badblocks.retry" else fail "no blocks to retry" fi set -- "$@" -R"$tmp/$tag/badblocks.retry" if [ -f "$tmp/$tag/iso" ]; then mv "$tmp/$tag/iso" "$tmp/$tag/iso.new" fi ;; esac if [ ! -f "$tmp/$tag/iso" ]; then run "$DVD_SECTOR_COPY" -cs ${params+"-B$params"} \ -b"$tmp/$tag/badblocks.new" "$@" "$dev" "$tmp/$tag/iso.new" run mv "$tmp/$tag/iso.new" "$tmp/$tag/iso" accumulate_badblocks rm -f "$tmp/$tag/device" case $retry in t) rm -f "$tmp/$tag/badblocks.retry" ;; esac if [ -f "$tmp/$tag/badblocks" ]; then fail "bad sectors found: check \`$tmp/$tag/iso', run again if ok" fi case $msz in nil) ;; *) newmsz=$(blockdev --getsize64 "$dev") case $newmsz in $msz) ;; *) fail "medium size changed ($msz -> $newmsz): try again" ;; esac ;; esac fi rm -f "$tmp/$tag/device" run mv "$tmp/$tag/dest.new" "$tmp/$tag/dest" if [ -f "$tmp/$tag/eject" ]; then eject=t; else eject=nil; fi if [ -f "$tmp/$tag/ding" ]; then ding=t; else ding=nil; fi run "$DVDRIP_UPLOAD" case $eject in t) run eject "$dev" ;; esac case $ding in t) if [ -t 1 ]; then exec 3>&1 elif [ -t 2 ]; then exec 3>&2 else exec 3>/dev/tty fi printf "\a" >&3 exec 3>&- ;; esac