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.
This commit is contained in:
		| @@ -65,28 +65,12 @@ int copy_file(const char *source, const char *dest, int flags) | |||||||
| 		DIR *dp; | 		DIR *dp; | ||||||
| 		struct dirent *d; | 		struct dirent *d; | ||||||
| 		mode_t saved_umask = 0; | 		mode_t saved_umask = 0; | ||||||
| 		char *dstparent; |  | ||||||
| 		struct stat dstparent_stat; |  | ||||||
|  |  | ||||||
| 		if (!(flags & FILEUTILS_RECUR)) { | 		if (!(flags & FILEUTILS_RECUR)) { | ||||||
| 			bb_error_msg("%s: omitting directory", source); | 			bb_error_msg("%s: omitting directory", source); | ||||||
| 			return -1; | 			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.  */ | 		/* Create DEST.  */ | ||||||
| 		if (dest_exists) { | 		if (dest_exists) { | ||||||
| 			if (!S_ISDIR(dest_stat.st_mode)) { | 			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); | 			umask(saved_umask); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		add_to_ino_dev_hashtable(&dest_stat, source); | ||||||
|  |  | ||||||
| 		/* Recursively copy files in SOURCE.  */ | 		/* Recursively copy files in SOURCE.  */ | ||||||
| 		if ((dp = opendir(source)) == NULL) { | 		if ((dp = opendir(source)) == NULL) { | ||||||
| 			bb_perror_msg("unable to open directory `%s'", source); | 			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); | 			new_source = concat_subpath_file(source, d->d_name); | ||||||
| 			if(new_source == NULL) | 			if(new_source == NULL) | ||||||
| 				continue; | 				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); | 			new_dest = concat_path_file(dest, d->d_name); | ||||||
| 			if (copy_file(new_source, new_dest, flags) < 0) | 			if (copy_file(new_source, new_dest, flags) < 0) | ||||||
| 				status = -1; | 				status = -1; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user