aboutsummaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
Diffstat (limited to 'gnu')
-rw-r--r--gnu/local.mk1
-rw-r--r--gnu/packages/cdrom.scm59
-rw-r--r--gnu/packages/patches/cdrtools-3.01-mkisofs-isoinfo.patch514
3 files changed, 573 insertions, 1 deletions
diff --git a/gnu/local.mk b/gnu/local.mk
index 0d8daf766a..33e1c775fd 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -517,6 +517,7 @@ dist_patch_DATA = \
%D%/packages/patches/calibre-drop-unrar.patch \
%D%/packages/patches/calibre-no-updates-dialog.patch \
%D%/packages/patches/cdparanoia-fpic.patch \
+ %D%/packages/patches/cdrtools-3.01-mkisofs-isoinfo.patch \
%D%/packages/patches/ceph-disable-cpu-optimizations.patch \
%D%/packages/patches/ceph-disable-unittest-throttle.patch \
%D%/packages/patches/ceph-skip-collect-sys-info-test.patch \
diff --git a/gnu/packages/cdrom.scm b/gnu/packages/cdrom.scm
index 7e86753abe..c0ba337da1 100644
--- a/gnu/packages/cdrom.scm
+++ b/gnu/packages/cdrom.scm
@@ -26,7 +26,7 @@
(define-module (gnu packages cdrom)
#:use-module (guix download)
#:use-module (guix packages)
- #:use-module ((guix licenses) #:select (lgpl2.1+ gpl2 gpl2+ gpl3+))
+ #:use-module ((guix licenses) #:select (lgpl2.1+ gpl2 gpl2+ gpl3+ cddl1.0))
#:use-module (guix build-system cmake)
#:use-module (guix build-system gnu)
#:use-module (guix build-system glib-or-gtk)
@@ -197,6 +197,63 @@ extra-robust data verification, synchronization, error handling and scratch
reconstruction capability.")
(license gpl2))) ; libraries under lgpl2.1
+(define-public cdrtools
+ (package
+ (name "cdrtools")
+ (version "3.01")
+ (source (origin
+ (method url-fetch)
+ (uri (string-append
+ "mirror://sourceforge/cdrtools/cdrtools-" version ".tar.bz2"))
+ (sha256
+ (base32
+ "03w6ypsmwwy4d7vh6zgwpc60v541vc5ywp8bdb758hbc4yv2wa7d"))
+ (patches (search-patches "cdrtools-3.01-mkisofs-isoinfo.patch"))))
+ (build-system gnu-build-system)
+ ;; XXX cdrtools bundles a modified, relicensed early version of cdparanoia.
+ (inputs
+ `(("linux-headers" ,linux-libre-headers)))
+ (arguments
+ `(#:phases
+ (modify-phases %standard-phases
+ (delete 'configure)
+ (add-before 'build 'set-linux-headers
+ (lambda _
+ (substitute* "autoconf/configure"
+ (("/usr/src/linux")
+ (assoc-ref %build-inputs "linux-headers")))
+ #t))
+ (add-before 'build 'substitute-dirs
+ (lambda _
+ (substitute* (append (find-files "DEFAULTS" "^Defaults\\.")
+ (find-files "DEFAULTS_ENG" "^Defaults\\.")
+ (find-files "TEMPLATES" "^Defaults\\."))
+ (("/opt/schily") (assoc-ref %outputs "out")))
+ #t))
+ (replace 'build
+ (lambda _
+ (zero?
+ (system* "make" "CONFIG_SHELL=sh" "CCOM=gcc" "RM=rm"))))
+ (replace 'install
+ (lambda _
+ (zero?
+ (system* "make"
+ "RM=rm" "LN=ln" "SYMLINK=ln -s"
+ (string-append "INS_BASE=" (assoc-ref %outputs "out"))
+ (string-append "INS_RBASE=" (assoc-ref %outputs "out"))
+ "install" )))))
+ #:tests? #f)) ; no tests
+ (synopsis "Command line utilities to manipulate and burn CD/DVD/BD images")
+ (description "cdrtools is a collection of command line utilities to create
+CD's, DVD's or Blue Ray discs. The most important components are
+@command{cdrecord}, a burning program, @command{cdda2wav}, a CD audio ripper
+which uses libparanoia, and @command{mkisofs}, which can create various disc
+images.")
+ (home-page "http://cdrtools.sourceforge.net/private/cdrecord.html")
+
+ ;; mkisofs is GPL, the other programs are CDDL.
+ (license (list cddl1.0 gpl2))))
+
(define-public dvdisaster
(package
(name "dvdisaster")
diff --git a/gnu/packages/patches/cdrtools-3.01-mkisofs-isoinfo.patch b/gnu/packages/patches/cdrtools-3.01-mkisofs-isoinfo.patch
new file mode 100644
index 0000000000..9c817d4198
--- /dev/null
+++ b/gnu/packages/patches/cdrtools-3.01-mkisofs-isoinfo.patch
@@ -0,0 +1,514 @@
+Patch for version 3.01, taken from upstream at
+https://sourceforge.net/projects/cdrtools/files/cdrtools-3.01-fix-20151126-mkisofs-isoinfo.patch
+
+--- cdrtools-3.01.orig/mkisofs/diag/isoinfo.c 2015-07-22 20:36:45.000000000 +0000
++++ cdrtools-3.01/mkisofs/diag/isoinfo.c 2015-11-17 19:35:40.000000000 +0000
+@@ -1,8 +1,8 @@
+-/* @(#)isoinfo.c 1.95 15/07/22 joerg */
++/* @(#)isoinfo.c 1.100 15/11/17 joerg */
+ #include <schily/mconfig.h>
+ #ifndef lint
+ static UConst char sccsid[] =
+- "@(#)isoinfo.c 1.95 15/07/22 joerg";
++ "@(#)isoinfo.c 1.100 15/11/17 joerg";
+ #endif
+ /*
+ * File isodump.c - dump iso9660 directory information.
+@@ -148,8 +148,10 @@ LOCAL char er_id[256];
+ LOCAL int su_version = 0;
+ LOCAL int rr_version = 0;
+ LOCAL int aa_version = 0;
++LOCAL int cl_extent = 0;
+ LOCAL int ucs_level = 0;
+ LOCAL BOOL iso9660_inodes = FALSE;
++LOCAL uid_t myuid;
+
+ #ifdef USE_FIND
+ LOCAL findn_t *find_node; /* syntaxtree from find_parse() */
+@@ -208,6 +210,9 @@ LOCAL void extract __PR((char *rootname
+ LOCAL void extract_file __PR((int f,
+ struct iso_directory_record * idr,
+ char *fname));
++LOCAL void parse_cl_dir __PR((struct iso_directory_record *idr,
++ int extent));
++LOCAL BOOL parse_de __PR((struct iso_directory_record *idr));
+ LOCAL void parse_dir __PR((char * rootname, int extent, int len));
+ LOCAL void usage __PR((int excode));
+ EXPORT int main __PR((int argc, char *argv[]));
+@@ -459,7 +464,6 @@ parse_rr(pnt, len, cont_flag)
+ int slen;
+ int xlen;
+ int ncount;
+- int cl_extent;
+ int pl_extent;
+ int cont_extent, cont_offset, cont_size;
+ int flag1, flag2;
+@@ -469,7 +473,7 @@ parse_rr(pnt, len, cont_flag)
+
+ symlinkname[0] = 0;
+
+- cont_extent = cont_offset = cont_size = 0;
++ cl_extent = cont_extent = cont_offset = cont_size = 0;
+
+ ncount = 0;
+ flag1 = -1;
+@@ -714,6 +718,7 @@ struct todo
+ };
+
+ LOCAL struct todo *todo_idr = NULL;
++LOCAL struct todo **todo_pp = &todo_idr;
+
+ LOCAL char *months[12] = {"Jan", "Feb", "Mar", "Apr",
+ "May", "Jun", "Jul",
+@@ -962,8 +967,14 @@ static BOOL isfirst = TRUE;
+ close(f);
+ return;
+ setmode:
+- fchmodat(AT_FDCWD, fname, fstat_buf.st_mode, AT_SYMLINK_NOFOLLOW);
+ fchownat(AT_FDCWD, fname, fstat_buf.st_uid, fstat_buf.st_gid, AT_SYMLINK_NOFOLLOW);
++ if (myuid != 0 && S_ISDIR(fstat_buf.st_mode)) {
++ /*
++ * Temporary hack until we have a dirstack like star.
++ */
++ fstat_buf.st_mode |= S_IWUSR;
++ }
++ fchmodat(AT_FDCWD, fname, fstat_buf.st_mode, AT_SYMLINK_NOFOLLOW);
+ times[0].tv_sec = fstat_buf.st_atime;
+ times[0].tv_nsec = stat_ansecs(&fstat_buf);
+ times[1].tv_sec = fstat_buf.st_mtime;
+@@ -1001,6 +1012,143 @@ extract_file(f, idr, fname)
+ }
+ }
+
++
++LOCAL void
++parse_cl_dir(idr, extent)
++ struct iso_directory_record *idr;
++ int extent;
++{
++ char cl_name_buf[256*3];
++
++ strlcpy(cl_name_buf, name_buf, sizeof (cl_name_buf));
++#ifdef USE_SCG
++ readsecs(extent - sector_offset, idr, 1);
++#else
++ lseek(fileno(infile), ((off_t)(extent - sector_offset)) << 11, SEEK_SET);
++ read(fileno(infile), idr, 2048);
++#endif
++
++ if (parse_de(idr) && use_rock)
++ dump_rr(idr);
++ strlcpy(name_buf, cl_name_buf, sizeof (name_buf));
++}
++
++LOCAL BOOL
++parse_de(idr)
++ struct iso_directory_record *idr;
++{
++ unsigned char uc;
++
++ if (idr->length[0] == 0)
++ return (FALSE);
++ memset(&fstat_buf, 0, sizeof (fstat_buf));
++ found_rr = 0;
++ name_buf[0] = xname[0] = 0;
++ fstat_buf.st_size = (off_t)(unsigned)isonum_733((unsigned char *)idr->size);
++ if (idr->flags[0] & 2)
++ fstat_buf.st_mode |= S_IFDIR;
++ else
++ fstat_buf.st_mode |= S_IFREG;
++ if (idr->name_len[0] == 1 && idr->name[0] == 0)
++ strcpy(name_buf, ".");
++ else if (idr->name_len[0] == 1 && idr->name[0] == 1)
++ strcpy(name_buf, "..");
++ else {
++ switch (ucs_level) {
++ case 3:
++ case 2:
++ case 1:
++ /*
++ * Unicode name. Convert as best we can.
++ */
++ {
++ int j;
++ name_buf[0] = '\0';
++#ifdef USE_ICONV
++ if (use_iconv(unls)) {
++ int u;
++ char *to = name_buf;
++
++ for (j = 0, u = 0; j < (int)idr->name_len[0] / 2; j++) {
++ char *ibuf = (char *)&idr->name[j*2];
++ size_t isize = 2; /* UCS-2 character size */
++ size_t osize = 4;
++
++ if (iconv(unls->sic_uni2cd, (__IC_CONST char **)&ibuf, &isize,
++ (char **)&to, &osize) == -1) {
++ int err = geterrno();
++
++ if ((err == EINVAL || err == EILSEQ) &&
++ osize == 4) {
++ *to = '_';
++ u += 1;
++ to++;
++ }
++ } else {
++ u += 4 - osize;
++ to = &name_buf[u];
++ }
++ }
++ j = u;
++ } else
++#endif
++ for (j = 0; j < (int)idr->name_len[0] / 2; j++) {
++ UInt16_t unichar;
++
++ unichar = (idr->name[j*2] & 0xFF) * 256 +
++ (idr->name[j*2+1] & 0xFF);
++
++ /*
++ * Get the backconverted char
++ */
++ if (unls)
++ uc = sic_uni2c(unls, unichar);
++ else
++ uc = unichar > 255 ? '_' : unichar;
++
++ name_buf[j] = uc ? uc : '_';
++ }
++ name_buf[j] = '\0';
++ }
++ break;
++ case 0:
++ /*
++ * Normal non-Unicode name.
++ */
++ strncpy(name_buf, idr->name, idr->name_len[0]);
++ name_buf[idr->name_len[0]] = 0;
++ break;
++ default:
++ /*
++ * Don't know how to do these yet. Maybe they are the same
++ * as one of the above.
++ */
++ exit(1);
++ }
++ }
++ memcpy(date_buf, idr->date, 9);
++ /*
++ * Always first set up time stamps and file modes from
++ * ISO-9660. This is used as a fallback in case that
++ * there is no related Rock Ridge based data.
++ */
++ fstat_buf.st_atime =
++ fstat_buf.st_mtime =
++ fstat_buf.st_ctime = iso9660_time(date_buf, NULL, FALSE);
++ fstat_buf.st_mode |= S_IRUSR|S_IXUSR |
++ S_IRGRP|S_IXGRP |
++ S_IROTH|S_IXOTH;
++ fstat_buf.st_nlink = 1;
++ fstat_buf.st_ino = 0;
++ fstat_buf.st_uid = 0;
++ fstat_buf.st_gid = 0;
++ if (iso9660_inodes) {
++ fstat_buf.st_ino = (unsigned long)
++ isonum_733((unsigned char *)idr->extent);
++ }
++ return (TRUE);
++}
++
+ LOCAL void
+ parse_dir(rootname, extent, len)
+ char *rootname;
+@@ -1012,12 +1160,13 @@ parse_dir(rootname, extent, len)
+ struct iso_directory_record * idr;
+ struct iso_directory_record didr;
+ struct stat dstat;
+- unsigned char uc;
++ unsigned char cl_buffer[2048];
+ unsigned char flags = 0;
+ Llong size = 0;
+ int sextent = 0;
+ int rlen;
+ int blen;
++ int rr_flags = 0;
+ static char *n = 0;
+ static int nlen = 0;
+
+@@ -1039,115 +1188,23 @@ static int nlen = 0;
+ i = 0;
+ while (1 == 1) {
+ idr = (struct iso_directory_record *) &buffer[i];
+- if (idr->length[0] == 0) break;
+- memset(&fstat_buf, 0, sizeof (fstat_buf));
+- found_rr = 0;
+- name_buf[0] = xname[0] = 0;
+- fstat_buf.st_size = (off_t)(unsigned)isonum_733((unsigned char *)idr->size);
+- if (idr->flags[0] & 2)
+- fstat_buf.st_mode |= S_IFDIR;
+- else
+- fstat_buf.st_mode |= S_IFREG;
+- if (idr->name_len[0] == 1 && idr->name[0] == 0)
+- strcpy(name_buf, ".");
+- else if (idr->name_len[0] == 1 && idr->name[0] == 1)
+- strcpy(name_buf, "..");
+- else {
+- switch (ucs_level) {
+- case 3:
+- case 2:
+- case 1:
+- /*
+- * Unicode name. Convert as best we can.
+- */
+- {
+- int j;
+-
+- name_buf[0] = '\0';
+-#ifdef USE_ICONV
+- if (use_iconv(unls)) {
+- int u;
+- char *to = name_buf;
+-
+- for (j = 0, u = 0; j < (int)idr->name_len[0] / 2; j++) {
+- char *ibuf = (char *)&idr->name[j*2];
+- size_t isize = 2; /* UCS-2 character size */
+- size_t osize = 4;
+-
+- if (iconv(unls->sic_uni2cd, (__IC_CONST char **)&ibuf, &isize,
+- (char **)&to, &osize) == -1) {
+- int err = geterrno();
+-
+- if ((err == EINVAL || err == EILSEQ) &&
+- osize == 4) {
+- *to = '_';
+- u += 1;
+- to++;
+- }
+- } else {
+- u += 4 - osize;
+- to = &name_buf[u];
+- }
+- }
+- j = u;
+- } else
+-#endif
+- for (j = 0; j < (int)idr->name_len[0] / 2; j++) {
+- UInt16_t unichar;
+-
+- unichar = (idr->name[j*2] & 0xFF) * 256 +
+- (idr->name[j*2+1] & 0xFF);
+-
+- /*
+- * Get the backconverted char
+- */
+- if (unls)
+- uc = sic_uni2c(unls, unichar);
+- else
+- uc = unichar > 255 ? '_' : unichar;
++ if (idr->length[0] == 0)
++ break;
++ parse_de(idr);
++ if (use_rock) {
++ rr_flags = dump_rr(idr);
+
+- name_buf[j] = uc ? uc : '_';
+- }
+- name_buf[j] = '\0';
+- }
+- break;
+- case 0:
++ if (rr_flags & RR_FLAG_CL) {
+ /*
+- * Normal non-Unicode name.
++ * Need to reparse the child link
++ * but note that we parse "CL/."
++ * so we get no usable file name.
+ */
+- strncpy(name_buf, idr->name, idr->name_len[0]);
+- name_buf[idr->name_len[0]] = 0;
+- break;
+- default:
+- /*
+- * Don't know how to do these yet. Maybe they are the same
+- * as one of the above.
+- */
+- exit(1);
+- }
++ idr = (struct iso_directory_record *) cl_buffer;
++ parse_cl_dir(idr, cl_extent);
++ } else if (rr_flags & RR_FLAG_RE)
++ goto cont; /* skip rr_moved */
+ }
+- memcpy(date_buf, idr->date, 9);
+- /*
+- * Always first set up time stamps and file modes from
+- * ISO-9660. This is used as a fallback in case that
+- * there is no related Rock Ridge based data.
+- */
+- fstat_buf.st_atime =
+- fstat_buf.st_mtime =
+- fstat_buf.st_ctime = iso9660_time(date_buf, NULL, FALSE);
+- fstat_buf.st_mode |= S_IRUSR|S_IXUSR |
+- S_IRGRP|S_IXGRP |
+- S_IROTH|S_IXOTH;
+- fstat_buf.st_nlink = 1;
+- fstat_buf.st_ino = 0;
+- fstat_buf.st_uid = 0;
+- fstat_buf.st_gid = 0;
+- if (iso9660_inodes) {
+- fstat_buf.st_ino = (unsigned long)
+- isonum_733((unsigned char *)idr->extent);
+- }
+- if (use_rock)
+- dump_rr(idr);
+ if (Xtract &&
+ (idr->flags[0] & 2) != 0 &&
+ idr->name_len[0] == 1 &&
+@@ -1170,30 +1227,30 @@ static int nlen = 0;
+ n[rlen] = '\0';
+
+ if ((idr->flags[0] & 2) != 0 &&
+- (idr->name_len[0] != 1 ||
++ ((rr_flags & RR_FLAG_CL) ||
++ idr->name_len[0] != 1 ||
+ (idr->name[0] != 0 && idr->name[0] != 1))) {
+ /*
+ * This is a plain directory (neither "xxx/."
+ * nor "xxx/..").
+ * Add this directory to the todo list.
+ */
+- td = todo_idr;
+- if (td != NULL) {
+- while (td->next != NULL)
+- td = td->next;
+- td->next = (struct todo *) malloc(sizeof (*td));
+- td = td->next;
+- } else {
+- todo_idr = td = (struct todo *) malloc(sizeof (*td));
+- }
++ td = (struct todo *) malloc(sizeof (*td));
++ if (td == NULL)
++ comerr(_("No memory.\n"));
+ td->next = NULL;
+ td->extent = isonum_733((unsigned char *)idr->extent);
+ td->length = isonum_733((unsigned char *)idr->size);
+ td->name = (char *) malloc(strlen(rootname)
+ + strlen(name_buf) + 2);
++ if (td->name == NULL)
++ comerr(_("No memory.\n"));
+ strcpy(td->name, rootname);
+ strcat(td->name, name_buf);
+ strcat(td->name, "/");
++
++ *todo_pp = td;
++ todo_pp = &td->next;
+ } else {
+ if (xtract && strcmp(xtract, n) == 0) {
+ extract_file(STDOUT_FILENO, idr, "stdout");
+@@ -1253,6 +1310,7 @@ static int nlen = 0;
+ if ((idr->flags[0] & ISO_MULTIEXTENT) == 0)
+ size = 0;
+ }
++ cont:
+ i += buffer[i];
+ if (i > 2048 - offsetof(struct iso_directory_record, name[0])) break;
+ }
+@@ -1381,12 +1439,13 @@ main(argc, argv)
+ usage(0);
+ if (prvers) {
+ printf(_("isoinfo %s (%s-%s-%s) Copyright (C) 1993-1999 %s (C) 1999-2015 %s\n"),
+- VERSION,
++ "3.02a02",
+ HOST_CPU, HOST_VENDOR, HOST_OS,
+ _("Eric Youngdale"),
+ _("Joerg Schilling"));
+ exit(0);
+ }
++ myuid = getuid();
+ #ifdef USE_FIND
+ if (do_find) {
+ finda_t fa;
+--- cdrtools-3.01.orig/mkisofs/udf.c 2013-04-24 20:45:18.000000000 +0000
++++ cdrtools-3.01/mkisofs/udf.c 2015-11-25 22:07:30.000000000 +0000
+@@ -1,15 +1,15 @@
+-/* @(#)udf.c 1.42 13/04/24 Copyright 2001-2013 J. Schilling */
++/* @(#)udf.c 1.43 15/11/25 Copyright 2001-2015 J. Schilling */
+ #include <schily/mconfig.h>
+ #ifndef lint
+ static UConst char sccsid[] =
+- "@(#)udf.c 1.42 13/04/24 Copyright 2001-2013 J. Schilling";
++ "@(#)udf.c 1.43 15/11/25 Copyright 2001-2015 J. Schilling";
+ #endif
+ /*
+ * udf.c - UDF support for mkisofs
+ *
+ * Written by Ben Rudiak-Gould (2001).
+ *
+- * Copyright 2001-2013 J. Schilling.
++ * Copyright 2001-2015 J. Schilling.
+ */
+ /*
+ * This program is free software; you can redistribute it and/or modify
+@@ -98,7 +98,7 @@ static UConst char sccsid[] =
+ extern int use_sparcboot;
+
+ extern struct directory *root;
+-extern time_t begun;
++extern struct timeval tv_begun;
+
+ static unsigned lba_main_seq;
+ static unsigned lba_main_seq_copy;
+@@ -110,7 +110,7 @@ static unsigned lba_end_anchor_vol_desc;
+ static unsigned num_udf_files;
+ static unsigned num_udf_directories;
+
+-static unsigned volume_set_id[2];
++static unsigned volume_set_id[2] = { 0, 0 };
+
+ #define UDF_MAIN_SEQ_LENGTH (16)
+ #define UDF_INTEG_SEQ_LENGTH (2)
+@@ -723,7 +723,7 @@ set_primary_vol_desc(buf, lba)
+ /*pvd->volume_abstract;*/
+ /*pvd->volume_copyright_notice;*/
+ /*pvd->application_ident;*/
+- set_timestamp_from_time_t(&pvd->recording_date_and_time, begun);
++ set_timestamp_from_time_t(&pvd->recording_date_and_time, tv_begun.tv_sec);
+ set_impl_ident(&pvd->impl_ident);
+ set_tag(&pvd->desc_tag, UDF_TAGID_PRIMARY_VOLUME_DESC, lba, 512);
+ }
+@@ -831,7 +831,7 @@ set_logical_vol_integrity_desc(buf, lba)
+ udf_logical_volume_integrity_desc *lvid =
+ (udf_logical_volume_integrity_desc *)buf;
+
+- set_timestamp_from_time_t(&lvid->recording_date, begun);
++ set_timestamp_from_time_t(&lvid->recording_date, tv_begun.tv_sec);
+ set32(&lvid->integrity_type, UDF_INTEGRITY_TYPE_CLOSE);
+ /*lvid->next_integrity_extent;*/
+ set64(&lvid->logical_volume_contents_use.unique_id,
+@@ -859,7 +859,7 @@ set_file_set_desc(buf, rba)
+ {
+ udf_file_set_desc *fsd = (udf_file_set_desc *)buf;
+
+- set_timestamp_from_time_t(&fsd->recording_date_and_time, begun);
++ set_timestamp_from_time_t(&fsd->recording_date_and_time, tv_begun.tv_sec);
+ set16(&fsd->interchange_level, 3);
+ set16(&fsd->maximum_interchange_level, 3);
+ set32(&fsd->character_set_list, 1);
+@@ -1986,8 +1986,10 @@ udf_main_seq_write(out)
+ * volume_set_id needs to be set to a (64-bit) "unique" number.
+ * This will have to do for now.
+ */
+- volume_set_id[0] = begun;
+- volume_set_id[1] = (unsigned)clock(); /* XXX Maybe non-portable */
++ if (volume_set_id[0] == 0) {
++ volume_set_id[0] = tv_begun.tv_sec;
++ volume_set_id[1] = (unsigned)tv_begun.tv_usec;
++ }
+
+ memset(buf, 0, sizeof (buf));
+ set_primary_vol_desc(buf, last_extent_written++);
+--- cdrtools-3.01.orig/mkisofs/mkisofs.c 2015-01-01 14:19:51.000000000 +0000
++++ cdrtools-3.01/mkisofs/mkisofs.c
+@@ -69 +69 @@ int path_ind;
+-char version_string[] = VERSION;
++char version_string[] = "3.01-fix-20151126";