Package: halibut / 1.2-2

source-date-epoch.patch Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
From 7570c1374f373d6152f5324c3e8749049009088e Mon Sep 17 00:00:00 2001
From: Colin Watson <cjwatson@debian.org>
Date: Fri, 6 Nov 2015 16:21:15 +0000
Subject: Implement SOURCE_DATE_EPOCH for reproducible builds.

Forwarded: no
Last-Update: 2015-11-06

Patch-Name: source-date-epoch.patch
---
 error.c   | 17 +++++++++++++++++
 halibut.h |  8 ++++++++
 input.c   |  4 ++--
 misc.c    | 33 +++++++++++++++++++++++++++++++++
 4 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/error.c b/error.c
index 7589175..1b9024b 100644
--- a/error.c
+++ b/error.c
@@ -5,6 +5,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
+#include <errno.h>
+#include <string.h>
 #include "halibut.h"
 
 /*
@@ -369,3 +371,18 @@ void err_chm_badname(const filepos *fpos, const char *sp)
     do_error(fpos, "CHM internal file name `%s' begins with"
              " a reserved character", sp);
 }
+
+void err_epoch_strtol(void)
+{
+    do_error(NULL, "$SOURCE_DATE_EPOCH: strtol: %s", strerror(errno));
+}
+
+void err_epoch_nodigits(const char *trailing)
+{
+    do_error(NULL, "$SOURCE_DATE_EPOCH: no digits found: %s", trailing);
+}
+
+void err_epoch_trailing_garbage(const char *trailing)
+{
+    do_error(NULL, "$SOURCE_DATE_EPOCH: trailing garbage: %s", trailing);
+}
diff --git a/halibut.h b/halibut.h
index 327562e..3a78910 100644
--- a/halibut.h
+++ b/halibut.h
@@ -324,6 +324,12 @@ void err_sfntbadhdr(const filepos *fpos);
 void err_sfntbadglyph(const filepos *fpos, unsigned wc);
 /* CHM internal file names can't start with # or $ */
 void err_chm_badname(const filepos *fpos, const char *sp);
+/* source date epoch: strtol failed */
+void err_epoch_strtol(void);
+/* source date epoch: no digits found */
+void err_epoch_nodigits(const char *trailing);
+/* source date epoch: trailing garbage */
+void err_epoch_trailing_garbage(const char *trailing);
 
 /*
  * malloc.c
@@ -455,6 +461,8 @@ void cmdline_cfg_add(paragraph *cfg, char *string);
 paragraph *cmdline_cfg_new(void);
 paragraph *cmdline_cfg_simple(char *string, ...);
 
+time_t current_time(void);
+
 /*
  * input.c
  */
diff --git a/input.c b/input.c
index 88ace8f..4294000 100644
--- a/input.c
+++ b/input.c
@@ -1301,7 +1301,7 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx,
 		    dtor(t), t = get_token(in);
 		    if (t.type != tok_lbrace) {
 			if (wd.type == word_Normal) {
-			    time_t thetime = time(NULL);
+			    time_t thetime = current_time();
 			    struct tm *broken = localtime(&thetime);
 			    already = TRUE;
 			    wdtext = ustrftime(NULL, broken);
@@ -1320,7 +1320,7 @@ static void read_file(paragraph ***ret, input *in, indexdata *idx,
 				rdadds(&rs, t.text);
 			}
 			if (wd.type == word_Normal) {
-			    time_t thetime = time(NULL);
+			    time_t thetime = current_time();
 			    struct tm *broken = localtime(&thetime);
 			    wdtext = ustrftime(rs.text, broken);
 			    wd.type = style;
diff --git a/misc.c b/misc.c
index 8a426f2..a4f5679 100644
--- a/misc.c
+++ b/misc.c
@@ -3,6 +3,9 @@
  */
 
 #include <stdarg.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <limits.h>
 #include "halibut.h"
 
 char *adv(char *s) {
@@ -580,3 +583,33 @@ paragraph *cmdline_cfg_simple(char *string, ...)
 
     return p;
 }
+
+time_t current_time(void)
+{
+    char *source_date_epoch;
+
+    source_date_epoch = getenv("SOURCE_DATE_EPOCH");
+    if (source_date_epoch) {
+	char *endptr;
+	long epoch;
+
+	errno = 0;
+	epoch = strtol(source_date_epoch, &endptr, 10);
+
+	if ((errno == ERANGE && (epoch == LONG_MAX || epoch == LONG_MIN)) ||
+	    (errno != 0 && epoch == 0)) {
+	    err_epoch_strtol();
+	    exit(EXIT_FAILURE);
+	}
+	if (endptr == source_date_epoch) {
+	    err_epoch_nodigits(endptr);
+	    exit(EXIT_FAILURE);
+	}
+	if (*endptr != '\0') {
+	    err_epoch_trailing_garbage(endptr);
+	    exit(EXIT_FAILURE);
+	}
+	return epoch;
+    } else
+	return time(NULL);
+}