From 6bdb0ec1bf5f771b7a2e7bfac5b08f128e4697a8 Mon Sep 17 00:00:00 2001 From: Chris Lamb Date: Mon, 29 Oct 2018 16:38:39 -0400 Subject: [PATCH] misc.c: Make the output reproducible Whilst working on the Reproducible Builds effort [0], we noticed that mtools generates non-reproducible output. This is because it uses the current time of day as a default timestamp, such as when adding files to an existing file. Patch attached that uses the SOURCE_DATE_EPOCH [1] environment variables. It was initially filed in Debian bug #900410 [2]) and has been incorporated into the version distributed by that operating system seemingly without issue. [0] https://reproducible-builds.org/ [1] https://https://reproducible-builds.org/specs/source-date-epoch/ [2] https://bugs.debian.org/900410 --- misc.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/misc.c b/misc.c index 6adf33b..d6bcee1 100644 --- a/misc.c +++ b/misc.c @@ -109,7 +109,8 @@ FILE *open_mcwd(const char *mode) * Ignore the info, if the file is more than 6 hours old */ getTimeNow(&now); - if (now - sbuf.st_mtime > 6 * 60 * 60) { + if (now - sbuf.st_mtime > 6 * 60 * 60 + && getenv("SOURCE_DATE_EPOCH") == NULL) { fprintf(stderr, "Warning: \"%s\" is out of date, removing it\n", file); @@ -159,11 +160,33 @@ void print_sector(const char *message, unsigned char *data, int size) time_t getTimeNow(time_t *now) { + char *endptr; + char *source_date_epoch; + unsigned long long epoch; static int haveTime = 0; static time_t sharedNow; if(!haveTime) { - time(&sharedNow); + source_date_epoch = getenv("SOURCE_DATE_EPOCH"); + if (source_date_epoch) { + epoch = strtoull(source_date_epoch, &endptr, 10); + + if (endptr == source_date_epoch) + fprintf(stderr, "SOURCE_DATE_EPOCH invalid\n"); + else if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0)) + || (errno != 0 && epoch == 0)) + fprintf(stderr, "SOURCE_DATE_EPOCH: strtoull: %s: %llu\n", + strerror(errno), epoch); + else if (*endptr != '\0') + fprintf(stderr, "SOURCE_DATE_EPOCH has trailing garbage\n"); + else if (epoch > ULONG_MAX) + fprintf(stderr, "SOURCE_DATE_EPOCH must be <= %lu but saw: %llu\n", ULONG_MAX, epoch); + else { + sharedNow = epoch; + } + } else { + time(&sharedNow); + } haveTime = 1; } if(now) -- 2.19.1