diff options
author | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 1998-07-03 16:43:57 +0000 |
---|---|---|
committer | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 1998-07-03 16:43:57 +0000 |
commit | 86b025b6d4d2afedf502954c8ced3206ce9c8b07 (patch) | |
tree | 8b44d5312a08213ea94188713417e62ce3c05410 /bin/cp | |
parent | a4815bfcbb3698855374b247505353ece73d92ad (diff) |
Fix handling of trailing slashes. Don't ever strip them, because that's
the way the user tells us that he really wants a directory. Also, a
trailing slash does not mean that the last component is null (in fact,
according to POSIX, a component can't be 0 bytes). Rather, the last
component is the one directly preceding the trailing slashes.
Diffstat (limited to 'bin/cp')
-rw-r--r-- | bin/cp/cp.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/bin/cp/cp.c b/bin/cp/cp.c index fdac621fb20..86bd676da14 100644 --- a/bin/cp/cp.c +++ b/bin/cp/cp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cp.c,v 1.11 1997/11/08 23:17:11 todd Exp $ */ +/* $OpenBSD: cp.c,v 1.12 1998/07/03 16:43:56 csapuntz Exp $ */ /* $NetBSD: cp.c,v 1.14 1995/09/07 06:14:51 jtc Exp $ */ /* @@ -47,7 +47,7 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)cp.c 8.5 (Berkeley) 4/29/95"; #else -static char rcsid[] = "$OpenBSD: cp.c,v 1.11 1997/11/08 23:17:11 todd Exp $"; +static char rcsid[] = "$OpenBSD: cp.c,v 1.12 1998/07/03 16:43:56 csapuntz Exp $"; #endif #endif /* not lint */ @@ -98,6 +98,7 @@ enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE }; int copy __P((char *[], enum op, int)); int mastercmp __P((const FTSENT **, const FTSENT **)); +char *find_last_component __P((char *)); int main(argc, argv) @@ -188,7 +189,6 @@ main(argc, argv) *to.p_end++ = '.'; *to.p_end = '\0'; } - STRIP_TRAILING_SLASH(to); to.target_end = to.p_end; /* Set end of argument list for fts(3). */ @@ -247,6 +247,33 @@ main(argc, argv) exit (copy(argv, type, fts_options)); } +char * +find_last_component(path) + char *path; + +{ + char *p; + + if ((p = strrchr(path, '/')) == NULL) + p = path; + else { + /* Special case foo/ */ + if (!*(p+1)) { + while ((p >= path) && + *p == '/') + p--; + + while ((p >= path) && + *p != '/') + p--; + } + + p++; + } + + return (p); +} + int copy(argv, type, fts_options) char *argv[]; @@ -305,10 +332,9 @@ copy(argv, type, fts_options) */ if (curr->fts_level == FTS_ROOTLEVEL) if (type != DIR_TO_DNE) { - p = strrchr(curr->fts_path, '/'); - base = (p == NULL) ? 0 : - (int)(p - curr->fts_path + 1); - + p = find_last_component(curr->fts_path); + base = p - curr->fts_path; + if (!strcmp(&curr->fts_path[base], "..")) base += 1; @@ -330,7 +356,6 @@ copy(argv, type, fts_options) (void)strncat(target_mid, p, nlen); to.p_end = target_mid + nlen; *to.p_end = '\0'; - STRIP_TRAILING_SLASH(to); } /* Not an error but need to remember it happened */ |