]>
Commit | Line | Data |
---|---|---|
8ea48dfc LP |
1 | /*** |
2 | This file is part of systemd. | |
3 | ||
4 | Copyright 2014 Lennart Poettering | |
5 | ||
6 | systemd is free software; you can redistribute it and/or modify it | |
7 | under the terms of the GNU Lesser General Public License as published by | |
8 | the Free Software Foundation; either version 2.1 of the License, or | |
9 | (at your option) any later version. | |
10 | ||
11 | systemd is distributed in the hope that it will be useful, but | |
12 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | Lesser General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU Lesser General Public License | |
17 | along with systemd; If not, see <http://www.gnu.org/licenses/>. | |
18 | ***/ | |
19 | ||
3ffd4af2 | 20 | #include "fd-util.h" |
c004493c | 21 | #include "io-util.h" |
d7b8eec7 | 22 | #include "selinux-util.h" |
3ffd4af2 | 23 | #include "util.h" |
8ea48dfc | 24 | |
4aa4d2ae | 25 | #define MESSAGE \ |
fb8b0869 IS |
26 | "# This file was created by systemd-update-done. Its only \n" \ |
27 | "# purpose is to hold a timestamp of the time this directory\n" \ | |
28 | "# was updated. See systemd-update-done.service(8).\n" | |
4aa4d2ae | 29 | |
8ea48dfc | 30 | static int apply_timestamp(const char *path, struct timespec *ts) { |
0a2f9085 LP |
31 | struct timespec twice[2] = { |
32 | *ts, | |
33 | *ts | |
34 | }; | |
fb8b0869 IS |
35 | int fd = -1; |
36 | _cleanup_fclose_ FILE *f = NULL; | |
37 | int r; | |
8ea48dfc LP |
38 | |
39 | assert(path); | |
40 | assert(ts); | |
41 | ||
fb8b0869 IS |
42 | /* |
43 | * We store the timestamp both as mtime of the file and in the file itself, | |
44 | * to support filesystems which cannot store nanosecond-precision timestamps. | |
45 | * Hence, don't bother updating the file, let's just rewrite it. | |
46 | */ | |
8ea48dfc | 47 | |
fb8b0869 IS |
48 | r = mac_selinux_create_file_prepare(path, S_IFREG); |
49 | if (r < 0) | |
50 | return log_error_errno(r, "Failed to set SELinux context for %s: %m", path); | |
8ea48dfc | 51 | |
fb8b0869 IS |
52 | fd = open(path, O_CREAT|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644); |
53 | mac_selinux_create_file_clear(); | |
8ea48dfc | 54 | |
fb8b0869 IS |
55 | if (fd < 0) { |
56 | if (errno == EROFS) | |
57 | return log_debug("Can't create timestamp file %s, file system is read-only.", path); | |
8ea48dfc | 58 | |
fb8b0869 IS |
59 | return log_error_errno(errno, "Failed to create/open timestamp file %s: %m", path); |
60 | } | |
7dbb1d08 | 61 | |
fb8b0869 IS |
62 | f = fdopen(fd, "w"); |
63 | if (!f) { | |
64 | safe_close(fd); | |
65 | return log_error_errno(errno, "Failed to fdopen() timestamp file %s: %m", path); | |
66 | } | |
8ea48dfc | 67 | |
fb8b0869 IS |
68 | (void) fprintf(f, |
69 | "%s" | |
70 | "TimestampNSec=" NSEC_FMT "\n", | |
71 | MESSAGE, timespec_load_nsec(ts)); | |
8ea48dfc | 72 | |
fb8b0869 | 73 | fflush(f); |
4aa4d2ae | 74 | |
fb8b0869 IS |
75 | if (futimens(fd, twice) < 0) |
76 | return log_error_errno(errno, "Failed to update timestamp on %s: %m", path); | |
8ea48dfc LP |
77 | |
78 | return 0; | |
79 | } | |
80 | ||
81 | int main(int argc, char *argv[]) { | |
82 | struct stat st; | |
7dbb1d08 | 83 | int r, q = 0; |
8ea48dfc LP |
84 | |
85 | log_set_target(LOG_TARGET_AUTO); | |
86 | log_parse_environment(); | |
87 | log_open(); | |
88 | ||
89 | if (stat("/usr", &st) < 0) { | |
755bde37 | 90 | log_error_errno(errno, "Failed to stat /usr: %m"); |
8ea48dfc LP |
91 | return EXIT_FAILURE; |
92 | } | |
93 | ||
c3dacc8b | 94 | r = mac_selinux_init(); |
7dbb1d08 | 95 | if (r < 0) { |
da927ba9 | 96 | log_error_errno(r, "SELinux setup failed: %m"); |
7dbb1d08 ZJS |
97 | goto finish; |
98 | } | |
8ea48dfc | 99 | |
7dbb1d08 | 100 | r = apply_timestamp("/etc/.updated", &st.st_mtim); |
8ea48dfc | 101 | q = apply_timestamp("/var/.updated", &st.st_mtim); |
8ea48dfc | 102 | |
7dbb1d08 ZJS |
103 | finish: |
104 | return r < 0 || q < 0 ? EXIT_FAILURE : EXIT_SUCCESS; | |
8ea48dfc | 105 | } |