From 8cec8b64393b3b9055a4d2ab9ca282d92e890d93 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Fri, 8 Apr 2022 17:10:21 +0100 Subject: [PATCH] @@@ dvd-sector-copy.c: Rearrange into a more logical order. --- dvd-sector-copy.c | 265 +++++++++++++++++++++++++++--------------------------- 1 file changed, 132 insertions(+), 133 deletions(-) diff --git a/dvd-sector-copy.c b/dvd-sector-copy.c index 8c4ba1f..a303239 100644 --- a/dvd-sector-copy.c +++ b/dvd-sector-copy.c @@ -8,6 +8,49 @@ static void usage(FILE *fp) prog); } +#define PRF_HYPHEN 1u +static int parse_range(const char *p, unsigned f, + secaddr *start_out, secaddr *end_out) +{ + char *q; + int err, rc; + unsigned long start, end; + + err = errno; + + if (ISDIGIT(*p)) { + start = strtoul(p, &q, 0); + if (errno || start >= SECLIMIT) { rc = -1; goto end; } + *start_out = start; p = q; + } else if (!(f&PRF_HYPHEN)) + { rc = -1; goto end; } + else + start = 0; + + if (f&PRF_HYPHEN) { + if (*p != '-') { rc = -1; goto end; } + p++; + } else { + if (!ISSPACE(*p)) { rc = -1; goto end; } + do p++; while (ISSPACE(*p)); + } + + if (ISDIGIT(*p)) { + end = strtoul(p, &q, 0); + if (errno || end > SECLIMIT || end < start) { rc = -1; goto end; } + *end_out = end; p = q; + } else if (!(f&PRF_HYPHEN)) + { rc = -1; goto end; } + + if (!(f&PRF_HYPHEN)) while (ISSPACE(*p)) p++; + if (*p && ((f&PRF_HYPHEN) || *p != '#')) { rc = -1; goto end; } + + rc = 0; +end: + errno = err; + return (rc); +} + #define MAXFILES (1 + 2*99 + 1) struct file { ident id; @@ -40,6 +83,39 @@ static int compare_event(const void *a, const void *b) return (0); } +#ifdef DEBUG +static void dump_eventq(const char *what) +{ + unsigned i; + const struct event *ev; + char fn[MAXFNSZ]; + + printf("\n;; event dump (%s):\n", what); + for (i = 0; i < eventq.n; i++) { + ev = &eventq.v[i]; + switch (ev->ev) { + case EV_BEGIN: + store_filename(fn, filetab.v[ev->file].id); + printf(";; %8"PRIuSEC": begin %s\n", ev->pos, fn); + break; + case EV_END: + store_filename(fn, filetab.v[ev->file].id); + printf(";; %8"PRIuSEC": end %s\n", ev->pos, fn); + break; + case EV_WRITE: + printf(";; %8"PRIuSEC": write\n", ev->pos); + break; + case EV_STOP: + printf(";; %8"PRIuSEC": stop\n", ev->pos); + break; + default: + printf(";; %8"PRIuSEC": ?%u\n", ev->pos, ev->ev); + break; + } + } +} +#endif + typedef uint_least32_t bits; static bits live[(MAXFILES + 31)/32]; @@ -136,17 +212,30 @@ static void put_title(dvd_reader_t *dvd, unsigned title) start[0], start[npart - 1] + SECTORS(len[npart - 1])); } -static secaddr last_pos, limit, nsectors, ndone; -static struct timeval last_time; -static double wsum, wcount; +static dvd_reader_t *dvd; +static int dvdfd = -1, outfd = -1; static struct file *file; +static dvd_file_t *vob; +static const char *mapfile; static FILE *mapfp; +static const char *errfile; static FILE *errfp; +static secaddr limit; static secaddr bad_start; static unsigned retry, max_retries = 4; + +static secaddr nsectors, ndone; +static secaddr last_pos; +static struct timeval last_time; +static double alpha = 0.1; +static double wsum, wcount; static int bad_err; static const char throbber[] = "|<-<|>->"; static unsigned throbix = 0; +static struct progress_item + copy_progress, disc_progress, + file_progress, badblock_progress; + static double scale_bytes(double n, const char **unit_out) { const char *unit = ""; @@ -155,14 +244,9 @@ static double scale_bytes(double n, const char **unit_out) if (n > 1600) { n /= 1024; unit = "M"; } if (n > 1600) { n /= 1024; unit = "G"; } if (n > 1600) { n /= 1024; unit = "T"; } - *unit_out = unit; return (n); } -static struct progress_item - copy_progress, disc_progress, - file_progress, badblock_progress; - #define TIMESTRMAX 16 static char *fmttime(unsigned long t, char *buf) { @@ -246,8 +330,6 @@ static void render_badblock_progress(struct progress_item *item, progress_shownotice(render, bg, 7); } -static double alpha = 0.1; - static void update_progress(secaddr pos) { struct timeval now; @@ -274,12 +356,6 @@ static void update_progress(secaddr pos) static void report_progress(secaddr pos) { update_progress(pos); progress_update(&progress); } -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); static badblock_v badblocks = VEC_INIT; @@ -365,45 +441,6 @@ static ssize_t read_sectors(secaddr pos, void *buf, secaddr want) return (!done && errno ? -1 : done); } -static void recovered(secaddr bad_lo, secaddr bad_hi) -{ - char fn[MAXFNSZ]; - - progress_clear(&progress); - - if (!file || id_kind(file->id) == RAW) - moan("skipping %"PRIuSEC" bad sectors (%"PRIuSEC" .. %"PRIuSEC")", - bad_hi - bad_lo, bad_lo, bad_hi); - else { - store_filename(fn, file->id); - moan("skipping %"PRIuSEC" bad sectors (%"PRIuSEC" .. %"PRIuSEC"; " - "`%s' %"PRIuSEC" .. %"PRIuSEC" of %"PRIuSEC")", - bad_hi - bad_lo, bad_lo, bad_hi, - fn, bad_lo - file->start, bad_hi - file->start, - file->end - file->start); - } - - if (mapfile) { - open_file_on_demand(mapfile, &mapfp, "bad-sector region map"); - fprintf(mapfp, "%"PRIuSEC" %"PRIuSEC" # %"PRIuSEC" sectors", - bad_lo, bad_hi, bad_hi - bad_lo); - - if (file && id_kind(file->id) != RAW) - fprintf(mapfp, "; `%s' %"PRIuSEC" .. %"PRIuSEC" of %"PRIuSEC"", - fn, bad_lo - file->start, bad_hi - file->start, - file->end - file->start); - - fputc('\n', mapfp); - check_write(mapfp, "bad-sector region map"); - } - - if (lseek(outfd, (off_t)(bad_hi - bad_lo)*SECTORSZ, SEEK_CUR) < 0) - bail_syserr(errno, "failed to seek past bad sectors"); - - progress_removeitem(&progress, &badblock_progress); - progress_update(&progress); -} - struct recoverybuf { unsigned char *buf; secaddr sz, pos, start, end; @@ -413,8 +450,7 @@ struct recoverybuf { static void rearrange_sectors(struct recoverybuf *r, secaddr dest, secaddr src, secaddr len) { - assert(dest + len <= r->sz); - assert(src + len <= r->sz); + assert(dest + len <= r->sz); assert(src + len <= r->sz); memmove(r->buf + dest*SECTORSZ, r->buf + src*SECTORSZ, len*SECTORSZ); } @@ -604,6 +640,45 @@ static secaddr clear_min = 1, clear_max = SECLIMIT; static double step_factor = 2.0; static secaddr step_min = 1, step_max = 0; +static void recovered(secaddr bad_lo, secaddr bad_hi) +{ + char fn[MAXFNSZ]; + + progress_clear(&progress); + + if (!file || id_kind(file->id) == RAW) + moan("skipping %"PRIuSEC" bad sectors (%"PRIuSEC" .. %"PRIuSEC")", + bad_hi - bad_lo, bad_lo, bad_hi); + else { + store_filename(fn, file->id); + moan("skipping %"PRIuSEC" bad sectors (%"PRIuSEC" .. %"PRIuSEC"; " + "`%s' %"PRIuSEC" .. %"PRIuSEC" of %"PRIuSEC")", + bad_hi - bad_lo, bad_lo, bad_hi, + fn, bad_lo - file->start, bad_hi - file->start, + file->end - file->start); + } + + if (mapfile) { + open_file_on_demand(mapfile, &mapfp, "bad-sector region map"); + fprintf(mapfp, "%"PRIuSEC" %"PRIuSEC" # %"PRIuSEC" sectors", + bad_lo, bad_hi, bad_hi - bad_lo); + + if (file && id_kind(file->id) != RAW) + fprintf(mapfp, "; `%s' %"PRIuSEC" .. %"PRIuSEC" of %"PRIuSEC"", + fn, bad_lo - file->start, bad_hi - file->start, + file->end - file->start); + + fputc('\n', mapfp); + check_write(mapfp, "bad-sector region map"); + } + + if (lseek(outfd, (off_t)(bad_hi - bad_lo)*SECTORSZ, SEEK_CUR) < 0) + bail_syserr(errno, "failed to seek past bad sectors"); + + progress_removeitem(&progress, &badblock_progress); + progress_update(&progress); +} + static secaddr run_length_wanted(secaddr pos, secaddr badlen, secaddr end) { secaddr want; @@ -798,82 +873,6 @@ static void emit(secaddr start, secaddr end) #undef BUFSECTORS } -#define PRF_HYPHEN 1u -static int parse_range(const char *p, unsigned f, - secaddr *start_out, secaddr *end_out) -{ - char *q; - int err, rc; - unsigned long start, end; - - err = errno; - - if (ISDIGIT(*p)) { - start = strtoul(p, &q, 0); - if (errno || start >= SECLIMIT) { rc = -1; goto end; } - *start_out = start; p = q; - } else if (!(f&PRF_HYPHEN)) - { rc = -1; goto end; } - else - start = 0; - - if (f&PRF_HYPHEN) { - if (*p != '-') { rc = -1; goto end; } - p++; - } else { - if (!ISSPACE(*p)) { rc = -1; goto end; } - do p++; while (ISSPACE(*p)); - } - - if (ISDIGIT(*p)) { - end = strtoul(p, &q, 0); - if (errno || end > SECLIMIT || end < start) { rc = -1; goto end; } - *end_out = end; p = q; - } else if (!(f&PRF_HYPHEN)) - { rc = -1; goto end; } - - if (!(f&PRF_HYPHEN)) while (ISSPACE(*p)) p++; - if (*p && ((f&PRF_HYPHEN) || *p != '#')) { rc = -1; goto end; } - - rc = 0; -end: - errno = err; - return (rc); -} - -#ifdef DEBUG -static void dump_eventq(const char *what) -{ - unsigned i; - const struct event *ev; - char fn[MAXFNSZ]; - - printf("\n;; event dump (%s):\n", what); - for (i = 0; i < eventq.n; i++) { - ev = &eventq.v[i]; - switch (ev->ev) { - case EV_BEGIN: - store_filename(fn, filetab.v[ev->file].id); - printf(";; %8"PRIuSEC": begin %s\n", ev->pos, fn); - break; - case EV_END: - store_filename(fn, filetab.v[ev->file].id); - printf(";; %8"PRIuSEC": end %s\n", ev->pos, fn); - break; - case EV_WRITE: - printf(";; %8"PRIuSEC": write\n", ev->pos); - break; - case EV_STOP: - printf(";; %8"PRIuSEC": stop\n", ev->pos); - break; - default: - printf(";; %8"PRIuSEC": ?%u\n", ev->pos, ev->ev); - break; - } - } -} -#endif - int main(int argc, char *argv[]) { unsigned f = 0; -- 2.11.0