update-done.c revision 0a2f9085e29c855ec1aaa996ded00fc36b06210c
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder This file is part of systemd.
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder Copyright 2014 Lennart Poettering
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder systemd is free software; you can redistribute it and/or modify it
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder under the terms of the GNU Lesser General Public License as published by
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder the Free Software Foundation; either version 2.1 of the License, or
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder (at your option) any later version.
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder systemd is distributed in the hope that it will be useful, but
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder WITHOUT ANY WARRANTY; without even the implied warranty of
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder Lesser General Public License for more details.
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder You should have received a copy of the GNU Lesser General Public License
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder along with systemd; If not, see <http://www.gnu.org/licenses/>.
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder "This file was created by systemd-update-done. Its only \n" \
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder "purpose is to hold a timestamp of the time this directory\n" \
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder "was updated. See systemd-update-done.service(8).\n"
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroederstatic int apply_timestamp(const char *path, struct timespec *ts) {
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder /* Is the timestamp file already newer than the OS? If so, there's nothing to do. */
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder if (st.st_mtim.tv_sec > ts->tv_sec ||
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder (st.st_mtim.tv_sec == ts->tv_sec && st.st_mtim.tv_nsec >= ts->tv_nsec))
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder /* It is older? Then let's update it */
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder if (utimensat(AT_FDCWD, path, twice, AT_SYMLINK_NOFOLLOW) < 0) {
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder return log_debug("Can't update timestamp file %s, file system is read-only.", path);
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder return log_error_errno(errno, "Failed to update timestamp on %s: %m", path);
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder /* The timestamp file doesn't exist yet? Then let's create it. */
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder r = mac_selinux_create_file_prepare(path, S_IFREG);
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder return log_error_errno(r, "Failed to set SELinux context for %s: %m", path);
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder fd = open(path, O_CREAT|O_EXCL|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder return log_debug("Can't create timestamp file %s, file system is read-only.", path);
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder return log_error_errno(errno, "Failed to create timestamp file %s: %m", path);
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder (void) loop_write(fd, MESSAGE, strlen(MESSAGE), false);
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder return log_error_errno(errno, "Failed to update timestamp on %s: %m", path);
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder log_error_errno(errno, "Failed to stat() timestamp file %s: %m", path);
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder int r, q = 0;
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder log_error_errno(errno, "Failed to stat /usr: %m");
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder log_error_errno(r, "SELinux setup failed: %m");
81f49ee02aaa3bc870401f8883bf52742eb3ea7aJonathan von Schroeder r = apply_timestamp("/etc/.updated", &st.st_mtim);
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder q = apply_timestamp("/var/.updated", &st.st_mtim);
db9680b2bbd9d091b198eaa4e324762921965fb3Christian Maeder return r < 0 || q < 0 ? EXIT_FAILURE : EXIT_SUCCESS;