aboutsummaryrefslogtreecommitdiff
path: root/libbb/copy_file.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-09-17 08:42:21 +0000
committerEric Andersen <andersen@codepoet.org>2002-09-17 08:42:21 +0000
commita9a220b92a9a88babb0080f0dfa6d27bac5edd6f (patch)
tree42c1d37565092225f6347cf87887be5615060eaf /libbb/copy_file.c
parentbf8bf105fb9866f35aee0cb835bc972d0056afa3 (diff)
downloadbusybox-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.c92
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