From: Mike Yuan Date: Tue, 20 Jan 2026 14:20:57 +0000 (+0100) Subject: install-file: add a generalized parser for $SOURCE_DATE_EPOCH X-Git-Tag: v260-rc1~349^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2f7fdef55e89ffff83a418ae674e893dd6e0a044;p=thirdparty%2Fsystemd.git install-file: add a generalized parser for $SOURCE_DATE_EPOCH --- diff --git a/src/repart/repart.c b/src/repart/repart.c index 48e05d3769c..100e03aab55 100644 --- a/src/repart/repart.c +++ b/src/repart/repart.c @@ -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); } diff --git a/src/shared/install-file.c b/src/shared/install-file.c index b84e0a2986e..5abbd554638 100644 --- a/src/shared/install-file.c +++ b/src/shared/install-file.c @@ -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); +} diff --git a/src/shared/install-file.h b/src/shared/install-file.h index f5e2fa33caa..6cd21c93c46 100644 --- a/src/shared/install-file.h +++ b/src/shared/install-file.h @@ -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); diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 3350826780f..a113928f977 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -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) {