X-Git-Url: https://git.distorted.org.uk/~mdw/dvdrip/blobdiff_plain/26a29c9768251dca5752c7508416af307c2963b4..a090d4b375305441fff8d6db728b6277a147cfc7:/dvd-sector-copy.c diff --git a/dvd-sector-copy.c b/dvd-sector-copy.c index 36b5425..90efce2 100644 --- a/dvd-sector-copy.c +++ b/dvd-sector-copy.c @@ -356,6 +356,9 @@ static struct timeval last_time; static double wsum, wcount; static struct file *file; +static const char throbber[] = "|<-<|>->"; +static unsigned throbix = 0; + static void report_progress(secaddr pos) { char etastr[32]; @@ -395,8 +398,9 @@ static void report_progress(secaddr pos) if (flags&F_ALLPROGRESS) percent = pos*100.0/limit; else percent = ndone*100.0/nsectors; print_progress - ("copied %.1f%% (%"PRIuSEC" of %"PRIuSEC"; %.1f %sB/s, ETA %s)", - percent, pos, limit, rate, unit, etastr); + ("%c copied %.1f%% (%"PRIuSEC" of %"PRIuSEC"; %.1f %sB/s, ETA %s)", + throbber[throbix], percent, pos, limit, rate, unit, etastr); + throbix++; if (!throbber[throbix]) throbix = 0; if (file && id_kind(file->id) == VOB) { append_progress(" -- %s %d %.1f%%", id_part(file->id) ? "title" : "menu", @@ -413,6 +417,7 @@ static dvd_reader_t *dvd; static int dvdfd = -1, outfd = -1; static dvd_file_t *vob; static const char *mapfile; static FILE *mapfp; +static const char *errfile; static FILE *errfp; struct badblock { secaddr start, end; }; DEFVEC(badblock_v, struct badblock); @@ -479,7 +484,13 @@ static ssize_t read_sectors(secaddr pos, void *buf, secaddr want) } if (n > 0) { done += n; pos += n; p += n*SECTORSZ; want -= n; } - else if (!n || errno != EINTR) break; + else if (!n) break; + else if (errno == EIO && errfile) { + open_file_on_demand(errfile, &errfp, "bad-sector error log"); + fprintf(errfp, "%"PRIuSEC" %"PRIuSEC"\n", pos, pos + 1); + check_write(errfp, "bad-sector error log"); + break; + } else if (errno != EINTR) break; } if (fakeerr && !errno) errno = fakeerr; return (!done && errno ? -1 : done); @@ -505,7 +516,7 @@ static void recovered(secaddr bad_lo, secaddr bad_hi) if (mapfile) { open_file_on_demand(mapfile, &mapfp, "bad-sector region map"); fprintf(mapfp, "%"PRIuSEC" %"PRIuSEC"", bad_lo, bad_hi); - if (file) + if (file && id_kind(file->id) != RAW) fprintf(mapfp, " # %s #%d %"PRIuSEC"..%"PRIuSEC" of %"PRIuSEC" (%.1f%%)", id_part(file->id) ? "title" : "menu", id_title(file->id), @@ -517,7 +528,6 @@ static void recovered(secaddr bad_lo, secaddr bad_hi) } if (lseek(outfd, (off_t)(bad_hi - bad_lo)*SECTORSZ, SEEK_CUR) < 0) bail_syserr(errno, "failed to seek past bad sectors"); - status = 1; } struct recoverybuf { @@ -656,6 +666,7 @@ static ssize_t recovery_read(struct recoverybuf *r, n = r->pos + r->end - pos; if (!n && want) n = -1; + else if (n > want) n = want; end: #ifdef DEBUG @@ -705,6 +716,12 @@ static ssize_t find_good_sector(secaddr *pos_inout, secaddr end, bad_lo = pos; bad_hi = pos + 1; for (;;) { report_bad_blocks_progress(bad_lo, bad_hi, errno); +#ifdef DEBUG + debug_clear_progress(); + printf(";; bounding bad-block region: " + "%"PRIuSEC" ..%"PRIuSEC".. %"PRIuSEC"\n", + bad_lo, bad_hi - bad_lo, bad_hi); +#endif if (bad_hi >= end) { clear_progress(); moan("giving up on this extent"); @@ -715,7 +732,6 @@ static ssize_t find_good_sector(secaddr *pos_inout, secaddr end, want = run_length_wanted(pos, step, sz, end); n = recovery_read(&r, pos, want); #ifdef DEBUG - debug_clear_progress(); printf(";; [bound] try reading %"PRIuSEC" .. %"PRIuSEC" -> %zd\n", pos, pos + want, n); #endif @@ -727,12 +743,17 @@ static ssize_t find_good_sector(secaddr *pos_inout, secaddr end, good = pos; while (good > bad_hi) { report_bad_blocks_progress(bad_lo, bad_hi, errno); +#ifdef DEBUG + debug_clear_progress(); + printf(";; limiting bad-block region: " + "%"PRIuSEC" ..%"PRIuSEC".. %"PRIuSEC" ..%"PRIuSEC".. %"PRIuSEC"\n", + bad_lo, bad_hi - bad_lo, bad_hi, good - bad_hi, good); +#endif pos = bad_hi + (good - bad_hi)/2; step = pos - bad_lo; want = run_length_wanted(pos, step, sz, end); n = recovery_read(&r, pos, want); #ifdef DEBUG - debug_clear_progress(); printf(";; [limit] try reading %"PRIuSEC" .. %"PRIuSEC" -> %zd\n", pos, pos + want, n); #endif @@ -916,7 +937,7 @@ static int parse_range(const char *p, unsigned f, { rc = -1; goto end; } if (!(f&PRF_HYPHEN)) while (ISSPACE(*p)) p++; - if (*p && ((f&PRF_HYPHEN) || *p != '=')) { rc = -1; goto end; } + if (*p && ((f&PRF_HYPHEN) || *p != '#')) { rc = -1; goto end; } rc = 0; end: @@ -953,9 +974,10 @@ int main(int argc, char *argv[]) p = strrchr(argv[0], '/'); prog = p ? p + 1 : argv[0]; for (;;) { - opt = getopt(argc, argv, "hFR:X:b:cr:"); if (opt < 0) break; + opt = getopt(argc, argv, "hE:FR:X:b:cr:"); if (opt < 0) break; switch (opt) { case 'h': usage(stderr); exit(0); + case 'E': errfile = optarg; break; case 'F': f |= f_fixup; break; case 'R': fp = fopen(optarg, "r"); @@ -1205,6 +1227,7 @@ int main(int argc, char *argv[]) if (dvdfd >= 0) close(dvdfd); if (outfd >= 0) close(outfd); carefully_fclose(mapfp, "bad-sector region map"); + carefully_fclose(errfp, "bad-sector error log"); #undef f_bogus #undef f_continue