diff options
| author | Rob Landley <rob@landley.net> | 2005-11-01 21:55:14 +0000 |
|---|---|---|
| committer | Rob Landley <rob@landley.net> | 2005-11-01 21:55:14 +0000 |
| commit | 2f30932eca235c9ff581f78c989e9d93ae9ca78f (patch) | |
| tree | f11d140c54335ce8af9b76574fb699d62901856f /libbb | |
| parent | dbc608b5687ebe1b828f921c70573280d6c3e313 (diff) | |
| download | busybox-w32-2f30932eca235c9ff581f78c989e9d93ae9ca78f.tar.gz busybox-w32-2f30932eca235c9ff581f78c989e9d93ae9ca78f.tar.bz2 busybox-w32-2f30932eca235c9ff581f78c989e9d93ae9ca78f.zip | |
Fix cp /dev/null filename, and a few in-passing cleanups.
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; |
