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