summaryrefslogtreecommitdiff
path: root/src/cp.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>1993-08-27 04:43:46 +0000
committerJim Meyering <jim@meyering.net>1993-08-27 04:43:46 +0000
commit27049d3bfc5acc53cc84a91a356441746b5608d6 (patch)
tree33e5ab1dc7246a3a549f4211ff6a6673daca1d2d /src/cp.c
parent429043125e1842b92f1cdbc6c0a2772316c9d34e (diff)
downloadcoreutils-27049d3bfc5acc53cc84a91a356441746b5608d6.tar.xz
merge with 3.8.3
Diffstat (limited to 'src/cp.c')
-rw-r--r--src/cp.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/src/cp.c b/src/cp.c
index 7ba654679..f6dd934e2 100644
--- a/src/cp.c
+++ b/src/cp.c
@@ -41,6 +41,7 @@ struct dir_attr
};
char *dirname ();
+char *xstrdup ();
enum backup_type get_version ();
int eaccess_stat ();
@@ -375,7 +376,7 @@ do_copy (argc, argv)
ap = basename (arg);
/* For `cp -R source/.. dest', don't copy into `dest/..'. */
if (!strcmp (ap, ".."))
- dst_path = dest;
+ dst_path = xstrdup (dest);
else
{
dst_path = xmalloc (strlen (dest) + strlen (ap) + 2);
@@ -400,6 +401,7 @@ do_copy (argc, argv)
}
}
+ free (dst_path);
++optind;
if (optind == argc - 1)
break;
@@ -408,7 +410,7 @@ do_copy (argc, argv)
}
else if (argc - optind == 2)
{
- char *dst_path;
+ char *new_dest;
char *source;
struct stat source_stats;
@@ -417,23 +419,32 @@ do_copy (argc, argv)
source = argv[optind];
+ /* When the destination is specified with a trailing slash and the
+ source exists but is not a directory, convert the user's command
+ `cp source dest/' to `cp source dest/basename(source)'. */
+
if (dest[strlen (dest) - 1] == '/'
&& lstat (source, &source_stats) == 0
&& !S_ISDIR (source_stats.st_mode))
{
- char *base;
+ char *source_base;
+ char *tmp_source;
+
+ tmp_source = (char *) alloca (strlen (source) + 1);
+ strcpy (tmp_source, source);
+ strip_trailing_slashes (tmp_source);
+ source_base = basename (tmp_source);
- strip_trailing_slashes (source);
- base = basename (source);
- dst_path = (char *) alloca (strlen (dest) + 1 + strlen (base) + 1);
- stpcpy (stpcpy (stpcpy (dst_path, dest), "/"), base);
+ new_dest = (char *) alloca (strlen (dest) + 1 +
+ strlen (source_base) + 1);
+ stpcpy (stpcpy (stpcpy (new_dest, dest), "/"), source_base);
}
else
{
- dst_path = dest;
+ new_dest = dest;
}
- return copy (argv[optind], dst_path, new_dst, 0, (struct dir_list *) 0);
+ return copy (source, new_dest, new_dst, 0, (struct dir_list *) 0);
}
else
usage ("when copying multiple files, last argument must be a directory");