diff options
author | Jim Meyering <jim@meyering.net> | 1993-08-27 04:43:46 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 1993-08-27 04:43:46 +0000 |
commit | 27049d3bfc5acc53cc84a91a356441746b5608d6 (patch) | |
tree | 33e5ab1dc7246a3a549f4211ff6a6673daca1d2d /src | |
parent | 429043125e1842b92f1cdbc6c0a2772316c9d34e (diff) | |
download | coreutils-27049d3bfc5acc53cc84a91a356441746b5608d6.tar.xz |
merge with 3.8.3
Diffstat (limited to 'src')
-rw-r--r-- | src/cp.c | 29 | ||||
-rw-r--r-- | src/install.c | 3 | ||||
-rw-r--r-- | src/ln.c | 58 | ||||
-rw-r--r-- | src/ls.c | 14 |
4 files changed, 78 insertions, 26 deletions
@@ -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"); diff --git a/src/install.c b/src/install.c index 9d579c22d..e6fc16276 100644 --- a/src/install.c +++ b/src/install.c @@ -91,6 +91,7 @@ int wait (); #define READ_SIZE (32 * 1024) char *basename (); +char *stpcpy (); char *xmalloc (); void error (); int make_path (); @@ -291,7 +292,7 @@ install_file_in_dir (from, to_dir) from_base = basename (from); to = xmalloc ((unsigned) (strlen (to_dir) + strlen (from_base) + 2)); - sprintf (to, "%s/%s", to_dir, from_base); + stpcpy (stpcpy (stpcpy (to, to_dir), "/"), from_base); ret = install_file_in_file (from, to); free (to); return ret; @@ -33,12 +33,33 @@ int link (); /* Some systems don't declare this anywhere. */ int symlink (); #endif +/* Construct a string NEW_DEST by concatenating DEST, a slash, and + basename(SOURCE) in alloca'd memory. Don't modify DEST or SOURCE. */ + +#define PATH_BASENAME_CONCAT(new_dest, dest, source) \ + do \ + { \ + 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); \ + \ + (new_dest) = (char *) alloca (strlen ((dest)) + 1 \ + + strlen (source_base) + 1); \ + stpcpy (stpcpy (stpcpy ((new_dest), (dest)), "/"), source_base);\ + } \ + while (0) + char *basename (); enum backup_type get_version (); int isdir (); int yesno (); void error (); void strip_trailing_slashes (); +char *stpcpy (); static void usage (); static int do_link (); @@ -174,7 +195,30 @@ main (argc, argv) errors = do_link (argv[optind], "."); else if (optind == argc - 2) { - errors = do_link (argv[optind], argv[optind + 1]); + struct stat source_stats; + char *source; + char *dest; + char *new_dest; + + source = argv[optind]; + dest = argv[optind + 1]; + + /* When the destination is specified with a trailing slash and the + source exists but is not a directory, convert the user's command + `ln source dest/' to `ln source dest/basename(source)'. */ + + if (dest[strlen (dest) - 1] == '/' + && lstat (source, &source_stats) == 0 + && !S_ISDIR (source_stats.st_mode)) + { + PATH_BASENAME_CONCAT (new_dest, dest, source); + } + else + { + new_dest = dest; + } + + errors = do_link (source, new_dest); } else { @@ -215,17 +259,7 @@ do_link (source, dest) { /* Target is a directory; build the full filename. */ char *new_dest; - 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); - new_dest = (char *) - alloca (strlen (source_base) + 1 + strlen (dest) + 1); - sprintf (new_dest, "%s/%s", dest, source_base); + PATH_BASENAME_CONCAT (new_dest, dest, source); dest = new_dest; } @@ -1218,6 +1218,8 @@ sort_files () case time_atime: func = sort_reverse ? rev_cmp_atime : compare_atime; break; + default: + abort (); } break; case sort_name: @@ -1229,6 +1231,8 @@ sort_files () case sort_size: func = sort_reverse ? rev_cmp_size : compare_size; break; + default: + abort (); } qsort (files, files_index, sizeof (struct file), func); @@ -1435,11 +1439,12 @@ print_long_format (f) } if (print_inode) - printf ("%6u ", f->stat.st_ino); + printf ("%6lu ", (unsigned long) f->stat.st_ino); if (print_block_size) printf ("%*u ", block_size_size, - convert_blocks (ST_NBLOCKS (f->stat), kilobyte_blocks)); + (unsigned) convert_blocks (ST_NBLOCKS (f->stat), + kilobyte_blocks)); /* The space between the mode and the number of links is the POSIX "optional alternate access method flag". */ @@ -1560,11 +1565,12 @@ print_file_name_and_frills (f) struct file *f; { if (print_inode) - printf ("%6u ", f->stat.st_ino); + printf ("%6lu ", (unsigned long) f->stat.st_ino); if (print_block_size) printf ("%*u ", block_size_size, - convert_blocks (ST_NBLOCKS (f->stat), kilobyte_blocks)); + (unsigned) convert_blocks (ST_NBLOCKS (f->stat), + kilobyte_blocks)); print_name_with_quoting (f->name); |