diff options
author | landley <landley@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2005-11-01 21:55:14 +0000 |
---|---|---|
committer | landley <landley@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2005-11-01 21:55:14 +0000 |
commit | 3c2f869f2a47139985df28bdfaced691f5448ee3 (patch) | |
tree | f11d140c54335ce8af9b76574fb699d62901856f /libbb | |
parent | 7ede910754646730b2ab92e5393790512930e459 (diff) | |
download | busybox-w32-3c2f869f2a47139985df28bdfaced691f5448ee3.tar.gz busybox-w32-3c2f869f2a47139985df28bdfaced691f5448ee3.tar.bz2 busybox-w32-3c2f869f2a47139985df28bdfaced691f5448ee3.zip |
Fix cp /dev/null filename, and a few in-passing cleanups.
git-svn-id: svn://busybox.net/trunk/busybox@12100 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/copy_file.c | 103 |
1 files changed, 44 insertions, 59 deletions
diff --git a/libbb/copy_file.c b/libbb/copy_file.c index cd6d38022..991fa8f5b 100644 --- a/libbb/copy_file.c +++ b/libbb/copy_file.c | |||
@@ -4,19 +4,7 @@ | |||
4 | * | 4 | * |
5 | * Copyright (C) 2001 by Matt Kraai <kraai@alumni.carnegiemellon.edu> | 5 | * Copyright (C) 2001 by Matt Kraai <kraai@alumni.carnegiemellon.edu> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | 8 | * |
21 | */ | 9 | */ |
22 | 10 | ||
@@ -32,6 +20,13 @@ | |||
32 | 20 | ||
33 | #include "busybox.h" | 21 | #include "busybox.h" |
34 | 22 | ||
23 | /* Compiler version-specific crap that should be in a header file somewhere. */ | ||
24 | |||
25 | #if !((__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)) | ||
26 | #define lchown chown | ||
27 | #endif | ||
28 | |||
29 | |||
35 | int copy_file(const char *source, const char *dest, int flags) | 30 | int copy_file(const char *source, const char *dest, int flags) |
36 | { | 31 | { |
37 | struct stat source_stat; | 32 | struct stat source_stat; |
@@ -100,7 +95,7 @@ int copy_file(const char *source, const char *dest, int flags) | |||
100 | if ((dp = opendir(source)) == NULL) { | 95 | if ((dp = opendir(source)) == NULL) { |
101 | bb_perror_msg("unable to open directory `%s'", source); | 96 | bb_perror_msg("unable to open directory `%s'", source); |
102 | status = -1; | 97 | status = -1; |
103 | goto end; | 98 | goto preserve_status; |
104 | } | 99 | } |
105 | 100 | ||
106 | while ((d = readdir(dp)) != NULL) { | 101 | while ((d = readdir(dp)) != NULL) { |
@@ -123,7 +118,8 @@ int copy_file(const char *source, const char *dest, int flags) | |||
123 | bb_perror_msg("unable to change permissions of `%s'", dest); | 118 | bb_perror_msg("unable to change permissions of `%s'", dest); |
124 | status = -1; | 119 | status = -1; |
125 | } | 120 | } |
126 | } else if (S_ISREG(source_stat.st_mode)) { | 121 | } else if (S_ISREG(source_stat.st_mode) || (flags & FILEUTILS_DEREFERENCE)) |
122 | { | ||
127 | int src_fd; | 123 | int src_fd; |
128 | int dst_fd; | 124 | int dst_fd; |
129 | #ifdef CONFIG_FEATURE_PRESERVE_HARDLINKS | 125 | #ifdef CONFIG_FEATURE_PRESERVE_HARDLINKS |
@@ -138,6 +134,7 @@ int copy_file(const char *source, const char *dest, int flags) | |||
138 | 134 | ||
139 | return 0; | 135 | return 0; |
140 | } | 136 | } |
137 | add_to_ino_dev_hashtable(&source_stat, dest); | ||
141 | #endif | 138 | #endif |
142 | src_fd = open(source, O_RDONLY); | 139 | src_fd = open(source, O_RDONLY); |
143 | if (src_fd == -1) { | 140 | if (src_fd == -1) { |
@@ -193,8 +190,7 @@ int copy_file(const char *source, const char *dest, int flags) | |||
193 | bb_perror_msg("unable to close `%s'", source); | 190 | bb_perror_msg("unable to close `%s'", source); |
194 | status = -1; | 191 | status = -1; |
195 | } | 192 | } |
196 | } | 193 | } else if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) || |
197 | else if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) || | ||
198 | S_ISSOCK(source_stat.st_mode) || S_ISFIFO(source_stat.st_mode) || | 194 | S_ISSOCK(source_stat.st_mode) || S_ISFIFO(source_stat.st_mode) || |
199 | S_ISLNK(source_stat.st_mode)) { | 195 | S_ISLNK(source_stat.st_mode)) { |
200 | 196 | ||
@@ -208,65 +204,54 @@ int copy_file(const char *source, const char *dest, int flags) | |||
208 | return -1; | 204 | return -1; |
209 | } | 205 | } |
210 | } | 206 | } |
211 | } else { | 207 | if (S_ISFIFO(source_stat.st_mode)) { |
212 | bb_error_msg("internal error: unrecognized file type"); | 208 | if (mkfifo(dest, source_stat.st_mode) < 0) { |
213 | return -1; | 209 | bb_perror_msg("cannot create fifo `%s'", dest); |
214 | } | 210 | return -1; |
215 | if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) || | 211 | } |
216 | S_ISSOCK(source_stat.st_mode)) { | 212 | } else if (S_ISLNK(source_stat.st_mode)) { |
217 | if (mknod(dest, source_stat.st_mode, source_stat.st_rdev) < 0) { | 213 | char *lpath; |
218 | bb_perror_msg("unable to create `%s'", dest); | ||
219 | return -1; | ||
220 | } | ||
221 | } else if (S_ISFIFO(source_stat.st_mode)) { | ||
222 | if (mkfifo(dest, source_stat.st_mode) < 0) { | ||
223 | bb_perror_msg("cannot create fifo `%s'", dest); | ||
224 | return -1; | ||
225 | } | ||
226 | } else if (S_ISLNK(source_stat.st_mode)) { | ||
227 | char *lpath; | ||
228 | |||
229 | lpath = xreadlink(source); | ||
230 | if (symlink(lpath, dest) < 0) { | ||
231 | bb_perror_msg("cannot create symlink `%s'", dest); | ||
232 | return -1; | ||
233 | } | ||
234 | free(lpath); | ||
235 | 214 | ||
236 | #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) | 215 | lpath = xreadlink(source); |
237 | if (flags & FILEUTILS_PRESERVE_STATUS) | 216 | if (symlink(lpath, dest) < 0) { |
238 | if (lchown(dest, source_stat.st_uid, source_stat.st_gid) < 0) | 217 | bb_perror_msg("cannot create symlink `%s'", dest); |
239 | bb_perror_msg("unable to preserve ownership of `%s'", dest); | 218 | return -1; |
240 | #endif | 219 | } |
220 | free(lpath); | ||
241 | 221 | ||
242 | #ifdef CONFIG_FEATURE_PRESERVE_HARDLINKS | 222 | if (flags & FILEUTILS_PRESERVE_STATUS) |
243 | add_to_ino_dev_hashtable(&source_stat, dest); | 223 | if (lchown(dest, source_stat.st_uid, source_stat.st_gid) < 0) |
244 | #endif | 224 | bb_perror_msg("unable to preserve ownership of `%s'", dest); |
245 | 225 | ||
246 | return 0; | 226 | return 0; |
247 | } | ||
248 | 227 | ||
249 | #ifdef CONFIG_FEATURE_PRESERVE_HARDLINKS | 228 | } else { |
250 | if (! S_ISDIR(source_stat.st_mode)) { | 229 | if (mknod(dest, source_stat.st_mode, source_stat.st_rdev) < 0) { |
251 | add_to_ino_dev_hashtable(&source_stat, dest); | 230 | bb_perror_msg("unable to create `%s'", dest); |
231 | return -1; | ||
232 | } | ||
233 | } | ||
234 | } else { | ||
235 | bb_error_msg("internal error: unrecognized file type"); | ||
236 | return -1; | ||
252 | } | 237 | } |
253 | #endif | ||
254 | 238 | ||
255 | end: | 239 | preserve_status: |
256 | 240 | ||
257 | if (flags & FILEUTILS_PRESERVE_STATUS) { | 241 | if (flags & FILEUTILS_PRESERVE_STATUS) { |
258 | struct utimbuf times; | 242 | struct utimbuf times; |
243 | char *msg="unable to preserve %s of `%s'"; | ||
259 | 244 | ||
260 | times.actime = source_stat.st_atime; | 245 | times.actime = source_stat.st_atime; |
261 | times.modtime = source_stat.st_mtime; | 246 | times.modtime = source_stat.st_mtime; |
262 | if (utime(dest, ×) < 0) | 247 | if (utime(dest, ×) < 0) |
263 | bb_perror_msg("unable to preserve times of `%s'", dest); | 248 | bb_perror_msg(msg, "times", dest); |
264 | if (chown(dest, source_stat.st_uid, source_stat.st_gid) < 0) { | 249 | if (chown(dest, source_stat.st_uid, source_stat.st_gid) < 0) { |
265 | source_stat.st_mode &= ~(S_ISUID | S_ISGID); | 250 | source_stat.st_mode &= ~(S_ISUID | S_ISGID); |
266 | bb_perror_msg("unable to preserve ownership of `%s'", dest); | 251 | bb_perror_msg(msg, "ownership", dest); |
267 | } | 252 | } |
268 | if (chmod(dest, source_stat.st_mode) < 0) | 253 | if (chmod(dest, source_stat.st_mode) < 0) |
269 | bb_perror_msg("unable to preserve permissions of `%s'", dest); | 254 | bb_perror_msg(msg, "permissions", dest); |
270 | } | 255 | } |
271 | 256 | ||
272 | return status; | 257 | return status; |