static void usage(FILE *fp)
{
fprintf(fp,
- "usage: %s [-c] [-D DEV] [-R MAP] "
- "[-b OUTMAP] [-o OUTFILE] [-r [START]-[END]]\n",
+ "usage: %s [-c] [-R MAP] [-b OUTMAP] [-r [START]-[END]]\n"
+ "\tDEVICE OUTFILE\n",
prog);
}
static int progresslen = 0;
static void clear_progress_internal(void)
- { while (progresslen) { fputs("\b \b", stdout); progresslen--; } }
+{
+ while (progresslen) { fputs("\b \b", stdout); progresslen--; }
+ putchar('\r');
+}
static void clear_progress(void)
{ clear_progress_internal(); fflush(stdout); }
static void vappend_progress(const char *fmt, va_list ap)
if (ferror(mapfp))
bail_syserr(errno, "error writing bad-sector map file");
}
- if (outfd >= 0 &&
- lseek(outfd, (off_t)(bad_hi - bad_lo)*SECTORSZ, SEEK_CUR) < 0)
+ if (lseek(outfd, (off_t)(bad_hi - bad_lo)*SECTORSZ, SEEK_CUR) < 0)
bail_syserr(errno, "failed to seek past bad sectors");
status = 1;
}
uint64_t volsz;
secaddr pos;
off_t off;
- secaddr start, end;
+ secaddr start, end, last;
const struct event *ev;
- const char *device = "/dev/dvd", *outfile = 0;
+ const char *device, *outfile;
int opt, blksz;
unsigned n;
size_t i;
p = strrchr(argv[0], '/'); prog = p ? p + 1 : argv[0];
for (;;) {
- opt = getopt(argc, argv, "hD:FR:b:co:r:"); if (opt < 0) break;
+ opt = getopt(argc, argv, "hFR:X:b:cr:"); if (opt < 0) break;
switch (opt) {
case 'h': usage(stderr); exit(0);
- case 'D': device = optarg; break;
case 'F': f |= f_fixup; break;
case 'R':
fp = fopen(optarg, "r");
if (!fp)
bail_syserr(errno, "failed to open ranges file `%s'", optarg);
- i = 0;
+ i = 0; last = -1;
for (;;) {
BUF_REWIND(&buf); if (read_line(fp, &buf)) break;
p = buf.p; i++;
(last <= SECLIMIT && start < last))
bail("bad range `%s' at `%s' line %zu", buf.p, optarg, i);
if (start < end) {
- put_event(EV_WRITE, 0, start);
- put_event(EV_STOP, 0, end);
+ if (start == last)
+ eventq.v[eventq.n - 1].pos = end;
+ else {
+ put_event(EV_WRITE, 0, start);
+ put_event(EV_STOP, 0, end);
+ }
+ last = end;
}
}
if (ferror(fp))
mapfile = optarg;
break;
case 'c': f |= f_continue; break;
- case 'o': outfile = optarg; break;
case 'r':
start = 0; end = -1;
if (parse_range(optarg, PRF_HYPHEN, &start, &end))
default: f |= f_bogus; break;
}
}
- if (optind < argc) f |= f_bogus;
+ if (argc - optind != 2) f |= f_bogus;
if (f&f_bogus) { usage(stderr); exit(2); }
+ device = argv[optind]; outfile = argv[optind + 1];
+
dvdfd = open(device, O_RDONLY);
if (dvdfd < 0)
bail_syserr(errno, "failed to open device `%s'", device);
}
if (f&f_continue) {
- if (!outfile) bail("can't continue without output file");
off = lseek(outfd, 0, SEEK_END);
if (off < 0)
bail_syserr(errno, "failed to seek to end of output file `%s'",
break;
case EV_WRITE:
gettimeofday(&last_time, 0); last_pos = pos;
- if (outfd >= 0 &&
- lseek(outfd, (off_t)ev->pos*SECTORSZ, SEEK_SET) < 0)
+ if (lseek(outfd, (off_t)ev->pos*SECTORSZ, SEEK_SET) < 0)
bail_syserr(errno,
"failed to seek to resume position "
"(sector %"PRIuSEC") in output file `%s'",
if (progresslen) putchar('\n');
- if (outfd >= 0 && ftruncate(outfd, (off_t)limit*SECTORSZ) < 0)
+ if (ftruncate(outfd, (off_t)limit*SECTORSZ) < 0)
bail_syserr(errno, "failed to set output file `%s' length", outfile);
if (dvd) DVDClose(dvd);