VirtualBox

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

Last change on this file since 2060 was 1630, checked in by bird, 17 years ago

Forgot to read the environment.

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