X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=libbb%2Fcopy_file.c;h=9333a8d4992b833db6ecea304e59f3ed767a5f8c;hb=eced0c78a54bbecc61f1717d33f64ee7d99804bb;hp=adcfe2111f23dc68bb7b8619779fb2abce6b6862;hpb=389cca4b9ed07be8d873b2aae01f3eb0c3474f7c;p=oweals%2Fbusybox.git diff --git a/libbb/copy_file.c b/libbb/copy_file.c index adcfe2111..9333a8d49 100644 --- a/libbb/copy_file.c +++ b/libbb/copy_file.c @@ -5,7 +5,7 @@ * Copyright (C) 2001 by Matt Kraai * SELinux support by Yuichi Nakamura * - * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ #include "libbb.h" @@ -78,12 +78,12 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags) /* NB: each struct stat is ~100 bytes */ struct stat source_stat; struct stat dest_stat; - signed char retval = 0; - signed char dest_exists = 0; - signed char ovr; + smallint retval = 0; + smallint dest_exists = 0; + smallint ovr; /* Inverse of cp -d ("cp without -d") */ -#define FLAGS_DEREF (flags & FILEUTILS_DEREFERENCE) +#define FLAGS_DEREF (flags & (FILEUTILS_DEREFERENCE + FILEUTILS_DEREFERENCE_L0)) if ((FLAGS_DEREF ? stat : lstat)(source, &source_stat) < 0) { /* This may be a dangling symlink. @@ -147,7 +147,6 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags) return -1; } - /* Create DEST */ if (dest_exists) { if (!S_ISDIR(dest_stat.st_mode)) { bb_error_msg("target '%s' is not a directory", dest); @@ -156,6 +155,7 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags) /* race here: user can substitute a symlink between * this check and actual creation of files inside dest */ } else { + /* Create DEST */ mode_t mode; saved_umask = umask(0); @@ -194,7 +194,7 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags) if (new_source == NULL) continue; new_dest = concat_path_file(dest, d->d_name); - if (copy_file(new_source, new_dest, flags) < 0) + if (copy_file(new_source, new_dest, flags & ~FILEUTILS_DEREFERENCE_L0) < 0) retval = -1; free(new_source); free(new_dest); @@ -316,9 +316,9 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags) #endif if (bb_copyfd_eof(src_fd, dst_fd) == -1) retval = -1; - /* Ok, writing side I can understand... */ + /* Careful with writing... */ if (close(dst_fd) < 0) { - bb_perror_msg("can't close '%s'", dest); + bb_perror_msg("error writing to '%s'", dest); retval = -1; } /* ...but read size is already checked by bb_copyfd_eof */ @@ -374,12 +374,12 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags) /* Cannot happen: */ /* && !(flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) */ ) { - struct timeval times; + struct timeval times[2]; - times.tv_sec = source_stat.st_mtime; - times.tv_usec = 0; + times[1].tv_sec = times[0].tv_sec = source_stat.st_mtime; + times[1].tv_usec = times[0].tv_usec = 0; /* BTW, utimes sets usec-precision time - just FYI */ - if (utimes(dest, ×) < 0) + if (utimes(dest, times) < 0) bb_perror_msg("can't preserve %s of '%s'", "times", dest); if (chown(dest, source_stat.st_uid, source_stat.st_gid) < 0) { source_stat.st_mode &= ~(S_ISUID | S_ISGID);