chkdvdimg.c: Retrieve device size using the new function.
[dvdrip] / dvd-sector-copy.c
index ea34461..cdd2849 100644 (file)
@@ -3,7 +3,7 @@
 static void usage(FILE *fp)
 {
   fprintf(fp,
-         "usage: %s [-c] [-B PARAM=VALUE,...] [-R MAP]\n"
+         "usage: %s [-ci] [-B PARAM=VALUE,...] [-R MAP]\n"
          "\t[-b OUTMAP] [-r [START]-[END]] DEVICE OUTFILE\n",
          prog);
 }
@@ -940,7 +940,7 @@ int main(int argc, char *argv[])
 {
   unsigned f = 0;
   const char *p;
-  uint64_t volsz;
+  off_t volsz;
   secaddr pos;
   off_t off;
   secaddr start, end, last;
@@ -955,8 +955,8 @@ int main(int argc, char *argv[])
   struct timeval tv0, tv1;
   double t, rate, tot;
   const char *rateunit, *totunit;
-  char timebuf[TIMESTRMAX];
-  struct stat st;
+  char timebuf[TIMESTRMAX], id_in[MAXIDSZ], id_out[MAXIDSZ];
+  dvd_reader_t *dvd_out;
 #ifdef DEBUG
   const struct file *file;
   char fn[MAXFNSZ];
@@ -966,11 +966,12 @@ int main(int argc, char *argv[])
 #define f_continue 2u
 #define f_fixup 4u
 #define f_stats 8u
+#define f_checkid 16u
 #define f_write 256u
 
   set_prog(argv[0]);
   for (;;) {
-    opt = getopt(argc, argv, "hB:E:FR:X:b:cr:s"); if (opt < 0) break;
+    opt = getopt(argc, argv, "hB:E:FR:X:b:cir:s"); if (opt < 0) break;
     switch (opt) {
       case 'h': usage(stderr); exit(0);
       case 'B':
@@ -1090,25 +1091,24 @@ int main(int argc, char *argv[])
   }
 
   open_dvd(device, &dvdfd, &dvd);
-  if (fstat(dvdfd, &st))
-    bail_syserr(errno, "failed to stat device `%s'", device);
-  if (S_ISREG(st.st_mode)) {
-    blksz = SECTORSZ;
-    volsz = st.st_size;
-  } else if (S_ISBLK(st.st_mode)) {
-    if (ioctl(dvdfd, BLKSSZGET, &blksz))
-      bail_syserr(errno, "failed to get block size for `%s'", device);
-    if (ioctl(dvdfd, BLKGETSIZE64, &volsz))
-      bail_syserr(errno, "failed to get volume size for `%s'", device);
-  } else
-    bail("can't use `%s' as source: expected file or block device", device);
 
+  blksz = SECTORSZ; volsz = device_size(dvdfd, device, &blksz);
   if (blksz != SECTORSZ)
     bail("device `%s' block size %d /= %d", device, blksz, SECTORSZ);
   if (volsz%SECTORSZ)
     bail("device `%s' volume size %"PRIu64" not a multiple of %d",
         device, volsz, SECTORSZ);
 
+  if (f&f_checkid) {
+    open_dvd(outfile, 0, &dvd_out);
+    if (dvd_id(id_in, dvd, DIF_MUSTIFOHASH, device) ||
+       dvd_id(id_out, dvd_out, DIF_MUSTIFOHASH, device))
+      exit(2);
+    if (STRCMP(id_in, !=, id_out))
+      bail("DVD id mismatch: input `%s' is `%s'; output `%s' is `%s'",
+          device, id_in, outfile, id_out);
+  }
+
   outfd = open(outfile, O_WRONLY | O_CREAT, 0666);
   if (outfd < 0)
     bail_syserr(errno, "failed to create output file `%s'", outfile);