Woes of absolute path names in tar
anw at nott-cs.UUCP
anw at nott-cs.UUCP
Sat Jun 4 04:22:42 AEST 1988
Many years ago, some kind soul [may even have been me, :-(, I tend to forget
such things] installed a shell script on our PDP 11 [probably when it was a
34 running V6, perhaps when it was a 70 running V7 -- now it's a 44 running
V7, gloom] to copy file hierarchies. Well, time passes; and as the discs
fill up, I archive elderly subdirectories:
copy old-dir /nicedisc/anw/archive
: check that all is well, then ...
rm -rf old-dir
Repeat as necessary. More time passes. Yesterday, we re-organised our
discs a bit, and suddenly there is oodles of space around my home directory.
Wouldn't it be nice to get all that stuff back in the right place?
mkdir old-dir
copy /nicedisc/anw/archive old-dir
: Aaarrrggghhh! Lots of error messages
Yikes! Look in the archive directory. Funny, all those files are still there,
and "ls -l" shows they haven't been altered, but "cat" one or two, and they're
empty. More tests -- they aren't actually empty, they've been NULlified.
All my beloved old files! Hope this wasn't too long ago, might not be able
to find a useful dump tape. Phew, they are on that morning's dump tape, all
correct, and 10 mins later my sanity and the files are restored.
What happened? Well, you've guessed from the "Subject:" line, but I
had to scrat around for a bit. Here is "/usr/bin/copy", as was:
echo copying from $1 to $2
tar cvf - $1 | (cd $2; tar xfp -)
[I don't think this is my code, even from 10 years ago, if only 'cos I
always put quotes around parameters. Well, nearly always.] Someone has
been reading the "tar" manual entry; but this is disastrous. If "$1"
begins with "/", the right-hand "tar" overwrites the directory the left-
hand "tar" is reading from, zapping most of the files, but restoring the
modified times, etc., with potentially terrible consequences, as I found out.
There are other bugs as well, but to cut a long story short, "/usr/bin/copy"
*now* looks like this:
error () { echo $0: "$@" 1>&2; exit 1; }
case $# in
0) echo usage: $0 fromdir todir; exit 0 ;;
1) error must supply target directory ;;
2) ;;
*) error too many parameters
esac
[ -d "$1" -a -d "$2" ] ||
error parameters must be existing directories
case "$1" in
/*) error first param must not begin with /
esac
FROM=`(cd "$1"; pwd)`
TO=`(cd "$2"; pwd)`
case "$TO" in
"$FROM") error must not copy directory to itself ;;
"$FROM"/*) error must not copy directory to sub-dir
esac
echo copying from "$1" to "$2"
sleep 10
tar cvf - "$1" | (cd "$2"; tar xfp -)
Still not perfect, but at least somewhat safer. And the morals are:
a) Good dumping strategies are essential.
b) Even your most ancient and trusted tools can suddenly bite you.
c) Those of you with whizzo "cpio"s, and other bells and whistles,
and much more careful "tar"s, and Suns, and Crays, and what
have-you, please spare a thought for your less fortunate
brethren and cistern.
I'd better stop before I get too "comp.RISK"-ish. Thank you for listening.
--
Andy Walker, Maths Dept., Nott'm Univ., UK
anw at maths.nott.ac.uk
More information about the Comp.unix.wizards
mailing list