From 4325d27dddd3e17b4ec7a1baeef1820e073c8271 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Wed, 3 Apr 1996 05:42:14 +0000 Subject: [PATCH] =?utf8?q?Include=20assert.h=20(disabled).=20(path=5Fconca?= =?utf8?q?t):=20New=20function.=20(do=5Fcopy):=20Use=20path=5Fconcat=20ins?= =?utf8?q?tead=20of=20open-coding=20part=20of=20its=20functionality=20in?= =?utf8?q?=20two=20places.=20=20This=20has=20the=20additional=20benefit=20?= =?utf8?q?of=20avoiding=20forming=20destination=20names=20like=20`D//file'?= =?utf8?q?=20when=20the=20destination=20directory=20D=20includes=20a=20tra?= =?utf8?q?iling=20slash=20--=20as=20would=20happen=20when=20cp=20is=20used?= =?utf8?q?=20like=20this:=20mkdir=20D;=20touch=20file=20D/file;=20cp=20-i?= =?utf8?q?=20file=20D/=20Reported=20by=20Fran=E7ois=20Pinard.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- src/cp.c | 55 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/src/cp.c b/src/cp.c index b12704a998..bb03ff6ae1 100644 --- a/src/cp.c +++ b/src/cp.c @@ -23,6 +23,10 @@ #include #include + +#define NDEBUG +#include + #include #include "cp.h" #include "backupfile.h" @@ -355,7 +359,29 @@ main (int argc, char **argv) exit (exit_status); } - + +/* Concatenate two pathname components, DIR and BASE, in newly-allocated + storage and return the result. Be careful that in the result they are + separated by a slash. That is, if DIR ends with a slash or if BASE + begins with one, don't add a separating slash. Otherwise, add one. */ + +static char * +path_concat (const char *dir, const char *base) +{ + char *dir_end; + char *p_concat; + + assert (strlen (dir) > 0); + p_concat = xmalloc (strlen (dir) + strlen (base) + 2); + dir_end = stpcpy (p_concat, dir); + if (*(dir_end - 1) == '/') + --dir_end; + else if (*base == '/') + ++base; + stpcpy (stpcpy (dir_end, "/"), base); + return p_concat; +} + /* Scan the arguments, and copy each by calling copy. Return 0 if successful, 1 if any errors occur. */ @@ -416,17 +442,16 @@ do_copy (int argc, char **argv) if (flag_path) { /* Append all of `arg' to `dest'. */ - dst_path = xmalloc (strlen (dest) + strlen (arg) + 2); - stpcpy (stpcpy (stpcpy (dst_path, dest), "/"), arg); + dst_path = path_concat (dest, arg); /* For --parents, we have to make sure that the directory dirname (dst_path) exists. We may have to create a few leading directories. */ parent_exists = !make_path_private (dst_path, - strlen (dest) + 1, 0700, - flag_verbose ? "%s -> %s\n" : - (char *) NULL, - &attr_list, &new_dst); + strlen (dest) + 1, 0700, + (flag_verbose + ? "%s -> %s\n" : NULL), + &attr_list, &new_dst); } else { @@ -434,18 +459,14 @@ do_copy (int argc, char **argv) ap = basename (arg); /* For `cp -R source/.. dest', don't copy into `dest/..'. */ - if (!strcmp (ap, "..")) - dst_path = xstrdup (dest); - else - { - dst_path = xmalloc (strlen (dest) + strlen (ap) + 2); - stpcpy (stpcpy (stpcpy (dst_path, dest), "/"), ap); - } + dst_path = (strcmp (ap, "..") == 0 + ? xstrdup (dest) + : path_concat (dest, ap)); } if (!parent_exists) { - /* make_path_private failed, so we shouldn't even attempt the copy. */ + /* make_path_private failed, so don't even attempt the copy. */ ret = 1; } else @@ -455,8 +476,7 @@ do_copy (int argc, char **argv) if (flag_path) { - ret |= re_protect (dst_path, strlen (dest) + 1, - attr_list); + ret |= re_protect (dst_path, strlen (dest) + 1, attr_list); } } @@ -1221,6 +1241,7 @@ copy_reg (char *src_path, char *dst_path) /* If the file has fewer blocks than would normally be needed for a file of its size, then at least one of the blocks in the file is a hole. */ + /* FIXME: isn't there risk of overflow here? */ if (S_ISREG (sb.st_mode) && sb.st_size > sb.st_blocks * DEV_BSIZE) make_holes = 1; } -- 2.47.2