Hi fellow monks,

Winzip and Archive::Tar do not play well together. I hit a problem while writing a small utility that among other things recursively 'tar and gzips' a directory. To support systems that do not ship with a built-in 'tar' utility (MS windows), the utility script falls back to using Archive::Tar. I encountered a problem with my code and sought the help of monks on the ChatterBox.

This writeup is intended to:

  1. Ensure other monks using Archive::Tar do not end up repeating the same mistakes.
  2. This is the important part. It highlights the fact that sometimes the problem may not always be in the code per se. You need to keep an open mind when investigating issue - do not prejudge the code.

The original problem:
I was able to successfully create a archive file 'data.tar.gz' but opening the file in WinZip showed that the archive did not preserve the folder/path structure. The archive was basically "flattened" out. I needed to preserve the file structure inside the archive.

My Code:
The following is a stripped down version of the two approaches for creating the archive file:

#!/usr/bin/perl # # Sample test script # use strict; use warnings; use Archive::Tar; use File::Find; $Archive::Tar::DEBUG=1; my $srcDir = 'C:\Temp\data'; ## Attempt 1 - add the files to the archive in the callback code. my $archive = Archive::Tar->new(); find(\&callback1, $srcDir); $archive->write('one.tar.gz', 9); print "---------ONE-------------------\n"; print join("\n", $archive->list_files()); print "---------ONE-------------------\n"; ## Attempt 2 - prepare a list of files and add to the archive in one p +lace my @files = (); # not using $archive->clear() - I want this to be independent of previ +ous # attempt $archive = Archive::Tar->new(); find(\&callback2, $srcDir); $archive->create_archive('two.tar.gz', 9, @files); print "---------TWO-------------------\n"; print join("\n", @files); print "---------TWO-------------------\n"; sub callback1() { $archive->add_files($File::Find::name); } sub callback2() { push(@files, $File::Find::name); }
The output of above:
---------ONE------------------- C:/Temp/data C:/Temp/data/SpaceMonger.exe C:/Temp/data/spacemonger_README.TXT C:/Temp/data/tcpvcon.exe C:/Temp/data/bar C:/Temp/data/bar/Tcpview.exe C:/Temp/data/bar/TCPVIEW.HLP C:/Temp/data/bar/tcpview_README.TXT C:/Temp/data/foo C:/Temp/data/foo/nc.exe C:/Temp/data/foo/nc_license.txt C:/Temp/data/foo/nc_readme.txt---------ONE------------------- ---------TWO------------------- C:\Temp\data C:\Temp\data/SpaceMonger.exe C:\Temp\data/spacemonger_README.TXT C:\Temp\data/tcpvcon.exe C:\Temp\data/bar C:\Temp\data/bar/Tcpview.exe C:\Temp\data/bar/TCPVIEW.HLP C:\Temp\data/bar/tcpview_README.TXT C:\Temp\data/foo C:\Temp\data/foo/nc.exe C:\Temp\data/foo/nc_license.txt C:\Temp\data/foo/nc_readme.txt---------TWO-------------------

The learnings from this experience:
The code is very simple and still it did not work. I was sure I was missing something obvious and trivial. I looked at the code, debugged it, went through the documentation, asked monks on the CB and followed their suggestions. I could not make progress towards resolving the problem until Corion pointed out a possible issue. It seems that Winzip cannot correctly interpret the archives created by Archive::Tar. It will open up the tar file, but not interpret the file paths correctly and show them as "blank". This gives the wrong impression that the archive does not preserve file paths. This undocumented "feature" gives the wrong impression that there is something wrong with the Perl code and misleads the developer. Testing the archive on a Unix machine showed the file structure correctly. The culprit was Winzip in this scenario.

When using Archive::Tar in a windows environment, test the created archive using a non-Winzip utility (unxutils.sourceforge.net) or on a *nix environment. Sometimes you may be looking at the issue in the wrong location. It turned out that the verification step was defective. The code was OK and confirmed to the module documentation. I am not ruling out bugs in Archive::Tar but it was not immediately obvious to me **where** the problem was located. This was a good lesson to learn.

Thanks to Zaxo, Corion, bart and Intrepid on CB for not only helping me out in identifying the problem but also for providing suggestions on how to improve the utility and alternate implementation ideas.

Regards,
Mahesh


In reply to Problem with Archive::Tar created archives and Winzip by smahesh

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.