>From c111bb75c4793bbde55d173969492828d83496db Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 27 Aug 2014 09:06:26 +0100 Subject: [PATCH] Implement `SOURCE_DATE_EPOCH' for reproducible builds. * src/include/curtime.h: New file. * src/libs/libgroff/curtime.cpp: New file. * src/libs/libgroff/libgroff.am (libgroff_a_SOURCES): Add src/libs/libgroff/curtime.cpp. * src/roff/troff/input.cpp (init_registers): Use `current_time' instead of `time(0)'. * src/devices/grohtml/post-html.cpp (html_printer::do_file_components): Likewise. (html_printer::~html_printer): Likewise. * src/devices/grops/ps.cpp (ps_printer::~ps_printer): Likewise. * src/devices/gropdf/gropdf.pl: Use `$ENV{SOURCE_DATE_EPOCH}` if available in preference to `time`. * doc/groff.texi (Environment): Document `SOURCE_DATE_EPOCH'. * src/devices/grohtml/grohtml.1.man (ENVIRONMENT): Likewise. * src/devices/gropdf/gropdf.1.man (ENVIRONMENT): Likewise. * src/devices/grops/grops.1.man (ENVIRONMENT): Likewise. --- ChangeLog | 23 ++++++++++++++++++ doc/groff.texi | 6 +++++ src/devices/grohtml/grohtml.1.man | 7 ++++++ src/devices/grohtml/post-html.cpp | 5 ++-- src/devices/gropdf/gropdf.1.man | 7 ++++++ src/devices/gropdf/gropdf.pl | 3 ++- src/devices/grops/grops.1.man | 7 ++++++ src/devices/grops/ps.cpp | 3 ++- src/include/curtime.h | 23 ++++++++++++++++++ src/libs/libgroff/curtime.cpp | 51 +++++++++++++++++++++++++++++++++++++++ src/libs/libgroff/libgroff.am | 1 + src/roff/troff/input.cpp | 3 ++- 12 files changed, 134 insertions(+), 5 deletions(-) create mode 100644 src/include/curtime.h create mode 100644 src/libs/libgroff/curtime.cpp diff --git a/ChangeLog b/ChangeLog index 2333859..98eac45 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2015-11-05 Colin Watson + + Implement `SOURCE_DATE_EPOCH' for reproducible builds. + + * src/include/curtime.h: New file. + * src/libs/libgroff/curtime.cpp: New file. + * src/libs/libgroff/libgroff.am (libgroff_a_SOURCES): Add + src/libs/libgroff/curtime.cpp. + + * src/roff/troff/input.cpp (init_registers): Use `current_time' + instead of `time(0)'. + * src/devices/grohtml/post-html.cpp + (html_printer::do_file_components): Likewise. + (html_printer::~html_printer): Likewise. + * src/devices/grops/ps.cpp (ps_printer::~ps_printer): Likewise. + * src/devices/gropdf/gropdf.pl: Use `$ENV{SOURCE_DATE_EPOCH}` if + available in preference to `time`. + + * doc/groff.texi (Environment): Document `SOURCE_DATE_EPOCH'. + * src/devices/grohtml/grohtml.1.man (ENVIRONMENT): Likewise. + * src/devices/gropdf/gropdf.1.man (ENVIRONMENT): Likewise. + * src/devices/grops/grops.1.man (ENVIRONMENT): Likewise. + 2015-10-27 Deri James gropdf was choking on -I flag passed by groff, now uses diff --git a/doc/groff.texi b/doc/groff.texi index 00a0f6d..9dc63eb 100644 --- a/doc/groff.texi +++ b/doc/groff.texi @@ -1453,6 +1453,12 @@ default directory (on Unix and GNU/Linux systems, this is usually @item GROFF_TYPESETTER @tindex address@hidden, environment variable} The default output device. + address@hidden SOURCE_DATE_EPOCH address@hidden address@hidden, 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 address@hidden @end table Note that MS-DOS and MS-Windows ports of @code{groff} use semi-colons, diff --git a/src/devices/grohtml/grohtml.1.man b/src/devices/grohtml/grohtml.1.man index 2efdd81..f8c45dd 100644 --- a/src/devices/grohtml/grohtml.1.man +++ b/src/devices/grohtml/grohtml.1.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 fefbf01..b5fc516 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.1.man b/src/devices/gropdf/gropdf.1.man index 25287a6..4a06c0f 100644 --- a/src/devices/gropdf/gropdf.1.man +++ b/src/devices/gropdf/gropdf.1.man @@ -1024,6 +1024,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 0744378..b95169e 100644 --- a/src/devices/gropdf/gropdf.pl +++ b/src/devices/gropdf/gropdf.pl @@ -259,13 +259,14 @@ elsif (exists($ppsz{$papersz})) @address@hidden(0,0,$ppsz{$papersz}->[0],$ppsz{$papersz}->[1]); } -my (@dt)=localtime(time); +my (@dt)=localtime($ENV{SOURCE_DATE_EPOCH} || time); my $dt=PDFDate(address@hidden); 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.1.man b/src/devices/grops/grops.1.man index e7064d2..55b26f7 100644 --- a/src/devices/grops/grops.1.man +++ b/src/devices/grops/grops.1.man @@ -1423,6 +1423,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 745a503..03e6537 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 0000000..a410519 --- /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/curtime.cpp b/src/libs/libgroff/curtime.cpp new file mode 100644 index 0000000..00821b7 --- /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/libs/libgroff/libgroff.am b/src/libs/libgroff/libgroff.am index 78e3394..e215f2e 100644 --- a/src/libs/libgroff/libgroff.am +++ b/src/libs/libgroff/libgroff.am @@ -33,6 +33,7 @@ libgroff_a_SOURCES = \ src/libs/libgroff/cmap.cpp \ src/libs/libgroff/color.cpp \ src/libs/libgroff/cset.cpp\ + src/libs/libgroff/curtime.cpp \ src/libs/libgroff/device.cpp \ src/libs/libgroff/errarg.cpp \ src/libs/libgroff/error.cpp \ diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp index 9594f07..f7d2c18 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)); -- 2.6.2