--- /dev/null
+#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);
+}
--- /dev/null
+#! /bin/bash -e
+
+prog=${0##*/}
+bogus=nil
+usage () {
+ cat <<EOF
+usage: $prog DIR ...
+EOF
+}
+while getopts "h" opt; do
+ case $opt in
+ h) usage; exit 0 ;;
+ *) bogus=t ;;
+ esac
+done
+shift $(( $OPTIND - 1 ))
+case $# in 0) bogus=t ;; esac
+case $bogus in t) usage >&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
--- /dev/null
+#! /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