/* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates
* them in the file system. This is intended to be used to create
/* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates
* them in the file system. This is intended to be used to create
CREATE_DIRECTORY = 'd',
TRUNCATE_DIRECTORY = 'D',
CREATE_FIFO = 'p',
CREATE_SYMLINK = 'L',
CREATE_CHAR_DEVICE = 'c',
CREATE_BLOCK_DEVICE = 'b',
CREATE_DIRECTORY = 'd',
TRUNCATE_DIRECTORY = 'D',
CREATE_FIFO = 'p',
CREATE_SYMLINK = 'L',
CREATE_CHAR_DEVICE = 'c',
CREATE_BLOCK_DEVICE = 'b',
IGNORE_PATH = 'x',
IGNORE_DIRECTORY_PATH = 'X',
REMOVE_PATH = 'r',
RECURSIVE_REMOVE_PATH = 'R',
IGNORE_PATH = 'x',
IGNORE_DIRECTORY_PATH = 'X',
REMOVE_PATH = 'r',
RECURSIVE_REMOVE_PATH = 'R',
- h = alloca(MAX_HANDLE_SZ);
-
- h->handle_bytes = MAX_HANDLE_SZ;
- r_p = name_to_handle_at(dirfd(d), ".", h, &mount_id_parent, 0);
+ r_p = name_to_handle_at(dirfd(d), ".", &h.handle, &mount_id_parent, 0);
- h->handle_bytes = MAX_HANDLE_SZ;
- r = name_to_handle_at(dirfd(d), subdir, h, &mount_id, 0);
+ h.handle.handle_bytes = MAX_HANDLE_SZ;
+ r = name_to_handle_at(dirfd(d), subdir, &h.handle, &mount_id, 0);
- if (asprintf(&sub_path, "%s/%s", p, dent->d_name) < 0) {
+ sub_path = strjoin(p, "/", dent->d_name, NULL);
+ if (!sub_path) {
}
q = dir_cleanup(i, sub_path, sub_dir, &s, cutoff, rootdev, false, maxdepth-1, false);
}
q = dir_cleanup(i, sub_path, sub_dir, &s, cutoff, rootdev, false, maxdepth-1, false);
/* not using i->path directly because it may be a glob */
if (i->mode_set)
if (chmod(path, i->mode) < 0) {
/* not using i->path directly because it may be a glob */
if (i->mode_set)
if (chmod(path, i->mode) < 0) {
flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND :
i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC : 0;
RUN_WITH_UMASK(0) {
label_context_set(path, S_IFREG);
fd = open(path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY|O_NOFOLLOW, i->mode);
flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND :
i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC : 0;
RUN_WITH_UMASK(0) {
label_context_set(path, S_IFREG);
fd = open(path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY|O_NOFOLLOW, i->mode);
if (n < 0 || (size_t) n < l) {
log_error("Failed to write file %s: %s", path, n < 0 ? strerror(-n) : "Short write");
if (n < 0 || (size_t) n < l) {
log_error("Failed to write file %s: %s", path, n < 0 ? strerror(-n) : "Short write");
if (stat(path, &st) < 0) {
log_error("stat(%s) failed: %m", path);
if (stat(path, &st) < 0) {
log_error("stat(%s) failed: %m", path);
- if (asprintf(&entry_path, "%s/%s", path, de->d_name) < 0) {
- if (ret == 0)
- ret = -ENOMEM;
- continue;
- }
-
- if (de->d_type == DT_UNKNOWN) {
- struct stat st;
-
- if (lstat(entry_path, &st) < 0) {
- if (ret == 0 && errno != ENOENT)
- ret = -errno;
- continue;
- }
-
- is_dir = S_ISDIR(st.st_mode);
-
- } else
- is_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 (is_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;
- 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;
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);
- case WRITE_FILE:
- r = glob_item(i, write_one_file);
+ case COPY_FILES:
+ r = copy_tree(i->argument, i->path);
+ if (r < 0) {
+ log_error("Failed to copy files: %s", strerror(-r));
+ return r;
+ }
+
+ r = item_set_perms(i, i->path);
label_context_set(i->path, S_IFLNK);
r = symlink(i->argument, i->path);
label_context_set(i->path, S_IFLNK);
r = symlink(i->argument, i->path);
if (r < 0 && errno != EEXIST) {
log_error("symlink(%s, %s) failed: %m", i->argument, i->path);
if (r < 0 && errno != EEXIST) {
log_error("symlink(%s, %s) failed: %m", i->argument, i->path);
RUN_WITH_UMASK(0000) {
label_context_set(i->path, file_type);
r = mknod(i->path, i->mode | file_type, i->major_minor);
RUN_WITH_UMASK(0000) {
label_context_set(i->path, file_type);
r = mknod(i->path, i->mode | file_type, i->major_minor);
clean_item_instance(i, i->path);
break;
case IGNORE_DIRECTORY_PATH:
clean_item_instance(i, i->path);
break;
case IGNORE_DIRECTORY_PATH:
- _cleanup_item_free_ Item *i = NULL;
+ _cleanup_free_ char *action = NULL, *mode = NULL, *user = NULL, *group = NULL, *age = NULL, *path = NULL;
+ _cleanup_(item_freep) Item *i = NULL;
+ case COPY_FILES:
+ if (!i->argument) {
+ log_error("[%s:%u] Copy files requires argument.", fname, line);
+ return -EBADMSG;
+ }
+
+ if (!path_is_absolute(i->argument)) {
+ log_error("[%s:%u] Source path is not absolute.", fname, line);
+ return -EBADMSG;
+ }
+
+ path_kill_slashes(i->argument);
+ break;
+
" --remove Remove marked files/directories\n"
" --boot Execute actions only safe at boot\n"
" --prefix=PATH Only apply rules that apply to paths with the specified prefix\n"
" --remove Remove marked files/directories\n"
" --boot Execute actions only safe at boot\n"
" --prefix=PATH Only apply rules that apply to paths with the specified prefix\n"
- " --exclude-prefix=PATH Ignore rules that apply to paths with the specified prefix\n",
+ " --exclude-prefix=PATH Ignore rules that apply to paths with the specified prefix\n"
+ " --root=PATH Operate on an alternate filesystem root\n",
{ "boot", no_argument, NULL, ARG_BOOT },
{ "prefix", required_argument, NULL, ARG_PREFIX },
{ "exclude-prefix", required_argument, NULL, ARG_EXCLUDE_PREFIX },
{ "boot", no_argument, NULL, ARG_BOOT },
{ "prefix", required_argument, NULL, ARG_PREFIX },
{ "exclude-prefix", required_argument, NULL, ARG_EXCLUDE_PREFIX },
- r = search_and_fopen_nulstr(fn, "re", conf_file_dirs, &f);
+ r = search_and_fopen_nulstr(fn, "re", arg_root, conf_file_dirs, &f);
- r = conf_files_list_nulstr(&files, ".conf", NULL, conf_file_dirs);
+ r = conf_files_list_nulstr(&files, ".conf", arg_root, conf_file_dirs);