Package: cdrkit
Version: 9:1.1.11-3
Severity: wishlist
Tags: patch
User: reproducible-bui...@lists.alioth.debian.org
Usertags: toolchain timestamps

Hi!

While working on the “reproducible builds” effort [1], we have noticed
that ISO images created by genisoimages could not be reproduced at a
later time. The times written the PVD are always set to the current
clock time. Same goes for RR relocations and files created on the fly
like the boot catalog.

The attached patch adds a “-creation-date” option to which can be
given an arbitrary epoch that will further be used in the PVD and for
the aforementioned files.

 [1]: https://wiki.debian.org/ReproducibleBuilds

-- 
Lunar                                             <lu...@torproject.org>
diff --git a/genisoimage/.eltorito.c.swp b/genisoimage/.eltorito.c.swp
new file mode 100644
index 0000000..a49fcbd
Binary files /dev/null and b/genisoimage/.eltorito.c.swp differ
diff --git a/genisoimage/genisoimage.1 b/genisoimage/genisoimage.1
index d05b24a..d69a1d4 100644
--- a/genisoimage/genisoimage.1
+++ b/genisoimage/genisoimage.1
@@ -976,6 +976,12 @@ in the
 .I .genisoimagerc
 file.
 .TP
+.BI \-creation-date " epoch"
+Specifies the date to be used as creation, modification and effective
+date in the volume descriptor and for files and relocations created
+on the fly. Specified as a number of second since
+1970-01-01 00:00:00 +0000 (UTC); if 0, the current time is used.
+.TP
 .B \-print\-size
 Print estimated filesystem size in multiples of the sector size (2048 bytes)
 and exit. This option is needed for
diff --git a/genisoimage/genisoimage.c b/genisoimage/genisoimage.c
index cfd079a..58397e9 100644
--- a/genisoimage/genisoimage.c
+++ b/genisoimage/genisoimage.c
@@ -169,6 +169,7 @@ char	*abstract = ABSTRACT_DEFAULT;
 char	*volset_id = VOLSET_ID_DEFAULT;
 char	*volume_id = VOLUME_ID_DEFAULT;
 char	*system_id = SYSTEM_ID_DEFAULT;
+time_t  creation_date = 0;
 char	*boot_catalog = BOOT_CATALOG_DEFAULT;
 char	*boot_image = BOOT_IMAGE_DEFAULT;
 char	*genboot_image = BOOT_IMAGE_DEFAULT;
@@ -405,6 +406,8 @@ struct ld_option {
 #define	OPTION_ALLOW_LEADING_DOTS	1070
 #define	OPTION_PUBLISHER		1071
 
+#define OPTION_CREATION_DATE            1072
+
 #ifdef		JIGDO_TEMPLATE
 #define	OPTION_JTT_OUTPUT		1101
 #define	OPTION_JTJ_OUTPUT		1102
@@ -522,6 +525,8 @@ static const struct ld_option ld_options[] =
 	'\0', "FILE", "Check all ISO9660 names from previous session", ONE_DASH},
 	{{"copyright", required_argument, NULL, OPTION_COPYRIGHT},
 	'\0', "FILE", "Set Copyright filename", ONE_DASH},
+	{{"creation-date", required_argument, NULL, OPTION_CREATION_DATE},
+	'\0', NULL, "Set volume creation date", ONE_DASH},
 	{{"debug", no_argument, NULL, OPTION_DEBUG},
 	'\0', NULL, "Set debug flag", ONE_DASH},
 	{{"eltorito-boot", required_argument, NULL, 'b'},
@@ -1721,6 +1726,22 @@ int main(int argc, char *argv[])
 #endif
 			}
 			break;
+		case OPTION_CREATION_DATE:
+		{
+			char	*end = 0;
+
+			creation_date = strtol(optarg, &end, 10);
+			if (!end || *end != 0) {
+#ifdef	USE_LIBSCHILY
+				comerrno(EX_BAD, "Bad epoch for -creation-date\n");
+#else
+				fprintf(stderr, "Bad epoch for -creation-date\n");
+				exit(1);
+#endif
+			}
+			break;
+		}
+
 		case OPTION_DEBUG:
 			debug++;
 			break;
diff --git a/genisoimage/genisoimage.h b/genisoimage/genisoimage.h
index bbedfb0..c49576c 100644
--- a/genisoimage/genisoimage.h
+++ b/genisoimage/genisoimage.h
@@ -650,6 +650,7 @@ extern char	*appid;
 extern char	*volset_id;
 extern char	*system_id;
 extern char	*volume_id;
+extern time_t	creation_date;
 extern char	*boot_catalog;
 extern char	*boot_image;
 extern char	*genboot_image;
diff --git a/genisoimage/tree.c b/genisoimage/tree.c
index 7805888..f17a662 100644
--- a/genisoimage/tree.c
+++ b/genisoimage/tree.c
@@ -783,7 +783,11 @@ generate_reloc_directory()
 	struct directory_entry *s_entry;
 
 	/* Create an  entry for our internal tree */
-	time(&current_time);
+	if (creation_date == 0) {
+		time(&current_time);
+	} else {
+		current_time = creation_date;
+	}
 	reloc_dir = (struct directory *)
 		e_malloc(sizeof (struct directory));
 	memset(reloc_dir, 0, sizeof (struct directory));
@@ -2680,7 +2684,11 @@ init_fstatbuf()
 	time_t	current_time;
 
 	if (fstatbuf.st_ctime == 0) {
-		time(&current_time);
+		if (creation_date == 0) {
+			time(&current_time);
+		} else {
+			current_time = creation_date;
+		}
 		if (rationalize_uid)
 			fstatbuf.st_uid = uid_to_use;
 		else
diff --git a/genisoimage/write.c b/genisoimage/write.c
index a423ab1..f63507c 100644
--- a/genisoimage/write.c
+++ b/genisoimage/write.c
@@ -1885,12 +1885,17 @@ pvd_write(FILE *outfile)
 	int		should_write;
 	struct tm	local;
 	struct tm	gmt;
+	time_t		pvd_date;
 
 
 	time(&begun);
 
-	local = *localtime(&begun);
-	gmt = *gmtime(&begun);
+	if (creation_date == 0) {
+		creation_date = begun;
+	}
+
+	local = *localtime(&creation_date);
+	gmt = *gmtime(&creation_date);
 
 	/*
 	 * There was a comment here about breaking in the year 2000.

Attachment: signature.asc
Description: Digital signature

Reply via email to