]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/copy.c
Merge pull request #14081 from poettering/xattr-list-rework
[thirdparty/systemd.git] / src / basic / copy.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
849958d1 2
11c3a366
TA
3#include <errno.h>
4#include <fcntl.h>
5#include <stddef.h>
6#include <stdio.h>
7#include <stdlib.h>
cda134ab 8#include <sys/sendfile.h>
e6bd041c 9#include <sys/xattr.h>
11c3a366 10#include <unistd.h>
cda134ab 11
b5efdb8a 12#include "alloc-util.h"
d7c7c334 13#include "btrfs-util.h"
c8b3094d 14#include "chattr-util.h"
3ffd4af2 15#include "copy.h"
a0956174 16#include "dirent-util.h"
3ffd4af2 17#include "fd-util.h"
f4f15635 18#include "fs-util.h"
c004493c 19#include "io-util.h"
11c3a366 20#include "macro.h"
f5947a5e 21#include "missing_syscall.h"
049af8ad 22#include "mountpoint-util.h"
f9bbb4dc 23#include "nulstr-util.h"
609d3473 24#include "stat-util.h"
07630cea 25#include "string-util.h"
8420fa3a 26#include "strv.h"
93cc7779 27#include "time-util.h"
e4de7287 28#include "tmpfile-util.h"
affb60b1 29#include "umask-util.h"
d01cd401 30#include "user-util.h"
89a5a90c 31#include "xattr-util.h"
849958d1 32
575a07d2
LP
33#define COPY_BUFFER_SIZE (16U*1024U)
34
35/* A safety net for descending recursively into file system trees to copy. On Linux PATH_MAX is 4096, which means the
36 * deepest valid path one can build is around 2048, which we hence use as a safety net here, to not spin endlessly in
37 * case of bind mount cycles and suchlike. */
38#define COPY_DEPTH_MAX 2048U
f2cbe59e 39
75036dce
LP
40static ssize_t try_copy_file_range(
41 int fd_in, loff_t *off_in,
42 int fd_out, loff_t *off_out,
43 size_t len,
14cb109d 44 unsigned flags) {
75036dce 45
a44202e9
ZJS
46 static int have = -1;
47 ssize_t r;
48
75036dce 49 if (have == 0)
a44202e9
ZJS
50 return -ENOSYS;
51
52 r = copy_file_range(fd_in, off_in, fd_out, off_out, len, flags);
75036dce 53 if (have < 0)
a44202e9 54 have = r >= 0 || errno != ENOSYS;
75036dce 55 if (r < 0)
a44202e9 56 return -errno;
75036dce
LP
57
58 return r;
a44202e9
ZJS
59}
60
e0c5c7d8
LP
61enum {
62 FD_IS_NO_PIPE,
63 FD_IS_BLOCKING_PIPE,
64 FD_IS_NONBLOCKING_PIPE,
65};
66
67static int fd_is_nonblock_pipe(int fd) {
68 struct stat st;
69 int flags;
70
4436e5a7 71 /* Checks whether the specified file descriptor refers to a pipe, and if so if O_NONBLOCK is set. */
e0c5c7d8
LP
72
73 if (fstat(fd, &st) < 0)
74 return -errno;
75
76 if (!S_ISFIFO(st.st_mode))
77 return FD_IS_NO_PIPE;
78
79 flags = fcntl(fd, F_GETFL);
80 if (flags < 0)
81 return -errno;
82
d94a24ca 83 return FLAGS_SET(flags, O_NONBLOCK) ? FD_IS_NONBLOCKING_PIPE : FD_IS_BLOCKING_PIPE;
e0c5c7d8
LP
84}
85
85559592
LP
86static int sigint_pending(void) {
87 sigset_t ss;
88
89 assert_se(sigemptyset(&ss) >= 0);
90 assert_se(sigaddset(&ss, SIGINT) >= 0);
91
92 if (sigtimedwait(&ss, NULL, &(struct timespec) { 0, 0 }) < 0) {
93 if (errno == EAGAIN)
94 return false;
95
96 return -errno;
97 }
98
99 return true;
100}
101
7a23c7fd
LP
102int copy_bytes_full(
103 int fdf, int fdt,
104 uint64_t max_bytes,
105 CopyFlags copy_flags,
106 void **ret_remains,
b3cade0c
LP
107 size_t *ret_remains_size,
108 copy_progress_bytes_t progress,
109 void *userdata) {
7a23c7fd 110
a44202e9 111 bool try_cfr = true, try_sendfile = true, try_splice = true;
e0c5c7d8 112 int r, nonblock_pipe = -1;
7c2da2ca 113 size_t m = SSIZE_MAX; /* that is the maximum that sendfile and c_f_r accept */
cda134ab 114
849958d1
LP
115 assert(fdf >= 0);
116 assert(fdt >= 0);
117
78ba8cf7
LP
118 /* Tries to copy bytes from the file descriptor 'fdf' to 'fdt' in the smartest possible way. Copies a maximum
119 * of 'max_bytes', which may be specified as UINT64_MAX, in which no maximum is applied. Returns negative on
7a23c7fd
LP
120 * error, zero if EOF is hit before the bytes limit is hit and positive otherwise. If the copy fails for some
121 * reason but we read but didn't yet write some data an ret_remains/ret_remains_size is not NULL, then it will
122 * be initialized with an allocated buffer containing this "remaining" data. Note that these two parameters are
123 * initialized with a valid buffer only on failure and only if there's actually data already read. Otherwise
124 * these parameters if non-NULL are set to NULL. */
125
126 if (ret_remains)
127 *ret_remains = NULL;
128 if (ret_remains_size)
129 *ret_remains_size = 0;
78ba8cf7 130
5de6e116
LP
131 /* Try btrfs reflinks first. This only works on regular, seekable files, hence let's check the file offsets of
132 * source and destination first. */
133 if ((copy_flags & COPY_REFLINK)) {
134 off_t foffset;
135
136 foffset = lseek(fdf, 0, SEEK_CUR);
137 if (foffset >= 0) {
138 off_t toffset;
139
140 toffset = lseek(fdt, 0, SEEK_CUR);
141 if (toffset >= 0) {
142
143 if (foffset == 0 && toffset == 0 && max_bytes == UINT64_MAX)
144 r = btrfs_reflink(fdf, fdt); /* full file reflink */
145 else
146 r = btrfs_clone_range(fdf, foffset, fdt, toffset, max_bytes == UINT64_MAX ? 0 : max_bytes); /* partial reflink */
147 if (r >= 0) {
148 off_t t;
149
150 /* This worked, yay! Now — to be fully correct — let's adjust the file pointers */
151 if (max_bytes == UINT64_MAX) {
152
153 /* We cloned to the end of the source file, let's position the read
154 * pointer there, and query it at the same time. */
155 t = lseek(fdf, 0, SEEK_END);
156 if (t < 0)
157 return -errno;
158 if (t < foffset)
159 return -ESPIPE;
160
161 /* Let's adjust the destination file write pointer by the same number
162 * of bytes. */
163 t = lseek(fdt, toffset + (t - foffset), SEEK_SET);
164 if (t < 0)
165 return -errno;
166
167 return 0; /* we copied the whole thing, hence hit EOF, return 0 */
168 } else {
169 t = lseek(fdf, foffset + max_bytes, SEEK_SET);
170 if (t < 0)
171 return -errno;
172
173 t = lseek(fdt, toffset + max_bytes, SEEK_SET);
174 if (t < 0)
175 return -errno;
176
177 return 1; /* we copied only some number of bytes, which worked, but this means we didn't hit EOF, return 1 */
178 }
179 }
5de6e116
LP
180 }
181 }
0254b455
LP
182 }
183
849958d1 184 for (;;) {
cda134ab 185 ssize_t n;
93240d3a 186
dd641ad1
LP
187 if (max_bytes <= 0)
188 return 1; /* return > 0 if we hit the max_bytes limit */
93240d3a 189
85559592
LP
190 if (FLAGS_SET(copy_flags, COPY_SIGINT)) {
191 r = sigint_pending();
192 if (r < 0)
193 return r;
194 if (r > 0)
195 return -EINTR;
196 }
197
dd641ad1
LP
198 if (max_bytes != UINT64_MAX && m > max_bytes)
199 m = max_bytes;
93240d3a 200
a44202e9
ZJS
201 /* First try copy_file_range(), unless we already tried */
202 if (try_cfr) {
203 n = try_copy_file_range(fdf, NULL, fdt, NULL, m, 0u);
204 if (n < 0) {
6402d5c6 205 if (!IN_SET(n, -EINVAL, -ENOSYS, -EXDEV, -EBADF))
a44202e9
ZJS
206 return n;
207
208 try_cfr = false;
209 /* use fallback below */
210 } else if (n == 0) /* EOF */
211 break;
212 else
213 /* Success! */
214 goto next;
215 }
216
cda134ab
LP
217 /* First try sendfile(), unless we already tried */
218 if (try_sendfile) {
cda134ab
LP
219 n = sendfile(fdt, fdf, NULL, m);
220 if (n < 0) {
00a8cf77 221 if (!IN_SET(errno, EINVAL, ENOSYS))
cda134ab
LP
222 return -errno;
223
224 try_sendfile = false;
225 /* use fallback below */
226 } else if (n == 0) /* EOF */
227 break;
00a8cf77 228 else
81d20007
LP
229 /* Success! */
230 goto next;
231 }
232
e0c5c7d8
LP
233 /* Then try splice, unless we already tried. */
234 if (try_splice) {
235
236 /* splice()'s asynchronous I/O support is a bit weird. When it encounters a pipe file
237 * descriptor, then it will ignore its O_NONBLOCK flag and instead only honour the
238 * SPLICE_F_NONBLOCK flag specified in its flag parameter. Let's hide this behaviour here, and
239 * check if either of the specified fds are a pipe, and if so, let's pass the flag
240 * automatically, depending on O_NONBLOCK being set.
241 *
242 * Here's a twist though: when we use it to move data between two pipes of which one has
243 * O_NONBLOCK set and the other has not, then we have no individual control over O_NONBLOCK
244 * behaviour. Hence in that case we can't use splice() and still guarantee systematic
245 * O_NONBLOCK behaviour, hence don't. */
246
247 if (nonblock_pipe < 0) {
248 int a, b;
249
250 /* Check if either of these fds is a pipe, and if so non-blocking or not */
251 a = fd_is_nonblock_pipe(fdf);
252 if (a < 0)
253 return a;
254
255 b = fd_is_nonblock_pipe(fdt);
256 if (b < 0)
257 return b;
258
259 if ((a == FD_IS_NO_PIPE && b == FD_IS_NO_PIPE) ||
260 (a == FD_IS_BLOCKING_PIPE && b == FD_IS_NONBLOCKING_PIPE) ||
261 (a == FD_IS_NONBLOCKING_PIPE && b == FD_IS_BLOCKING_PIPE))
262
263 /* splice() only works if one of the fds is a pipe. If neither is, let's skip
264 * this step right-away. As mentioned above, if one of the two fds refers to a
265 * blocking pipe and the other to a non-blocking pipe, we can't use splice()
266 * either, hence don't try either. This hence means we can only use splice() if
267 * either only one of the two fds is a pipe, or if both are pipes with the same
268 * nonblocking flag setting. */
269
270 try_splice = false;
271 else
272 nonblock_pipe = a == FD_IS_NONBLOCKING_PIPE || b == FD_IS_NONBLOCKING_PIPE;
273 }
274 }
275
81d20007 276 if (try_splice) {
e0c5c7d8 277 n = splice(fdf, NULL, fdt, NULL, m, nonblock_pipe ? SPLICE_F_NONBLOCK : 0);
81d20007 278 if (n < 0) {
00a8cf77 279 if (!IN_SET(errno, EINVAL, ENOSYS))
81d20007
LP
280 return -errno;
281
282 try_splice = false;
283 /* use fallback below */
284 } else if (n == 0) /* EOF */
285 break;
00a8cf77 286 else
81d20007 287 /* Success! */
cda134ab
LP
288 goto next;
289 }
290
291 /* As a fallback just copy bits by hand */
292 {
7a23c7fd
LP
293 uint8_t buf[MIN(m, COPY_BUFFER_SIZE)], *p = buf;
294 ssize_t z;
849958d1 295
00a8cf77 296 n = read(fdf, buf, sizeof buf);
cda134ab
LP
297 if (n < 0)
298 return -errno;
299 if (n == 0) /* EOF */
300 break;
301
7a23c7fd
LP
302 z = (size_t) n;
303 do {
304 ssize_t k;
305
306 k = write(fdt, p, z);
307 if (k < 0) {
308 r = -errno;
309
310 if (ret_remains) {
311 void *copy;
312
313 copy = memdup(p, z);
314 if (!copy)
315 return -ENOMEM;
316
317 *ret_remains = copy;
318 }
319
320 if (ret_remains_size)
321 *ret_remains_size = z;
322
323 return r;
324 }
325
326 assert(k <= z);
327 z -= k;
328 p += k;
329 } while (z > 0);
cda134ab 330 }
93240d3a 331
cda134ab 332 next:
b3cade0c
LP
333 if (progress) {
334 r = progress(n, userdata);
335 if (r < 0)
336 return r;
337 }
338
59f448cf
LP
339 if (max_bytes != (uint64_t) -1) {
340 assert(max_bytes >= (uint64_t) n);
93240d3a
LP
341 max_bytes -= n;
342 }
b3cade0c 343
00a8cf77
ZJS
344 /* sendfile accepts at most SSIZE_MAX-offset bytes to copy,
345 * so reduce our maximum by the amount we already copied,
346 * but don't go below our copy buffer size, unless we are
61233823 347 * close the limit of bytes we are allowed to copy. */
00a8cf77 348 m = MAX(MIN(COPY_BUFFER_SIZE, max_bytes), m - n);
849958d1
LP
349 }
350
f6d9c616 351 return 0; /* return 0 if we hit EOF earlier than the size limit */
849958d1
LP
352}
353
d01cd401
LP
354static int fd_copy_symlink(
355 int df,
356 const char *from,
357 const struct stat *st,
358 int dt,
359 const char *to,
360 uid_t override_uid,
361 gid_t override_gid,
362 CopyFlags copy_flags) {
363
849958d1
LP
364 _cleanup_free_ char *target = NULL;
365 int r;
366
367 assert(from);
368 assert(st);
369 assert(to);
370
371 r = readlinkat_malloc(df, from, &target);
372 if (r < 0)
373 return r;
374
e156347e 375 if (symlinkat(target, dt, to) < 0)
849958d1 376 return -errno;
849958d1 377
d01cd401
LP
378 if (fchownat(dt, to,
379 uid_is_valid(override_uid) ? override_uid : st->st_uid,
380 gid_is_valid(override_gid) ? override_gid : st->st_gid,
381 AT_SYMLINK_NOFOLLOW) < 0)
849958d1
LP
382 return -errno;
383
384 return 0;
385}
386
d01cd401
LP
387static int fd_copy_regular(
388 int df,
389 const char *from,
390 const struct stat *st,
391 int dt,
392 const char *to,
393 uid_t override_uid,
394 gid_t override_gid,
b3cade0c
LP
395 CopyFlags copy_flags,
396 copy_progress_bytes_t progress,
397 void *userdata) {
d01cd401 398
849958d1 399 _cleanup_close_ int fdf = -1, fdt = -1;
ebd93cb6 400 struct timespec ts[2];
849958d1
LP
401 int r, q;
402
403 assert(from);
404 assert(st);
405 assert(to);
406
407 fdf = openat(df, from, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
408 if (fdf < 0)
409 return -errno;
410
411 fdt = openat(dt, to, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, st->st_mode & 07777);
e156347e 412 if (fdt < 0)
849958d1 413 return -errno;
849958d1 414
b3cade0c 415 r = copy_bytes_full(fdf, fdt, (uint64_t) -1, copy_flags, NULL, NULL, progress, userdata);
849958d1 416 if (r < 0) {
7b938dfb 417 (void) unlinkat(dt, to, 0);
849958d1
LP
418 return r;
419 }
420
d01cd401
LP
421 if (fchown(fdt,
422 uid_is_valid(override_uid) ? override_uid : st->st_uid,
423 gid_is_valid(override_gid) ? override_gid : st->st_gid) < 0)
849958d1
LP
424 r = -errno;
425
426 if (fchmod(fdt, st->st_mode & 07777) < 0)
427 r = -errno;
428
ebd93cb6
LP
429 ts[0] = st->st_atim;
430 ts[1] = st->st_mtim;
431 (void) futimens(fdt, ts);
e6bd041c
LP
432 (void) copy_xattr(fdf, fdt);
433
849958d1
LP
434 q = close(fdt);
435 fdt = -1;
436
437 if (q < 0) {
438 r = -errno;
7b938dfb 439 (void) unlinkat(dt, to, 0);
849958d1
LP
440 }
441
442 return r;
443}
444
d01cd401
LP
445static int fd_copy_fifo(
446 int df,
447 const char *from,
448 const struct stat *st,
449 int dt,
450 const char *to,
451 uid_t override_uid,
452 gid_t override_gid,
453 CopyFlags copy_flags) {
849958d1
LP
454 int r;
455
456 assert(from);
457 assert(st);
458 assert(to);
459
460 r = mkfifoat(dt, to, st->st_mode & 07777);
e156347e 461 if (r < 0)
849958d1 462 return -errno;
849958d1 463
d01cd401
LP
464 if (fchownat(dt, to,
465 uid_is_valid(override_uid) ? override_uid : st->st_uid,
466 gid_is_valid(override_gid) ? override_gid : st->st_gid,
467 AT_SYMLINK_NOFOLLOW) < 0)
849958d1
LP
468 r = -errno;
469
470 if (fchmodat(dt, to, st->st_mode & 07777, 0) < 0)
471 r = -errno;
472
473 return r;
474}
475
d01cd401
LP
476static int fd_copy_node(
477 int df,
478 const char *from,
479 const struct stat *st,
480 int dt,
481 const char *to,
482 uid_t override_uid,
483 gid_t override_gid,
484 CopyFlags copy_flags) {
849958d1
LP
485 int r;
486
487 assert(from);
488 assert(st);
489 assert(to);
490
491 r = mknodat(dt, to, st->st_mode, st->st_rdev);
e156347e 492 if (r < 0)
849958d1 493 return -errno;
849958d1 494
d01cd401
LP
495 if (fchownat(dt, to,
496 uid_is_valid(override_uid) ? override_uid : st->st_uid,
497 gid_is_valid(override_gid) ? override_gid : st->st_gid,
498 AT_SYMLINK_NOFOLLOW) < 0)
849958d1
LP
499 r = -errno;
500
501 if (fchmodat(dt, to, st->st_mode & 07777, 0) < 0)
502 r = -errno;
503
504 return r;
505}
506
d7c7c334
LP
507static int fd_copy_directory(
508 int df,
509 const char *from,
510 const struct stat *st,
511 int dt,
512 const char *to,
513 dev_t original_device,
575a07d2 514 unsigned depth_left,
d01cd401
LP
515 uid_t override_uid,
516 gid_t override_gid,
b3cade0c
LP
517 CopyFlags copy_flags,
518 const char *display_path,
519 copy_progress_path_t progress_path,
520 copy_progress_bytes_t progress_bytes,
521 void *userdata) {
d7c7c334 522
849958d1
LP
523 _cleanup_close_ int fdf = -1, fdt = -1;
524 _cleanup_closedir_ DIR *d = NULL;
525 struct dirent *de;
609d3473 526 bool exists, created;
849958d1
LP
527 int r;
528
849958d1
LP
529 assert(st);
530 assert(to);
531
575a07d2
LP
532 if (depth_left == 0)
533 return -ENAMETOOLONG;
534
d7c7c334
LP
535 if (from)
536 fdf = openat(df, from, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
537 else
538 fdf = fcntl(df, F_DUPFD_CLOEXEC, 3);
b498c53d
LP
539 if (fdf < 0)
540 return -errno;
849958d1
LP
541
542 d = fdopendir(fdf);
543 if (!d)
544 return -errno;
545 fdf = -1;
546
609d3473
RG
547 exists = false;
548 if (copy_flags & COPY_MERGE_EMPTY) {
549 r = dir_is_empty_at(dt, to);
550 if (r < 0 && r != -ENOENT)
551 return r;
552 else if (r == 1)
553 exists = true;
554 }
555
556 if (exists)
849958d1 557 created = false;
609d3473
RG
558 else {
559 r = mkdirat(dt, to, st->st_mode & 07777);
560 if (r >= 0)
561 created = true;
562 else if (errno == EEXIST && (copy_flags & COPY_MERGE))
563 created = false;
564 else
565 return -errno;
566 }
849958d1
LP
567
568 fdt = openat(dt, to, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
569 if (fdt < 0)
570 return -errno;
571
2c455af4
LP
572 r = 0;
573
8420fa3a 574 FOREACH_DIRENT_ALL(de, d, return -errno) {
b3cade0c
LP
575 const char *child_display_path = NULL;
576 _cleanup_free_ char *dp = NULL;
849958d1
LP
577 struct stat buf;
578 int q;
579
49bfc877 580 if (dot_or_dot_dot(de->d_name))
8420fa3a
LP
581 continue;
582
85559592
LP
583 if (FLAGS_SET(copy_flags, COPY_SIGINT)) {
584 r = sigint_pending();
585 if (r < 0)
586 return r;
587 if (r > 0)
588 return -EINTR;
589 }
590
849958d1
LP
591 if (fstatat(dirfd(d), de->d_name, &buf, AT_SYMLINK_NOFOLLOW) < 0) {
592 r = -errno;
593 continue;
594 }
595
b3cade0c
LP
596 if (progress_path) {
597 if (display_path)
657ee2d8 598 child_display_path = dp = path_join(display_path, de->d_name);
b3cade0c
LP
599 else
600 child_display_path = de->d_name;
601
602 r = progress_path(child_display_path, &buf, userdata);
603 if (r < 0)
604 return r;
605 }
606
ef202b84 607 if (S_ISDIR(buf.st_mode)) {
f6a77804
LP
608 /*
609 * Don't descend into directories on other file systems, if this is requested. We do a simple
610 * .st_dev check here, which basically comes for free. Note that we do this check only on
611 * directories, not other kind of file system objects, for two reason:
612 *
613 * • The kernel's overlayfs pseudo file system that overlays multiple real file systems
614 * propagates the .st_dev field of the file system a file originates from all the way up
615 * through the stack to stat(). It doesn't do that for directories however. This means that
616 * comparing .st_dev on non-directories suggests that they all are mount points. To avoid
617 * confusion we hence avoid relying on this check for regular files.
618 *
619 * • The main reason we do this check at all is to protect ourselves from bind mount cycles,
620 * where we really want to avoid descending down in all eternity. However the .st_dev check
621 * is usually not sufficient for this protection anyway, as bind mount cycles from the same
575a07d2
LP
622 * file system onto itself can't be detected that way. (Note we also do a recursion depth
623 * check, which is probably the better protection in this regard, which is why
624 * COPY_SAME_MOUNT is optional).
f6a77804
LP
625 */
626
627 if (FLAGS_SET(copy_flags, COPY_SAME_MOUNT)) {
628 if (buf.st_dev != original_device)
629 continue;
630
631 r = fd_is_mount_point(dirfd(d), de->d_name, 0);
632 if (r < 0)
633 return r;
634 if (r > 0)
635 continue;
636 }
637
b3cade0c 638 q = fd_copy_directory(dirfd(d), de->d_name, &buf, fdt, de->d_name, original_device, depth_left-1, override_uid, override_gid, copy_flags, child_display_path, progress_path, progress_bytes, userdata);
ef202b84 639 } else if (S_ISREG(buf.st_mode))
b3cade0c 640 q = fd_copy_regular(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags, progress_bytes, userdata);
849958d1 641 else if (S_ISLNK(buf.st_mode))
d01cd401 642 q = fd_copy_symlink(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags);
849958d1 643 else if (S_ISFIFO(buf.st_mode))
d01cd401 644 q = fd_copy_fifo(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags);
0e2b2cac 645 else if (S_ISBLK(buf.st_mode) || S_ISCHR(buf.st_mode) || S_ISSOCK(buf.st_mode))
d01cd401 646 q = fd_copy_node(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags);
849958d1 647 else
15411c0c 648 q = -EOPNOTSUPP;
849958d1 649
85559592
LP
650 if (q == -EINTR) /* Propagate SIGINT up instantly */
651 return q;
1c876927 652 if (q == -EEXIST && (copy_flags & COPY_MERGE))
e156347e 653 q = 0;
849958d1
LP
654 if (q < 0)
655 r = q;
656 }
657
3b8483c0
LP
658 if (created) {
659 struct timespec ut[2] = {
660 st->st_atim,
661 st->st_mtim
662 };
663
d01cd401
LP
664 if (fchown(fdt,
665 uid_is_valid(override_uid) ? override_uid : st->st_uid,
666 gid_is_valid(override_gid) ? override_gid : st->st_gid) < 0)
3b8483c0
LP
667 r = -errno;
668
669 if (fchmod(fdt, st->st_mode & 07777) < 0)
670 r = -errno;
671
672 (void) copy_xattr(dirfd(d), fdt);
673 (void) futimens(fdt, ut);
674 }
675
849958d1
LP
676 return r;
677}
678
b3cade0c
LP
679int copy_tree_at_full(
680 int fdf,
681 const char *from,
682 int fdt,
683 const char *to,
684 uid_t override_uid,
685 gid_t override_gid,
686 CopyFlags copy_flags,
687 copy_progress_path_t progress_path,
688 copy_progress_bytes_t progress_bytes,
689 void *userdata) {
690
849958d1
LP
691 struct stat st;
692
693 assert(from);
694 assert(to);
695
f2cbe59e 696 if (fstatat(fdf, from, &st, AT_SYMLINK_NOFOLLOW) < 0)
849958d1
LP
697 return -errno;
698
699 if (S_ISREG(st.st_mode))
b3cade0c 700 return fd_copy_regular(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags, progress_bytes, userdata);
849958d1 701 else if (S_ISDIR(st.st_mode))
b3cade0c 702 return fd_copy_directory(fdf, from, &st, fdt, to, st.st_dev, COPY_DEPTH_MAX, override_uid, override_gid, copy_flags, NULL, progress_path, progress_bytes, userdata);
849958d1 703 else if (S_ISLNK(st.st_mode))
d01cd401 704 return fd_copy_symlink(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags);
849958d1 705 else if (S_ISFIFO(st.st_mode))
d01cd401 706 return fd_copy_fifo(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags);
0e2b2cac 707 else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode) || S_ISSOCK(st.st_mode))
d01cd401 708 return fd_copy_node(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags);
849958d1 709 else
15411c0c 710 return -EOPNOTSUPP;
849958d1
LP
711}
712
b3cade0c
LP
713int copy_directory_fd_full(
714 int dirfd,
715 const char *to,
716 CopyFlags copy_flags,
717 copy_progress_path_t progress_path,
718 copy_progress_bytes_t progress_bytes,
719 void *userdata) {
f2cbe59e 720
d7c7c334
LP
721 struct stat st;
722
723 assert(dirfd >= 0);
724 assert(to);
725
726 if (fstat(dirfd, &st) < 0)
727 return -errno;
728
729 if (!S_ISDIR(st.st_mode))
730 return -ENOTDIR;
731
b3cade0c 732 return fd_copy_directory(dirfd, NULL, &st, AT_FDCWD, to, st.st_dev, COPY_DEPTH_MAX, UID_INVALID, GID_INVALID, copy_flags, NULL, progress_path, progress_bytes, userdata);
d7c7c334
LP
733}
734
b3cade0c
LP
735int copy_directory_full(
736 const char *from,
737 const char *to,
738 CopyFlags copy_flags,
739 copy_progress_path_t progress_path,
740 copy_progress_bytes_t progress_bytes,
741 void *userdata) {
742
9a50e3ca
LP
743 struct stat st;
744
745 assert(from);
746 assert(to);
747
748 if (lstat(from, &st) < 0)
749 return -errno;
750
751 if (!S_ISDIR(st.st_mode))
752 return -ENOTDIR;
753
b3cade0c 754 return fd_copy_directory(AT_FDCWD, from, &st, AT_FDCWD, to, st.st_dev, COPY_DEPTH_MAX, UID_INVALID, GID_INVALID, copy_flags, NULL, progress_path, progress_bytes, userdata);
9a50e3ca
LP
755}
756
b3cade0c
LP
757int copy_file_fd_full(
758 const char *from,
759 int fdt,
760 CopyFlags copy_flags,
761 copy_progress_bytes_t progress_bytes,
762 void *userdata) {
763
cda134ab 764 _cleanup_close_ int fdf = -1;
e6bd041c 765 int r;
849958d1
LP
766
767 assert(from);
cda134ab 768 assert(fdt >= 0);
849958d1
LP
769
770 fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
771 if (fdf < 0)
772 return -errno;
773
b3cade0c 774 r = copy_bytes_full(fdf, fdt, (uint64_t) -1, copy_flags, NULL, NULL, progress_bytes, userdata);
e6bd041c 775
adc6f43b 776 (void) copy_times(fdf, fdt, copy_flags);
e6bd041c
LP
777 (void) copy_xattr(fdf, fdt);
778
779 return r;
cda134ab
LP
780}
781
b3cade0c
LP
782int copy_file_full(
783 const char *from,
784 const char *to,
785 int flags,
786 mode_t mode,
787 unsigned chattr_flags,
8a016c74 788 unsigned chattr_mask,
b3cade0c
LP
789 CopyFlags copy_flags,
790 copy_progress_bytes_t progress_bytes,
791 void *userdata) {
792
a7f7d1bd 793 int fdt = -1, r;
cda134ab
LP
794
795 assert(from);
796 assert(to);
797
ebd93cb6
LP
798 RUN_WITH_UMASK(0000) {
799 fdt = open(to, flags|O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode);
800 if (fdt < 0)
801 return -errno;
802 }
849958d1 803
8a016c74
LP
804 if (chattr_mask != 0)
805 (void) chattr_fd(fdt, chattr_flags, chattr_mask & CHATTR_EARLY_FL, NULL);
f2068bcc 806
b3cade0c 807 r = copy_file_fd_full(from, fdt, copy_flags, progress_bytes, userdata);
849958d1 808 if (r < 0) {
cda134ab 809 close(fdt);
7b938dfb 810 (void) unlink(to);
849958d1
LP
811 return r;
812 }
813
8a016c74
LP
814 if (chattr_mask != 0)
815 (void) chattr_fd(fdt, chattr_flags, chattr_mask & ~CHATTR_EARLY_FL, NULL);
816
cda134ab
LP
817 if (close(fdt) < 0) {
818 unlink_noerrno(to);
819 return -errno;
849958d1
LP
820 }
821
822 return 0;
823}
e6bd041c 824
b3cade0c
LP
825int copy_file_atomic_full(
826 const char *from,
827 const char *to,
828 mode_t mode,
829 unsigned chattr_flags,
8a016c74 830 unsigned chattr_mask,
b3cade0c
LP
831 CopyFlags copy_flags,
832 copy_progress_bytes_t progress_bytes,
833 void *userdata) {
834
ec6bdf72
LP
835 _cleanup_(unlink_and_freep) char *t = NULL;
836 _cleanup_close_ int fdt = -1;
ebd93cb6
LP
837 int r;
838
839 assert(from);
840 assert(to);
841
ec6bdf72
LP
842 /* We try to use O_TMPFILE here to create the file if we can. Note that that only works if COPY_REPLACE is not
843 * set though as we need to use linkat() for linking the O_TMPFILE file into the file system but that system
844 * call can't replace existing files. Hence, if COPY_REPLACE is set we create a temporary name in the file
845 * system right-away and unconditionally which we then can renameat() to the right name after we completed
846 * writing it. */
847
848 if (copy_flags & COPY_REPLACE) {
849 r = tempfn_random(to, NULL, &t);
850 if (r < 0)
851 return r;
852
853 fdt = open(t, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|O_WRONLY|O_CLOEXEC, 0600);
854 if (fdt < 0) {
855 t = mfree(t);
856 return -errno;
857 }
858 } else {
859 fdt = open_tmpfile_linkable(to, O_WRONLY|O_CLOEXEC, &t);
860 if (fdt < 0)
861 return fdt;
862 }
ebd93cb6 863
8a016c74
LP
864 if (chattr_mask != 0)
865 (void) chattr_fd(fdt, chattr_flags, chattr_mask & CHATTR_EARLY_FL, NULL);
ec6bdf72 866
b3cade0c 867 r = copy_file_fd_full(from, fdt, copy_flags, progress_bytes, userdata);
ebd93cb6
LP
868 if (r < 0)
869 return r;
870
ec6bdf72
LP
871 if (fchmod(fdt, mode) < 0)
872 return -errno;
873
1c876927 874 if (copy_flags & COPY_REPLACE) {
ec6bdf72
LP
875 if (renameat(AT_FDCWD, t, AT_FDCWD, to) < 0)
876 return -errno;
877 } else {
878 r = link_tmpfile(fdt, t, to);
f85ef957 879 if (r < 0)
ec6bdf72 880 return r;
ebd93cb6
LP
881 }
882
8a016c74
LP
883 if (chattr_mask != 0)
884 (void) chattr_fd(fdt, chattr_flags, chattr_mask & ~CHATTR_EARLY_FL, NULL);
885
ec6bdf72 886 t = mfree(t);
ebd93cb6
LP
887 return 0;
888}
889
adc6f43b 890int copy_times(int fdf, int fdt, CopyFlags flags) {
e6bd041c
LP
891 struct timespec ut[2];
892 struct stat st;
e6bd041c
LP
893
894 assert(fdf >= 0);
895 assert(fdt >= 0);
896
897 if (fstat(fdf, &st) < 0)
898 return -errno;
899
900 ut[0] = st.st_atim;
901 ut[1] = st.st_mtim;
902
903 if (futimens(fdt, ut) < 0)
904 return -errno;
905
adc6f43b
LP
906 if (FLAGS_SET(flags, COPY_CRTIME)) {
907 usec_t crtime;
908
909 if (fd_getcrtime(fdf, &crtime) >= 0)
910 (void) fd_setcrtime(fdt, crtime);
911 }
e6bd041c
LP
912
913 return 0;
914}
915
916int copy_xattr(int fdf, int fdt) {
f9bbb4dc
LP
917 _cleanup_free_ char *names = NULL;
918 int ret = 0, r;
e6bd041c
LP
919 const char *p;
920
f9bbb4dc
LP
921 r = flistxattr_malloc(fdf, &names);
922 if (r < 0)
923 return r;
e6bd041c 924
f9bbb4dc
LP
925 NULSTR_FOREACH(p, names) {
926 _cleanup_free_ char *value = NULL;
e6bd041c 927
f9bbb4dc
LP
928 if (!startswith(p, "user."))
929 continue;
e6bd041c 930
f9bbb4dc
LP
931 r = fgetxattr_malloc(fdf, p, &value);
932 if (r == -ENODATA)
933 continue; /* gone by now */
934 if (r < 0)
935 return r;
e6bd041c 936
f9bbb4dc
LP
937 if (fsetxattr(fdt, p, value, r, 0) < 0)
938 ret = -errno;
e6bd041c
LP
939 }
940
941 return ret;
942}