VirtualBox

source: kBuild/trunk/src/kmk/kmkbuiltin/cp.c@ 3173

Last change on this file since 3173 was 3148, checked in by bird, 7 years ago

kmk: Make sure we use our fts.h, never the system one (except OS/2).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.3 KB
Line 
1/*
2 * Copyright (c) 1988, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * David Hitz of Auspex Systems Inc.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 4. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#if 0
34#ifndef lint
35static char const copyright[] =
36"@(#) Copyright (c) 1988, 1993, 1994\n\
37 The Regents of the University of California. All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41static char sccsid[] = "@(#)cp.c 8.2 (Berkeley) 4/1/94";
42#endif /* not lint */
43#include <sys/cdefs.h>
44__FBSDID("$FreeBSD: src/bin/cp/cp.c,v 1.50 2004/04/06 20:06:44 markm Exp $");
45#endif
46
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 "config.h"
63#include <sys/types.h>
64#include <sys/stat.h>
65
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#include "getopt.h"
76#include "k/kDefs.h"
77#ifdef _MSC_VER
78# include "mscfakes.h"
79#endif
80#include "cp_extern.h"
81#include "kmkbuiltin.h"
82#include "kbuild_protection.h"
83
84#if defined(_MSC_VER) || defined(__gnu_linux__) || defined(__linux__)
85extern size_t strlcpy(char *, const char *, size_t);
86#endif
87
88
89#ifndef S_IFWHT
90#define S_IFWHT 0
91#define S_ISWHT(s) 0
92#define undelete(s) (-1)
93#endif
94
95#ifndef S_ISTXT
96#ifdef S_ISVTX
97#define S_ISTXT S_ISVTX
98#else
99#define S_ISTXT 0
100#endif
101#endif /* !S_ISTXT */
102
103#ifndef __unused
104# define __unused
105#endif
106
107#if K_OS == K_OS_WINDOWS || K_OS == K_OS_OS2
108# define IS_SLASH(ch) ((ch) == '/' || (ch) == '\\')
109#else
110# define IS_SLASH(ch) ((ch) == '/')
111#endif
112
113#define STRIP_TRAILING_SLASH(p) { \
114 while ((p).p_end > (p).p_path + 1 && IS_SLASH((p).p_end[-1])) \
115 *--(p).p_end = 0; \
116}
117
118/* have wrappers for globals in cp_extern! */
119
120static KBUILDPROTECTION g_ProtData;
121const char *cp_argv0;
122static char emptystring[] = "";
123
124PATH_T to = { to.p_path, emptystring, "" };
125
126int fflag, iflag, nflag, pflag, vflag;
127static int Rflag, rflag;
128volatile sig_atomic_t info;
129static int cp_ignore_non_existing, cp_changed_only;
130
131enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE };
132
133enum cp_arg {
134 CP_OPT_HELP = 261,
135 CP_OPT_VERSION,
136 CP_OPT_IGNORE_NON_EXISTING,
137 CP_OPT_CHANGED,
138 CP_OPT_DISABLE_PROTECTION,
139 CP_OPT_ENABLE_PROTECTION,
140 CP_OPT_ENABLE_FULL_PROTECTION,
141 CP_OPT_DISABLE_FULL_PROTECTION,
142 CP_OPT_PROTECTION_DEPTH
143};
144static struct option long_options[] =
145{
146 { "help", no_argument, 0, CP_OPT_HELP },
147 { "version", no_argument, 0, CP_OPT_VERSION },
148 { "ignore-non-existing", no_argument, 0, CP_OPT_IGNORE_NON_EXISTING },
149 { "changed", no_argument, 0, CP_OPT_CHANGED },
150 { "disable-protection", no_argument, 0, CP_OPT_DISABLE_PROTECTION },
151 { "enable-protection", no_argument, 0, CP_OPT_ENABLE_PROTECTION },
152 { "enable-full-protection", no_argument, 0, CP_OPT_ENABLE_FULL_PROTECTION },
153 { "disable-full-protection", no_argument, 0, CP_OPT_DISABLE_FULL_PROTECTION },
154 { "protection-depth", required_argument, 0, CP_OPT_PROTECTION_DEPTH },
155 { 0, 0, 0, 0 },
156};
157
158
159static int copy(char *[], enum op, int);
160static int mastercmp(const FTSENT **, const FTSENT **);
161#ifdef SIGINFO
162static void siginfo(int __unused);
163#endif
164static int usage(FILE *);
165
166int
167kmk_builtin_cp(int argc, char *argv[], char **envp)
168{
169 struct stat to_stat, tmp_stat;
170 enum op type;
171 int Hflag, Lflag, Pflag, ch, fts_options, r, have_trailing_slash, rc;
172 char *target;
173
174 /* init globals */
175 cp_argv0 = argv[0];
176 to.p_end = to.p_path;
177 to.target_end = emptystring;
178 memset(to.p_path, 0, sizeof(to.p_path));
179 fflag = iflag = nflag = pflag = vflag = Rflag = rflag = 0;
180 info = 0;
181 cp_ignore_non_existing = cp_changed_only = 0;
182 kBuildProtectionInit(&g_ProtData);
183
184 /* reset getopt and set progname. */
185 g_progname = argv[0];
186 opterr = 1;
187 optarg = NULL;
188 optopt = 0;
189 optind = 0; /* init */
190
191 Hflag = Lflag = Pflag = 0;
192 while ((ch = getopt_long(argc, argv, "HLPRfinprv", long_options, NULL)) != -1)
193 switch (ch) {
194 case 'H':
195 Hflag = 1;
196 Lflag = Pflag = 0;
197 break;
198 case 'L':
199 Lflag = 1;
200 Hflag = Pflag = 0;
201 break;
202 case 'P':
203 Pflag = 1;
204 Hflag = Lflag = 0;
205 break;
206 case 'R':
207 Rflag = 1;
208 break;
209 case 'f':
210 fflag = 1;
211 iflag = nflag = 0;
212 break;
213 case 'i':
214 iflag = 1;
215 fflag = nflag = 0;
216 break;
217 case 'n':
218 nflag = 1;
219 fflag = iflag = 0;
220 break;
221 case 'p':
222 pflag = 1;
223 break;
224 case 'r':
225 rflag = 1;
226 break;
227 case 'v':
228 vflag = 1;
229 break;
230 case CP_OPT_HELP:
231 usage(stdout);
232 kBuildProtectionTerm(&g_ProtData);
233 return 0;
234 case CP_OPT_VERSION:
235 kBuildProtectionTerm(&g_ProtData);
236 return kbuild_version(argv[0]);
237 case CP_OPT_IGNORE_NON_EXISTING:
238 cp_ignore_non_existing = 1;
239 break;
240 case CP_OPT_CHANGED:
241 cp_changed_only = 1;
242 break;
243 case CP_OPT_DISABLE_PROTECTION:
244 kBuildProtectionDisable(&g_ProtData, KBUILDPROTECTIONTYPE_RECURSIVE);
245 break;
246 case CP_OPT_ENABLE_PROTECTION:
247 kBuildProtectionEnable(&g_ProtData, KBUILDPROTECTIONTYPE_RECURSIVE);
248 break;
249 case CP_OPT_ENABLE_FULL_PROTECTION:
250 kBuildProtectionEnable(&g_ProtData, KBUILDPROTECTIONTYPE_FULL);
251 break;
252 case CP_OPT_DISABLE_FULL_PROTECTION:
253 kBuildProtectionDisable(&g_ProtData, KBUILDPROTECTIONTYPE_FULL);
254 break;
255 case CP_OPT_PROTECTION_DEPTH:
256 if (kBuildProtectionSetDepth(&g_ProtData, optarg)) {
257 kBuildProtectionTerm(&g_ProtData);
258 return 1;
259 }
260 break;
261 default:
262 kBuildProtectionTerm(&g_ProtData);
263 return usage(stderr);
264 }
265 argc -= optind;
266 argv += optind;
267
268 if (argc < 2) {
269 kBuildProtectionTerm(&g_ProtData);
270 return usage(stderr);
271 }
272
273 fts_options = FTS_NOCHDIR | FTS_PHYSICAL;
274 if (rflag) {
275 if (Rflag) {
276 kBuildProtectionTerm(&g_ProtData);
277 return errx(1,
278 "the -R and -r options may not be specified together.");
279 }
280 if (Hflag || Lflag || Pflag)
281 errx(1,
282 "the -H, -L, and -P options may not be specified with the -r option.");
283 fts_options &= ~FTS_PHYSICAL;
284 fts_options |= FTS_LOGICAL;
285 }
286 if (Rflag) {
287 if (Hflag)
288 fts_options |= FTS_COMFOLLOW;
289 if (Lflag) {
290 fts_options &= ~FTS_PHYSICAL;
291 fts_options |= FTS_LOGICAL;
292 }
293 } else {
294 fts_options &= ~FTS_PHYSICAL;
295 fts_options |= FTS_LOGICAL | FTS_COMFOLLOW;
296 }
297#ifdef SIGINFO
298 (void)signal(SIGINFO, siginfo);
299#endif
300
301 /* Save the target base in "to". */
302 target = argv[--argc];
303 if (strlcpy(to.p_path, target, sizeof(to.p_path)) >= sizeof(to.p_path)) {
304 kBuildProtectionTerm(&g_ProtData);
305 return errx(1, "%s: name too long", target);
306 }
307 to.p_end = to.p_path + strlen(to.p_path);
308 if (to.p_path == to.p_end) {
309 *to.p_end++ = '.';
310 *to.p_end = 0;
311 }
312 have_trailing_slash = IS_SLASH(to.p_end[-1]);
313 if (have_trailing_slash)
314 STRIP_TRAILING_SLASH(to);
315 to.target_end = to.p_end;
316
317 /* Set end of argument list for fts(3). */
318 argv[argc] = NULL;
319
320 /*
321 * Cp has two distinct cases:
322 *
323 * cp [-R] source target
324 * cp [-R] source1 ... sourceN directory
325 *
326 * In both cases, source can be either a file or a directory.
327 *
328 * In (1), the target becomes a copy of the source. That is, if the
329 * source is a file, the target will be a file, and likewise for
330 * directories.
331 *
332 * In (2), the real target is not directory, but "directory/source".
333 */
334 r = stat(to.p_path, &to_stat);
335 if (r == -1 && errno != ENOENT) {
336 kBuildProtectionTerm(&g_ProtData);
337 return err(1, "stat: %s", to.p_path);
338 }
339 if (r == -1 || !S_ISDIR(to_stat.st_mode)) {
340 /*
341 * Case (1). Target is not a directory.
342 */
343 if (argc > 1) {
344 kBuildProtectionTerm(&g_ProtData);
345 return usage(stderr);
346 }
347 /*
348 * Need to detect the case:
349 * cp -R dir foo
350 * Where dir is a directory and foo does not exist, where
351 * we want pathname concatenations turned on but not for
352 * the initial mkdir().
353 */
354 if (r == -1) {
355 if (rflag || (Rflag && (Lflag || Hflag)))
356 stat(*argv, &tmp_stat);
357 else
358 lstat(*argv, &tmp_stat);
359
360 if (S_ISDIR(tmp_stat.st_mode) && (Rflag || rflag))
361 type = DIR_TO_DNE;
362 else
363 type = FILE_TO_FILE;
364 } else
365 type = FILE_TO_FILE;
366
367 if (have_trailing_slash && type == FILE_TO_FILE) {
368 kBuildProtectionTerm(&g_ProtData);
369 if (r == -1)
370 return errx(1, "directory %s does not exist",
371 to.p_path);
372 else
373 return errx(1, "%s is not a directory", to.p_path);
374 }
375 } else
376 /*
377 * Case (2). Target is a directory.
378 */
379 type = FILE_TO_DIR;
380
381 /* Finally, check that the "to" directory isn't protected. */
382 rc = 1;
383 if (!kBuildProtectionScanEnv(&g_ProtData, envp, "KMK_CP_")
384 && !kBuildProtectionEnforce(&g_ProtData,
385 Rflag || rflag
386 ? KBUILDPROTECTIONTYPE_RECURSIVE
387 : KBUILDPROTECTIONTYPE_FULL,
388 to.p_path)) {
389 rc = copy(argv, type, fts_options);
390 }
391
392 kBuildProtectionTerm(&g_ProtData);
393 return rc;
394}
395
396static int
397copy(char *argv[], enum op type, int fts_options)
398{
399 struct stat to_stat;
400 FTS *ftsp;
401 FTSENT *curr;
402 int base = 0, dne, badcp, rval;
403 size_t nlen;
404 char *p, *target_mid;
405 mode_t mask, mode;
406
407 /*
408 * Keep an inverted copy of the umask, for use in correcting
409 * permissions on created directories when not using -p.
410 */
411 mask = ~umask(0777);
412 umask(~mask);
413
414 if ((ftsp = fts_open(argv, fts_options, mastercmp)) == NULL)
415 return err(1, "fts_open");
416 for (badcp = rval = 0; (curr = fts_read(ftsp)) != NULL; badcp = 0) {
417 int copied = 0;
418
419 switch (curr->fts_info) {
420 case FTS_NS:
421 if ( cp_ignore_non_existing
422 && curr->fts_errno == ENOENT) {
423 if (vflag) {
424 warnx("fts: %s: %s", curr->fts_path,
425 strerror(curr->fts_errno));
426 }
427 continue;
428 }
429 /* fall thru */
430 case FTS_DNR:
431 case FTS_ERR:
432 warnx("fts: %s: %s",
433 curr->fts_path, strerror(curr->fts_errno));
434 badcp = rval = 1;
435 continue;
436 case FTS_DC: /* Warn, continue. */
437 warnx("%s: directory causes a cycle", curr->fts_path);
438 badcp = rval = 1;
439 continue;
440 default:
441 ;
442 }
443
444 /*
445 * If we are in case (2) or (3) above, we need to append the
446 * source name to the target name.
447 */
448 if (type != FILE_TO_FILE) {
449 /*
450 * Need to remember the roots of traversals to create
451 * correct pathnames. If there's a directory being
452 * copied to a non-existent directory, e.g.
453 * cp -R a/dir noexist
454 * the resulting path name should be noexist/foo, not
455 * noexist/dir/foo (where foo is a file in dir), which
456 * is the case where the target exists.
457 *
458 * Also, check for "..". This is for correct path
459 * concatenation for paths ending in "..", e.g.
460 * cp -R .. /tmp
461 * Paths ending in ".." are changed to ".". This is
462 * tricky, but seems the easiest way to fix the problem.
463 *
464 * XXX
465 * Since the first level MUST be FTS_ROOTLEVEL, base
466 * is always initialized.
467 */
468 if (curr->fts_level == FTS_ROOTLEVEL) {
469 if (type != DIR_TO_DNE) {
470 p = strrchr(curr->fts_path, '/');
471#if K_OS == K_OS_WINDOWS || K_OS == K_OS_OS2
472 if (strrchr(curr->fts_path, '\\') > p)
473 p = strrchr(curr->fts_path, '\\');
474#endif
475 base = (p == NULL) ? 0 :
476 (int)(p - curr->fts_path + 1);
477
478 if (!strcmp(&curr->fts_path[base],
479 ".."))
480 base += 1;
481 } else
482 base = curr->fts_pathlen;
483 }
484
485 p = &curr->fts_path[base];
486 nlen = curr->fts_pathlen - base;
487 target_mid = to.target_end;
488 if (!IS_SLASH(*p) && !IS_SLASH(target_mid[-1]))
489 *target_mid++ = '/';
490 *target_mid = 0;
491 if (target_mid - to.p_path + nlen >= PATH_MAX) {
492 warnx("%s%s: name too long (not copied)",
493 to.p_path, p);
494 badcp = rval = 1;
495 continue;
496 }
497 (void)strncat(target_mid, p, nlen);
498 to.p_end = target_mid + nlen;
499 *to.p_end = 0;
500 STRIP_TRAILING_SLASH(to);
501 }
502
503 if (curr->fts_info == FTS_DP) {
504 /*
505 * We are nearly finished with this directory. If we
506 * didn't actually copy it, or otherwise don't need to
507 * change its attributes, then we are done.
508 */
509 if (!curr->fts_number)
510 continue;
511 /*
512 * If -p is in effect, set all the attributes.
513 * Otherwise, set the correct permissions, limited
514 * by the umask. Optimise by avoiding a chmod()
515 * if possible (which is usually the case if we
516 * made the directory). Note that mkdir() does not
517 * honour setuid, setgid and sticky bits, but we
518 * normally want to preserve them on directories.
519 */
520 if (pflag) {
521 if (setfile(curr->fts_statp, -1))
522 rval = 1;
523 } else {
524 mode = curr->fts_statp->st_mode;
525 if ((mode & (S_ISUID | S_ISGID | S_ISTXT)) ||
526 ((mode | S_IRWXU) & mask) != (mode & mask))
527 if (chmod(to.p_path, mode & mask) != 0){
528 warn("chmod: %s", to.p_path);
529 rval = 1;
530 }
531 }
532 continue;
533 }
534
535 /* Not an error but need to remember it happened */
536 if (stat(to.p_path, &to_stat) == -1)
537 dne = 1;
538 else {
539 if (to_stat.st_dev == curr->fts_statp->st_dev &&
540 to_stat.st_dev != 0 &&
541 to_stat.st_ino == curr->fts_statp->st_ino &&
542 to_stat.st_ino != 0) {
543 warnx("%s and %s are identical (not copied).",
544 to.p_path, curr->fts_path);
545 badcp = rval = 1;
546 if (S_ISDIR(curr->fts_statp->st_mode))
547 (void)fts_set(ftsp, curr, FTS_SKIP);
548 continue;
549 }
550 if (!S_ISDIR(curr->fts_statp->st_mode) &&
551 S_ISDIR(to_stat.st_mode)) {
552 warnx("cannot overwrite directory %s with "
553 "non-directory %s",
554 to.p_path, curr->fts_path);
555 badcp = rval = 1;
556 continue;
557 }
558 dne = 0;
559 }
560
561 switch (curr->fts_statp->st_mode & S_IFMT) {
562#ifdef S_IFLNK
563 case S_IFLNK:
564 /* Catch special case of a non-dangling symlink */
565 if ((fts_options & FTS_LOGICAL) ||
566 ((fts_options & FTS_COMFOLLOW) &&
567 curr->fts_level == 0)) {
568 if (copy_file(curr, dne, cp_changed_only, &copied))
569 badcp = rval = 1;
570 } else {
571 if (copy_link(curr, !dne))
572 badcp = rval = 1;
573 }
574 break;
575#endif
576 case S_IFDIR:
577 if (!Rflag && !rflag) {
578 warnx("%s is a directory (not copied).",
579 curr->fts_path);
580 (void)fts_set(ftsp, curr, FTS_SKIP);
581 badcp = rval = 1;
582 break;
583 }
584 /*
585 * If the directory doesn't exist, create the new
586 * one with the from file mode plus owner RWX bits,
587 * modified by the umask. Trade-off between being
588 * able to write the directory (if from directory is
589 * 555) and not causing a permissions race. If the
590 * umask blocks owner writes, we fail..
591 */
592 if (dne) {
593 if (mkdir(to.p_path,
594 curr->fts_statp->st_mode | S_IRWXU) < 0)
595 return err(1, "mkdir: %s", to.p_path);
596 } else if (!S_ISDIR(to_stat.st_mode)) {
597 errno = ENOTDIR;
598 return err(1, "to-mode: %s", to.p_path);
599 }
600 /*
601 * Arrange to correct directory attributes later
602 * (in the post-order phase) if this is a new
603 * directory, or if the -p flag is in effect.
604 */
605 curr->fts_number = pflag || dne;
606 break;
607#ifdef S_IFBLK
608 case S_IFBLK:
609#endif
610 case S_IFCHR:
611 if (Rflag) {
612 if (copy_special(curr->fts_statp, !dne))
613 badcp = rval = 1;
614 } else {
615 if (copy_file(curr, dne, cp_changed_only, &copied))
616 badcp = rval = 1;
617 }
618 break;
619#ifdef S_IFIFO
620 case S_IFIFO:
621#endif
622 if (Rflag) {
623 if (copy_fifo(curr->fts_statp, !dne))
624 badcp = rval = 1;
625 } else {
626 if (copy_file(curr, dne, cp_changed_only, &copied))
627 badcp = rval = 1;
628 }
629 break;
630 default:
631 if (copy_file(curr, dne, cp_changed_only, &copied))
632 badcp = rval = 1;
633 break;
634 }
635 if (vflag && !badcp)
636 (void)printf(copied ? "%s -> %s\n" : "%s matches %s - not copied\n",
637 curr->fts_path, to.p_path);
638 }
639 if (errno)
640 return err(1, "fts_read");
641 return (rval);
642}
643
644/*
645 * mastercmp --
646 * The comparison function for the copy order. The order is to copy
647 * non-directory files before directory files. The reason for this
648 * is because files tend to be in the same cylinder group as their
649 * parent directory, whereas directories tend not to be. Copying the
650 * files first reduces seeking.
651 */
652static int
653mastercmp(const FTSENT **a, const FTSENT **b)
654{
655 int a_info, b_info;
656
657 a_info = (*a)->fts_info;
658 if (a_info == FTS_ERR || a_info == FTS_NS || a_info == FTS_DNR)
659 return (0);
660 b_info = (*b)->fts_info;
661 if (b_info == FTS_ERR || b_info == FTS_NS || b_info == FTS_DNR)
662 return (0);
663 if (a_info == FTS_D)
664 return (-1);
665 if (b_info == FTS_D)
666 return (1);
667 return (0);
668}
669
670#ifdef SIGINFO
671static void
672siginfo(int sig __unused)
673{
674
675 info = 1;
676}
677#endif
678
679
680static int
681usage(FILE *fp)
682{
683 fprintf(fp,
684"usage: %s [options] src target\n"
685" or: %s [options] src1 ... srcN directory\n"
686" or: %s --help\n"
687" or: %s --version\n"
688"\n"
689"Options:\n"
690" -R Recursive copy.\n"
691" -H Follow symbolic links on the commandline. Only valid with -R.\n"
692" -L Follow all symbolic links. Only valid with -R.\n"
693" -P Do not follow symbolic links. Default. Only valid with -R\n"
694" -f Force. Overrides -i and -n.\n"
695" -i Iteractive. Overrides -n and -f.\n"
696" -n Don't overwrite any files. Overrides -i and -f.\n"
697" -v Verbose.\n"
698" --ignore-non-existing\n"
699" Don't fail if the specified source file doesn't exist.\n"
700" --changed\n"
701" Only copy if changed (i.e. compare first).\n"
702" --disable-protection\n"
703" Will disable the protection file protection applied with -R.\n"
704" --enable-protection\n"
705" Will enable the protection file protection applied with -R.\n"
706" --enable-full-protection\n"
707" Will enable the protection file protection for all operations.\n"
708" --disable-full-protection\n"
709" Will disable the protection file protection for all operations.\n"
710" --protection-depth\n"
711" Number or path indicating the file protection depth. Default: %d\n"
712"\n"
713"Environment:\n"
714" KMK_CP_DISABLE_PROTECTION\n"
715" Same as --disable-protection. Overrides command line.\n"
716" KMK_CP_ENABLE_PROTECTION\n"
717" Same as --enable-protection. Overrides everyone else.\n"
718" KMK_CP_ENABLE_FULL_PROTECTION\n"
719" Same as --enable-full-protection. Overrides everyone else.\n"
720" KMK_CP_DISABLE_FULL_PROTECTION\n"
721" Same as --disable-full-protection. Overrides command line.\n"
722" KMK_CP_PROTECTION_DEPTH\n"
723" Same as --protection-depth. Overrides command line.\n"
724"\n"
725"The file protection of the top %d layers of the file hierarchy is there\n"
726"to try prevent makefiles from doing bad things to your system. This\n"
727"protection is not bulletproof, but should help prevent you from shooting\n"
728"yourself in the foot.\n"
729 ,
730 g_progname, g_progname, g_progname, g_progname,
731 kBuildProtectionDefaultDepth(), kBuildProtectionDefaultDepth());
732 return 1;
733}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette