develooper Front page | perl.perl5.porters | Postings from April 2000

Archive-Tar status

From:
Gurusamy Sarathy
Date:
April 26, 2000 18:10
Subject:
Archive-Tar status
Message ID:
200004270109.SAA01615@molotok.activestate.com
Somebody just asked me for the Nth time why ActiveState isn't shipping
the "latest" Archive-Tar 0.21, and I went adigging.  That version
has the nice feature that it doesn't keep everything in memory, but
it would also be nice if it worked. :-)

Archive-Tar doesn't appear to have been updated in a while, so I've
cc-ed p5p to see if we can find a volunteer to do the fixups.

Thanks.


Sarathy
gsar@activestate.com

>>> todo:1364

Delivery-Date: Tue Mar  2 18:03:21 1999

Message-Id: <199903030203.SAA25174@activestate.com>
Date:    Tue, 02 Mar 1999 18:03:20 PST

From:    Gurusamy Sarathy <gsar@ActiveState.com>
To:      gibreel@pobox.com
cc:      gsar@activestate.com

Subject: Archive-Tar-0.21


_make_special_file() is busted, so extraction fails if there are
symlinks in the tar file.  Here's a patch.


Sarathy
gsar@activestate.com
-----------------------------------8<-----------------------------------
--- Archive-Tar-0.21/Tar.pm	Tue Feb  2 08:37:13 1999
+++ Archive/Tar.pm	Tue Mar  2 19:45:41 1999
@@ -116,60 +116,62 @@
 }
 
 sub _make_special_file_UNIX {
-    my ($file) = @_;
+    # $file is the last component of $entry->{name}
+    my ($entry, $file) = @_;
 
-    if ($file->{type} == SYMLINK) {
-	symlink $_->{linkname}, $file or
-	    $^W && carp ("Making symbolic link from ", $file->{linkname}, 
-			 " to ", $file->{name}, ", failed.\n");
-    }
-    elsif ($file->{type} == HARDLINK) {
-	link $_->{linkname}, $file or
-	    $^W && carp ("Hard linking ", $_->{linkname}, 
-			 " to ", $file, ", failed.\n");
+    if ($entry->{type} == SYMLINK) {
+	symlink $entry->{linkname}, $file or
+	    $^W && carp ("Making symbolic link from ", $entry->{linkname}, 
+			 " to ", $entry->{name}, ", failed.\n");
+    }
+    elsif ($entry->{type} == HARDLINK) {
+	link $entry->{linkname}, $file or
+	    $^W && carp ("Hard linking ", $entry->{linkname}, 
+			 " to ", $entry->{name}, ", failed.\n");
     }
-    elsif ($file->{type} == FIFO) {
+    elsif ($entry->{type} == FIFO) {
 	system("mknod","$file","p") or
-	    $^W && carp "Making fifo ", $file, ", failed.\n";
+	    $^W && carp "Making fifo ", $entry->{name}, ", failed.\n";
     }
-    elsif ($file->{type} == BLOCKDEV) {
-	system("mknod","$file","b",$_->{devmajor},$_->{devminor}) or
-	    $^W && carp ("Making block device ", $file,
-			 " (maj=", $_->{devmajor}, 
-			 ", min=", $_->{devminor}, "), failed.\n");
-    }
-    elsif ($file->{type} == CHARDEV) {
-	system("mknod", "$file", "c", $_->{devmajor}, $_->{devminor}) or
-	    $^W && carp ("Making block device ", $file, 
-			 " (maj=", $_->{devmajor}, 
-			 " ,min=", $_->{devminor}, "), failed.\n");
+    elsif ($entry->{type} == BLOCKDEV) {
+	system("mknod","$file","b",$entry->{devmajor},$entry->{devminor}) or
+	    $^W && carp ("Making block device ", $entry->{name},
+			 " (maj=", $entry->{devmajor}, 
+			 ", min=", $entry->{devminor}, "), failed.\n");
+    }
+    elsif ($entry->{type} == CHARDEV) {
+	system("mknod", "$file", "c", $entry->{devmajor}, $entry->{devminor}) or
+	    $^W && carp ("Making block device ", $entry->{name}, 
+			 " (maj=", $entry->{devmajor}, 
+			 " ,min=", $entry->{devminor}, "), failed.\n");
     }
 }
 
 sub _make_special_file_Win32 {
-    my ($file) = @_;
+    # $file is the last component of $entry->{name}
+    my ($entry, $file) = @_;
 
-    if ($file->{type} == SYMLINK) {
-	$^W && carp ("Making symbolic link from ", $file->{linkname}, 
-		     " to ", $file->{name}, ", failed.\n");
-    }
-    elsif ($file->{type} == HARDLINK) {
-	link $_->{linkname}, $file->{name} or
-	    $^W && carp ("Making hard link from ", $file->{linkname}, 
-			 " to ", $file->{name}, ", failed.\n");
-    }
-    elsif ($file->{type} == FIFO) {
-	$^W && carp "Making fifo ", $file, ", failed.\n";
-    }
-    elsif ($file->{type} == BLOCKDEV) {
-	$^W && carp ("Making block device ", $file->{name},
-		     " (maj=", $file->{devmajor}, 
-		     ", min=", $file->{devminor}, "), failed.\n");
-    }
-    elsif ($file->{type} == CHARDEV) {
-	$^W && carp ("Making block device ", $file->{name},
-		     " (maj=", $file->{devmajor}, 
-		     " ,min=", $file->{devminor}, "), failed.\n");
+    if ($entry->{type} == SYMLINK) {
+	$^W && carp ("Making symbolic link from ", $entry->{linkname}, 
+		     " to ", $entry->{name}, ", failed.\n");
+    }
+    elsif ($entry->{type} == HARDLINK) {
+	link $entry->{linkname}, $file or
+	    $^W && carp ("Making hard link from ", $entry->{linkname}, 
+			 " to ", $entry->{name}, ", failed.\n");
+    }
+    elsif ($entry->{type} == FIFO) {
+	$^W && carp "Making fifo ", $entry->{name}, ", failed.\n";
+    }
+    elsif ($entry->{type} == BLOCKDEV) {
+	$^W && carp ("Making block device ", $entry->{name},
+		     " (maj=", $entry->{devmajor}, 
+		     ", min=", $entry->{devminor}, "), failed.\n");
+    }
+    elsif ($entry->{type} == CHARDEV) {
+	$^W && carp ("Making block device ", $entry->{name},
+		     " (maj=", $entry->{devmajor}, 
+		     " ,min=", $entry->{devminor}, "), failed.\n");
     }
 }
 
@@ -580,7 +582,7 @@
 	return undef;
     }
     else {
-	_make_special_file ($entry);
+	_make_special_file ($entry, $file);
     }
     utime time, $entry->{mtime}, $file;
 
End of Patch.



>>> todo:1445

Delivery-Date: Wed Mar  3 19:41:40 1999
Organisation: speaking through, but not for, McKesson Corp.
Lines:   11
User-Agent: Gnus/5.070075 (Pterodactyl Gnus v0.75) XEmacs/20.4 (Emerald)

Message-Id: <87yalec9gv.fsf@wsfs05.mckesson.com>
Date:    03 Mar 1999 17:46:56 PST

From:    Stephen Zander <gibreel@pobox.com>
To:      Gurusamy Sarathy <gsar@activestate.com>

Subject: Re: Archive-Tar-0.21

>>>>> "Gurusamy" == Gurusamy Sarathy <gsar@activestate.com> writes:

    Gurusamy> _make_special_file() is busted, so extraction fails if
    Gurusamy> there are symlinks in the tar file.  Here's a patch.

Thatnks. Patch applied & CPAN update on the way.

-- 
Stephen
---
Long noun chains don't automatically imply security. - Bruce Schneier



>>> todo:2166

Replied: Wed, 07 Apr 1999 04:10:22 -0700
Replied: gsar
Replied: gibreel@pobox.com
Delivery-Date: Wed Apr  7 01:33:05 1999

Message-Id: <199904070833.BAA08422@activestate.com>
Date:    Wed, 07 Apr 1999 01:33:04 PDT

From:    Gurusamy Sarathy <gsar@ActiveState.com>
To:      gibreel@pobox.com
cc:      gsar@activestate.com

Subject: Archive-Tar-0.21 bugs

There isn't enough binmode-ness when writing files on DOSish platforms.

The handling of special files is also broken.  I don't recall if
I already sent you the fix for the latter, so I've attached that too.


Sarathy
gsar@activestate.com
-----------------------------------8<-----------------------------------
diff -ur Archive-Tar-0.21/Tar.pm Archive-Tar/Tar.pm
--- Archive-Tar-0.21/Tar.pm	Tue Feb  2 08:37:13 1999
+++ Archive-Tar/Tar.pm	Wed Apr  7 01:13:46 1999
@@ -116,60 +116,62 @@
 }
 
 sub _make_special_file_UNIX {
-    my ($file) = @_;
+    # $file is the last component of $entry->{name}
+    my ($entry, $file) = @_;
 
-    if ($file->{type} == SYMLINK) {
-	symlink $_->{linkname}, $file or
-	    $^W && carp ("Making symbolic link from ", $file->{linkname}, 
-			 " to ", $file->{name}, ", failed.\n");
-    }
-    elsif ($file->{type} == HARDLINK) {
-	link $_->{linkname}, $file or
-	    $^W && carp ("Hard linking ", $_->{linkname}, 
-			 " to ", $file, ", failed.\n");
+    if ($entry->{type} == SYMLINK) {
+	symlink $entry->{linkname}, $file or
+	    $^W && carp ("Making symbolic link from ", $entry->{linkname}, 
+			 " to ", $entry->{name}, ", failed.\n");
+    }
+    elsif ($entry->{type} == HARDLINK) {
+	link $entry->{linkname}, $file or
+	    $^W && carp ("Hard linking ", $entry->{linkname}, 
+			 " to ", $entry->{name}, ", failed.\n");
     }
-    elsif ($file->{type} == FIFO) {
+    elsif ($entry->{type} == FIFO) {
 	system("mknod","$file","p") or
-	    $^W && carp "Making fifo ", $file, ", failed.\n";
+	    $^W && carp "Making fifo ", $entry->{name}, ", failed.\n";
     }
-    elsif ($file->{type} == BLOCKDEV) {
-	system("mknod","$file","b",$_->{devmajor},$_->{devminor}) or
-	    $^W && carp ("Making block device ", $file,
-			 " (maj=", $_->{devmajor}, 
-			 ", min=", $_->{devminor}, "), failed.\n");
-    }
-    elsif ($file->{type} == CHARDEV) {
-	system("mknod", "$file", "c", $_->{devmajor}, $_->{devminor}) or
-	    $^W && carp ("Making block device ", $file, 
-			 " (maj=", $_->{devmajor}, 
-			 " ,min=", $_->{devminor}, "), failed.\n");
+    elsif ($entry->{type} == BLOCKDEV) {
+	system("mknod","$file","b",$entry->{devmajor},$entry->{devminor}) or
+	    $^W && carp ("Making block device ", $entry->{name},
+			 " (maj=", $entry->{devmajor}, 
+			 ", min=", $entry->{devminor}, "), failed.\n");
+    }
+    elsif ($entry->{type} == CHARDEV) {
+	system("mknod", "$file", "c", $entry->{devmajor}, $entry->{devminor}) or
+	    $^W && carp ("Making block device ", $entry->{name}, 
+			 " (maj=", $entry->{devmajor}, 
+			 " ,min=", $entry->{devminor}, "), failed.\n");
     }
 }
 
 sub _make_special_file_Win32 {
-    my ($file) = @_;
+    # $file is the last component of $entry->{name}
+    my ($entry, $file) = @_;
 
-    if ($file->{type} == SYMLINK) {
-	$^W && carp ("Making symbolic link from ", $file->{linkname}, 
-		     " to ", $file->{name}, ", failed.\n");
-    }
-    elsif ($file->{type} == HARDLINK) {
-	link $_->{linkname}, $file->{name} or
-	    $^W && carp ("Making hard link from ", $file->{linkname}, 
-			 " to ", $file->{name}, ", failed.\n");
-    }
-    elsif ($file->{type} == FIFO) {
-	$^W && carp "Making fifo ", $file, ", failed.\n";
-    }
-    elsif ($file->{type} == BLOCKDEV) {
-	$^W && carp ("Making block device ", $file->{name},
-		     " (maj=", $file->{devmajor}, 
-		     ", min=", $file->{devminor}, "), failed.\n");
-    }
-    elsif ($file->{type} == CHARDEV) {
-	$^W && carp ("Making block device ", $file->{name},
-		     " (maj=", $file->{devmajor}, 
-		     " ,min=", $file->{devminor}, "), failed.\n");
+    if ($entry->{type} == SYMLINK) {
+	$^W && carp ("Making symbolic link from ", $entry->{linkname}, 
+		     " to ", $entry->{name}, ", failed.\n");
+    }
+    elsif ($entry->{type} == HARDLINK) {
+	link $entry->{linkname}, $file or
+	    $^W && carp ("Making hard link from ", $entry->{linkname}, 
+			 " to ", $entry->{name}, ", failed.\n");
+    }
+    elsif ($entry->{type} == FIFO) {
+	$^W && carp "Making fifo ", $entry->{name}, ", failed.\n";
+    }
+    elsif ($entry->{type} == BLOCKDEV) {
+	$^W && carp ("Making block device ", $entry->{name},
+		     " (maj=", $entry->{devmajor}, 
+		     ", min=", $entry->{devminor}, "), failed.\n");
+    }
+    elsif ($entry->{type} == CHARDEV) {
+	$^W && carp ("Making block device ", $entry->{name},
+		     " (maj=", $entry->{devmajor}, 
+		     " ,min=", $entry->{devminor}, "), failed.\n");
     }
 }
 
@@ -235,8 +237,6 @@
     }
     else {
 	$fh = bless *{$_[0]}{IO}, "Archive::Tar::_io";
-	binmode $fh
-	    or goto &_drat;
     }
 
     return $fh;
@@ -580,7 +580,7 @@
 	return undef;
     }
     else {
-	_make_special_file ($entry);
+	_make_special_file ($entry, $file);
     }
     utime time, $entry->{mtime}, $file;
 
@@ -616,7 +616,7 @@
     $handle = gensym;
     open $handle, ref ($file) ? ">&". fileno ($file) : ">" . $file
 	or goto &_drat;
-
+    binmode $handle;
     _write_tar (_get_handle ($handle, int ($compress)),
 		map {_add_file ($_)} @_);
 }
@@ -629,6 +629,7 @@
     $handle = gensym;
     open $handle, ref ($file) ? "<&". fileno ($file) : "<" . $file
 	or goto &_drat;
+    binmode $handle;
 
     my $data = _read_tar (_get_handle ($handle), 1);
 
@@ -647,6 +648,7 @@
     $handle = gensym;
     open $handle, ref ($file) ? "<&". fileno ($file) : "<" . $file
 	or goto &_drat;
+    binmode $handle;
 
     _read_tar (_get_handle ($handle), 0, 1);
 }
@@ -681,6 +683,7 @@
     $self->{_handle} = gensym;
     open $self->{_handle}, ref ($file) ? "<&". fileno ($file) : "<" . $file
 	or goto &_drat;
+    binmode $self->{_handle};
 
     $self->{_data} = _read_tar (_get_handle ($self->{_handle}), 
 				  sysseek $self->{_handle}, 0, 1);
@@ -697,6 +700,7 @@
     my $handle = gensym;
     open $handle, ref ($file) ? ">&". fileno ($file) : ">" . $file
 	or goto &_drat;
+    binmode $handle;
 
     if ($compress && !$compression) {
 	$error = "Compression not available.\n";
Only in Archive-Tar: Tar.pm.orig
diff -ur Archive-Tar-0.21/ptar Archive-Tar/ptar
--- Archive-Tar-0.21/ptar	Sat Jan  9 03:37:55 1999
+++ Archive-Tar/ptar	Wed Apr  7 01:13:46 1999
@@ -10,6 +10,8 @@
 my $list = 0;
 my $extract = 0;
 my $debug = 0;
+my $compress = 0;
+my $verbose = 0;
 
 if (!$switches) {
     print<<EOF;
End of Patch.



>>> todo:2172

Delivery-Date: Wed Apr  7 04:10:23 1999

Message-Id: <199904071110.EAA10056@activestate.com>
Date:    Wed, 07 Apr 1999 04:10:22 PDT

From:    Gurusamy Sarathy <gsar@ActiveState.com>
To:      gibreel@pobox.com
cc:      gsar@activestate.com

Subject: More Archive-Tar-0.21 bugs 

The typical:

    my $tar = Archive::Tar->new('foo.tgz', 1);
    $tar->extract;
    ..do something else with foo.tgz..

fails on win32 because the extract() doesn't close open files
properly like 0.072 did.  In fact, it appears most open()s have
no corresponding close()s at all.  This makes it fail on win32,
where files must be properly closed before you can do other
things to them (like deleting them, for example).

I also find the new extract() is significantly slower than
the old everything-in-memory one.  The faster default probably
makes more sense in these days of cheap memory.

Anyway, I think I'll stick with 0.072 for now.  :-)


Sarathy
gsar@activestate.com



>>> todo:2176

Delivery-Date: Wed Apr  7 08:23:54 1999
Organisation: speaking through, but not for, McKesson Corp.
Lines:   30
User-Agent: Gnus/5.070075 (Pterodactyl Gnus v0.75) XEmacs/20.4 (Emerald)

Message-Id: <87wvzo31ry.fsf@wsfs05.mckesson.com>
Date:    07 Apr 1999 08:09:52 PDT

From:    Stephen Zander <gibreel@pobox.com>
To:      Gurusamy Sarathy <gsar@activestate.com>
cc:      gibreel@pobox.com

Subject: Re: More Archive-Tar-0.21 bugs

>>>>> "Sarathy" == Gurusamy Sarathy <gsar@activestate.com> writes:
    Sarathy> fails on win32 because the extract() doesn't close open
    Sarathy> files properly like 0.072 did.  In fact, it appears most
    Sarathy> open()s have no corresponding close()s at all.  This
    Sarathy> makes it fail on win32, where files must be properly
    Sarathy> closed before you can do other things to them (like
    Sarathy> deleting them, for example).

Bah.  I was relying on scope exit for that... oh well.

    Sarathy> I also find the new extract() is significantly slower
    Sarathy> than the old everything-in-memory one.  The faster
    Sarathy> default probably makes more sense in these days of cheap
    Sarathy> memory.

Have you tried using Archive::Tar->extract_archive() instead?
Archive::Tar is intended to make the 'common' archive operations
(create/list/extract) on gzip'd archives as fast as possible, at the
possible expense of those who'd like to carry Archive::Tar objects
around.

Given that a tar file can be processed in one pass, it shouldn't make
that much difference whether you read the entire file and then spit
mutliple outputs or interleave the two operations.  Processing a 3Mb
gzip'd tar file should not require 9Mb of memory! :)

-- 
Stephen
---
Long noun chains don't automatically imply security. - Bruce Schneier



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About