diff options
author | Franck Bui <fbui@suse.com> | 2018-04-12 12:19:22 +0200 |
---|---|---|
committer | Franck Bui <fbui@suse.com> | 2018-07-30 15:54:02 +0200 |
commit | b1f7b17f9a6374ac621c80da5e0678c0e867fe18 (patch) | |
tree | 3d3bfb1da6ccee4dc037583bd88a4cc2766a9495 /src/tmpfiles | |
parent | tmpfiles: make write_one_file() safe (diff) | |
download | systemd-b1f7b17f9a6374ac621c80da5e0678c0e867fe18.tar.xz systemd-b1f7b17f9a6374ac621c80da5e0678c0e867fe18.zip |
tmpfiles: introduce copy_files() routine
No functional changes.
Diffstat (limited to 'src/tmpfiles')
-rw-r--r-- | src/tmpfiles/tmpfiles.c | 65 |
1 files changed, 36 insertions, 29 deletions
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 36784a3ad9..06ae67b403 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -1459,6 +1459,41 @@ static int truncate_file(Item *i, const char *path) { return fd_set_perms(i, fd, st); } +static int copy_files(Item *i) { + struct stat st; + int r; + + log_debug("Copying tree \"%s\" to \"%s\".", i->argument, i->path); + + r = copy_tree(i->argument, 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; + + if (r < 0) { + struct stat a, b; + + if (r != -EEXIST) + return log_error_errno(r, "Failed to copy files to %s: %m", i->path); + + if (stat(i->argument, &a) < 0) + return log_error_errno(errno, "stat(%s) failed: %m", i->argument); + + if (stat(i->path, &b) < 0) + return log_error_errno(errno, "stat(%s) failed: %m", i->path); + + if ((a.st_mode ^ b.st_mode) & S_IFMT) { + log_debug("Can't copy to %s, file exists already and is of different type", i->path); + return 0; + } + } + + return path_set_perms(i, i->path); +} + typedef int (*action_t)(Item *, const char *); typedef int (*fdaction_t)(Item *, int fd, const struct stat *st); @@ -1627,37 +1662,9 @@ static int create_item(Item *i) { RUN_WITH_UMASK(0000) (void) mkdir_parents_label(i->path, 0755); - log_debug("Copying tree \"%s\" to \"%s\".", i->argument, i->path); - r = copy_tree(i->argument, 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; - - if (r < 0) { - struct stat a, b; - - if (r != -EEXIST) - return log_error_errno(r, "Failed to copy files to %s: %m", i->path); - - if (stat(i->argument, &a) < 0) - return log_error_errno(errno, "stat(%s) failed: %m", i->argument); - - if (stat(i->path, &b) < 0) - return log_error_errno(errno, "stat(%s) failed: %m", i->path); - - if ((a.st_mode ^ b.st_mode) & S_IFMT) { - log_debug("Can't copy to %s, file exists already and is of different type", i->path); - return 0; - } - } - - r = path_set_perms(i, i->path); + r = copy_files(i); if (r < 0) return r; - break; case WRITE_FILE: |