1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1988, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * David Hitz of Auspex Systems Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 #if 0
36 #ifndef lint
37 static char const copyright[] =
38 "@(#) Copyright (c) 1988, 1993, 1994\n\
39 The Regents of the University of California. All rights reserved.\n";
40 #endif /* not lint */
41
42 #ifndef lint
43 static char sccsid[] = "@(#)cp.c 8.2 (Berkeley) 4/1/94";
44 #endif /* not lint */
45 #endif
46 #include <sys/cdefs.h>
47 /*
48 * Cp copies source files to target files.
49 *
50 * The global PATH_T structure "to" always contains the path to the
51 * current target file. Since fts(3) does not change directories,
52 * this path can be either absolute or dot-relative.
53 *
54 * The basic algorithm is to initialize "to" and use fts(3) to traverse
55 * the file hierarchy rooted in the argument list. A trivial case is the
56 * case of 'cp file1 file2'. The more interesting case is the case of
57 * 'cp file1 file2 ... fileN dir' where the hierarchy is traversed and the
58 * path (relative to the root of the traversal) is appended to dir (stored
59 * in "to") to form the final target path.
60 */
61
62 #include <sys/types.h>
63 #include <sys/stat.h>
64
65 #include <assert.h>
66 #include <err.h>
67 #include <errno.h>
68 #include <fts.h>
69 #include <limits.h>
70 #include <signal.h>
71 #include <stdio.h>
72 #include <stdlib.h>
73 #include <string.h>
74 #include <unistd.h>
75
76 #include "extern.h"
77
78 #define STRIP_TRAILING_SLASH(p) { \
79 while ((p).p_end > (p).p_path + 1 && (p).p_end[-1] == '/') \
80 *--(p).p_end = 0; \
81 }
82
83 static char emptystring[] = "";
84
85 PATH_T to = { to.p_path, emptystring, "" };
86
87 int Nflag, fflag, iflag, lflag, nflag, pflag, sflag, vflag;
88 static int Hflag, Lflag, Pflag, Rflag, rflag;
89 volatile sig_atomic_t info;
90
91 enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE };
92
93 static int copy(char *[], enum op, int, struct stat *);
94 static void siginfo(int __unused);
95
96 int
main(int argc,char * argv[])97 main(int argc, char *argv[])
98 {
99 struct stat to_stat, tmp_stat;
100 enum op type;
101 int ch, fts_options, r, have_trailing_slash;
102 char *target;
103
104 fts_options = FTS_NOCHDIR | FTS_PHYSICAL;
105 while ((ch = getopt(argc, argv, "HLPRafilNnprsvx")) != -1)
106 switch (ch) {
107 case 'H':
108 Hflag = 1;
109 Lflag = Pflag = 0;
110 break;
111 case 'L':
112 Lflag = 1;
113 Hflag = Pflag = 0;
114 break;
115 case 'P':
116 Pflag = 1;
117 Hflag = Lflag = 0;
118 break;
119 case 'R':
120 Rflag = 1;
121 break;
122 case 'a':
123 pflag = 1;
124 Rflag = 1;
125 Pflag = 1;
126 Hflag = Lflag = 0;
127 break;
128 case 'f':
129 fflag = 1;
130 iflag = nflag = 0;
131 break;
132 case 'i':
133 iflag = 1;
134 fflag = nflag = 0;
135 break;
136 case 'l':
137 lflag = 1;
138 break;
139 case 'N':
140 Nflag = 1;
141 break;
142 case 'n':
143 nflag = 1;
144 fflag = iflag = 0;
145 break;
146 case 'p':
147 pflag = 1;
148 break;
149 case 'r':
150 rflag = Lflag = 1;
151 Hflag = Pflag = 0;
152 break;
153 case 's':
154 sflag = 1;
155 break;
156 case 'v':
157 vflag = 1;
158 break;
159 case 'x':
160 fts_options |= FTS_XDEV;
161 break;
162 default:
163 usage();
164 break;
165 }
166 argc -= optind;
167 argv += optind;
168
169 if (argc < 2)
170 usage();
171
172 if (Rflag && rflag)
173 errx(1, "the -R and -r options may not be specified together");
174 if (lflag && sflag)
175 errx(1, "the -l and -s options may not be specified together");
176 if (rflag)
177 Rflag = 1;
178 if (Rflag) {
179 if (Hflag)
180 fts_options |= FTS_COMFOLLOW;
181 if (Lflag) {
182 fts_options &= ~FTS_PHYSICAL;
183 fts_options |= FTS_LOGICAL;
184 }
185 } else if (!Pflag) {
186 fts_options &= ~FTS_PHYSICAL;
187 fts_options |= FTS_LOGICAL | FTS_COMFOLLOW;
188 }
189 (void)signal(SIGINFO, siginfo);
190
191 /* Save the target base in "to". */
192 target = argv[--argc];
193 if (strlcpy(to.p_path, target, sizeof(to.p_path)) >= sizeof(to.p_path))
194 errx(1, "%s: name too long", target);
195 to.p_end = to.p_path + strlen(to.p_path);
196 if (to.p_path == to.p_end) {
197 *to.p_end++ = '.';
198 *to.p_end = 0;
199 }
200 have_trailing_slash = (to.p_end[-1] == '/');
201 if (have_trailing_slash)
202 STRIP_TRAILING_SLASH(to);
203 to.target_end = to.p_end;
204
205 /* Set end of argument list for fts(3). */
206 argv[argc] = NULL;
207
208 /*
209 * Cp has two distinct cases:
210 *
211 * cp [-R] source target
212 * cp [-R] source1 ... sourceN directory
213 *
214 * In both cases, source can be either a file or a directory.
215 *
216 * In (1), the target becomes a copy of the source. That is, if the
217 * source is a file, the target will be a file, and likewise for
218 * directories.
219 *
220 * In (2), the real target is not directory, but "directory/source".
221 */
222 r = stat(to.p_path, &to_stat);
223 if (r == -1 && errno != ENOENT)
224 err(1, "%s", to.p_path);
225 if (r == -1 || !S_ISDIR(to_stat.st_mode)) {
226 /*
227 * Case (1). Target is not a directory.
228 */
229 if (argc > 1)
230 errx(1, "%s is not a directory", to.p_path);
231
232 /*
233 * Need to detect the case:
234 * cp -R dir foo
235 * Where dir is a directory and foo does not exist, where
236 * we want pathname concatenations turned on but not for
237 * the initial mkdir().
238 */
239 if (r == -1) {
240 if (Rflag && (Lflag || Hflag))
241 stat(*argv, &tmp_stat);
242 else
243 lstat(*argv, &tmp_stat);
244
245 if (S_ISDIR(tmp_stat.st_mode) && Rflag)
246 type = DIR_TO_DNE;
247 else
248 type = FILE_TO_FILE;
249 } else
250 type = FILE_TO_FILE;
251
252 if (have_trailing_slash && type == FILE_TO_FILE) {
253 if (r == -1) {
254 errx(1, "directory %s does not exist",
255 to.p_path);
256 } else
257 errx(1, "%s is not a directory", to.p_path);
258 }
259 } else
260 /*
261 * Case (2). Target is a directory.
262 */
263 type = FILE_TO_DIR;
264
265 /*
266 * For DIR_TO_DNE, we could provide copy() with the to_stat we've
267 * already allocated on the stack here that isn't being used for
268 * anything. Not doing so, though, simplifies later logic a little bit
269 * as we need to skip checking root_stat on the first iteration and
270 * ensure that we set it with the first mkdir().
271 */
272 exit (copy(argv, type, fts_options, (type == DIR_TO_DNE ? NULL :
273 &to_stat)));
274 }
275
276 /* Does the right thing based on -R + -H/-L/-P */
277 static int
copy_stat(const char * path,struct stat * sb)278 copy_stat(const char *path, struct stat *sb)
279 {
280
281 /*
282 * For -R -H/-P, we need to lstat() instead; copy() cares about the link
283 * itself rather than the target if we're not following links during the
284 * traversal.
285 */
286 if (!Rflag || Lflag)
287 return (stat(path, sb));
288 return (lstat(path, sb));
289 }
290
291
292 static int
copy(char * argv[],enum op type,int fts_options,struct stat * root_stat)293 copy(char *argv[], enum op type, int fts_options, struct stat *root_stat)
294 {
295 char rootname[NAME_MAX];
296 struct stat created_root_stat, to_stat;
297 FTS *ftsp;
298 FTSENT *curr;
299 int base = 0, dne, badcp, rval;
300 size_t nlen;
301 char *p, *recurse_path, *target_mid;
302 mode_t mask, mode;
303
304 /*
305 * Keep an inverted copy of the umask, for use in correcting
306 * permissions on created directories when not using -p.
307 */
308 mask = ~umask(0777);
309 umask(~mask);
310
311 recurse_path = NULL;
312 if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL)
313 err(1, "fts_open");
314 for (badcp = rval = 0; (curr = fts_read(ftsp)) != NULL; badcp = 0) {
315 switch (curr->fts_info) {
316 case FTS_NS:
317 case FTS_DNR:
318 case FTS_ERR:
319 warnc(curr->fts_errno, "%s", curr->fts_path);
320 badcp = rval = 1;
321 continue;
322 case FTS_DC: /* Warn, continue. */
323 warnx("%s: directory causes a cycle", curr->fts_path);
324 badcp = rval = 1;
325 continue;
326 default:
327 ;
328 }
329
330 /*
331 * Stash the root basename off for detecting recursion later.
332 *
333 * This will be essential if the root is a symlink and we're
334 * rolling with -L or -H. The later bits will need this bit in
335 * particular.
336 */
337 if (curr->fts_level == FTS_ROOTLEVEL) {
338 strlcpy(rootname, curr->fts_name, sizeof(rootname));
339 }
340
341 /*
342 * If we are in case (2) or (3) above, we need to append the
343 * source name to the target name.
344 */
345 if (type != FILE_TO_FILE) {
346 /*
347 * Need to remember the roots of traversals to create
348 * correct pathnames. If there's a directory being
349 * copied to a non-existent directory, e.g.
350 * cp -R a/dir noexist
351 * the resulting path name should be noexist/foo, not
352 * noexist/dir/foo (where foo is a file in dir), which
353 * is the case where the target exists.
354 *
355 * Also, check for "..". This is for correct path
356 * concatenation for paths ending in "..", e.g.
357 * cp -R .. /tmp
358 * Paths ending in ".." are changed to ".". This is
359 * tricky, but seems the easiest way to fix the problem.
360 *
361 * XXX
362 * Since the first level MUST be FTS_ROOTLEVEL, base
363 * is always initialized.
364 */
365 if (curr->fts_level == FTS_ROOTLEVEL) {
366 if (type != DIR_TO_DNE) {
367 p = strrchr(curr->fts_path, '/');
368 base = (p == NULL) ? 0 :
369 (int)(p - curr->fts_path + 1);
370
371 if (!strcmp(&curr->fts_path[base],
372 ".."))
373 base += 1;
374 } else
375 base = curr->fts_pathlen;
376 }
377
378 p = &curr->fts_path[base];
379 nlen = curr->fts_pathlen - base;
380 target_mid = to.target_end;
381 if (*p != '/' && target_mid[-1] != '/')
382 *target_mid++ = '/';
383 *target_mid = 0;
384 if (target_mid - to.p_path + nlen >= PATH_MAX) {
385 warnx("%s%s: name too long (not copied)",
386 to.p_path, p);
387 badcp = rval = 1;
388 continue;
389 }
390 (void)strncat(target_mid, p, nlen);
391 to.p_end = target_mid + nlen;
392 *to.p_end = 0;
393 STRIP_TRAILING_SLASH(to);
394
395 /*
396 * We're on the verge of recursing on ourselves. Either
397 * we need to stop right here (we knowingly just created
398 * it), or we will in an immediate descendant. Record
399 * the path of the immediate descendant to make our
400 * lives a little less complicated looking.
401 */
402 if (curr->fts_info == FTS_D && root_stat != NULL &&
403 root_stat->st_dev == curr->fts_statp->st_dev &&
404 root_stat->st_ino == curr->fts_statp->st_ino) {
405 assert(recurse_path == NULL);
406
407 if (root_stat == &created_root_stat) {
408 /*
409 * This directory didn't exist when we
410 * started, we created it as part of
411 * traversal. Stop right here before we
412 * do something silly.
413 */
414 fts_set(ftsp, curr, FTS_SKIP);
415 continue;
416 }
417
418
419 if (asprintf(&recurse_path, "%s/%s", to.p_path,
420 rootname) == -1)
421 err(1, "asprintf");
422 }
423
424 if (recurse_path != NULL &&
425 strcmp(to.p_path, recurse_path) == 0) {
426 fts_set(ftsp, curr, FTS_SKIP);
427 continue;
428 }
429 }
430
431 if (curr->fts_info == FTS_DP) {
432 /*
433 * We are nearly finished with this directory. If we
434 * didn't actually copy it, or otherwise don't need to
435 * change its attributes, then we are done.
436 */
437 if (!curr->fts_number)
438 continue;
439 /*
440 * If -p is in effect, set all the attributes.
441 * Otherwise, set the correct permissions, limited
442 * by the umask. Optimise by avoiding a chmod()
443 * if possible (which is usually the case if we
444 * made the directory). Note that mkdir() does not
445 * honour setuid, setgid and sticky bits, but we
446 * normally want to preserve them on directories.
447 */
448 if (pflag) {
449 if (setfile(curr->fts_statp, -1))
450 rval = 1;
451 if (preserve_dir_acls(curr->fts_statp,
452 curr->fts_accpath, to.p_path) != 0)
453 rval = 1;
454 } else {
455 mode = curr->fts_statp->st_mode;
456 if ((mode & (S_ISUID | S_ISGID | S_ISTXT)) ||
457 ((mode | S_IRWXU) & mask) != (mode & mask))
458 if (chmod(to.p_path, mode & mask) !=
459 0) {
460 warn("chmod: %s", to.p_path);
461 rval = 1;
462 }
463 }
464 continue;
465 }
466
467 /* Not an error but need to remember it happened. */
468 if (copy_stat(to.p_path, &to_stat) == -1)
469 dne = 1;
470 else {
471 if (to_stat.st_dev == curr->fts_statp->st_dev &&
472 to_stat.st_ino == curr->fts_statp->st_ino) {
473 warnx("%s and %s are identical (not copied).",
474 to.p_path, curr->fts_path);
475 badcp = rval = 1;
476 if (S_ISDIR(curr->fts_statp->st_mode))
477 (void)fts_set(ftsp, curr, FTS_SKIP);
478 continue;
479 }
480 if (!S_ISDIR(curr->fts_statp->st_mode) &&
481 S_ISDIR(to_stat.st_mode)) {
482 warnx("cannot overwrite directory %s with "
483 "non-directory %s",
484 to.p_path, curr->fts_path);
485 badcp = rval = 1;
486 continue;
487 }
488 dne = 0;
489 }
490
491 switch (curr->fts_statp->st_mode & S_IFMT) {
492 case S_IFLNK:
493 if ((fts_options & FTS_LOGICAL) ||
494 ((fts_options & FTS_COMFOLLOW) &&
495 curr->fts_level == 0)) {
496 /*
497 * We asked FTS to follow links but got
498 * here anyway, which means the target is
499 * nonexistent or inaccessible. Let
500 * copy_file() deal with the error.
501 */
502 if (copy_file(curr, dne))
503 badcp = rval = 1;
504 } else {
505 /* Copy the link. */
506 if (copy_link(curr, !dne))
507 badcp = rval = 1;
508 }
509 break;
510 case S_IFDIR:
511 if (!Rflag) {
512 warnx("%s is a directory (not copied).",
513 curr->fts_path);
514 (void)fts_set(ftsp, curr, FTS_SKIP);
515 badcp = rval = 1;
516 break;
517 }
518 /*
519 * If the directory doesn't exist, create the new
520 * one with the from file mode plus owner RWX bits,
521 * modified by the umask. Trade-off between being
522 * able to write the directory (if from directory is
523 * 555) and not causing a permissions race. If the
524 * umask blocks owner writes, we fail.
525 */
526 if (dne) {
527 mode = curr->fts_statp->st_mode | S_IRWXU;
528 if (mkdir(to.p_path, mode) != 0) {
529 warn("%s", to.p_path);
530 (void)fts_set(ftsp, curr, FTS_SKIP);
531 badcp = rval = 1;
532 break;
533 }
534 /*
535 * First DNE with a NULL root_stat is the root
536 * path, so set root_stat. We can't really
537 * tell in all cases if the target path is
538 * within the src path, so we just stat() the
539 * first directory we created and use that.
540 */
541 if (root_stat == NULL &&
542 stat(to.p_path, &created_root_stat) != 0) {
543 warn("%s", to.p_path);
544 (void)fts_set(ftsp, curr, FTS_SKIP);
545 badcp = rval = 1;
546 break;
547 }
548 if (root_stat == NULL)
549 root_stat = &created_root_stat;
550 } else if (!S_ISDIR(to_stat.st_mode)) {
551 warnc(ENOTDIR, "%s", to.p_path);
552 (void)fts_set(ftsp, curr, FTS_SKIP);
553 badcp = rval = 1;
554 break;
555 }
556 /*
557 * Arrange to correct directory attributes later
558 * (in the post-order phase) if this is a new
559 * directory, or if the -p flag is in effect.
560 */
561 curr->fts_number = pflag || dne;
562 break;
563 case S_IFBLK:
564 case S_IFCHR:
565 if (Rflag && !sflag) {
566 if (copy_special(curr->fts_statp, !dne))
567 badcp = rval = 1;
568 } else {
569 if (copy_file(curr, dne))
570 badcp = rval = 1;
571 }
572 break;
573 case S_IFSOCK:
574 warnx("%s is a socket (not copied).",
575 curr->fts_path);
576 break;
577 case S_IFIFO:
578 if (Rflag && !sflag) {
579 if (copy_fifo(curr->fts_statp, !dne))
580 badcp = rval = 1;
581 } else {
582 if (copy_file(curr, dne))
583 badcp = rval = 1;
584 }
585 break;
586 default:
587 if (copy_file(curr, dne))
588 badcp = rval = 1;
589 break;
590 }
591 if (vflag && !badcp)
592 (void)printf("%s -> %s\n", curr->fts_path, to.p_path);
593 }
594 if (errno)
595 err(1, "fts_read");
596 fts_close(ftsp);
597 free(recurse_path);
598 return (rval);
599 }
600
601 static void
siginfo(int sig __unused)602 siginfo(int sig __unused)
603 {
604
605 info = 1;
606 }
607