1
0
mirror of git://git.sv.gnu.org/coreutils.git synced 2026-04-20 02:36:16 +02:00

Accept new option: --target-directory=DIR

(TARGET_DIRECTORY_OPTION): Define.
(SPARSE_OPTION): Define.
(usage): Describe it.
(do_copy): Change meanings/names of first two parameters: use `n_files'
in place of `argc - optind', and `file' instead of `argv + optind'.
Add parameter, target_directory.
(main): Pass new arg, target_directory.
This commit is contained in:
Jim Meyering
1999-10-17 10:01:30 +00:00
parent a374a307c5
commit f893b3807d

View File

@@ -55,6 +55,14 @@ struct dir_attr
struct dir_attr *next;
};
/* For long options that have no equivalent short option, use a
non-character as a pseudo short option, starting with CHAR_MAX + 1. */
enum
{
TARGET_DIRECTORY_OPTION = CHAR_MAX + 1,
SPARSE_OPTION = CHAR_MAX + 2
};
int stat ();
int lstat ();
@@ -91,7 +99,7 @@ static struct option const long_opts[] =
{"archive", no_argument, NULL, 'a'},
{"backup", optional_argument, NULL, 'b'},
{"force", no_argument, NULL, 'f'},
{"sparse", required_argument, NULL, CHAR_MAX + 1},
{"sparse", required_argument, NULL, SPARSE_OPTION},
{"interactive", no_argument, NULL, 'i'},
{"link", no_argument, NULL, 'l'},
{"no-dereference", no_argument, NULL, 'd'},
@@ -102,6 +110,7 @@ static struct option const long_opts[] =
{"recursive", no_argument, NULL, 'R'},
{"suffix", required_argument, NULL, 'S'},
{"symbolic-link", no_argument, NULL, 's'},
{"target-directory", required_argument, NULL, TARGET_DIRECTORY_OPTION},
{"update", no_argument, NULL, 'u'},
{"verbose", no_argument, NULL, 'v'},
{"version-control", required_argument, NULL, 'V'}, /* Deprecated. FIXME. */
@@ -121,6 +130,7 @@ usage (int status)
printf (_("\
Usage: %s [OPTION]... SOURCE DEST\n\
or: %s [OPTION]... SOURCE... DIRECTORY\n\
or: %s [OPTION]... --target-directory=DIRECTORY SOURCE...\n\
"),
program_name, program_name);
printf (_("\
@@ -139,6 +149,7 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\
-R, --recursive copy directories recursively\n\
-s, --symbolic-link make symbolic links instead of copying\n\
-S, --suffix=SUFFIX override the usual backup suffix\n\
--target-directory=DIR move all SOURCE arguments into directory DIR\n\
-u, --update copy only when the SOURCE file is newer\n\
than the destination file or when the\n\
destination file is missing\n\
@@ -387,25 +398,33 @@ make_path_private (const char *const_dirpath, int src_offset, int mode,
Return 0 if successful, 1 if any errors occur. */
static int
do_copy (int argc, char **argv, const struct cp_options *x)
do_copy (int n_files, char **file, const char *target_directory,
const struct cp_options *x)
{
char *dest;
struct stat sb;
int new_dst = 0;
int ret = 0;
int dest_is_dir = 0;
if (optind >= argc)
if (n_files <= 0)
{
error (0, 0, _("missing file arguments"));
usage (1);
}
if (optind >= argc - 1)
if (n_files == 1 && !target_directory)
{
error (0, 0, _("missing destination file"));
usage (1);
}
dest = argv[argc - 1];
if (target_directory)
dest = target_directory;
else
{
dest = file[n_files - 1];
--n_files;
}
if (lstat (dest, &sb))
{
@@ -414,8 +433,8 @@ do_copy (int argc, char **argv, const struct cp_options *x)
error (0, errno, "%s", dest);
return 1;
}
else
new_dst = 1;
new_dst = 1;
}
else
{
@@ -426,24 +445,42 @@ do_copy (int argc, char **argv, const struct cp_options *x)
into symlinks to directories. */
if (stat (dest, &sbx) == 0)
sb = sbx;
dest_is_dir = S_ISDIR (sb.st_mode);
}
if (!new_dst && S_ISDIR (sb.st_mode))
if (!dest_is_dir)
{
if (target_directory)
{
error (0, 0, _("specified target, `%s' is not a directory"), dest);
usage (1);
}
if (n_files > 1)
{
error (0, 0,
_("copying multiple files, but last argument (%s) is not a directory"),
dest);
usage (1);
}
}
if (dest_is_dir)
{
/* cp file1...filen edir
Copy the files `file1' through `filen'
to the existing directory `edir'. */
int i;
for (;;)
for (i = 0; i < n_files; i++)
{
char *arg;
char *ap;
char *dst_path;
int parent_exists = 1; /* True if dir_name (dst_path) exists. */
struct dir_attr *attr_list;
char *arg_in_concat = NULL;
arg = argv[optind];
char *arg = file[i];
strip_trailing_slashes (arg);
@@ -495,13 +532,10 @@ do_copy (int argc, char **argv, const struct cp_options *x)
}
free (dst_path);
++optind;
if (optind == argc - 1)
break;
}
return ret;
}
else if (argc - optind == 2)
else /* if (n_files == 1) */
{
char *new_dest;
char *source;
@@ -511,11 +545,11 @@ do_copy (int argc, char **argv, const struct cp_options *x)
if (flag_path)
{
error (0, 0,
_("when preserving paths, last argument must be a directory"));
_("when preserving paths, the destination must be a directory"));
usage (1);
}
source = argv[optind];
source = file[0];
/* When the force and backup options have been specified and
the source and destination are the same name for an existing
@@ -574,17 +608,8 @@ do_copy (int argc, char **argv, const struct cp_options *x)
return copy (source, new_dest, new_dst, x, &unused, NULL);
}
else
{
error (0, 0,
_("copying multiple files, but last argument (%s) \
is not a directory"),
dest);
usage (1);
}
/* unreachable */
return 0;
}
static void
@@ -629,6 +654,7 @@ main (int argc, char **argv)
char *backup_suffix_string;
char *version_control_string = NULL;
struct cp_options x;
char *target_directory = NULL;
program_name = argv[0];
setlocale (LC_ALL, "");
@@ -649,7 +675,7 @@ main (int argc, char **argv)
case 0:
break;
case CHAR_MAX + 1:
case SPARSE_OPTION:
x.sparse_mode = XARGMATCH ("--sparse", optarg,
sparse_type_string, sparse_type);
break;
@@ -721,6 +747,10 @@ main (int argc, char **argv)
#endif
break;
case TARGET_DIRECTORY_OPTION:
target_directory = optarg;
break;
case 'u':
x.update = 1;
break;
@@ -776,7 +806,7 @@ main (int argc, char **argv)
hash_init (INITIAL_HASH_MODULE, INITIAL_ENTRY_TAB_SIZE);
exit_status |= do_copy (argc, argv, &x);
exit_status |= do_copy (argc - optind, argv + optind, target_directory, &x);
if (x.verbose)
close_stdout ();