1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
From: Horst von Brand <vonbrand@sleipnir.valparaiso.cl>
Subject: Re: Warning! Bug in GNU fileutils-3.13s cp
Date: Thu, 15 Aug 1996 21:41:36 -0400
To: fawcett@nynexst.com
Yes, I got a fix for that one. Unfortunately (?), a short time after I
bought a new disk drive (2.5Gb! My first drive (I was _very_ proud of it!!)
had 20Mb... sic transit gloria mundii). As Murphy's law demands, after I
installed everything (RedHat this time) and had a full backup stashed away
on the new disk, it crashed... and took the backups with it. I could get
the accounts and basic configuration back, but my working copy of yard is
gone. I have had a busy time getting this machine into working order
(tweaking around, you will say ;-) and I still not completely familiar with
it. But a new set of rescue disks has now reached the top of my priority
list. Here is the patch I got. I stripped the '> ' from the patch proper,
so you can patch directly with my message.
> -- using template mhl.format --
> Date: Fri, 19 Jul 1996 23:54:15 EST
> To: vonbrand@sleipnir.valparaiso.cl
> cc: bug-gnu-utils@prep.ai.mit.edu, carlos@riglos.fisica.ufpr.br
>
> From: Jim Meyering <meyering@asic.sc.ti.com>
> Subject: Re: fileutils-3.13: cp -P -R /tmp/xxx /tmp/yyy doesn't work
>
> Return-Path: meyering@asic.sc.ti.com
> X-Authentication-Warning: appaloosa.asic.sc.ti.com: meyering owned process doin
> ***g -bs
> Reply-To: meyering@na-net.ornl.gov
> In-Reply-To: Your message of "Tue, 16 Jul 1996 18:58:35 -0400"
> References: <199607162258.SAA18174@sleipnir.valparaiso.cl>
> Mime-Version: 1.0
>
> Thanks again for the bug report.
> Here's a patch:
>
Fri Jul 19 23:28:36 1996 Jim Meyering <meyering@na-net.ornl.gov>
* src/cp.c (path_concat): Rewrite to return new parameter.
(do_copy): Update uses of path_concat to use new parameter.
Use that new pointer to compute correct offset for make_path_private.
Before, cp --recursive --parents SRC DEST failed when SRC was
an absolute file name. E.g.,
% cd /tmp; rm -rf d f; mkdir d; touch f; cp -PR /tmp/f d
cp: tmp: No such file or directory
Reported by Horst von Brand vonbrand@sleipnir.valparaiso.cl.
Index: cp.c
===================================================================
RCS file: /x/t/a/fileutils/src/cp.c,v
retrieving revision 1.61
diff -u -F^[_a-zA-Z$][_a-zA-Z0-9$]*.(\(.*)[^;]*\|[^;]+,$\) -r1.61 cp.c
--- cp.c 1996-06-23 14:15:15-05 1.61
+++ cp.c 1996-07-19 20:52:22-05
@@ -367,23 +367,33 @@ main (int argc, char **argv)
/* 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. */
+ separated by a slash. That is, if DIR ends with a slash and BASE
+ begins with one, elide one slash at the end of DIR. If DIR doesn't end
+ with a slash and BASE doesn't begin with one, insert a slash between
+ them in the concatenation. Otherwise, simply concatenate DIR and BASE.
+ In any case, if BASE_IN_RESULT is non-NULL, set *BASE_IN_RESULT to point
+ to the copy of BASE in the returned concatenation. */
static char *
-path_concat (const char *dir, const char *base)
+path_concat (const char *dir, const char *base, char **base_in_result)
{
- char *dir_end;
+ char *p;
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);
+ p = stpcpy (p_concat, dir);
+
+ if (*(p - 1) == '/' && *base == '/')
+ --p;
+ else if (*(p - 1) != '/' && *base != '/')
+ p = stpcpy (p, "/");
+
+ if (base_in_result)
+ *base_in_result = p;
+
+ stpcpy (p, base);
+
return p_concat;
}
@@ -439,6 +449,7 @@ do_copy (int argc, char **argv)
char *dst_path;
int parent_exists = 1; /* True if dirname (dst_path) exists. */
struct dir_attr *attr_list;
+ char *arg_in_concat = NULL;
arg = argv[optind];
@@ -447,13 +458,14 @@ do_copy (int argc, char **argv)
if (flag_path)
{
/* Append all of `arg' to `dest'. */
- dst_path = path_concat (dest, arg);
+ dst_path = path_concat (dest, arg, &arg_in_concat);
/* 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,
+ arg_in_concat - dst_path,
+ 0700,
(flag_verbose
? "%s -> %s\n" : NULL),
&attr_list, &new_dst);
@@ -466,7 +478,7 @@ do_copy (int argc, char **argv)
/* For `cp -R source/.. dest', don't copy into `dest/..'. */
dst_path = (STREQ (ap, "..")
? xstrdup (dest)
- : path_concat (dest, ap));
+ : path_concat (dest, ap, NULL));
}
if (!parent_exists)
@@ -481,7 +493,8 @@ do_copy (int argc, char **argv)
if (flag_path)
{
- ret |= re_protect (dst_path, strlen (dest) + 1, attr_list);
+ ret |= re_protect (dst_path, arg_in_concat - dst_path,
+ attr_list);
}
}
|