Source: apt Version: 1.4~beta2 Severity: wishlist Tags: patch User: reproducible-bui...@lists.alioth.debian.org Usertags: timestamps randomness X-Debbugs-Cc: reproducible-b...@lists.alioth.debian.org
Hi, Whilst working on the Reproducible Builds effort [0], we noticed that apt could not moo reproducibly. Patch attached. [0] https://reproducible-builds.org/ Regards, -- ,''`. : :' : Chris Lamb `. `'` la...@debian.org / chris-lamb.co.uk `-
diff --git a/apt-private/private-moo.cc b/apt-private/private-moo.cc index a879991..d55df8a 100644 --- a/apt-private/private-moo.cc +++ b/apt-private/private-moo.cc @@ -15,6 +15,7 @@ #include <apt-private/private-moo.h> #include <apt-private/private-output.h> +#include <apt-private/private-utils.h> #include <stddef.h> #include <string.h> @@ -27,7 +28,7 @@ /*}}}*/ static std::string getMooLine() { /*{{{*/ - time_t const timenow = time(NULL); + time_t const timenow = GetTimeNow(); struct tm special; localtime_r(&timenow, &special); enum { NORMAL, PACKAGEMANAGER, APPRECIATION, AGITATION, AIRBORN } line; @@ -163,7 +164,8 @@ bool DoMooApril(CommandLine &) /*{{{*/ /*}}}*/ bool DoMoo(CommandLine &CmdL) /*{{{*/ { - time_t const timenow = time(NULL); + const time_t timenow = GetTimeNow(); + struct tm april; localtime_r(&timenow, &april); if (april.tm_mday == 1 && april.tm_mon == 3) diff --git a/apt-private/private-utils.cc b/apt-private/private-utils.cc index 775bf7e..64eb23d 100644 --- a/apt-private/private-utils.cc +++ b/apt-private/private-utils.cc @@ -1,11 +1,15 @@ #include <config.h> #include <apt-pkg/configuration.h> +#include <apt-pkg/error.h> #include <apt-pkg/fileutl.h> #include <apt-private/private-utils.h> #include <cstdlib> +#include <errno.h> +#include <limits.h> +#include <string.h> #include <unistd.h> // DisplayFileInPager - Display File with pager /*{{{*/ @@ -74,3 +78,32 @@ bool EditFileInSensibleEditor(std::string const &filename) return ExecWait(Process, "editor", false); } /*}}}*/ +time_t GetTimeNow() /*{{{*/ +{ + const char *source_date_epoch = getenv("SOURCE_DATE_EPOCH"); + + if (!source_date_epoch) { + return time(NULL); + } + + errno = 0; + char *endptr; + const unsigned long long epoch = strtoull(source_date_epoch, &endptr, 10); + + if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0)) + || (errno != 0 && epoch == 0)) { + _error->Error("SOURCE_DATE_EPOCH: strtoull: %s\n", strerror(errno)); + } + if (endptr == source_date_epoch) { + _error->Error("SOURCE_DATE_EPOCH: No digits were found: %s\n", endptr); + } + if (*endptr != '\0') { + _error->Error("SOURCE_DATE_EPOCH: Trailing garbage: %s\n", endptr); + } + if (epoch > ULONG_MAX) { + _error->Error("SOURCE_DATE_EPOCH: %llu must be <= %lu", epoch, ULONG_MAX); + } + + return (time_t) epoch; +} + /*}}}*/ diff --git a/apt-private/private-utils.h b/apt-private/private-utils.h index b3b2496..2024777 100644 --- a/apt-private/private-utils.h +++ b/apt-private/private-utils.h @@ -5,5 +5,6 @@ bool DisplayFileInPager(std::string const &filename); bool EditFileInSensibleEditor(std::string const &filename); +time_t GetTimeNow(); #endif