diff options
| author | Eric Andersen <andersen@codepoet.org> | 2004-02-19 01:52:29 +0000 |
|---|---|---|
| committer | Eric Andersen <andersen@codepoet.org> | 2004-02-19 01:52:29 +0000 |
| commit | e7d244cc962c2aae6a153c6e5cf07efbbed7cb94 (patch) | |
| tree | 6b20400d3b391301ee5e7e45451ab4d61db29381 /libbb | |
| parent | e0cbe4863704c78ea703c06c0dd2d76ebac90f75 (diff) | |
| download | busybox-w32-e7d244cc962c2aae6a153c6e5cf07efbbed7cb94.tar.gz busybox-w32-e7d244cc962c2aae6a153c6e5cf07efbbed7cb94.tar.bz2 busybox-w32-e7d244cc962c2aae6a153c6e5cf07efbbed7cb94.zip | |
Chris Larson (kergoth) writes:
As Manuel points out, this is a flawed fix, and doesnt fix the
following:
mkdir -p cpa cpb cpc
cp -a cpa cpa/cpb/cpc
Attached what appears to be a more sane fix. Apply on top of previous.
Please confirm sanity.
Diffstat (limited to 'libbb')
| -rw-r--r-- | libbb/copy_file.c | 22 |
1 files changed, 6 insertions, 16 deletions
diff --git a/libbb/copy_file.c b/libbb/copy_file.c index 637b8179b..7a13e9968 100644 --- a/libbb/copy_file.c +++ b/libbb/copy_file.c | |||
| @@ -65,28 +65,12 @@ int copy_file(const char *source, const char *dest, int flags) | |||
| 65 | DIR *dp; | 65 | DIR *dp; |
| 66 | struct dirent *d; | 66 | struct dirent *d; |
| 67 | mode_t saved_umask = 0; | 67 | mode_t saved_umask = 0; |
| 68 | char *dstparent; | ||
| 69 | struct stat dstparent_stat; | ||
| 70 | 68 | ||
| 71 | if (!(flags & FILEUTILS_RECUR)) { | 69 | if (!(flags & FILEUTILS_RECUR)) { |
| 72 | bb_error_msg("%s: omitting directory", source); | 70 | bb_error_msg("%s: omitting directory", source); |
| 73 | return -1; | 71 | return -1; |
| 74 | } | 72 | } |
| 75 | 73 | ||
| 76 | dstparent = dirname(bb_xstrdup(dest)); | ||
| 77 | if (lstat(dstparent, &dstparent_stat) < 0) { | ||
| 78 | bb_perror_msg("unable to stat `%s'", dstparent); | ||
| 79 | free(dstparent); | ||
| 80 | return -1; | ||
| 81 | } | ||
| 82 | free(dstparent); | ||
| 83 | |||
| 84 | if (source_stat.st_dev == dstparent_stat.st_dev && | ||
| 85 | source_stat.st_ino == dstparent_stat.st_ino) { | ||
| 86 | bb_error_msg("cannot copy a directory, `%s', into itself, `%s'", source, dest); | ||
| 87 | return -1; | ||
| 88 | } | ||
| 89 | |||
| 90 | /* Create DEST. */ | 74 | /* Create DEST. */ |
| 91 | if (dest_exists) { | 75 | if (dest_exists) { |
| 92 | if (!S_ISDIR(dest_stat.st_mode)) { | 76 | if (!S_ISDIR(dest_stat.st_mode)) { |
| @@ -111,6 +95,8 @@ int copy_file(const char *source, const char *dest, int flags) | |||
| 111 | umask(saved_umask); | 95 | umask(saved_umask); |
| 112 | } | 96 | } |
| 113 | 97 | ||
| 98 | add_to_ino_dev_hashtable(&dest_stat, source); | ||
| 99 | |||
| 114 | /* Recursively copy files in SOURCE. */ | 100 | /* Recursively copy files in SOURCE. */ |
| 115 | if ((dp = opendir(source)) == NULL) { | 101 | if ((dp = opendir(source)) == NULL) { |
| 116 | bb_perror_msg("unable to open directory `%s'", source); | 102 | bb_perror_msg("unable to open directory `%s'", source); |
| @@ -124,6 +110,10 @@ int copy_file(const char *source, const char *dest, int flags) | |||
| 124 | new_source = concat_subpath_file(source, d->d_name); | 110 | new_source = concat_subpath_file(source, d->d_name); |
| 125 | if(new_source == NULL) | 111 | if(new_source == NULL) |
| 126 | continue; | 112 | continue; |
| 113 | if (is_in_ino_dev_hashtable(&dest_stat, &new_source)) { | ||
| 114 | bb_error_msg("cannot copy a directory, `%s', into itself, `%s'", new_source, dest); | ||
| 115 | continue; | ||
| 116 | } | ||
| 127 | new_dest = concat_path_file(dest, d->d_name); | 117 | new_dest = concat_path_file(dest, d->d_name); |
| 128 | if (copy_file(new_source, new_dest, flags) < 0) | 118 | if (copy_file(new_source, new_dest, flags) < 0) |
| 129 | status = -1; | 119 | status = -1; |
