PerlPowerTools
view release on metacpan or search on metacpan
print "\n<$name>\n\n" if $verbose;
print $pAr->{$name}[6];
}
else {
warn "entry not found in archive: '$name'\n";
}
}
# writes a directory-style listing for the specified archive member
sub printList {
my ( $name, $pAr, $verbose ) = @_;
my $attr = $pAr->{$name};
unless ( defined $attr ) {
warn "entry not found in archive: '$name'\n";
return;
}
if ($verbose) {
printf "%9s %7d/%-7d %7d %s %s\n",
strmode( $attr->[4] ),
$attr->[2],
$attr->[3],
$attr->[5],
strftime( "%b %e %H:%M %Y", localtime( $attr->[1] ) ),
$name;
}
else {
print "$name\n";
}
}
# extracts $name from archive and writes to current working directory
sub extractMember {
my ( $name, $pAr, $verbose, $settime, $update ) = @_;
my $attr = $pAr->{$name};
# get current uid/gid and mode
my @stat = stat($name) if -e $name;
my ( $uid, $gid, $mode, $modt );
if (@stat) {
( $uid, $gid, $mode, $modt ) = ( $stat[4], $stat[5], $stat[2], $stat[9] );
# skip if -u and existing file is newer
if ($update) {
return if $modt >= $attr->[1];
}
}
else {
( $uid, $gid, $mode, $modt ) = ( int( $attr->[2] ), int( $attr->[3] ), oct( $attr->[4] ), int( $attr->[1] ) );
}
my $out = FileHandle->new( $name, 'w' ) or die "$name: $!\n";
binmode($out);
$out->print( $attr->[6] );
$out->close();
# these might fail, but that's OK
chmod $mode, $name;
chown $uid, $gid, $name;
if ($settime) {
utime $modt, $modt, $name;
}
print "x - $name\n" if $verbose;
}
# read in a new file and return array ref of
# [ undef, $modt, $uid, $gid, $mode, $sz, $data ]
sub readFile {
my ($file) = @_;
my $in = FileHandle->new( $file, 'r' ) or die "$file: $!\n";
binmode($in);
# read the data in one swell foop
undef $/;
my $data = <$in>;
# get some attributes
my @stat = stat($file);
# return an array ref of attrs and data
return [ undef, $stat[9], $stat[4], $stat[5], sprintf( "%o", $stat[2] ), $stat[7], $data ];
}
# try to read an archive from $archive.
# returns a ref to a hash of name => [ index, header, data ]
# and a ref to an array of names in order, i.e., [ [name1], [name2], etc. ]
sub readAr {
my ($archive) = @_;
# hash of header/data
my %Ar;
# names in order in file
my @Names = (undef);
my $arfh = FileHandle->new( $archive, 'r' ) or die "$0: $archive: $!\n";
binmode($arfh);
# read magic
my $magic;
my $nread = read $arfh, $magic, length(MAGIC);
die "$0: $archive: $!\n" unless defined $nread;
if ( $magic ne MAGIC ) {
die "$0: $archive: Inappropriate file type or format\n";
}
while ( !$arfh->eof() ) {
# read header
my ( $name, $modt, $uid, $gid, $mode, $sz, $delim );
( $arfh->read( $name, 16 ) == 16
and $arfh->read( $modt, 12 ) == 12
and $arfh->read( $uid, 6 ) == 6
and $arfh->read( $gid, 6 ) == 6
and $arfh->read( $mode, 8 ) == 8
and $arfh->read( $sz, 10 ) == 10
and $arfh->read( $delim, 2 ) == 2
and $delim eq "`\n" )
or die "$0: $archive: Inappropriate file type or format\n";
( run in 0.561 second using v1.01-cache-2.11-cpan-5511b514fd6 )