"m" so far has been a non-globbing version of "z". Since this makes it
quite redundant, let's get rid of it. Remove "m" from the man pages,
beef up "z" docs instead, and make "m" nothing more than a compatibility
alias for "z".
<listitem><para>Recursively copy a file or directory, if the destination files or directories don't exist yet.</para></listitem>
</varlistentry>
<listitem><para>Recursively copy a file or directory, if the destination files or directories don't exist yet.</para></listitem>
</varlistentry>
- <varlistentry>
- <term><varname>m</varname></term>
- <listitem><para>If the
- specified file path exists,
- adjust its access mode, group
- and user to the specified
- values and reset the SELinux
- security context. If it does not exist, do
- nothing.</para></listitem>
- </varlistentry>
-
<varlistentry>
<term><varname>x</varname></term>
<listitem><para>Ignore a path
<varlistentry>
<term><varname>x</varname></term>
<listitem><para>Ignore a path
<varlistentry>
<term><varname>z</varname></term>
<varlistentry>
<term><varname>z</varname></term>
- <listitem><para>Restore
- SELinux security context
- and set ownership and access
- mode of a file or directory if
- it exists. Lines of this type
- accept shell-style globs in
- place of normal path names.
+ <listitem><para>Adjust the
+ access mode, group and user,
+ and restore the SELinux security
+ context of a file or directory,
+ if it exists. Lines of this
+ type accept shell-style globs
+ in place of normal path names.
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>Z</varname></term>
<listitem><para>Recursively
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>Z</varname></term>
<listitem><para>Recursively
- restore SELinux security
- context and set
- ownership and access mode of a
- path and all its
- subdirectories (if it is a
- directory). Lines of this type
- accept shell-style globs in
- place of normal path
+ set the access mode, group and
+ user, and restore the SELinux
+ security context of a file or
+ directory if it exists, as
+ well as of its subdirectories
+ and the files contained
+ therein (if applicable). Lines
+ of this type accept
+ shell-style globs in place of
+ normal path
names.</para></listitem>
</varlistentry>
</variablelist>
names.</para></listitem>
</varlistentry>
</variablelist>
if (r < 0)
return log_oom();
} else {
if (r < 0)
return log_oom();
} else {
- r = is_dir(arg_output);
+ r = is_dir(arg_output, true);
if (r > 0) {
r = asprintf(&output,
"%s/remote-%s.journal", arg_output, name);
if (r > 0) {
r = asprintf(&output,
"%s/remote-%s.journal", arg_output, name);
return mkdir_safe_internal(path, mode, uid, gid, mkdir);
}
return mkdir_safe_internal(path, mode, uid, gid, mkdir);
}
-int is_dir(const char* path) {
+int is_dir(const char* path, bool follow) {
- if (stat(path, &st) < 0)
- return -errno;
+ if (follow) {
+ if (stat(path, &st) < 0)
+ return -errno;
+ } else {
+ if (lstat(path, &st) < 0)
+ return -errno;
+ }
return S_ISDIR(st.st_mode);
}
return S_ISDIR(st.st_mode);
}
return 0;
p = strndupa(path, e - path);
return 0;
p = strndupa(path, e - path);
if (r > 0)
return 0;
if (r == 0)
if (r > 0)
return 0;
if (r == 0)
return r;
r = _mkdir(path, mode);
return r;
r = _mkdir(path, mode);
- if (r < 0 && (errno != EEXIST || is_dir(path) <= 0))
+ if (r < 0 && (errno != EEXIST || is_dir(path, true) <= 0))
int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, mkdir_func_t _mkdir);
int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir);
int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir);
int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, mkdir_func_t _mkdir);
int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir);
int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir);
-int is_dir(const char *path);
+int is_dir(const char *path, bool is_dir);
CREATE_CHAR_DEVICE = 'c',
CREATE_BLOCK_DEVICE = 'b',
COPY_FILES = 'C',
CREATE_CHAR_DEVICE = 'c',
CREATE_BLOCK_DEVICE = 'b',
COPY_FILES = 'C',
/* These ones take globs */
WRITE_FILE = 'w',
/* These ones take globs */
WRITE_FILE = 'w',
IGNORE_DIRECTORY_PATH = 'X',
REMOVE_PATH = 'r',
RECURSIVE_REMOVE_PATH = 'R',
IGNORE_DIRECTORY_PATH = 'X',
REMOVE_PATH = 'r',
RECURSIVE_REMOVE_PATH = 'R',
+ ADJUST_MODE = 'm', /* legacy, 'z' is identical to this */
- RECURSIVE_RELABEL_PATH = 'Z'
+ RECURSIVE_RELABEL_PATH = 'Z',
} ItemType;
typedef struct Item {
} ItemType;
typedef struct Item {
IGNORE_DIRECTORY_PATH,
REMOVE_PATH,
RECURSIVE_REMOVE_PATH,
IGNORE_DIRECTORY_PATH,
REMOVE_PATH,
RECURSIVE_REMOVE_PATH,
RELABEL_PATH,
RECURSIVE_RELABEL_PATH);
}
RELABEL_PATH,
RECURSIVE_RELABEL_PATH);
}
-static int recursive_relabel_children(Item *i, const char *path) {
+static int item_set_perms_children(Item *i, const char *path) {
_cleanup_closedir_ DIR *d;
_cleanup_closedir_ DIR *d;
+ int r = 0;
+
+ assert(i);
+ assert(path);
/* This returns the first error we run into, but nevertheless
* tries to go on */
d = opendir(path);
if (!d)
/* This returns the first error we run into, but nevertheless
* tries to go on */
d = opendir(path);
if (!d)
- return errno == ENOENT ? 0 : -errno;
+ return errno == ENOENT || errno == ENOTDIR ? 0 : -errno;
+ _cleanup_free_ char *p = NULL;
- bool dir;
- int r;
- _cleanup_free_ char *entry_path = NULL;
errno = 0;
de = readdir(d);
errno = 0;
de = readdir(d);
- if (!de && errno != 0) {
- if (ret == 0)
- ret = -errno;
- break;
- }
+ if (!de) {
+ if (errno != 0 && r == 0)
+ r = -errno;
if (streq(de->d_name, ".") || streq(de->d_name, ".."))
continue;
if (streq(de->d_name, ".") || streq(de->d_name, ".."))
continue;
- if (asprintf(&entry_path, "%s/%s", path, de->d_name) < 0) {
- if (ret == 0)
- ret = -ENOMEM;
- continue;
- }
-
- if (de->d_type == DT_UNKNOWN) {
- r = is_dir(entry_path);
- if (r < 0) {
- if (ret == 0 && errno != ENOENT)
- ret = -errno;
- continue;
- }
-
- dir = r;
-
- } else
- dir = de->d_type == DT_DIR;
+ p = strjoin(path, "/", de->d_name, NULL);
+ if (!p)
+ return -ENOMEM;
- r = item_set_perms(i, entry_path);
- if (r < 0) {
- if (ret == 0 && r != -ENOENT)
- ret = r;
- continue;
- }
+ q = item_set_perms(i, p);
+ if (q < 0 && q != -ENOENT && r == 0)
+ r = q;
- if (dir) {
- r = recursive_relabel_children(i, entry_path);
- if (r < 0 && ret == 0)
- ret = r;
+ if (IN_SET(de->d_type, DT_UNKNOWN, DT_DIR)) {
+ q = item_set_perms_children(i, p);
+ if (q < 0 && r == 0)
+ r = q;
-static int recursive_relabel(Item *i, const char *path) {
- int r;
- struct stat st;
+static int item_set_perms_recursive(Item *i, const char *path) {
+ int r, q;
+
+ assert(i);
+ assert(path);
r = item_set_perms(i, path);
if (r < 0)
return r;
r = item_set_perms(i, path);
if (r < 0)
return r;
- if (lstat(path, &st) < 0)
- return -errno;
-
- if (S_ISDIR(st.st_mode))
- r = recursive_relabel_children(i, path);
+ q = item_set_perms_children(i, path);
+ if (q < 0 && r == 0)
+ r = q;
return r;
}
static int glob_item(Item *i, int (*action)(Item *, const char *)) {
return r;
}
static int glob_item(Item *i, int (*action)(Item *, const char *)) {
_cleanup_globfree_ glob_t g = {};
_cleanup_globfree_ glob_t g = {};
char **fn;
errno = 0;
k = glob(i->path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
char **fn;
errno = 0;
k = glob(i->path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
- if (k != 0)
- if (k != GLOB_NOMATCH) {
- if (errno > 0)
- errno = EIO;
+ if (k != 0 && k != GLOB_NOMATCH) {
+ if (errno == 0)
+ errno = EIO;
- log_error("glob(%s) failed: %m", i->path);
- return -errno;
- }
+ log_error("glob(%s) failed: %m", i->path);
+ return -errno;
+ }
STRV_FOREACH(fn, g.gl_pathv) {
k = action(i, *fn);
STRV_FOREACH(fn, g.gl_pathv) {
k = action(i, *fn);
- 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 TRUNCATE_DIRECTORY:
case CREATE_DIRECTORY:
case RELABEL_PATH:
r = glob_item(i, item_set_perms);
case RELABEL_PATH:
r = glob_item(i, item_set_perms);
case RECURSIVE_RELABEL_PATH:
case RECURSIVE_RELABEL_PATH:
- r = glob_item(i, recursive_relabel);
+ r = glob_item(i, item_set_perms_recursive);
}
log_debug("%s created successfully.", i->path);
}
log_debug("%s created successfully.", i->path);
case CREATE_CHAR_DEVICE:
case IGNORE_PATH:
case IGNORE_DIRECTORY_PATH:
case CREATE_CHAR_DEVICE:
case IGNORE_PATH:
case IGNORE_DIRECTORY_PATH:
case RELABEL_PATH:
case RECURSIVE_RELABEL_PATH:
case WRITE_FILE:
case COPY_FILES:
case RELABEL_PATH:
case RECURSIVE_RELABEL_PATH:
case WRITE_FILE:
case COPY_FILES:
case CREATE_BLOCK_DEVICE:
case IGNORE_PATH:
case IGNORE_DIRECTORY_PATH:
case CREATE_BLOCK_DEVICE:
case IGNORE_PATH:
case IGNORE_DIRECTORY_PATH:
case RELABEL_PATH:
case RECURSIVE_RELABEL_PATH:
case WRITE_FILE:
case COPY_FILES:
case RELABEL_PATH:
case RECURSIVE_RELABEL_PATH:
case WRITE_FILE:
case COPY_FILES:
case IGNORE_DIRECTORY_PATH:
case REMOVE_PATH:
case RECURSIVE_REMOVE_PATH:
case IGNORE_DIRECTORY_PATH:
case REMOVE_PATH:
case RECURSIVE_REMOVE_PATH:
case RELABEL_PATH:
case RECURSIVE_RELABEL_PATH:
case RELABEL_PATH:
case RECURSIVE_RELABEL_PATH:
break;
case CREATE_SYMLINK:
break;
case CREATE_SYMLINK:
d /run/systemd/netif/links 0755 systemd-network systemd-network -
d /run/systemd/netif/leases 0755 systemd-network systemd-network -
d /run/systemd/netif/links 0755 systemd-network systemd-network -
d /run/systemd/netif/leases 0755 systemd-network systemd-network -
-m /var/log/journal 2755 root systemd-journal - -
+z /var/log/journal 2755 root systemd-journal - -
Z /var/log/journal/%m 2755 root systemd-journal - -
Z /var/log/journal/%m 2755 root systemd-journal - -
-m /run/log/journal 2755 root systemd-journal - -
+z /run/log/journal 2755 root systemd-journal - -
Z /run/log/journal/%m 2755 root systemd-journal - -
Z /run/log/journal/%m 2755 root systemd-journal - -