From 39eec43ebb1367dffbc6911846dbcb7e673891db Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sun, 6 Mar 2022 01:11:00 +0000 Subject: [PATCH] New programs for dealing with VOBs ripped without being decrypted. When my drives were configured with the wrong region, `libdvdcss' would have to crack the keys the hard way, and it sometimes failed. I mostly shrugged my shoulders, but now I've fixed this problem, I thought I'd track down the miscopied VOBs and make some tools for fixing the problem. --- .gitignore | 1 + Makefile | 6 ++++ dvd-check-keys.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++ dvdrip-check-batch | 33 +++++++++++++++++++ dvdrip-retry-botched-vobs | 27 ++++++++++++++++ 5 files changed, 148 insertions(+) create mode 100644 dvd-check-keys.c create mode 100755 dvdrip-check-batch create mode 100755 dvdrip-retry-botched-vobs diff --git a/.gitignore b/.gitignore index de68a31..86f1d2f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ *.o /dvd-cache-keys +/dvd-check-keys /dvd-id /dvd-sector-copy diff --git a/Makefile b/Makefile index eecede2..f858660 100644 --- a/Makefile +++ b/Makefile @@ -45,9 +45,15 @@ dvd-cache-keys_SRCS = dvd-cache-keys.c lib.c multiprogress.c PROGS += dvd-id dvd-id_SRCS = dvd-id.c lib.c multiprogress.c +PROGS += dvd-check-keys +dvd-check-keys_SRCS = dvd-check-keys.c lib.c multiprogress.c +dvd-check-keys_LIBS = -ldvdcss + SCRIPTS += dvdrip SCRIPTS += dvdrip-upload SCRIPTS += dvdrip-monitor +SCRIPTS += dvdrip-check-batch +SCRIPTS += dvdrip-retry-botched-vobs %.o: %.c $(call v-tag,CC)$(CC) -c $(CFLAGS) -o$@ -MD -MF $*.dep $< diff --git a/dvd-check-keys.c b/dvd-check-keys.c new file mode 100644 index 0000000..9aecc49 --- /dev/null +++ b/dvd-check-keys.c @@ -0,0 +1,81 @@ +#include "lib.h" +#include "dvdcss/dvdcss.h" + +static void usage(FILE *fp) + { fprintf(fp, "usage: %s [-b BADFILE] DEVICE\n", prog); } + +static dvd_reader_t *dvd; +static dvdcss_t css; + +static FILE *badfp; +static const char *badfile; + +static int check_vob(unsigned index, unsigned titlep) +{ + secaddr start, end, pos, len; + char fn[MAXFNSZ], fn2[MAXFNSZ]; + unsigned j; + int rc = 0; + + store_filename(fn, mkident(VOB, index, titlep)); + start = UDFFindFile(dvd, fn, &len); + if (!start) return (0); + end = start + SECTORS(len); + + if (dvdcss_seek(css, start, DVDCSS_SEEK_KEY) < 0) { + if (titlep) + for (j = 2; j < 10; j++) { + store_filename(fn2, mkident(VOB, index, j)); + pos = UDFFindFile(dvd, fn2, &len); + if (!pos) break; + assert(pos == end); + end += SECTORS(len); + } + open_file_on_demand(badfile, &badfp, "uncracked video objects"); + fprintf(badfp, "%"PRIuSEC" %"PRIuSEC" # %s\n", start, end, fn); + rc = -1; + } + + return (rc); +} + +int main(int argc, char *argv[]) +{ + int opt, rc = 0; + unsigned j, f = 0; +#define f_bogus 1u + + set_prog(argv[0]); + for (;;) { + opt = getopt(argc, argv, "hb:"); if (opt < 0) break; + switch (opt) { + case 'h': usage(stderr); exit(0); + case 'b': badfile = optarg; break; + default: f |= f_bogus; break; + } + } + if (argc - optind != 1) f |= f_bogus; + if (f&f_bogus) { usage(stderr); exit(2); } + + if (!badfile) badfp = stdout; + + setlocale(LC_ALL, ""); + progress_init(&progress); + + open_dvd(argv[optind], 0, &dvd); + css = dvdcss_open(argv[optind]); + if (!css) + bail_syserr(errno, "failed to attach CSS machinery to `%s'", + argv[optind]); + + for (j = 0; j < 100; j++) { + if (check_vob(j, 0)) rc = 1; + if (j && check_vob(j, 1)) rc = 1; + } + + dvdcss_close(css); + DVDClose(dvd); + progress_free(&progress); + carefully_fclose(badfp, "uncracked objects file"); + return (rc); +} diff --git a/dvdrip-check-batch b/dvdrip-check-batch new file mode 100755 index 0000000..f0f8d37 --- /dev/null +++ b/dvdrip-check-batch @@ -0,0 +1,33 @@ +#! /bin/bash -e + +prog=${0##*/} +bogus=nil +usage () { + cat <&2; exit 2 ;; esac + +if [ -t 1 ]; then red=$(tput setaf 1) green=$(tput setaf 2) plain=$(tput op) +else red= green= plain=; fi + +DVDCSS_CACHE=off; export DVDCSS_CACHE +find "$@" -type f -name "*.iso" | sort | while IFS= read -r iso; do + echo -n "check $iso..." + retry=${iso%.iso}.retry + set +e; dvd-check-keys -b"$retry.new" "$iso"; rc=$?; set -e + case $rc in + 0) rm -f "$retry" echo " ${green}ok${plain}" ;; + 1) mv "$retry.new" "$retry"; echo " ${red}FAILED${plain}" ;; + *) echo " ${red}ERROR${plain}"; exit 2 ;; + esac +done diff --git a/dvdrip-retry-botched-vobs b/dvdrip-retry-botched-vobs new file mode 100755 index 0000000..4504aad --- /dev/null +++ b/dvdrip-retry-botched-vobs @@ -0,0 +1,27 @@ +#! /bin/sh -e + +dev=${DVDRIP_DEVICE-/dev/dvd} + +find "$@" -type f -name "*.retry" -print | while IFS= read -r r; do + iso=${r%.retry}.iso + + want_id=$(dvd-id "$iso") + echo "Insert $iso..." + while :; do + id=$(dvd-id "$dev") + case $id in "$want_id") break ;; esac + sleep 2 + done + + for try in 3 2 1 0; do + dvd-sector-copy -R"$r" "$dev" "$iso" + + set +e; DVDCSS_CACHE=off dvd-check-keys -b"$r.new" "$dev"; rc=$?; set -e + case $rc,$try in + 0,*) rm -f "$retry"; break ;; + 1,0) echo "Giving up :-("; mv "$r.new" "$r"; break ;; + 1,*) echo "Still broken! Let's try again..." ;; + *) echo "Failed! :-("; exit 2 ;; + esac + done +done -- 2.11.0