]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/tmpfiles/tmpfiles.c
build-sys: use #if Y instead of #ifdef Y everywhere
[thirdparty/systemd.git] / src / tmpfiles / tmpfiles.c
index c4f4d46ca10497feabf06052945decd474a8ee89..a3df548002a3f28b9762b2a92f674fb9d04c9437 100644 (file)
@@ -116,7 +116,7 @@ typedef struct Item {
         char *path;
         char *argument;
         char **xattrs;
-#ifdef HAVE_ACL
+#if HAVE_ACL
         acl_t acl_access;
         acl_t acl_default;
 #endif
@@ -617,8 +617,20 @@ static int path_set_perms(Item *i, const char *path) {
          * O_PATH. */
 
         fd = open(path, O_NOFOLLOW|O_CLOEXEC|O_PATH);
-        if (fd < 0)
-                return log_error_errno(errno, "Adjusting owner and mode for %s failed: %m", path);
+        if (fd < 0) {
+                int level = LOG_ERR, r = -errno;
+
+                /* Option "e" operates only on existing objects. Do not
+                 * print errors about non-existent files or directories */
+                if (i->type == EMPTY_DIRECTORY && errno == ENOENT) {
+                        level = LOG_DEBUG;
+                        r = 0;
+                }
+
+                log_full_errno(level, errno, "Adjusting owner and mode for %s failed: %m", path);
+
+                return r;
+        }
 
         if (fstatat(fd, "", &st, AT_EMPTY_PATH) < 0)
                 return log_error_errno(errno, "Failed to fstat() file %s: %m", path);
@@ -724,16 +736,15 @@ static int path_set_xattrs(Item *i, const char *path) {
 
                 n = strlen(*value);
                 log_debug("Setting extended attribute '%s=%s' on %s.", *name, *value, path);
-                if (lsetxattr(path, *name, *value, n, 0) < 0) {
-                        log_error("Setting extended attribute %s=%s on %s failed: %m", *name, *value, path);
-                        return -errno;
-                }
+                if (lsetxattr(path, *name, *value, n, 0) < 0)
+                        return log_error_errno(errno, "Setting extended attribute %s=%s on %s failed: %m",
+                                               *name, *value, path);
         }
         return 0;
 }
 
 static int parse_acls_from_arg(Item *item) {
-#ifdef HAVE_ACL
+#if HAVE_ACL
         int r;
 
         assert(item);
@@ -751,7 +762,7 @@ static int parse_acls_from_arg(Item *item) {
         return 0;
 }
 
-#ifdef HAVE_ACL
+#if HAVE_ACL
 static int path_set_acl(const char *path, const char *pretty, acl_type_t type, acl_t acl, bool modify) {
         _cleanup_(acl_free_charpp) char *t = NULL;
         _cleanup_(acl_freep) acl_t dup = NULL;
@@ -799,7 +810,7 @@ static int path_set_acl(const char *path, const char *pretty, acl_type_t type, a
 
 static int path_set_acls(Item *item, const char *path) {
         int r = 0;
-#ifdef HAVE_ACL
+#if HAVE_ACL
         char fn[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
         _cleanup_close_ int fd = -1;
         struct stat st;
@@ -872,7 +883,7 @@ static int parse_attribute_from_arg(Item *item) {
                 { 's', FS_SECRM_FL },        /* Secure deletion */
                 { 'u', FS_UNRM_FL },         /* Undelete */
                 { 't', FS_NOTAIL_FL },       /* file tail should not be merged */
-                { 'T', FS_TOPDIR_FL },       /* Top of directory hierarchies*/
+                { 'T', FS_TOPDIR_FL },       /* Top of directory hierarchies */
                 { 'C', FS_NOCOW_FL },        /* Do not cow file */
         };
 
@@ -920,7 +931,7 @@ static int parse_attribute_from_arg(Item *item) {
 
                 v = attributes[i].value;
 
-                SET_FLAG(value, v, (mode == MODE_ADD || mode == MODE_SET));
+                SET_FLAG(value, v, IN_SET(mode, MODE_ADD, MODE_SET));
 
                 mask |= v;
         }
@@ -973,7 +984,7 @@ static int path_set_attribute(Item *item, const char *path) {
 
         r = chattr_fd(fd, f, item->attribute_mask);
         if (r < 0)
-                log_full_errno(r == -ENOTTY ? LOG_DEBUG : LOG_WARNING,
+                log_full_errno(r == -ENOTTY || r == -EOPNOTSUPP ? LOG_DEBUG : LOG_WARNING,
                                r,
                                "Cannot set file attribute for '%s', value=0x%08x, mask=0x%08x: %m",
                                path, item->attribute_value, item->attribute_mask);
@@ -1093,19 +1104,14 @@ static int item_do_children(Item *i, const char *path, action_t action) {
 
 static int glob_item(Item *i, action_t action, bool recursive) {
         _cleanup_globfree_ glob_t g = {
-                .gl_closedir = (void (*)(void *)) closedir,
-                .gl_readdir = (struct dirent *(*)(void *)) readdir,
                 .gl_opendir = (void *(*)(const char *)) opendir_nomod,
-                .gl_lstat = lstat,
-                .gl_stat = stat,
         };
         int r = 0, k;
         char **fn;
 
-        errno = 0;
-        k = glob(i->path, GLOB_NOSORT|GLOB_BRACE|GLOB_ALTDIRFUNC, NULL, &g);
-        if (k != 0 && k != GLOB_NOMATCH)
-                return log_error_errno(errno ?: EIO, "glob(%s) failed: %m", i->path);
+        k = safe_glob(i->path, GLOB_NOSORT|GLOB_BRACE, &g);
+        if (k < 0 && k != -ENOENT)
+                return log_error_errno(k, "glob(%s) failed: %m", i->path);
 
         STRV_FOREACH(fn, g.gl_pathv) {
                 k = action(i, *fn);
@@ -1170,7 +1176,7 @@ static int create_item(Item *i) {
                         return log_error_errno(r, "Failed to substitute specifiers in copy source %s: %m", i->argument);
 
                 log_debug("Copying tree \"%s\" to \"%s\".", resolved, i->path);
-                r = copy_tree(resolved, i->path, false);
+                r = copy_tree(resolved, i->path, i->uid_set ? i->uid : UID_INVALID, i->gid_set ? i->gid : GID_INVALID, COPY_REFLINK);
 
                 if (r == -EROFS && stat(i->path, &st) == 0)
                         r = -EEXIST;
@@ -1359,6 +1365,15 @@ static int create_item(Item *i) {
                                         r = symlink_atomic(resolved, i->path);
                                         mac_selinux_create_file_clear();
 
+                                        if (IN_SET(r, -EEXIST, -ENOTEMPTY)) {
+                                                r = rm_rf(i->path, REMOVE_ROOT|REMOVE_PHYSICAL);
+                                                if (r < 0)
+                                                        return log_error_errno(r, "rm -fr %s failed: %m", i->path);
+
+                                                mac_selinux_create_file_prepare(i->path, S_IFLNK);
+                                                r = symlink(resolved, i->path) < 0 ? -errno : 0;
+                                                mac_selinux_create_file_clear();
+                                        }
                                         if (r < 0)
                                                 return log_error_errno(r, "symlink(%s, %s) failed: %m", resolved, i->path);
 
@@ -1649,6 +1664,9 @@ static int process_item(Item *i) {
                 }
         }
 
+        if (chase_symlinks(i->path, NULL, CHASE_NO_AUTOFS, NULL) == -EREMOTE)
+                return t;
+
         r = arg_create ? create_item(i) : 0;
         q = arg_remove ? remove_item(i) : 0;
         p = arg_clean ? clean_item(i) : 0;
@@ -1680,7 +1698,7 @@ static void item_free_contents(Item *i) {
         free(i->argument);
         strv_free(i->xattrs);
 
-#ifdef HAVE_ACL
+#if HAVE_ACL
         acl_free(i->acl_access);
         acl_free(i->acl_default);
 #endif
@@ -2282,7 +2300,7 @@ int main(int argc, char *argv[]) {
                 _cleanup_strv_free_ char **files = NULL;
                 char **f;
 
-                r = conf_files_list_nulstr(&files, ".conf", arg_root, conf_file_dirs);
+                r = conf_files_list_nulstr(&files, ".conf", arg_root, 0, conf_file_dirs);
                 if (r < 0) {
                         log_error_errno(r, "Failed to enumerate tmpfiles.d files: %m");
                         goto finish;