Просмотр исходного кода

dpkg-split: Make the deb-split(5) generation reproducible

Honor SOURCE_DATE_EPOCH, so that we can control the output and generate
reproducible split packages.
Guillem Jover лет назад: 10
Родитель
Сommit
6e5862ef6e
3 измененных файлов с 32 добавлено и 0 удалено
  1. 2 0
      debian/changelog
  2. 24 0
      dpkg-split/split.c
  3. 6 0
      man/dpkg-split.man

+ 2 - 0
debian/changelog

@@ -13,6 +13,8 @@ dpkg (1.18.11) UNRELEASED; urgency=medium
     name affected.
     name affected.
   * Do not emit epochs for unambiguous versions in deb-split package header.
   * Do not emit epochs for unambiguous versions in deb-split package header.
     Regression introduced in dpkg 1.18.0.
     Regression introduced in dpkg 1.18.0.
+  * Make the deb-split(5) generation in dpkg-split reproducible, by using the
+    timestamp from SOURCE_DATE_EPOCH.
   * Perl modules:
   * Perl modules:
     - Obsolete Source-Version substvar in Dpkg::Substvars by emitting errors.
     - Obsolete Source-Version substvar in Dpkg::Substvars by emitting errors.
   * Packaging:
   * Packaging:

+ 24 - 0
dpkg-split/split.c

@@ -26,6 +26,7 @@
 #include <sys/stat.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
 #include <sys/wait.h>
 
 
+#include <errno.h>
 #include <limits.h>
 #include <limits.h>
 #include <fcntl.h>
 #include <fcntl.h>
 #include <libgen.h>
 #include <libgen.h>
@@ -89,6 +90,20 @@ deb_parse_control(const char *filename)
 	return pkg;
 	return pkg;
 }
 }
 
 
+static time_t
+parse_timestamp(const char *value)
+{
+	time_t timestamp;
+	char *end;
+
+	errno = 0;
+	timestamp = strtol(value, &end, 10);
+	if (value == end || *end || errno != 0)
+		ohshite(_("unable to parse timestamp '%.255s'"), value);
+
+	return timestamp;
+}
+
 /* Cleanup filename for use in crippled msdos systems. */
 /* Cleanup filename for use in crippled msdos systems. */
 static char *
 static char *
 clean_msdos_filename(char *filename)
 clean_msdos_filename(char *filename)
@@ -117,6 +132,8 @@ mksplit(const char *file_src, const char *prefix, off_t maxpartsize,
 	struct dpkg_error err;
 	struct dpkg_error err;
 	int fd_src;
 	int fd_src;
 	struct stat st;
 	struct stat st;
+	time_t timestamp;
+	const char *timestamp_str;
 	const char *version;
 	const char *version;
 	char hash[MD5HASHLEN + 1];
 	char hash[MD5HASHLEN + 1];
 	int nparts, curpart;
 	int nparts, curpart;
@@ -143,6 +160,12 @@ mksplit(const char *file_src, const char *prefix, off_t maxpartsize,
 	pkg  = deb_parse_control(file_src);
 	pkg  = deb_parse_control(file_src);
 	version = versiondescribe(&pkg->available.version, vdew_nonambig);
 	version = versiondescribe(&pkg->available.version, vdew_nonambig);
 
 
+	timestamp_str = getenv("SOURCE_DATE_EPOCH");
+	if (timestamp_str)
+		timestamp = parse_timestamp(timestamp_str);
+	else
+		timestamp = time(NULL);
+
 	partsize = maxpartsize - HEADERALLOWANCE;
 	partsize = maxpartsize - HEADERALLOWANCE;
 	last_partsize = st.st_size % partsize;
 	last_partsize = st.st_size % partsize;
 	if (last_partsize == 0)
 	if (last_partsize == 0)
@@ -197,6 +220,7 @@ mksplit(const char *file_src, const char *prefix, off_t maxpartsize,
 
 
 		/* Split the data. */
 		/* Split the data. */
 		ar = dpkg_ar_create(file_dst.buf, 0644);
 		ar = dpkg_ar_create(file_dst.buf, 0644);
+		dpkg_ar_set_mtime(ar, timestamp);
 
 
 		/* Write the ar header. */
 		/* Write the ar header. */
 		dpkg_ar_put_magic(ar);
 		dpkg_ar_put_magic(ar);

+ 6 - 0
man/dpkg-split.man

@@ -215,6 +215,12 @@ a file that looked like a package part file but was corrupted, or
 interactions with the system, such as accesses to the database,
 interactions with the system, such as accesses to the database,
 memory allocations, etc.
 memory allocations, etc.
 .
 .
+.SH ENVIRONMENT
+.TP
+.B SOURCE_DATE_EPOCH
+If set, it will be used as the timestamp (as seconds since the epoch) in
+the \fBdeb\-split\fP(5)'s \fBar\fP(5) container.
+.
 .SH FILES
 .SH FILES
 .TP
 .TP
 .I %ADMINDIR%/parts
 .I %ADMINDIR%/parts