diff options
Diffstat (limited to 'src/update-done/update-done.c')
-rw-r--r-- | src/update-done/update-done.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/src/update-done/update-done.c b/src/update-done/update-done.c new file mode 100644 index 0000000..c76c2d1 --- /dev/null +++ b/src/update-done/update-done.c @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "alloc-util.h" +#include "fileio-label.h" +#include "selinux-util.h" +#include "util.h" + +#define MESSAGE \ + "# This file was created by systemd-update-done. Its only \n" \ + "# purpose is to hold a timestamp of the time this directory\n" \ + "# was updated. See man:systemd-update-done.service(8).\n" + +static int apply_timestamp(const char *path, struct timespec *ts) { + _cleanup_free_ char *message = NULL; + int r; + + /* + * We store the timestamp both as mtime of the file and in the file itself, + * to support filesystems which cannot store nanosecond-precision timestamps. + */ + + if (asprintf(&message, + MESSAGE + "TIMESTAMP_NSEC=" NSEC_FMT "\n", + timespec_load_nsec(ts)) < 0) + return log_oom(); + + r = write_string_file_atomic_label_ts(path, message, ts); + if (r == -EROFS) + return log_debug("Cannot create \"%s\", file system is read-only.", path); + if (r < 0) + return log_error_errno(r, "Failed to write \"%s\": %m", path); + return 0; +} + +int main(int argc, char *argv[]) { + struct stat st; + int r, q = 0; + + log_setup_service(); + + if (stat("/usr", &st) < 0) { + log_error_errno(errno, "Failed to stat /usr: %m"); + return EXIT_FAILURE; + } + + r = mac_selinux_init(); + if (r < 0) { + log_error_errno(r, "SELinux setup failed: %m"); + return EXIT_FAILURE; + } + + r = apply_timestamp("/etc/.updated", &st.st_mtim); + q = apply_timestamp("/var/.updated", &st.st_mtim); + + return r < 0 || q < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} |