Chris Larson (kergoth) writes:
authorEric Andersen <andersen@codepoet.org>
Thu, 19 Feb 2004 01:52:29 +0000 (01:52 -0000)
committerEric Andersen <andersen@codepoet.org>
Thu, 19 Feb 2004 01:52:29 +0000 (01:52 -0000)
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.

libbb/copy_file.c

index 637b817..7a13e99 100644 (file)
@@ -65,28 +65,12 @@ int copy_file(const char *source, const char *dest, int flags)
                DIR *dp;
                struct dirent *d;
                mode_t saved_umask = 0;
-               char *dstparent;
-               struct stat dstparent_stat;
 
                if (!(flags & FILEUTILS_RECUR)) {
                        bb_error_msg("%s: omitting directory", source);
                        return -1;
                }
 
-               dstparent = dirname(bb_xstrdup(dest));
-               if (lstat(dstparent, &dstparent_stat) < 0) {
-                       bb_perror_msg("unable to stat `%s'", dstparent);
-                       free(dstparent);
-                       return -1;
-               }
-               free(dstparent);
-
-               if (source_stat.st_dev == dstparent_stat.st_dev &&
-                       source_stat.st_ino == dstparent_stat.st_ino) {
-                       bb_error_msg("cannot copy a directory, `%s', into itself, `%s'", source, dest);
-                       return -1;
-               }
-
                /* Create DEST.  */
                if (dest_exists) {
                        if (!S_ISDIR(dest_stat.st_mode)) {
@@ -111,6 +95,8 @@ int copy_file(const char *source, const char *dest, int flags)
                        umask(saved_umask);
                }
 
+               add_to_ino_dev_hashtable(&dest_stat, source);
+
                /* Recursively copy files in SOURCE.  */
                if ((dp = opendir(source)) == NULL) {
                        bb_perror_msg("unable to open directory `%s'", source);
@@ -124,6 +110,10 @@ int copy_file(const char *source, const char *dest, int flags)
                        new_source = concat_subpath_file(source, d->d_name);
                        if(new_source == NULL)
                                continue;
+                       if (is_in_ino_dev_hashtable(&dest_stat, &new_source)) {
+                               bb_error_msg("cannot copy a directory, `%s', into itself, `%s'", new_source, dest);
+                               continue;
+                       }
                        new_dest = concat_path_file(dest, d->d_name);
                        if (copy_file(new_source, new_dest, flags) < 0)
                                status = -1;