]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
install-file: add a generalized parser for $SOURCE_DATE_EPOCH
authorMike Yuan <me@yhndnzj.com>
Tue, 20 Jan 2026 14:20:57 +0000 (15:20 +0100)
committerMike Yuan <me@yhndnzj.com>
Tue, 20 Jan 2026 14:54:55 +0000 (15:54 +0100)
src/repart/repart.c
src/shared/install-file.c
src/shared/install-file.h
src/sysusers/sysusers.c

index 48e05d3769ce71ae9e143060369ef6520249fc0c..100e03aab556496d5025adcd1e5b06f8d7600501 100644 (file)
@@ -31,7 +31,6 @@
 #include "dirent-util.h"
 #include "dissect-image.h"
 #include "efivars.h"
-#include "env-util.h"
 #include "errno-util.h"
 #include "extract-word.h"
 #include "factory-reset.h"
@@ -48,6 +47,7 @@
 #include "id128-util.h"
 #include "image-policy.h"
 #include "initrd-util.h"
+#include "install-file.h"
 #include "io-util.h"
 #include "json-util.h"
 #include "libmount-util.h"
@@ -6275,30 +6275,6 @@ static int make_subvolumes_by_source_inode_hashmap(
         return 0;
 }
 
-static usec_t epoch_or_infinity(void) {
-        static usec_t cache;
-        static bool cached = false;
-        uint64_t epoch;
-        int r;
-
-        if (cached)
-                return cache;
-
-        r = secure_getenv_uint64("SOURCE_DATE_EPOCH", &epoch);
-        if (r >= 0) {
-                if (epoch <= UINT64_MAX / USEC_PER_SEC) { /* Overflow check */
-                        cached = true;
-                        return (cache = epoch * USEC_PER_SEC);
-                }
-                r = -ERANGE;
-        }
-        if (r != -ENXIO)
-                log_debug_errno(r, "Failed to parse $SOURCE_DATE_EPOCH, ignoring: %m");
-
-        cached = true;
-        return (cache = USEC_INFINITY);
-}
-
 static int file_is_denylisted(const char *source, Hashmap *denylist) {
         _cleanup_close_ int pfd = -EBADF;
         struct stat st, rst;
@@ -6391,7 +6367,7 @@ static int do_copy_files(Context *context, Partition *p, const char *root) {
                 _cleanup_hashmap_free_ Hashmap *denylist = NULL;
                 _cleanup_hashmap_free_ Hashmap *subvolumes_by_source_inode = NULL;
                 _cleanup_close_ int sfd = -EBADF, pfd = -EBADF, tfd = -EBADF;
-                usec_t ts = epoch_or_infinity();
+                usec_t ts = parse_source_date_epoch();
 
                 r = make_copy_files_denylist(context, p, line->source, line->target, &denylist);
                 if (r < 0)
@@ -6532,7 +6508,7 @@ static int do_make_directories(Partition *p, const char *root) {
         }
 
         STRV_FOREACH(d, override_dirs ?: p->make_directories) {
-                r = mkdir_p_root_full(root, *d, UID_INVALID, GID_INVALID, 0755, epoch_or_infinity(), subvolumes);
+                r = mkdir_p_root_full(root, *d, UID_INVALID, GID_INVALID, 0755, parse_source_date_epoch(), subvolumes);
                 if (r < 0)
                         return log_error_errno(r, "Failed to create directory '%s' in file system: %m", *d);
         }
index b84e0a2986e4fbd4c1bd8568983a6f27b92c7b91..5abbd554638407096b05326b3eb454358a22dde0 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "btrfs-util.h"
 #include "chattr-util.h"
+#include "env-util.h"
 #include "errno-util.h"
 #include "fd-util.h"
 #include "fs-util.h"
@@ -13,6 +14,7 @@
 #include "log.h"
 #include "rm-rf.h"
 #include "sync-util.h"
+#include "time-util.h"
 
 static int fs_make_very_read_only(int fd) {
         struct stat st;
@@ -301,3 +303,38 @@ int install_file(int source_atfd, const char *source_name,
 
         return 0;
 }
+
+usec_t parse_source_date_epoch(void) {
+        static usec_t cache;
+        static bool cached = false;
+        int r;
+
+        if (cached)
+                return cache;
+
+        uint64_t t;
+        r = secure_getenv_uint64("SOURCE_DATE_EPOCH", &t);
+        if (r >= 0) {
+                if (MUL_SAFE(&cache, t, USEC_PER_SEC)) {
+                        cached = true;
+                        return cache;
+                }
+
+                r = -ERANGE;
+        }
+        if (r != -ENXIO)
+                log_debug_errno(r, "Failed to parse $SOURCE_DATE_EPOCH, ignoring: %m");
+
+        cached = true;
+        return (cache = USEC_INFINITY);
+}
+
+usec_t source_date_epoch_or_now(void) {
+        usec_t epoch;
+
+        epoch = parse_source_date_epoch();
+        if (epoch != USEC_INFINITY)
+                return epoch;
+
+        return now(CLOCK_REALTIME);
+}
index f5e2fa33caab83a69cf4ee17a1d1ec2ba7f73607..6cd21c93c463ef96ed7538047b0dab7a475190f3 100644 (file)
@@ -13,3 +13,6 @@ typedef enum InstallFileFlags {
 } InstallFileFlags;
 
 int install_file(int source_atfd, const char *source_name, int target_atfd, const char *target_name, InstallFileFlags flags);
+
+usec_t parse_source_date_epoch(void);
+usec_t source_date_epoch_or_now(void);
index 3350826780faa47757463ea33ee86b193b2c2fc6..a113928f97789a164434c25dbdea5f6bdfb257c2 100644 (file)
@@ -12,7 +12,6 @@
 #include "copy.h"
 #include "creds-util.h"
 #include "dissect-image.h"
-#include "env-util.h"
 #include "errno-util.h"
 #include "extract-word.h"
 #include "fd-util.h"
@@ -21,6 +20,7 @@
 #include "fs-util.h"
 #include "hashmap.h"
 #include "image-policy.h"
+#include "install-file.h"
 #include "label-util.h"
 #include "libaudit-util.h"
 #include "libcrypt-util.h"
@@ -596,18 +596,6 @@ done:
         return 0;
 }
 
-static usec_t epoch_or_now(void) {
-        uint64_t epoch;
-
-        if (secure_getenv_uint64("SOURCE_DATE_EPOCH", &epoch) >= 0) {
-                if (epoch > UINT64_MAX/USEC_PER_SEC) /* Overflow check */
-                        return USEC_INFINITY;
-                return (usec_t) epoch * USEC_PER_SEC;
-        }
-
-        return now(CLOCK_REALTIME);
-}
-
 static int write_temporary_shadow(
                 Context *c,
                 const char *shadow_path,
@@ -635,7 +623,7 @@ static int write_temporary_shadow(
         if (r < 0)
                 return log_debug_errno(r, "Failed to open temporary copy of %s: %m", shadow_path);
 
-        lstchg = (long) (epoch_or_now() / USEC_PER_DAY);
+        lstchg = (long) (source_date_epoch_or_now() / USEC_PER_DAY);
 
         original = fopen(shadow_path, "re");
         if (original) {