VirtualBox

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

Last change on this file since 2134 was 2113, checked in by bird, 16 years ago

kmkbuiltin: include config.h

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

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