From: Mark Wooding Date: Sun, 6 Mar 2022 17:32:51 +0000 (+0000) Subject: dvd-id.c, lib.[ch]: Improve DVD ID computation. X-Git-Url: https://git.distorted.org.uk/~mdw/dvdrip/commitdiff_plain/9b86c33fd71be1d0310c6e32e12b8fb16c55f690 dvd-id.c, lib.[ch]: Improve DVD ID computation. Move the code to the library. Accept flags (to the library function and the utility) to fail if portions of the ID can't be determined. Also, improve `dvd-id' to print IDs for multiple disc images. --- diff --git a/dvd-id.c b/dvd-id.c index 971be05..e89945a 100644 --- a/dvd-id.c +++ b/dvd-id.c @@ -1,54 +1,42 @@ #include "lib.h" -static void usage(FILE *fp) { fprintf(fp, "usage: %s DEVICE\n", prog); } - -static void puthex(const unsigned char *p, size_t sz, FILE *fp) - { while (sz) { fprintf(fp, "%02x", *p++); sz--; } } +static void usage(FILE *fp) + { fprintf(fp, "usage: %s [-IV] DEVICE ...\n", prog); } int main(int argc, char *argv[]) { - char volid[33]; - unsigned char volsetid[16], discid[16]; - int rc, opt; - unsigned f = 0; + char id[MAXIDSZ]; + int i, opt, st = 0; + unsigned f = 0, dif = 0; static dvd_reader_t *dvd; #define f_bogus 1u set_prog(argv[0]); for (;;) { - opt = getopt(argc, argv, "h"); if (opt < 0) break; + opt = getopt(argc, argv, "hIV"); if (opt < 0) break; switch (opt) { case 'h': usage(stderr); exit(0); + case 'I': dif |= DIF_MUSTIFOHASH; break; + case 'V': dif |= DIF_MUSTVOLINF; break; default: f |= f_bogus; break; } } - if (argc - optind != 1) f |= f_bogus; + if (argc - optind < 1) f |= f_bogus; if (f&f_bogus) { usage(stderr); exit(2); } setlocale(LC_ALL, ""); progress_init(&progress); - open_dvd(argv[optind], 0, &dvd); - - rc = DVDUDFVolumeInfo(dvd, - volid, sizeof(volid), - volsetid, sizeof(volsetid)); - if (rc) { - moan("failed to read volume info"); - strcpy(volid, ""); - memset(volsetid, 0xff, sizeof(volsetid)); - } - - rc = DVDDiscID(dvd, discid); - if (rc) { - moan("failed to determine disc id"); - memset(discid, 0xff, sizeof(discid)); + for (i = optind; i < argc; i++) { + open_dvd(argv[i], 0, &dvd); + if (dvd_id(id, dvd, dif, argv[i])) + st = 2; + else { + if (argc - optind > 1) printf("%s: ", argv[i]); + printf("%s\n", id); + } + DVDClose(dvd); } - fputs(volid, stdout); fputc('-', stdout); - puthex(volsetid, sizeof(volsetid), stdout); fputc(':', stdout); - puthex(discid, sizeof(discid), stdout); fputc('\n', stdout); - - if (dvd) DVDClose(dvd); progress_free(&progress); - return (0); + return (st); } diff --git a/lib.c b/lib.c index 69532e8..80b1507 100644 --- a/lib.c +++ b/lib.c @@ -109,6 +109,57 @@ void store_filename(char *buf, ident id) } } +static char *copy_string(char *p, const char *q) +{ + while (*q) *p++ = *q++; + *p = 0; return (p); +} + +static char *copy_hex(char *p, const unsigned char *q, size_t sz) +{ + while (sz) { + sprintf(p, "%02x", *q); + p += 2; q++; sz--; + } + return (p); +} + +int dvd_id(char *p, dvd_reader_t *dvd, unsigned f, const char *file) +{ + char volid[33]; + unsigned char volsetid[16], discid[16]; + int rc; + size_t n; + + rc = DVDUDFVolumeInfo(dvd, + volid, sizeof(volid), + volsetid, sizeof(volsetid)); + if (!rc) { + p = copy_string(p, volid); + *p++ = '-'; + for (n = sizeof(volsetid); n && !volsetid[n - 1]; n--); + p = copy_hex(p, volsetid, n); + } else if (f&DIF_MUSTVOLINF) { + if (file) moan("failed to read volume info for `%s'", file); + else moan("failed to read volume info"); + return (-1); + } else + p = copy_string(p, ""); + + *p++ = ':'; + rc = DVDDiscID(dvd, discid); + if (!rc) + p = copy_hex(p, discid, sizeof(discid)); + else if (f&DIF_MUSTIFOHASH) { + if (file) moan("failed to determine disc id of `%s'", file); + else moan("failed to determine disc id"); + return (-1); + } else + p = copy_string(p, ""); + + return (0); +} + struct progress_state progress = PROGRESS_STATE_INIT; static struct banner_progress_item banner_progress; diff --git a/lib.h b/lib.h index 0198c34..bad7c3b 100644 --- a/lib.h +++ b/lib.h @@ -93,6 +93,11 @@ static inline unsigned id_part(ident id) { return ((id >> 16)&0x0ff); } #define MAXFNSZ (1 + 8 + 1 + 12 + 1) extern void store_filename(char *buf, ident id); +#define DIF_MUSTVOLINF 1u +#define DIF_MUSTIFOHASH 2u +#define MAXIDSZ 99 +extern int dvd_id(char *p, dvd_reader_t *dvd, unsigned f, const char *file); + struct banner_progress_item { struct progress_item _base; const char *msg;