summaryrefslogtreecommitdiff
path: root/apt-private
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2017-01-19 11:50:41 +0100
committerDavid Kalnischkies <david@kalnischkies.de>2017-01-19 11:50:41 +0100
commit25a14d4ccfceb2698edce01092bc6a1dbe9fb217 (patch)
tree82eddea84f59333847c594e9fe0a97cd0e4f6176 /apt-private
parent2984d7aec37e09b473c7b99f43d20622c25dc99d (diff)
make the moo reproducible
Normal cows moo every time they feel like it and it might be a "moo", "moo!" or "moo?". This is completely unacceptable behaviour in our super cow through as as a superior being it has to show its superiority over the common cows and the meager easter eggs by being fully reproducible! The second version of Chris' patch is modified to include an array of tests for this feature – which doubles as explanation for some of the moo lines by giving more exact dates – and falling back to current time if the environment is invalid + passing time around instead of having an invalid environment be an unrecoverable error (aka: Guru Meditation) as that is more inline with how apt usually behaves: The wisdom of super cow should be available to everyone, even to the most misfortune users not capable of having a valid environment variable. That makes the code slightly more ugly, so instead of requiring a young follower to produce a third version a high priest of the cult applied the finishing touches as he is used to the pain by now – and another round with the slowpoke high priest would have been a serious threat to the Debian release schedule which the cow would not approve. Closes: #848721 Signed-off-by: Super Cow Thanks: Chris Lamb for initial patch and guru meditation
Diffstat (limited to 'apt-private')
-rw-r--r--apt-private/private-moo.cc45
-rw-r--r--apt-private/private-moo.h4
-rw-r--r--apt-private/private-utils.cc22
-rw-r--r--apt-private/private-utils.h1
4 files changed, 47 insertions, 25 deletions
diff --git a/apt-private/private-moo.cc b/apt-private/private-moo.cc
index a87999150..b8ed6efbd 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>
@@ -26,8 +27,8 @@
#include <apti18n.h>
/*}}}*/
-static std::string getMooLine() { /*{{{*/
- time_t const timenow = time(NULL);
+static std::string getMooLine(time_t const timenow) /*{{{*/
+{
struct tm special;
localtime_r(&timenow, &special);
enum { NORMAL, PACKAGEMANAGER, APPRECIATION, AGITATION, AIRBORN } line;
@@ -64,17 +65,18 @@ static std::string getMooLine() { /*{{{*/
return out.str();
}
/*}}}*/
-static bool printMooLine() { /*{{{*/
- std::cerr << getMooLine() << std::endl;
+static bool printMooLine(time_t const timenow) /*{{{*/
+{
+ std::cerr << getMooLine(timenow);
return true;
}
/*}}}*/
-bool DoMoo1(CommandLine &) /*{{{*/
+static bool DoMoo1(time_t const timenow) /*{{{*/
{
// our trustworthy super cow since 2001
if (_config->FindI("quiet") >= 2)
- return printMooLine();
- std::string const moo = getMooLine();
+ return printMooLine(timenow);
+ std::string const moo = getMooLine(timenow);
size_t const depth = moo.length()/4;
c1out <<
OutputInDepth(depth, " ") << " (__) \n" <<
@@ -87,12 +89,12 @@ bool DoMoo1(CommandLine &) /*{{{*/
return true;
}
/*}}}*/
-bool DoMoo2(CommandLine &) /*{{{*/
+static bool DoMoo2(time_t const timenow) /*{{{*/
{
// by Fernando Ribeiro in lp:56125
if (_config->FindI("quiet") >= 2)
- return printMooLine();
- std::string const moo = getMooLine();
+ return printMooLine(timenow);
+ std::string const moo = getMooLine(timenow);
size_t const depth = moo.length()/4;
if (_config->FindB("APT::Moo::Color", false) == false)
c1out <<
@@ -121,12 +123,12 @@ bool DoMoo2(CommandLine &) /*{{{*/
return true;
}
/*}}}*/
-bool DoMoo3(CommandLine &) /*{{{*/
+static bool DoMoo3(time_t const timenow) /*{{{*/
{
// by Robert Millan in deb:134156
if (_config->FindI("quiet") >= 2)
- return printMooLine();
- std::string const moo = getMooLine();
+ return printMooLine(timenow);
+ std::string const moo = getMooLine(timenow);
size_t const depth = moo.length()/16;
c1out <<
OutputInDepth(depth, " ") << " \\_/ \n" <<
@@ -138,7 +140,7 @@ bool DoMoo3(CommandLine &) /*{{{*/
return true;
}
/*}}}*/
-bool DoMooApril(CommandLine &) /*{{{*/
+static bool DoMooApril() /*{{{*/
{
// by Christopher Allan Webber and proposed by Paul Tagliamonte
// in a "Community outreach": https://lists.debian.org/debian-devel/2013/04/msg00045.html
@@ -163,11 +165,12 @@ bool DoMooApril(CommandLine &) /*{{{*/
/*}}}*/
bool DoMoo(CommandLine &CmdL) /*{{{*/
{
- time_t const timenow = time(NULL);
+ time_t const timenow = GetSecondsSinceEpoch();
+
struct tm april;
localtime_r(&timenow, &april);
if (april.tm_mday == 1 && april.tm_mon == 3)
- return DoMooApril(CmdL);
+ return DoMooApril();
signed short SuperCow = 1;
if (CmdL.FileSize() != 0)
@@ -185,11 +188,11 @@ bool DoMoo(CommandLine &CmdL) /*{{{*/
}
switch(SuperCow) {
- case 1: return DoMoo1(CmdL);
- case 2: return DoMoo2(CmdL);
- case 3: return DoMoo3(CmdL);
- case 4: return DoMooApril(CmdL);
- default: return DoMoo1(CmdL);
+ case 1: return DoMoo1(timenow);
+ case 2: return DoMoo2(timenow);
+ case 3: return DoMoo3(timenow);
+ case 4: return DoMooApril();
+ default: return DoMoo1(timenow);
}
return true;
diff --git a/apt-private/private-moo.h b/apt-private/private-moo.h
index bc8b3e7dd..c230ce2e1 100644
--- a/apt-private/private-moo.h
+++ b/apt-private/private-moo.h
@@ -6,9 +6,5 @@
class CommandLine;
APT_PUBLIC bool DoMoo(CommandLine &CmdL);
-bool DoMoo1(CommandLine &CmdL);
-bool DoMoo2(CommandLine &CmdL);
-bool DoMoo3(CommandLine &CmdL);
-bool DoMooApril(CommandLine &CmdL);
#endif
diff --git a/apt-private/private-utils.cc b/apt-private/private-utils.cc
index 775bf7e79..5863925b9 100644
--- a/apt-private/private-utils.cc
+++ b/apt-private/private-utils.cc
@@ -1,11 +1,13 @@
#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 <sstream>
#include <unistd.h>
// DisplayFileInPager - Display File with pager /*{{{*/
@@ -74,3 +76,23 @@ bool EditFileInSensibleEditor(std::string const &filename)
return ExecWait(Process, "editor", false);
}
/*}}}*/
+time_t GetSecondsSinceEpoch() /*{{{*/
+{
+ auto const source_date_epoch = getenv("SOURCE_DATE_EPOCH");
+ if (source_date_epoch == nullptr)
+ return time(nullptr);
+
+ time_t epoch;
+ std::stringstream ss(source_date_epoch);
+ ss >> epoch;
+
+ if (ss.fail() || !ss.eof())
+ {
+ _error->Warning("Environment variable SOURCE_DATE_EPOCH was ignored as it has an invalid value: \"%s\"",
+ source_date_epoch);
+ return time(nullptr);
+ }
+
+ return epoch;
+}
+ /*}}}*/
diff --git a/apt-private/private-utils.h b/apt-private/private-utils.h
index b3b249689..4d48bd1ba 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 GetSecondsSinceEpoch();
#endif