bug-tar
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Bug-tar] Bug in --remove-files with --append/-r


From: Nathan Stratton Treadway
Subject: Re: [Bug-tar] Bug in --remove-files with --append/-r
Date: Sun, 22 Sep 2013 15:21:35 -0400
User-agent: Mutt/1.5.20 (2009-06-14)

On Sat, Sep 21, 2013 at 01:29:25 -0400, Nathan Stratton Treadway wrote:
> I looked around a little, and as far as I was able to find:
>   * create.c:create_archive() and names_notfound()/label_notfound() within 
>     names.c itself are the only places that call name_next() with 
>     change_dirs set to 1
>   * there aren't any hard-coded "name_next_elt (1)" calls
>   * name_next_elt() contains the only remaining call to the
>     plain "chdir()" function
>   * misc.c:normalize_filename() contains the only remaining call to
>     xgetcwd()/getcwd()
> 
> So I wonder if the "proper" fix at this point would be to switch
> everything to using the "virtual chdir" approach?

I found another situation where the current operation of
normalize_filename() causes trouble. 

The value returned by that function is used to populate the "caname"
field in both the "directory" structure in incremen.c and the "name"
structure in names.c, and in both cases that field is then used in the
"hash" and "compare" functions for the related hash tables.  Thus, the
fact that the returned value doesn't reflect the operation of previous
"-C" options means that it's possible for two different directories to
be given the same "caname" value in the hashed structure and thus end up
being confused with each other.

Listed incremental mode's restriction to one -C option limits the
chances of this happening in normal practice, but it's still possible to
trigger it when dumping both relative paths after -C and absolute paths
that match the process's current working directory....

For example, given the following directory structure:

  $ mkdir tartest
  $ cd tartest
  $ mkdir foo
  $ mkdir foo/subdir
  $ mkdir foo/subdir/contents_of_foo-subdir
  $ mkdir subdir
  $ mkdir subdir/contents_of_subdir
  $ find
  .
  ./subdir
  ./subdir/contents_of_subdir
  ./foo
  ./foo/subdir
  ./foo/subdir/contents_of_foo-subdir

, if I then dump both "-C foo ." and "$PWD", tar confuses "[-C foo] ./subdir"
with "$PWD/subdir":

  $ tar --version
  tar (GNU tar) 1.26.90
  [...]
  $ tar -cvf foo.tar --listed-incremental=foo.snar0 -C foo .  $PWD
  tar: .: Directory is new
  tar: ./subdir: Directory is new
  tar: ./subdir/contents_of_foo-subdir: Directory is new
  tar: /home/nathanst/tartest: Directory has been renamed
  tar: /home/nathanst/tartest/foo: Directory is new
  tar: /home/nathanst/tartest/foo/subdir: Directory has been renamed from 
`./subdir'
  tar: Removing leading `/' from member names
  ./subdir/contents_of_foo-subdir/
  /home/nathanst/tartest/
  /home/nathanst/tartest/foo/
  /home/nathanst/tartest/foo/subdir/
  /home/nathanst/tartest/foo/subdir/contents_of_foo-subdir/
  /home/nathanst/tartest/subdir/
  /home/nathanst/tartest/foo.snar0
  tar: /home/nathanst/tartest/foo.tar: file is the archive; not dumped
  $ tar -tf foo.tar 
  ./subdir/contents_of_foo-subdir/
  home/nathanst/tartest/
  home/nathanst/tartest/foo/
  home/nathanst/tartest/foo/subdir/
  home/nathanst/tartest/foo/subdir/contents_of_foo-subdir/
  home/nathanst/tartest/subdir/
  home/nathanst/tartest/foo.snar0

Note in particular that it says "/home/nathanst/tartest: Directory has
been renamed" and "/home/nathanst/tartest/foo: Directory is new", but in
fact the earlier "." entry represents /home/nathanst/tartest/foo and so
that should be the entry that's considered renamed, while
"/home/nathanst/tartest" should be the one considered new....

At the same time, note that home/nathanst/tartest/subdir/contents_of_subdir
is not included in the output archive (presumably because "[-C foo] ./subdir"
gets confused with "$PWD/subdir" as the list of names is collected, and
only the children of the former are kept in the final list).

(For what it's worth, if I keep the "-C" but don't actually use any
relative path, then there is no such confusion:

  $ rm foo.snar0 
  $ tar -cvf foo.tar --listed-incremental=foo.snar0 -C foo   $PWD
  tar: /home/nathanst/tartest: Directory is new
  tar: /home/nathanst/tartest/foo: Directory is new
  tar: /home/nathanst/tartest/subdir: Directory is new
  tar: /home/nathanst/tartest/foo/subdir: Directory is new
  tar: /home/nathanst/tartest/foo/subdir/contents_of_foo-subdir: Directory is 
new
  tar: /home/nathanst/tartest/subdir/contents_of_subdir: Directory is new
  tar: Removing leading `/' from member names
  /home/nathanst/tartest/
  /home/nathanst/tartest/foo/
  /home/nathanst/tartest/foo/subdir/
  /home/nathanst/tartest/foo/subdir/contents_of_foo-subdir/
  /home/nathanst/tartest/subdir/
  /home/nathanst/tartest/subdir/contents_of_subdir/
  /home/nathanst/tartest/foo.snar0
  tar: /home/nathanst/tartest/foo.tar: file is the archive; not dumped
  
  $ rm foo.snar0 
  $ tar -cvf foo.tar --listed-incremental=foo.snar0 -C foo $PWD/foo $PWD
  tar: /home/nathanst/tartest/foo: Directory is new
  tar: /home/nathanst/tartest/foo/subdir: Directory is new
  tar: /home/nathanst/tartest/foo/subdir/contents_of_foo-subdir: Directory is 
new
  tar: /home/nathanst/tartest: Directory is new
  tar: /home/nathanst/tartest/subdir: Directory is new
  tar: /home/nathanst/tartest/subdir/contents_of_subdir: Directory is new
  tar: Removing leading `/' from member names
  /home/nathanst/tartest/
  /home/nathanst/tartest/foo/
  /home/nathanst/tartest/foo/subdir/
  /home/nathanst/tartest/foo/subdir/contents_of_foo-subdir/
  /home/nathanst/tartest/subdir/
  /home/nathanst/tartest/subdir/contents_of_subdir/
  /home/nathanst/tartest/foo.snar0
  tar: /home/nathanst/tartest/foo.tar: file is the archive; not dumped
)


                                                        Nathan

----------------------------------------------------------------------------
Nathan Stratton Treadway  -  address@hidden  -  Mid-Atlantic region
Ray Ontko & Co.  -  Software consulting services  -   http://www.ontko.com/
 GPG Key: http://www.ontko.com/~nathanst/gpg_key.txt   ID: 1023D/ECFB6239
 Key fingerprint = 6AD8 485E 20B9 5C71 231C  0C32 15F3 ADCD ECFB 6239



reply via email to

[Prev in Thread] Current Thread [Next in Thread]