From 27049d3bfc5acc53cc84a91a356441746b5608d6 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Fri, 27 Aug 1993 04:43:46 +0000 Subject: merge with 3.8.3 --- src/cp.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'src/cp.c') 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"); -- cgit v1.2.3-70-g09d2