Adds support for the environment variable SOURCE_DATE_EPOCH. See: https://sources.debian.net/patches/groff/1.22.3-9/source-date-epoch.patch/ From abc23bc9245e18468817f2838361c3a08f7521e2 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 5 Nov 2015 11:47:34 +0000 Subject: Implement `SOURCE_DATE_EPOCH' for reproducible builds. Author: Colin Watson Forwarded: yes Last-Update: 2015-11-05 Patch-Name: source-date-epoch.patch --- doc/groff.texinfo | 6 +++++ src/devices/grohtml/grohtml.man | 7 ++++++ src/devices/grohtml/post-html.cpp | 5 ++-- src/devices/gropdf/gropdf.man | 7 ++++++ src/devices/gropdf/gropdf.pl | 3 ++- src/devices/grops/grops.man | 7 ++++++ src/devices/grops/ps.cpp | 3 ++- src/include/curtime.h | 23 ++++++++++++++++++ src/libs/libgroff/Makefile.sub | 2 ++ src/libs/libgroff/curtime.cpp | 51 +++++++++++++++++++++++++++++++++++++++ src/roff/troff/input.cpp | 3 ++- 11 files changed, 112 insertions(+), 5 deletions(-) create mode 100644 src/include/curtime.h create mode 100644 src/libs/libgroff/curtime.cpp diff --git a/doc/groff.texinfo b/doc/groff.texinfo index 066b5274..1d3c7a9f 100644 --- a/doc/groff.texinfo +++ b/doc/groff.texinfo @@ -1453,6 +1453,12 @@ default directory (on Unix and GNU/Linux systems, this is usually @item GROFF_TYPESETTER @tindex GROFF_TYPESETTER@r{, environment variable} The default output device. + +@item SOURCE_DATE_EPOCH +@tindex SOURCE_DATE_EPOCH@r{, environment variable} +A timestamp (expressed as seconds since the Unix epoch) to use in place of +the current time when initializing time-based built-in registers such as +@code{\n[seconds]}. @end table Note that MS-DOS and MS-Windows ports of @code{groff} use semi-colons, diff --git a/src/devices/grohtml/grohtml.man b/src/devices/grohtml/grohtml.man index 51eae224..4be4abbc 100644 --- a/src/devices/grohtml/grohtml.man +++ b/src/devices/grohtml/grohtml.man @@ -419,6 +419,13 @@ and for more details. . . +.TP +.SM +.B SOURCE_DATE_EPOCH +A timestamp (expressed as seconds since the Unix epoch) to use as the +creation timestamp in place of the current time. +. +. .\" -------------------------------------------------------------------- .SH BUGS .\" -------------------------------------------------------------------- diff --git a/src/devices/grohtml/post-html.cpp b/src/devices/grohtml/post-html.cpp index fefbf014..b5fc5167 100644 --- a/src/devices/grohtml/post-html.cpp +++ b/src/devices/grohtml/post-html.cpp @@ -28,6 +28,7 @@ along with this program. If not, see . */ #include "html.h" #include "html-text.h" #include "html-table.h" +#include "curtime.h" #include @@ -5013,7 +5014,7 @@ void html_printer::do_file_components (void) .put_string(Version_string) .end_comment(); - t = time(0); + t = current_time(); html.begin_comment("CreationDate: ") .put_string(ctime(&t), strlen(ctime(&t))-1) .end_comment(); @@ -5126,7 +5127,7 @@ html_printer::~html_printer() .put_string(Version_string) .end_comment(); - t = time(0); + t = current_time(); html.begin_comment("CreationDate: ") .put_string(ctime(&t), strlen(ctime(&t))-1) .end_comment(); diff --git a/src/devices/gropdf/gropdf.man b/src/devices/gropdf/gropdf.man index 3bbace6a..cc0c82f1 100644 --- a/src/devices/gropdf/gropdf.man +++ b/src/devices/gropdf/gropdf.man @@ -1029,6 +1029,13 @@ and for more details. . . +.TP +.SM +.B SOURCE_DATE_EPOCH +A timestamp (expressed as seconds since the Unix epoch) to use as the +creation timestamp in place of the current time. +. +. .\" -------------------------------------------------------------------- .SH FILES .\" -------------------------------------------------------------------- diff --git a/src/devices/gropdf/gropdf.pl b/src/devices/gropdf/gropdf.pl index 035d1238..c25c4c67 100644 --- a/src/devices/gropdf/gropdf.pl +++ b/src/devices/gropdf/gropdf.pl @@ -239,13 +239,14 @@ elsif (exists($ppsz{$papersz})) @defaultmb=@mediabox=(0,0,$ppsz{$papersz}->[0],$ppsz{$papersz}->[1]); } -my (@dt)=localtime(time); +my (@dt)=localtime($ENV{SOURCE_DATE_EPOCH} || time); my $dt=PDFDate(\@dt); my %info=('Creator' => "(groff version $cfg{GROFF_VERSION})", 'Producer' => "(gropdf version $cfg{GROFF_VERSION})", 'ModDate' => "($dt)", 'CreationDate' => "($dt)"); + while (<>) { chomp; diff --git a/src/devices/grops/grops.man b/src/devices/grops/grops.man index 99fb7486..272c2d18 100644 --- a/src/devices/grops/grops.man +++ b/src/devices/grops/grops.man @@ -1419,6 +1419,13 @@ and for more details. . . +.TP +.SM +.B SOURCE_DATE_EPOCH +A timestamp (expressed as seconds since the Unix epoch) to use as the +creation timestamp in place of the current time. +. +. .\" -------------------------------------------------------------------- .SH FILES .\" -------------------------------------------------------------------- diff --git a/src/devices/grops/ps.cpp b/src/devices/grops/ps.cpp index 745a503b..03e65372 100644 --- a/src/devices/grops/ps.cpp +++ b/src/devices/grops/ps.cpp @@ -28,6 +28,7 @@ along with this program. If not, see . */ #include "cset.h" #include "nonposix.h" #include "paper.h" +#include "curtime.h" #include "ps.h" #include @@ -1390,7 +1391,7 @@ ps_printer::~ps_printer() #else time_t #endif - t = time(0); + t = current_time(); fputs(ctime(&t), out.get_file()); } for (font_pointer_list *f = font_list; f; f = f->next) { diff --git a/src/include/curtime.h b/src/include/curtime.h new file mode 100644 index 00000000..a4105196 --- /dev/null +++ b/src/include/curtime.h @@ -0,0 +1,23 @@ +/* Copyright (C) 2015 Free Software Foundation, Inc. + +This file is part of groff. + +groff is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation, either version 2 of the License, or +(at your option) any later version. + +groff is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +The GNU General Public License version 2 (GPL2) is available in the +internet at . */ + +#ifdef LONG_FOR_TIME_T +long +#else +time_t +#endif +current_time(); diff --git a/src/libs/libgroff/Makefile.sub b/src/libs/libgroff/Makefile.sub index 840d9934..4cb4937a 100644 --- a/src/libs/libgroff/Makefile.sub +++ b/src/libs/libgroff/Makefile.sub @@ -32,6 +32,7 @@ OBJS=\ cmap.$(OBJEXT) \ color.$(OBJEXT) \ cset.$(OBJEXT) \ + curtime.$(OBJEXT) \ device.$(OBJEXT) \ errarg.$(OBJEXT) \ error.$(OBJEXT) \ @@ -82,6 +83,7 @@ CCSRCS=\ $(srcdir)/cmap.cpp \ $(srcdir)/color.cpp \ $(srcdir)/cset.cpp \ + $(srcdir)/curtime.cpp \ $(srcdir)/device.cpp \ $(srcdir)/errarg.cpp \ $(srcdir)/error.cpp \ diff --git a/src/libs/libgroff/curtime.cpp b/src/libs/libgroff/curtime.cpp new file mode 100644 index 00000000..00821b7f --- /dev/null +++ b/src/libs/libgroff/curtime.cpp @@ -0,0 +1,51 @@ +/* Copyright (C) 2015 Free Software Foundation, Inc. + +This file is part of groff. + +groff is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation, either version 2 of the License, or +(at your option) any later version. + +groff is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +The GNU General Public License version 2 (GPL2) is available in the +internet at . */ + +#include +#include +#include +#include +#include + +#include "errarg.h" +#include "error.h" + +#ifdef LONG_FOR_TIME_T +long +#else +time_t +#endif +current_time() +{ + char *source_date_epoch = getenv("SOURCE_DATE_EPOCH"); + + if (source_date_epoch) { + errno = 0; + char *endptr; + long epoch = strtol(source_date_epoch, &endptr, 10); + + if ((errno == ERANGE && (epoch == LONG_MAX || epoch == LONG_MIN)) || + (errno != 0 && epoch == 0)) + fatal("$SOURCE_DATE_EPOCH: strtol: %1", strerror(errno)); + if (endptr == source_date_epoch) + fatal("$SOURCE_DATE_EPOCH: no digits found: %1", endptr); + if (*endptr != '\0') + fatal("$SOURCE_DATE_EPOCH: trailing garbage: %1", endptr); + return epoch; + } else + return time(0); +} diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp index 9594f074..f7d2c18a 100644 --- a/src/roff/troff/input.cpp +++ b/src/roff/troff/input.cpp @@ -36,6 +36,7 @@ along with this program. If not, see . */ #include "input.h" #include "defs.h" #include "unicode.h" +#include "curtime.h" // Needed for getpid() and isatty() #include "posix.h" @@ -8138,7 +8139,7 @@ static void init_registers() #else /* not LONG_FOR_TIME_T */ time_t #endif /* not LONG_FOR_TIME_T */ - t = time(0); + t = current_time(); // Use struct here to work around misfeature in old versions of g++. struct tm *tt = localtime(&t); set_number_reg("seconds", int(tt->tm_sec));