1 /* cp.c -- file copying (main routines)
2 Copyright (C) 89, 90, 91, 1995-2002 Free Software Foundation.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 Written by Torbjorn Granlund, David MacKenzie, and Jim Meyering. */
26 #include <sys/types.h>
32 #include "backupfile.h"
37 #include "path-concat.h"
40 #define ASSIGN_BASENAME_STRDUPA(Dest, File_name) \
44 ASSIGN_STRDUPA (tmp_abns_, (File_name)); \
45 strip_trailing_slashes (tmp_abns_); \
46 Dest = base_name (tmp_abns_); \
50 /* The official name of this program (e.g., no `g' prefix). */
51 #define PROGRAM_NAME "cp"
53 #define AUTHORS N_ ("Torbjorn Granlund, David MacKenzie, and Jim Meyering")
55 #ifndef _POSIX_VERSION
59 /* Used by do_copy, make_path_private, and re_protect
60 to keep a list of leading directories whose protections
61 need to be fixed after copying. */
66 struct dir_attr
*next
;
69 /* For long options that have no equivalent short option, use a
70 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
73 COPY_CONTENTS_OPTION
= CHAR_MAX
+ 1,
74 NO_PRESERVE_ATTRIBUTES_OPTION
,
76 PRESERVE_ATTRIBUTES_OPTION
,
79 STRIP_TRAILING_SLASHES_OPTION
,
80 TARGET_DIRECTORY_OPTION
,
81 UNLINK_DEST_BEFORE_OPENING
84 /* Initial number of entries in each hash table entry's table of inodes. */
85 #define INITIAL_HASH_MODULE 100
87 /* Initial number of entries in the inode hash table. */
88 #define INITIAL_ENTRY_TAB_SIZE 70
90 /* The invocation name of this program. */
93 /* If nonzero, the command "cp x/e_file e_dir" uses "e_dir/x/e_file"
94 as its destination instead of the usual "e_dir/e_file." */
95 static int flag_path
= 0;
97 /* Remove any trailing slashes from each SOURCE argument. */
98 static int remove_trailing_slashes
;
100 static char const *const sparse_type_string
[] =
102 "never", "auto", "always", 0
105 static enum Sparse_type
const sparse_type
[] =
107 SPARSE_NEVER
, SPARSE_AUTO
, SPARSE_ALWAYS
110 /* Valid arguments to the `--reply' option. */
111 static char const* const reply_args
[] =
113 "yes", "no", "query", 0
116 /* The values that correspond to the above strings. */
117 static int const reply_vals
[] =
119 I_ALWAYS_YES
, I_ALWAYS_NO
, I_ASK_USER
122 /* The error code to return to the system. */
123 static int exit_status
= 0;
125 static struct option
const long_opts
[] =
127 {"archive", no_argument
, NULL
, 'a'},
128 {"backup", optional_argument
, NULL
, 'b'},
129 {"copy-contents", no_argument
, NULL
, COPY_CONTENTS_OPTION
},
130 {"dereference", no_argument
, NULL
, 'L'},
131 {"force", no_argument
, NULL
, 'f'},
132 {"interactive", no_argument
, NULL
, 'i'},
133 {"link", no_argument
, NULL
, 'l'},
134 {"no-dereference", no_argument
, NULL
, 'P'},
135 {"no-preserve", required_argument
, NULL
, NO_PRESERVE_ATTRIBUTES_OPTION
},
136 {"one-file-system", no_argument
, NULL
, 'x'},
137 {"parents", no_argument
, NULL
, PARENTS_OPTION
},
138 {"path", no_argument
, NULL
, PARENTS_OPTION
}, /* Deprecated. */
139 {"preserve", optional_argument
, NULL
, PRESERVE_ATTRIBUTES_OPTION
},
140 {"recursive", no_argument
, NULL
, 'R'},
141 {"remove-destination", no_argument
, NULL
, UNLINK_DEST_BEFORE_OPENING
},
142 {"reply", required_argument
, NULL
, REPLY_OPTION
},
143 {"sparse", required_argument
, NULL
, SPARSE_OPTION
},
144 {"strip-trailing-slashes", no_argument
, NULL
, STRIP_TRAILING_SLASHES_OPTION
},
145 {"suffix", required_argument
, NULL
, 'S'},
146 {"symbolic-link", no_argument
, NULL
, 's'},
147 {"target-directory", required_argument
, NULL
, TARGET_DIRECTORY_OPTION
},
148 {"update", no_argument
, NULL
, 'u'},
149 {"verbose", no_argument
, NULL
, 'v'},
150 {"version-control", required_argument
, NULL
, 'V'}, /* Deprecated. FIXME. */
151 {GETOPT_HELP_OPTION_DECL
},
152 {GETOPT_VERSION_OPTION_DECL
},
160 fprintf (stderr
, _("Try `%s --help' for more information.\n"),
165 Usage: %s [OPTION]... SOURCE DEST\n\
166 or: %s [OPTION]... SOURCE... DIRECTORY\n\
167 or: %s [OPTION]... --target-directory=DIRECTORY SOURCE...\n\
169 program_name
, program_name
, program_name
);
171 Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\
175 Mandatory arguments to long options are mandatory for short options too.\n\
178 -a, --archive same as -dpR\n\
179 --backup[=CONTROL] make a backup of each existing destination file\n\
180 -b like --backup but does not accept an argument\n\
181 --copy-contents copy contents of special files when recursive\n\
182 -d same as --no-dereference --preserve=link\n\
185 --no-dereference never follow symbolic links\n\
186 -f, --force if an existing destination file cannot be\n\
187 opened, remove it and try again\n\
188 -i, --interactive prompt before overwrite\n\
189 -H follow command-line symbolic links\n\
192 -l, --link link files instead of copying\n\
193 -L, --dereference always follow symbolic links\n\
194 -p same as --preserve=mode,ownership,timestamps\n\
195 --preserve[=ATTR_LIST] preserve the specified attributes (default:\n\
196 mode,ownership,timestamps), if possible\n\
197 additional attributes: links, all\n\
200 --no-preserve=ATTR_LIST don't preserve the specified attributes\n\
201 --parents append source path to DIRECTORY\n\
202 -P same as `--no-dereference'\n\
205 -R, -r, --recursive copy directories recursively\n\
206 --remove-destination remove each existing destination file before\n\
207 attempting to open it (contrast with --force)\n\
210 --reply={yes,no,query} specify how to handle the prompt about an\n\
211 existing destination file\n\
212 --sparse=WHEN control creation of sparse files\n\
213 --strip-trailing-slashes remove any trailing slashes from each SOURCE\n\
217 -s, --symbolic-link make symbolic links instead of copying\n\
218 -S, --suffix=SUFFIX override the usual backup suffix\n\
219 --target-directory=DIRECTORY move all SOURCE arguments into DIRECTORY\n\
222 -u, --update copy only when the SOURCE file is newer\n\
223 than the destination file or when the\n\
224 destination file is missing\n\
225 -v, --verbose explain what is being done\n\
226 -x, --one-file-system stay on this file system\n\
228 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
229 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
232 By default, sparse SOURCE files are detected by a crude heuristic and the\n\
233 corresponding DEST file is made sparse as well. That is the behavior\n\
234 selected by --sparse=auto. Specify --sparse=always to create a sparse DEST\n\
235 file whenever the SOURCE file contains a long enough sequence of zero bytes.\n\
236 Use --sparse=never to inhibit creation of sparse files.\n\
240 The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\
241 The version control method may be selected via the --backup option or through\n\
242 the VERSION_CONTROL environment variable. Here are the values:\n\
246 none, off never make backups (even if --backup is given)\n\
247 numbered, t make numbered backups\n\
248 existing, nil numbered if numbered backups exist, simple otherwise\n\
249 simple, never always make simple backups\n\
253 As a special case, cp makes a backup of SOURCE when the force and backup\n\
254 options are given and SOURCE and DEST are the same name for an existing,\n\
257 printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT
);
262 /* Ensure that the parent directories of CONST_DST_PATH have the
263 correct protections, for the --parents option. This is done
264 after all copying has been completed, to allow permissions
265 that don't include user write/execute.
267 SRC_OFFSET is the index in CONST_DST_PATH of the beginning of the
268 source directory name.
270 ATTR_LIST is a null-terminated linked list of structures that
271 indicates the end of the filename of each intermediate directory
272 in CONST_DST_PATH that may need to have its attributes changed.
273 The command `cp --parents --preserve a/b/c d/e_dir' changes the
274 attributes of the directories d/e_dir/a and d/e_dir/a/b to match
275 the corresponding source directories regardless of whether they
276 existed before the `cp' command was given.
278 Return 0 if the parent of CONST_DST_PATH and any intermediate
279 directories specified by ATTR_LIST have the proper permissions
280 when done, otherwise 1. */
283 re_protect (const char *const_dst_path
, int src_offset
,
284 struct dir_attr
*attr_list
, const struct cp_options
*x
)
287 char *dst_path
; /* A copy of CONST_DST_PATH we can change. */
288 char *src_path
; /* The source name in `dst_path'. */
289 uid_t myeuid
= geteuid ();
291 dst_path
= (char *) alloca (strlen (const_dst_path
) + 1);
292 strcpy (dst_path
, const_dst_path
);
293 src_path
= dst_path
+ src_offset
;
295 for (p
= attr_list
; p
; p
= p
->next
)
299 dst_path
[p
->slash_offset
] = '\0';
301 if ((*(x
->xstat
)) (src_path
, &src_sb
))
303 error (0, errno
, _("failed to get attributes of %s"),
308 /* Adjust the times (and if possible, ownership) for the copy.
309 chown turns off set[ug]id bits for non-root,
310 so do the chmod last. */
312 if (x
->preserve_timestamps
)
316 /* There's currently no interface to set file timestamps with
317 better than 1-second resolution, so discard any fractional
318 part of the source timestamp. */
320 utb
.actime
= src_sb
.st_atime
;
321 utb
.modtime
= src_sb
.st_mtime
;
323 if (utime (dst_path
, &utb
))
325 error (0, errno
, _("failed to preserve times for %s"),
331 if (x
->preserve_ownership
)
333 /* If non-root uses -p, it's ok if we can't preserve ownership.
334 But root probably wants to know, e.g. if NFS disallows it,
335 or if the target system doesn't support file ownership. */
336 if (chown (dst_path
, src_sb
.st_uid
, src_sb
.st_gid
)
337 && ((errno
!= EPERM
&& errno
!= EINVAL
) || myeuid
== 0))
339 error (0, errno
, _("failed to preserve ownership for %s"),
345 if (x
->preserve_mode
|| p
->is_new_dir
)
347 if (chmod (dst_path
, src_sb
.st_mode
& x
->umask_kill
))
349 error (0, errno
, _("failed to preserve permissions for %s"),
355 dst_path
[p
->slash_offset
] = '/';
360 /* Ensure that the parent directory of CONST_DIRPATH exists, for
361 the --parents option.
363 SRC_OFFSET is the index in CONST_DIRPATH (which is a destination
364 path) of the beginning of the source directory name.
365 Create any leading directories that don't already exist,
366 giving them permissions MODE.
367 If VERBOSE_FMT_STRING is nonzero, use it as a printf format
368 string for printing a message after successfully making a directory.
369 The format should take two string arguments: the names of the
370 source and destination directories.
371 Creates a linked list of attributes of intermediate directories,
372 *ATTR_LIST, for re_protect to use after calling copy.
373 Sets *NEW_DST to 1 if this function creates parent of CONST_DIRPATH.
375 Return 0 if parent of CONST_DIRPATH exists as a directory with the proper
376 permissions when done, otherwise 1. */
378 /* FIXME: find a way to synch this function with the one in lib/makepath.c. */
381 make_path_private (const char *const_dirpath
, int src_offset
, int mode
,
382 const char *verbose_fmt_string
, struct dir_attr
**attr_list
,
383 int *new_dst
, int (*xstat
)())
386 char *dirpath
; /* A copy of CONST_DIRPATH we can change. */
387 char *src
; /* Source name in `dirpath'. */
388 char *dst_dirname
; /* Leading path of `dirpath'. */
389 size_t dirlen
; /* Length of leading path of `dirpath'. */
391 dirpath
= (char *) alloca (strlen (const_dirpath
) + 1);
392 strcpy (dirpath
, const_dirpath
);
394 src
= dirpath
+ src_offset
;
396 dirlen
= dir_len (dirpath
);
397 dst_dirname
= (char *) alloca (dirlen
+ 1);
398 memcpy (dst_dirname
, dirpath
, dirlen
);
399 dst_dirname
[dirlen
] = '\0';
403 if ((*xstat
) (dst_dirname
, &stats
))
405 /* Parent of CONST_DIRNAME does not exist.
406 Make all missing intermediate directories. */
410 while (*slash
== '/')
412 while ((slash
= strchr (slash
, '/')))
414 /* Add this directory to the list of directories whose modes need
416 struct dir_attr
*new =
417 (struct dir_attr
*) xmalloc (sizeof (struct dir_attr
));
418 new->slash_offset
= slash
- dirpath
;
419 new->next
= *attr_list
;
423 if ((*xstat
) (dirpath
, &stats
))
425 /* This element of the path does not exist. We must set
426 *new_dst and new->is_new_dir inside this loop because,
427 for example, in the command `cp --parents ../a/../b/c e_dir',
428 make_path_private creates only e_dir/../a if ./b already
432 if (mkdir (dirpath
, mode
))
434 error (0, errno
, _("cannot make directory %s"),
440 if (verbose_fmt_string
!= NULL
)
441 printf (verbose_fmt_string
, src
, dirpath
);
444 else if (!S_ISDIR (stats
.st_mode
))
446 error (0, 0, _("%s exists but is not a directory"),
457 /* Avoid unnecessary calls to `stat' when given
458 pathnames containing multiple adjacent slashes. */
459 while (*slash
== '/')
464 /* We get here if the parent of `dirpath' already exists. */
466 else if (!S_ISDIR (stats
.st_mode
))
468 error (0, 0, _("%s exists but is not a directory"), quote (dst_dirname
));
478 /* Scan the arguments, and copy each by calling copy.
479 Return 0 if successful, 1 if any errors occur. */
482 do_copy (int n_files
, char **file
, const char *target_directory
,
483 struct cp_options
*x
)
493 error (0, 0, _("missing file arguments"));
496 if (n_files
== 1 && !target_directory
)
498 error (0, 0, _("missing destination file"));
502 if (target_directory
)
503 dest
= target_directory
;
506 dest
= file
[n_files
- 1];
510 /* Initialize these hash tables only if we'll need them.
511 The problems they're used to detect can arise only if
512 there are two or more files to copy. */
519 if (lstat (dest
, &sb
))
523 error (0, errno
, _("accessing %s"), quote (dest
));
533 /* If `dest' is not a symlink to a nonexistent file, use
534 the results of stat instead of lstat, so we can copy files
535 into symlinks to directories. */
536 if (stat (dest
, &sbx
) == 0)
539 dest_is_dir
= S_ISDIR (sb
.st_mode
);
544 if (target_directory
)
546 error (0, 0, _("%s: specified target is not a directory"),
554 _("copying multiple files, but last argument %s is not a directory"),
562 /* cp file1...filen edir
563 Copy the files `file1' through `filen'
564 to the existing directory `edir'. */
567 for (i
= 0; i
< n_files
; i
++)
570 int parent_exists
= 1; /* True if dir_name (dst_path) exists. */
571 struct dir_attr
*attr_list
;
572 char *arg_in_concat
= NULL
;
575 /* Trailing slashes are meaningful (i.e., maybe worth preserving)
576 only in the source file names. */
577 if (remove_trailing_slashes
)
578 strip_trailing_slashes (arg
);
582 char *arg_no_trailing_slash
;
584 /* Use `arg' without trailing slashes in constructing destination
585 file names. Otherwise, we can end up trying to create a
586 directory via `mkdir ("dst/foo/"...', which is not portable.
587 It fails, due to the trailing slash, on at least
588 NetBSD 1.[34] systems. */
589 ASSIGN_STRDUPA (arg_no_trailing_slash
, arg
);
590 strip_trailing_slashes (arg_no_trailing_slash
);
592 /* Append all of `arg' (minus any trailing slash) to `dest'. */
593 dst_path
= path_concat (dest
, arg_no_trailing_slash
,
595 if (dst_path
== NULL
)
598 /* For --parents, we have to make sure that the directory
599 dir_name (dst_path) exists. We may have to create a few
600 leading directories. */
601 parent_exists
= !make_path_private (dst_path
,
602 arg_in_concat
- dst_path
,
605 ? "%s -> %s\n" : NULL
),
606 &attr_list
, &new_dst
,
612 /* Append the last component of `arg' to `dest'. */
614 ASSIGN_BASENAME_STRDUPA (arg_base
, arg
);
615 /* For `cp -R source/.. dest', don't copy into `dest/..'. */
616 dst_path
= (STREQ (arg_base
, "..")
618 : path_concat (dest
, arg_base
, NULL
));
623 /* make_path_private failed, so don't even attempt the copy. */
629 ret
|= copy (arg
, dst_path
, new_dst
, x
, ©_into_self
, NULL
);
633 ret
|= re_protect (dst_path
, arg_in_concat
- dst_path
,
642 else /* if (n_files == 1) */
647 struct stat source_stats
;
652 _("when preserving paths, the destination must be a directory"));
658 /* When the force and backup options have been specified and
659 the source and destination are the same name for an existing
660 regular file, convert the user's command, e.g.,
661 `cp --force --backup foo foo' to `cp --force foo fooSUFFIX'
662 where SUFFIX is determined by any version control options used. */
664 if (x
->unlink_dest_after_failed_open
665 && x
->backup_type
!= none
666 && STREQ (source
, dest
)
667 && !new_dst
&& S_ISREG (sb
.st_mode
))
669 static struct cp_options x_tmp
;
671 new_dest
= find_backup_file_name (dest
, x
->backup_type
);
672 /* Set x->backup_type to `none' so that the normal backup
673 mechanism is not used when performing the actual copy.
674 backup_type must be set to `none' only *after* the above
675 call to find_backup_file_name -- that function uses
676 backup_type to determine the suffix it applies. */
678 x_tmp
.backup_type
= none
;
681 if (new_dest
== NULL
)
685 /* When the destination is specified with a trailing slash and the
686 source exists but is not a directory, convert the user's command
687 `cp source dest/' to `cp source dest/basename(source)'. Doing
688 this ensures that the command `cp non-directory file/' will now
689 fail rather than performing the copy. COPY diagnoses the case of
690 `cp directory non-directory'. */
692 else if (dest
[strlen (dest
) - 1] == '/'
693 && lstat (source
, &source_stats
) == 0
694 && !S_ISDIR (source_stats
.st_mode
))
698 ASSIGN_BASENAME_STRDUPA (source_base
, source
);
699 new_dest
= (char *) alloca (strlen (dest
)
700 + strlen (source_base
) + 1);
701 stpcpy (stpcpy (new_dest
, dest
), source_base
);
705 new_dest
= (char *) dest
;
708 return copy (source
, new_dest
, new_dst
, x
, &unused
, NULL
);
715 cp_option_init (struct cp_options
*x
)
717 x
->copy_as_regular
= 1;
718 x
->dereference
= DEREF_UNDEFINED
;
719 x
->unlink_dest_before_opening
= 0;
720 x
->unlink_dest_after_failed_open
= 0;
722 x
->interactive
= I_UNSPECIFIED
;
723 x
->myeuid
= geteuid ();
725 x
->one_file_system
= 0;
727 x
->preserve_ownership
= 0;
728 x
->preserve_links
= 0;
729 x
->preserve_mode
= 0;
730 x
->preserve_timestamps
= 0;
732 x
->require_preserve
= 0;
734 x
->sparse_mode
= SPARSE_AUTO
;
735 x
->symbolic_link
= 0;
742 /* Find out the current file creation mask, to knock the right bits
743 when using chmod. The creation mask is set to be liberal, so
744 that created directories can be written, even if it would not
745 have been allowed with the mask this process was started with. */
746 x
->umask_kill
= ~ umask (0);
754 /* Given a string, ARG, containing a comma-separated list of arguments
755 to the --preserve option, set the appropriate fields of X to ON_OFF. */
757 decode_preserve_arg (char const *arg
, struct cp_options
*x
, int on_off
)
767 static enum File_attribute
const preserve_vals
[] =
769 PRESERVE_MODE
, PRESERVE_TIMESTAMPS
,
770 PRESERVE_OWNERSHIP
, PRESERVE_LINK
, PRESERVE_ALL
773 /* Valid arguments to the `--reply' option. */
774 static char const* const preserve_args
[] =
776 "mode", "timestamps",
777 "ownership", "links", "all", 0
780 char *arg_writable
= xstrdup (arg
);
781 char *s
= arg_writable
;
784 /* find next comma */
785 char *comma
= strchr (s
, ',');
786 enum File_attribute val
;
788 /* put a NUL in its place */
793 val
= XARGMATCH ("--preserve", s
, preserve_args
, preserve_vals
);
797 x
->preserve_mode
= on_off
;
800 case PRESERVE_TIMESTAMPS
:
801 x
->preserve_timestamps
= on_off
;
804 case PRESERVE_OWNERSHIP
:
805 x
->preserve_ownership
= on_off
;
809 x
->preserve_links
= on_off
;
813 x
->preserve_mode
= on_off
;
814 x
->preserve_timestamps
= on_off
;
815 x
->preserve_ownership
= on_off
;
816 x
->preserve_links
= on_off
;
830 main (int argc
, char **argv
)
833 int make_backups
= 0;
834 char *backup_suffix_string
;
835 char *version_control_string
= NULL
;
837 int copy_contents
= 0;
838 char *target_directory
= NULL
;
840 program_name
= argv
[0];
841 setlocale (LC_ALL
, "");
842 bindtextdomain (PACKAGE
, LOCALEDIR
);
843 textdomain (PACKAGE
);
845 atexit (close_stdout
);
849 /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless
850 we'll actually use backup_suffix_string. */
851 backup_suffix_string
= getenv ("SIMPLE_BACKUP_SUFFIX");
853 while ((c
= getopt_long (argc
, argv
, "abdfHilLprsuvxPRS:V:", long_opts
, NULL
))
862 x
.sparse_mode
= XARGMATCH ("--sparse", optarg
,
863 sparse_type_string
, sparse_type
);
866 case 'a': /* Like -dpPR. */
867 x
.dereference
= DEREF_NEVER
;
868 x
.preserve_links
= 1;
869 x
.preserve_ownership
= 1;
871 x
.preserve_timestamps
= 1;
872 x
.require_preserve
= 1;
876 case 'V': /* FIXME: this is deprecated. Remove it in 2001. */
878 _("warning: --version-control (-V) is obsolete; support for\
879 it\nwill be removed in some future release. Use --backup=%s instead."
886 version_control_string
= optarg
;
889 case COPY_CONTENTS_OPTION
:
894 x
.preserve_links
= 1;
895 x
.dereference
= DEREF_NEVER
;
899 x
.unlink_dest_after_failed_open
= 1;
903 x
.dereference
= DEREF_COMMAND_LINE_ARGUMENTS
;
907 x
.interactive
= I_ASK_USER
;
915 x
.dereference
= DEREF_ALWAYS
;
919 x
.dereference
= DEREF_NEVER
;
922 case NO_PRESERVE_ATTRIBUTES_OPTION
:
923 decode_preserve_arg (optarg
, &x
, 0);
926 case PRESERVE_ATTRIBUTES_OPTION
:
929 /* Fall through to the case for `p' below. */
933 decode_preserve_arg (optarg
, &x
, 1);
934 x
.require_preserve
= 1;
939 x
.preserve_ownership
= 1;
941 x
.preserve_timestamps
= 1;
942 x
.require_preserve
= 1;
955 x
.interactive
= XARGMATCH ("--reply", optarg
,
956 reply_args
, reply_vals
);
959 case UNLINK_DEST_BEFORE_OPENING
:
960 x
.unlink_dest_before_opening
= 1;
963 case STRIP_TRAILING_SLASHES_OPTION
:
964 remove_trailing_slashes
= 1;
971 error (1, 0, _("symbolic links are not supported on this system"));
975 case TARGET_DIRECTORY_OPTION
:
976 target_directory
= optarg
;
988 x
.one_file_system
= 1;
993 backup_suffix_string
= optarg
;
996 case_GETOPT_HELP_CHAR
;
998 case_GETOPT_VERSION_CHAR (PROGRAM_NAME
, AUTHORS
);
1005 if (x
.hard_link
&& x
.symbolic_link
)
1007 error (0, 0, _("cannot make both hard and symbolic links"));
1011 if (backup_suffix_string
)
1012 simple_backup_suffix
= xstrdup (backup_suffix_string
);
1014 x
.backup_type
= (make_backups
1015 ? xget_version (_("backup type"),
1016 version_control_string
)
1019 if (x
.preserve_mode
== 1)
1020 x
.umask_kill
= ~ (mode_t
) 0;
1022 if (x
.dereference
== DEREF_UNDEFINED
)
1025 /* This is compatible with FreeBSD. */
1026 x
.dereference
= DEREF_NEVER
;
1028 x
.dereference
= DEREF_ALWAYS
;
1031 /* The key difference between -d (--no-dereference) and not is the version
1032 of `stat' to call. */
1034 if (x
.dereference
== DEREF_NEVER
)
1038 /* For DEREF_COMMAND_LINE_ARGUMENTS, x.xstat must be stat for
1039 each command line argument, but must later be `lstat' for
1040 any symlinks that are found via recursive traversal. */
1045 x
.copy_as_regular
= copy_contents
;
1047 /* If --force (-f) was specified and we're in link-creation mode,
1048 first remove any existing destination file. */
1049 if (x
.unlink_dest_after_failed_open
&& (x
.hard_link
|| x
.symbolic_link
))
1050 x
.unlink_dest_before_opening
= 1;
1052 /* Allocate space for remembering copied and created files. */
1056 exit_status
|= do_copy (argc
- optind
, argv
+ optind
, target_directory
, &x
);