aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2005-11-01 21:55:14 +0000
committerRob Landley <rob@landley.net>2005-11-01 21:55:14 +0000
commit2f30932eca235c9ff581f78c989e9d93ae9ca78f (patch)
treef11d140c54335ce8af9b76574fb699d62901856f /libbb
parentdbc608b5687ebe1b828f921c70573280d6c3e313 (diff)
downloadbusybox-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.c103
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
35int copy_file(const char *source, const char *dest, int flags) 30int 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
255end: 239preserve_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, &times) < 0) 247 if (utime(dest, &times) < 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;