CREATE_SYMLINK = 'L',
CREATE_CHAR_DEVICE = 'c',
CREATE_BLOCK_DEVICE = 'b',
+ ADJUST_MODE = 'm',
/* These ones take globs */
IGNORE_PATH = 'x',
dev_t rootdev,
bool mountpoint,
int maxdepth,
- bool keep_this_level)
-{
+ bool keep_this_level) {
+
struct dirent *dent;
struct timespec times[2];
bool deleted = false;
continue;
if (fstatat(dirfd(d), dent->d_name, &s, AT_SYMLINK_NOFOLLOW) < 0) {
+ if (errno == ENOENT)
+ continue;
- if (errno != ENOENT) {
+ /* FUSE, NFS mounts, SELinux might return EACCES */
+ if (errno == EACCES)
+ log_debug("stat(%s/%s) failed: %m", p, dent->d_name);
+ else
log_error("stat(%s/%s) failed: %m", p, dent->d_name);
- r = -errno;
- }
-
+ r = -errno;
continue;
}
return r;
}
-static int item_set_perms(Item *i, const char *path) {
+static int item_set_perms_full(Item *i, const char *path, bool ignore_enoent) {
+ int r;
+
/* not using i->path directly because it may be a glob */
if (i->mode_set)
if (chmod(path, i->mode) < 0) {
- log_error("chmod(%s) failed: %m", path);
- return -errno;
+ if (errno != ENOENT || !ignore_enoent) {
+ log_error("chmod(%s) failed: %m", path);
+ return -errno;
+ }
}
if (i->uid_set || i->gid_set)
i->uid_set ? i->uid : (uid_t) -1,
i->gid_set ? i->gid : (gid_t) -1) < 0) {
- log_error("chown(%s) failed: %m", path);
- return -errno;
+ if (errno != ENOENT || !ignore_enoent) {
+ log_error("chown(%s) failed: %m", path);
+ return -errno;
+ }
}
- return label_fix(path, false, false);
+ r = label_fix(path, false, false);
+ return r == -ENOENT && ignore_enoent ? 0 : r;
+}
+
+static int item_set_perms(Item *i, const char *path) {
+ return item_set_perms_full(i, path, false);
}
static int write_one_file(Item *i, const char *path) {
- int r, e, fd, flags;
+ int e, flags;
+ int fd = -1;
struct stat st;
+ int r = 0;
flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND :
i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC : 0;
}
static int create_item(Item *i) {
- int r, e;
+ int e;
struct stat st;
+ int r = 0;
assert(i);
if (r < 0)
return r;
break;
+
case WRITE_FILE:
r = glob_item(i, write_one_file);
if (r < 0)
break;
+ case ADJUST_MODE:
+ r = item_set_perms_full(i, i->path, true);
+ if (r < 0)
+ return r;
+
+ break;
+
case TRUNCATE_DIRECTORY:
case CREATE_DIRECTORY:
case RELABEL_PATH:
case RECURSIVE_RELABEL_PATH:
case WRITE_FILE:
+ case ADJUST_MODE:
break;
case REMOVE_PATH:
case RELABEL_PATH:
case RECURSIVE_RELABEL_PATH:
case WRITE_FILE:
+ case ADJUST_MODE:
break;
case REMOVE_PATH:
free(i);
}
-static inline void item_freep(Item **i) {
- if (*i)
- item_free(*i);
-}
+DEFINE_TRIVIAL_CLEANUP_FUNC(Item*, item_free);
#define _cleanup_item_free_ _cleanup_(item_freep)
static bool item_equal(Item *a, Item *b) {
case RECURSIVE_REMOVE_PATH:
case RELABEL_PATH:
case RECURSIVE_RELABEL_PATH:
+ case ADJUST_MODE:
break;
case CREATE_SYMLINK: