diff options
author | Eric Andersen <andersen@codepoet.org> | 2002-09-17 08:42:21 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2002-09-17 08:42:21 +0000 |
commit | a9a220b92a9a88babb0080f0dfa6d27bac5edd6f (patch) | |
tree | 42c1d37565092225f6347cf87887be5615060eaf /libbb/copy_file.c | |
parent | bf8bf105fb9866f35aee0cb835bc972d0056afa3 (diff) | |
download | busybox-w32-a9a220b92a9a88babb0080f0dfa6d27bac5edd6f.tar.gz busybox-w32-a9a220b92a9a88babb0080f0dfa6d27bac5edd6f.tar.bz2 busybox-w32-a9a220b92a9a88babb0080f0dfa6d27bac5edd6f.zip |
last_patch56 from vodz to simplify copy_file logic
Diffstat (limited to 'libbb/copy_file.c')
-rw-r--r-- | libbb/copy_file.c | 92 |
1 files changed, 18 insertions, 74 deletions
diff --git a/libbb/copy_file.c b/libbb/copy_file.c index d71dbf47d..5f667cf4f 100644 --- a/libbb/copy_file.c +++ b/libbb/copy_file.c | |||
@@ -36,7 +36,7 @@ int copy_file(const char *source, const char *dest, int flags) | |||
36 | { | 36 | { |
37 | struct stat source_stat; | 37 | struct stat source_stat; |
38 | struct stat dest_stat; | 38 | struct stat dest_stat; |
39 | int dest_exists = 1; | 39 | int dest_exists = 0; |
40 | int status = 0; | 40 | int status = 0; |
41 | 41 | ||
42 | if ((!(flags & FILEUTILS_DEREFERENCE) && | 42 | if ((!(flags & FILEUTILS_DEREFERENCE) && |
@@ -52,14 +52,14 @@ int copy_file(const char *source, const char *dest, int flags) | |||
52 | perror_msg("unable to stat `%s'", dest); | 52 | perror_msg("unable to stat `%s'", dest); |
53 | return -1; | 53 | return -1; |
54 | } | 54 | } |
55 | dest_exists = 0; | 55 | } else { |
56 | } | 56 | if (source_stat.st_dev == dest_stat.st_dev && |
57 | |||
58 | if (dest_exists && source_stat.st_dev == dest_stat.st_dev && | ||
59 | source_stat.st_ino == dest_stat.st_ino) { | 57 | source_stat.st_ino == dest_stat.st_ino) { |
60 | error_msg("`%s' and `%s' are the same file", source, dest); | 58 | error_msg("`%s' and `%s' are the same file", source, dest); |
61 | return -1; | 59 | return -1; |
62 | } | 60 | } |
61 | dest_exists = 1; | ||
62 | } | ||
63 | 63 | ||
64 | if (S_ISDIR(source_stat.st_mode)) { | 64 | if (S_ISDIR(source_stat.st_mode)) { |
65 | DIR *dp; | 65 | DIR *dp; |
@@ -116,13 +116,8 @@ int copy_file(const char *source, const char *dest, int flags) | |||
116 | free(new_source); | 116 | free(new_source); |
117 | free(new_dest); | 117 | free(new_dest); |
118 | } | 118 | } |
119 | 119 | /* closedir have only EBADF error, but "dp" not changes */ | |
120 | /* ??? What if an error occurs in readdir? */ | 120 | closedir(dp); |
121 | |||
122 | if (closedir(dp) < 0) { | ||
123 | perror_msg("unable to close directory `%s'", source); | ||
124 | status = -1; | ||
125 | } | ||
126 | 121 | ||
127 | if (!dest_exists && | 122 | if (!dest_exists && |
128 | chmod(dest, source_stat.st_mode & ~saved_umask) < 0) { | 123 | chmod(dest, source_stat.st_mode & ~saved_umask) < 0) { |
@@ -145,8 +140,7 @@ int copy_file(const char *source, const char *dest, int flags) | |||
145 | } | 140 | } |
146 | #endif | 141 | #endif |
147 | 142 | ||
148 | if ((sfp = fopen(source, "r")) == NULL) { | 143 | if ((sfp = wfopen(source, "r")) == NULL) { |
149 | perror_msg("unable to open `%s'", source); | ||
150 | return -1; | 144 | return -1; |
151 | } | 145 | } |
152 | 146 | ||
@@ -201,55 +195,28 @@ int copy_file(const char *source, const char *dest, int flags) | |||
201 | perror_msg("unable to close `%s'", source); | 195 | perror_msg("unable to close `%s'", source); |
202 | status = -1; | 196 | status = -1; |
203 | } | 197 | } |
204 | } else if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) || | ||
205 | S_ISSOCK(source_stat.st_mode)) { | ||
206 | |||
207 | if (dest_exists) { | ||
208 | if (flags & FILEUTILS_INTERACTIVE) { | ||
209 | fprintf(stderr, "%s: overwrite `%s'? ", applet_name, dest); | ||
210 | if (!ask_confirmation()) | ||
211 | return 0; | ||
212 | } | 198 | } |
199 | else if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) || | ||
200 | S_ISSOCK(source_stat.st_mode) || S_ISFIFO(source_stat.st_mode) || | ||
201 | S_ISLNK(source_stat.st_mode)) { | ||
213 | 202 | ||
214 | if (!(flags & FILEUTILS_FORCE)) { | 203 | if (dest_exists && |
204 | ((flags & FILEUTILS_FORCE) == 0 || unlink(dest) < 0)) { | ||
215 | perror_msg("unable to remove `%s'", dest); | 205 | perror_msg("unable to remove `%s'", dest); |
216 | return -1; | 206 | return -1; |
217 | } | ||
218 | 207 | ||
219 | if (unlink(dest) < 0) { | ||
220 | perror_msg("unable to remove `%s'", dest); | ||
221 | return -1; | ||
222 | } | 208 | } |
223 | 209 | } else { | |
224 | dest_exists = 0; | 210 | error_msg("internal error: unrecognized file type"); |
211 | return -1; | ||
225 | } | 212 | } |
226 | 213 | if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) || | |
214 | S_ISSOCK(source_stat.st_mode)) { | ||
227 | if (mknod(dest, source_stat.st_mode, source_stat.st_rdev) < 0) { | 215 | if (mknod(dest, source_stat.st_mode, source_stat.st_rdev) < 0) { |
228 | perror_msg("unable to create `%s'", dest); | 216 | perror_msg("unable to create `%s'", dest); |
229 | return -1; | 217 | return -1; |
230 | } | 218 | } |
231 | } else if (S_ISFIFO(source_stat.st_mode)) { | 219 | } else if (S_ISFIFO(source_stat.st_mode)) { |
232 | |||
233 | if (dest_exists) { | ||
234 | if (flags & FILEUTILS_INTERACTIVE) { | ||
235 | fprintf(stderr, "%s: overwrite `%s'? ", applet_name, dest); | ||
236 | if (!ask_confirmation()) | ||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | if (!(flags & FILEUTILS_FORCE)) { | ||
241 | perror_msg("unable to remove `%s'", dest); | ||
242 | return -1; | ||
243 | } | ||
244 | |||
245 | if (unlink(dest) < 0) { | ||
246 | perror_msg("unable to remove `%s'", dest); | ||
247 | return -1; | ||
248 | } | ||
249 | |||
250 | dest_exists = 0; | ||
251 | } | ||
252 | |||
253 | if (mkfifo(dest, source_stat.st_mode) < 0) { | 220 | if (mkfifo(dest, source_stat.st_mode) < 0) { |
254 | perror_msg("cannot create fifo `%s'", dest); | 221 | perror_msg("cannot create fifo `%s'", dest); |
255 | return -1; | 222 | return -1; |
@@ -257,26 +224,6 @@ int copy_file(const char *source, const char *dest, int flags) | |||
257 | } else if (S_ISLNK(source_stat.st_mode)) { | 224 | } else if (S_ISLNK(source_stat.st_mode)) { |
258 | char *lpath; | 225 | char *lpath; |
259 | 226 | ||
260 | if (dest_exists) { | ||
261 | if (flags & FILEUTILS_INTERACTIVE) { | ||
262 | fprintf(stderr, "%s: overwrite `%s'? ", applet_name, dest); | ||
263 | if (!ask_confirmation()) | ||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | if (!(flags & FILEUTILS_FORCE)) { | ||
268 | perror_msg("unable to remove `%s'", dest); | ||
269 | return -1; | ||
270 | } | ||
271 | |||
272 | if (unlink(dest) < 0) { | ||
273 | perror_msg("unable to remove `%s'", dest); | ||
274 | return -1; | ||
275 | } | ||
276 | |||
277 | dest_exists = 0; | ||
278 | } | ||
279 | |||
280 | lpath = xreadlink(source); | 227 | lpath = xreadlink(source); |
281 | if (symlink(lpath, dest) < 0) { | 228 | if (symlink(lpath, dest) < 0) { |
282 | perror_msg("cannot create symlink `%s'", dest); | 229 | perror_msg("cannot create symlink `%s'", dest); |
@@ -295,9 +242,6 @@ int copy_file(const char *source, const char *dest, int flags) | |||
295 | #endif | 242 | #endif |
296 | 243 | ||
297 | return 0; | 244 | return 0; |
298 | } else { | ||
299 | error_msg("internal error: unrecognized file type"); | ||
300 | return -1; | ||
301 | } | 245 | } |
302 | 246 | ||
303 | #ifdef CONFIG_FEATURE_PRESERVE_HARDLINKS | 247 | #ifdef CONFIG_FEATURE_PRESERVE_HARDLINKS |