summaryrefslogtreecommitdiffstats
path: root/bin/cp
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1994-12-30 13:12:12 +0000
committerbde <bde@FreeBSD.org>1994-12-30 13:12:12 +0000
commitb4e68b2cf59b4eea196ba19626abb0ba05640adc (patch)
tree0ed154f123258ae0f099c5b84cd7c961ac78e191 /bin/cp
parentcf6d909a92c93c2e65ac1330cfe9c8582e763efe (diff)
downloadFreeBSD-src-b4e68b2cf59b4eea196ba19626abb0ba05640adc.zip
FreeBSD-src-b4e68b2cf59b4eea196ba19626abb0ba05640adc.tar.gz
Don't strip off the last slash in the pathname "/". cp used to
stat the pathname "" in order to decide that the pathname "/" is a directory. This caused `cp kernel /' to fail if the kernel has the POSIX behaviour of not allowing the pathname "" to be an alias for ".". It presumably also caused `cp /etc/motd /' to fail in the unlikely event that "." is not stat'able. Be more careful about concatenating pathnames: don't check that the pathname fits until prefixes have been discarded (the check was too strict). Print the final pathname in error messages. Terminate the target directory name properly for error messages. Don't add a slash between components if there is already a slash.
Diffstat (limited to 'bin/cp')
-rw-r--r--bin/cp/cp.c33
1 files changed, 15 insertions, 18 deletions
diff --git a/bin/cp/cp.c b/bin/cp/cp.c
index 5a81a98..d8a2c8dc 100644
--- a/bin/cp/cp.c
+++ b/bin/cp/cp.c
@@ -33,7 +33,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: cp.c,v 1.2 1994/09/24 02:53:41 davidg Exp $
*/
#ifndef lint
@@ -79,7 +79,7 @@ static char sccsid[] = "@(#)cp.c 8.2 (Berkeley) 4/1/94";
#include "extern.h"
#define STRIP_TRAILING_SLASH(p) { \
- while ((p).p_end > (p).p_path && (p).p_end[-1] == '/') \
+ while ((p).p_end > (p).p_path + 1 && (p).p_end[-1] == '/') \
*--(p).p_end = 0; \
}
@@ -253,7 +253,7 @@ copy(argv, type, fts_options)
FTS *ftsp;
FTSENT *curr;
int base, dne, nlen, rval;
- char *p;
+ char *p, *target_mid;
if ((ftsp = fts_open(argv, fts_options, mastercmp)) == NULL)
err(1, NULL);
@@ -278,14 +278,6 @@ copy(argv, type, fts_options)
* source name to the target name.
*/
if (type != FILE_TO_FILE) {
- if ((curr->fts_namelen +
- to.target_end - to.p_path + 1) > MAXPATHLEN) {
- warnx("%s/%s: name too long (not copied)",
- to.p_path, curr->fts_name);
- rval = 1;
- continue;
- }
-
/*
* Need to remember the roots of traversals to create
* correct pathnames. If there's a directory being
@@ -317,15 +309,20 @@ copy(argv, type, fts_options)
} else
base = curr->fts_pathlen;
- if (to.target_end[-1] != '/') {
- *to.target_end = '/';
- *(to.target_end + 1) = 0;
- }
p = &curr->fts_path[base];
nlen = curr->fts_pathlen - base;
-
- (void)strncat(to.target_end + 1, p, nlen);
- to.p_end = to.target_end + nlen + 1;
+ target_mid = to.target_end;
+ if (*p != '/' && target_mid[-1] != '/')
+ *target_mid++ = '/';
+ *target_mid = 0;
+ if (target_mid - to.p_path + nlen > MAXPATHLEN) {
+ warnx("%s%s: name too long (not copied)",
+ to.p_path, p);
+ rval = 1;
+ continue;
+ }
+ (void)strncat(target_mid, p, nlen);
+ to.p_end = target_mid + nlen;
*to.p_end = 0;
STRIP_TRAILING_SLASH(to);
}
OpenPOWER on IntegriCloud