aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-08-02 11:41:36 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-08-02 11:41:36 +0200
commit402fc5a6000bf0ec12f05d4aa2b3e250ec85a60a (patch)
tree7d9a1b7bc77cbd0211e3e4cb31c079778207453a
parenteddb62072f4d4d2402d520e5041d9677fa6efdff (diff)
Implement support for SOURCE_DATE_EPOCH environment variable
reproducible-builds.org suggests the use of an environment variable as a source for time stamps: https://reproducible-builds.org/specs/source-date-epoch/ This commit adds support for setting the default mtime from the variable, if it is set and only defaulting to 0 if not. The timestamp given by the command line switch takes precedence. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--doc/gensquashfs.19
-rw-r--r--doc/tar2sqfs.19
-rw-r--r--include/util.h7
-rw-r--r--lib/Makemodule.am1
-rw-r--r--lib/fstree/fstree.c2
-rw-r--r--lib/util/source_date_epoch.c45
6 files changed, 71 insertions, 2 deletions
diff --git a/doc/gensquashfs.1 b/doc/gensquashfs.1
index d7b78a1..ab729d7 100644
--- a/doc/gensquashfs.1
+++ b/doc/gensquashfs.1
@@ -58,7 +58,7 @@ rd.
uid=<value>;0
gid=<value>;0
mode=<value>;0755
-mtime=<value>;0
+mtime=<value>;\fB$SOURCE\_DATE\_EPOCH\fR if set, 0 otherwise
.TE
.TP
.TP
@@ -148,6 +148,13 @@ file /bin/bash 0755 0 0
file "/opt/my app/\\"special\\"/data" 0600 0 0
.fi
.in
+.SH ENVIRONEMNT VARIABLES
+If the command line switch \fB\-\-defaults\fR is not used or no default mtime
+is specified, the value of the environment variable \fBSOURCE\_DATE\_EPOCH\fR
+is used for all file and filesystem timestamps.
+
+If \fBSOURCE\_DATE\_EPOCH\fR is not set, not a parsable number or it is out of
+range, the timestamps default to 0.
.SH AUTHOR
Written by David Oberhollenzer.
.SH COPYRIGHT
diff --git a/doc/tar2sqfs.1 b/doc/tar2sqfs.1
index 76178bf..7965a26 100644
--- a/doc/tar2sqfs.1
+++ b/doc/tar2sqfs.1
@@ -52,7 +52,7 @@ rd.
uid=<value>;0
gid=<value>;0
mode=<value>;0755
-mtime=<value>;0
+mtime=<value>;\fB$SOURCE\_DATE\_EPOCH\fR if set, 0 otherwise
.TE
.TP
.TP
@@ -95,6 +95,13 @@ If any unsupported section or extended attribute key is encountered in an
archive a warning message is written to stderr. If the \fB\-\-no\-skip\fR
option is set, processing aborts. By default, unknown sections and unsupported
extended attributes are simply skipped after issuing a warning.
+.SH ENVIRONEMNT VARIABLES
+If the command line switch \fB\-\-defaults\fR is not used or no default mtime
+is specified, the value of the environment variable \fBSOURCE\_DATE\_EPOCH\fR
+is used for all file and filesystem timestamps.
+
+If \fBSOURCE\_DATE\_EPOCH\fR is not set, not a parsable number or it is out of
+range, the timestamps default to 0.
.SH EXAMPLES
.TP
Turn an uncompressed tar archive into a squashfs image:
diff --git a/include/util.h b/include/util.h
index 9d5cc94..82e3177 100644
--- a/include/util.h
+++ b/include/util.h
@@ -83,4 +83,11 @@ int padd_file(int outfd, uint64_t size, size_t blocksize);
uint32_t update_crc32(uint32_t crc, const void *data, size_t size);
+/*
+ If the environment variable SOURCE_DATE_EPOCH is set to a parsable number
+ that fits into an unsigned 32 bit value, return its value. Otherwise,
+ default to 0.
+ */
+uint32_t get_source_date_epoch(void);
+
#endif /* UTIL_H */
diff --git a/lib/Makemodule.am b/lib/Makemodule.am
index 5a8ffaa..f49ff91 100644
--- a/lib/Makemodule.am
+++ b/lib/Makemodule.am
@@ -45,6 +45,7 @@ libutil_a_SOURCES += lib/util/print_version.c lib/util/mkdir_p.c
libutil_a_SOURCES += lib/util/str_table.c include/str_table.h
libutil_a_SOURCES += lib/util/dirstack.c lib/util/padd_file.c
libutil_a_SOURCES += lib/util/read_data_at.c lib/util/crc32.c
+libutil_a_SOURCES += lib/util/source_date_epoch.c
if WITH_GZIP
libcompress_a_SOURCES += lib/comp/gzip.c
diff --git a/lib/fstree/fstree.c b/lib/fstree/fstree.c
index 3c240e7..6955c17 100644
--- a/lib/fstree/fstree.c
+++ b/lib/fstree/fstree.c
@@ -7,6 +7,7 @@
#include "config.h"
#include "fstree.h"
+#include "util.h"
#include <string.h>
#include <stdlib.h>
@@ -110,6 +111,7 @@ int fstree_init(fstree_t *fs, size_t block_size, char *defaults)
memset(fs, 0, sizeof(*fs));
fs->defaults.st_mode = S_IFDIR | 0755;
fs->defaults.st_blksize = block_size;
+ fs->defaults.st_mtime = get_source_date_epoch();
fs->block_size = block_size;
if (defaults != NULL && process_defaults(&fs->defaults, defaults) != 0)
diff --git a/lib/util/source_date_epoch.c b/lib/util/source_date_epoch.c
new file mode 100644
index 0000000..1397e52
--- /dev/null
+++ b/lib/util/source_date_epoch.c
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * source_date_epoch.h
+ *
+ * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "config.h"
+#include "util.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+
+uint32_t get_source_date_epoch(void)
+{
+ const char *str, *ptr;
+ uint32_t x, tval = 0;
+
+ str = getenv("SOURCE_DATE_EPOCH");
+
+ if (str == NULL || *str == '\0')
+ return 0;
+
+ for (ptr = str; *ptr != '\0'; ++ptr) {
+ if (!isdigit(*ptr))
+ goto fail_nan;
+
+ x = (*ptr) - '0';
+
+ if (tval > (UINT32_MAX - x) / 10)
+ goto fail_ov;
+
+ tval = tval * 10 + x;
+ }
+
+ return tval;
+fail_ov:
+ fprintf(stderr, "WARNING: SOURCE_DATE_EPOCH=%s does not fit into "
+ "32 bit integer\n", str);
+ return 0;
+fail_nan:
+ fprintf(stderr, "WARNING: SOURCE_DATE_EPOCH=%s is not a positive "
+ "number\n", str);
+ return 0;
+}