1b39c5158Smillertpackage Archive::Tar::File; 2b39c5158Smillertuse strict; 3b39c5158Smillert 4b39c5158Smillertuse Carp (); 5b39c5158Smillertuse IO::File; 6b39c5158Smillertuse File::Spec::Unix (); 7b39c5158Smillertuse File::Spec (); 8b39c5158Smillertuse File::Basename (); 9b39c5158Smillert 10b39c5158Smillertuse Archive::Tar::Constant; 11b39c5158Smillert 12b39c5158Smillertuse vars qw[@ISA $VERSION]; 13b39c5158Smillert#@ISA = qw[Archive::Tar]; 14*3d61058aSafresh1$VERSION = '3.02_001'; 15b39c5158Smillert 16b39c5158Smillert### set value to 1 to oct() it during the unpack ### 17898184e3Ssthen 18b39c5158Smillertmy $tmpl = [ 19898184e3Ssthen name => 0, # string A100 20898184e3Ssthen mode => 1, # octal A8 21898184e3Ssthen uid => 1, # octal A8 22898184e3Ssthen gid => 1, # octal A8 23898184e3Ssthen size => 0, # octal # cdrake - not *always* octal.. A12 24898184e3Ssthen mtime => 1, # octal A12 25898184e3Ssthen chksum => 1, # octal A8 26898184e3Ssthen type => 0, # character A1 27898184e3Ssthen linkname => 0, # string A100 28898184e3Ssthen magic => 0, # string A6 29898184e3Ssthen version => 0, # 2 bytes A2 30898184e3Ssthen uname => 0, # string A32 31898184e3Ssthen gname => 0, # string A32 32898184e3Ssthen devmajor => 1, # octal A8 33898184e3Ssthen devminor => 1, # octal A8 34898184e3Ssthen prefix => 0, # A155 x 12 35b39c5158Smillert 36b39c5158Smillert### end UNPACK items ### 37b39c5158Smillert raw => 0, # the raw data chunk 38b39c5158Smillert data => 0, # the data associated with the file -- 39b39c5158Smillert # This might be very memory intensive 40b39c5158Smillert]; 41b39c5158Smillert 42b39c5158Smillert### install get/set accessors for this object. 43b39c5158Smillertfor ( my $i=0; $i<scalar @$tmpl ; $i+=2 ) { 44b39c5158Smillert my $key = $tmpl->[$i]; 45b39c5158Smillert no strict 'refs'; 46b39c5158Smillert *{__PACKAGE__."::$key"} = sub { 47b39c5158Smillert my $self = shift; 48b39c5158Smillert $self->{$key} = $_[0] if @_; 49b39c5158Smillert 50b39c5158Smillert ### just in case the key is not there or undef or something ### 51b39c5158Smillert { local $^W = 0; 52b39c5158Smillert return $self->{$key}; 53b39c5158Smillert } 54b39c5158Smillert } 55b39c5158Smillert} 56b39c5158Smillert 57b39c5158Smillert=head1 NAME 58b39c5158Smillert 59b39c5158SmillertArchive::Tar::File - a subclass for in-memory extracted file from Archive::Tar 60b39c5158Smillert 61b39c5158Smillert=head1 SYNOPSIS 62b39c5158Smillert 63b39c5158Smillert my @items = $tar->get_files; 64b39c5158Smillert 65b39c5158Smillert print $_->name, ' ', $_->size, "\n" for @items; 66b39c5158Smillert 67b39c5158Smillert print $object->get_content; 68b39c5158Smillert $object->replace_content('new content'); 69b39c5158Smillert 70b39c5158Smillert $object->rename( 'new/full/path/to/file.c' ); 71b39c5158Smillert 72b39c5158Smillert=head1 DESCRIPTION 73b39c5158Smillert 74*3d61058aSafresh1Archive::Tar::File provides a neat little object layer for in-memory 75b39c5158Smillertextracted files. It's mostly used internally in Archive::Tar to tidy 76b39c5158Smillertup the code, but there's no reason users shouldn't use this API as 77b39c5158Smillertwell. 78b39c5158Smillert 79b39c5158Smillert=head2 Accessors 80b39c5158Smillert 81b39c5158SmillertA lot of the methods in this package are accessors to the various 82b39c5158Smillertfields in the tar header: 83b39c5158Smillert 84b39c5158Smillert=over 4 85b39c5158Smillert 86b39c5158Smillert=item name 87b39c5158Smillert 88b39c5158SmillertThe file's name 89b39c5158Smillert 90b39c5158Smillert=item mode 91b39c5158Smillert 92b39c5158SmillertThe file's mode 93b39c5158Smillert 94b39c5158Smillert=item uid 95b39c5158Smillert 96b39c5158SmillertThe user id owning the file 97b39c5158Smillert 98b39c5158Smillert=item gid 99b39c5158Smillert 100b39c5158SmillertThe group id owning the file 101b39c5158Smillert 102b39c5158Smillert=item size 103b39c5158Smillert 104b39c5158SmillertFile size in bytes 105b39c5158Smillert 106b39c5158Smillert=item mtime 107b39c5158Smillert 108b39c5158SmillertModification time. Adjusted to mac-time on MacOS if required 109b39c5158Smillert 110b39c5158Smillert=item chksum 111b39c5158Smillert 112b39c5158SmillertChecksum field for the tar header 113b39c5158Smillert 114b39c5158Smillert=item type 115b39c5158Smillert 116b39c5158SmillertFile type -- numeric, but comparable to exported constants -- see 117b39c5158SmillertArchive::Tar's documentation 118b39c5158Smillert 119b39c5158Smillert=item linkname 120b39c5158Smillert 121b39c5158SmillertIf the file is a symlink, the file it's pointing to 122b39c5158Smillert 123b39c5158Smillert=item magic 124b39c5158Smillert 125b39c5158SmillertTar magic string -- not useful for most users 126b39c5158Smillert 127b39c5158Smillert=item version 128b39c5158Smillert 129b39c5158SmillertTar version string -- not useful for most users 130b39c5158Smillert 131b39c5158Smillert=item uname 132b39c5158Smillert 133b39c5158SmillertThe user name that owns the file 134b39c5158Smillert 135b39c5158Smillert=item gname 136b39c5158Smillert 137b39c5158SmillertThe group name that owns the file 138b39c5158Smillert 139b39c5158Smillert=item devmajor 140b39c5158Smillert 141b39c5158SmillertDevice major number in case of a special file 142b39c5158Smillert 143b39c5158Smillert=item devminor 144b39c5158Smillert 145b39c5158SmillertDevice minor number in case of a special file 146b39c5158Smillert 147b39c5158Smillert=item prefix 148b39c5158Smillert 149b39c5158SmillertAny directory to prefix to the extraction path, if any 150b39c5158Smillert 151b39c5158Smillert=item raw 152b39c5158Smillert 153b39c5158SmillertRaw tar header -- not useful for most users 154b39c5158Smillert 155b39c5158Smillert=back 156b39c5158Smillert 157b39c5158Smillert=head1 Methods 158b39c5158Smillert 159b39c5158Smillert=head2 Archive::Tar::File->new( file => $path ) 160b39c5158Smillert 161b39c5158SmillertReturns a new Archive::Tar::File object from an existing file. 162b39c5158Smillert 163b39c5158SmillertReturns undef on failure. 164b39c5158Smillert 165b39c5158Smillert=head2 Archive::Tar::File->new( data => $path, $data, $opt ) 166b39c5158Smillert 167b39c5158SmillertReturns a new Archive::Tar::File object from data. 168b39c5158Smillert 169b39c5158SmillertC<$path> defines the file name (which need not exist), C<$data> the 170b39c5158Smillertfile contents, and C<$opt> is a reference to a hash of attributes 171b39c5158Smillertwhich may be used to override the default attributes (fields in the 172b39c5158Smillerttar header), which are described above in the Accessors section. 173b39c5158Smillert 174b39c5158SmillertReturns undef on failure. 175b39c5158Smillert 176b39c5158Smillert=head2 Archive::Tar::File->new( chunk => $chunk ) 177b39c5158Smillert 178b39c5158SmillertReturns a new Archive::Tar::File object from a raw 512-byte tar 179b39c5158Smillertarchive chunk. 180b39c5158Smillert 181b39c5158SmillertReturns undef on failure. 182b39c5158Smillert 183b39c5158Smillert=cut 184b39c5158Smillert 185b39c5158Smillertsub new { 186b39c5158Smillert my $class = shift; 187b39c5158Smillert my $what = shift; 188b39c5158Smillert 189b39c5158Smillert my $obj = ($what eq 'chunk') ? __PACKAGE__->_new_from_chunk( @_ ) : 190b39c5158Smillert ($what eq 'file' ) ? __PACKAGE__->_new_from_file( @_ ) : 191b39c5158Smillert ($what eq 'data' ) ? __PACKAGE__->_new_from_data( @_ ) : 192b39c5158Smillert undef; 193b39c5158Smillert 194b39c5158Smillert return $obj; 195b39c5158Smillert} 196b39c5158Smillert 197b39c5158Smillert### copies the data, creates a clone ### 198b39c5158Smillertsub clone { 199b39c5158Smillert my $self = shift; 200b39c5158Smillert return bless { %$self }, ref $self; 201b39c5158Smillert} 202b39c5158Smillert 203b39c5158Smillertsub _new_from_chunk { 204b39c5158Smillert my $class = shift; 205b39c5158Smillert my $chunk = shift or return; # 512 bytes of tar header 206b39c5158Smillert my %hash = @_; 207b39c5158Smillert 208b39c5158Smillert ### filter any arguments on defined-ness of values. 209b39c5158Smillert ### this allows overriding from what the tar-header is saying 210b39c5158Smillert ### about this tar-entry. Particularly useful for @LongLink files 211b39c5158Smillert my %args = map { $_ => $hash{$_} } grep { defined $hash{$_} } keys %hash; 212b39c5158Smillert 213b39c5158Smillert ### makes it start at 0 actually... :) ### 214b39c5158Smillert my $i = -1; 215b39c5158Smillert my %entry = map { 216898184e3Ssthen my ($s,$v)=($tmpl->[++$i],$tmpl->[++$i]); # cdrake 217898184e3Ssthen ($_)=($_=~/^([^\0]*)/) unless($s eq 'size'); # cdrake 218898184e3Ssthen $s=> $v ? oct $_ : $_ # cdrake 219898184e3Ssthen # $tmpl->[++$i] => $tmpl->[++$i] ? oct $_ : $_ # removed by cdrake - mucks up binary sizes >8gb 220898184e3Ssthen } unpack( UNPACK, $chunk ); # cdrake 221898184e3Ssthen # } map { /^([^\0]*)/ } unpack( UNPACK, $chunk ); # old - replaced now by cdrake 222898184e3Ssthen 223898184e3Ssthen 224898184e3Ssthen if(substr($entry{'size'}, 0, 1) eq "\x80") { # binary size extension for files >8gigs (> octal 77777777777777) # cdrake 2256fb12b70Safresh1 my @sz=unpack("aCSNN",$entry{'size'}); $entry{'size'}=$sz[4]+(2**32)*$sz[3]+$sz[2]*(2**64); # Use the low 80 bits (should use the upper 15 as well, but as at year 2011, that seems unlikely to ever be needed - the numbers are just too big...) # cdrake 226898184e3Ssthen } else { # cdrake 227898184e3Ssthen ($entry{'size'})=($entry{'size'}=~/^([^\0]*)/); $entry{'size'}=oct $entry{'size'}; # cdrake 228898184e3Ssthen } # cdrake 229898184e3Ssthen 230b39c5158Smillert 231b39c5158Smillert my $obj = bless { %entry, %args }, $class; 232b39c5158Smillert 233b39c5158Smillert ### magic is a filetype string.. it should have something like 'ustar' or 234b39c5158Smillert ### something similar... if the chunk is garbage, skip it 235b39c5158Smillert return unless $obj->magic !~ /\W/; 236b39c5158Smillert 237b39c5158Smillert ### store the original chunk ### 238b39c5158Smillert $obj->raw( $chunk ); 239b39c5158Smillert 240b39c5158Smillert $obj->type(FILE) if ( (!length $obj->type) or ($obj->type =~ /\W/) ); 241b39c5158Smillert $obj->type(DIR) if ( ($obj->is_file) && ($obj->name =~ m|/$|) ); 242b39c5158Smillert 243b39c5158Smillert 244b39c5158Smillert return $obj; 245b39c5158Smillert 246b39c5158Smillert} 247b39c5158Smillert 248b39c5158Smillertsub _new_from_file { 249b39c5158Smillert my $class = shift; 250b39c5158Smillert my $path = shift; 251b39c5158Smillert 252b39c5158Smillert ### path has to at least exist 253b39c5158Smillert return unless defined $path; 254b39c5158Smillert 255b39c5158Smillert my $type = __PACKAGE__->_filetype($path); 256b39c5158Smillert my $data = ''; 257b39c5158Smillert 258b39c5158Smillert READ: { 259b39c5158Smillert unless ($type == DIR ) { 260b39c5158Smillert my $fh = IO::File->new; 261b39c5158Smillert 262b39c5158Smillert unless( $fh->open($path) ) { 263b39c5158Smillert ### dangling symlinks are fine, stop reading but continue 264b39c5158Smillert ### creating the object 265b39c5158Smillert last READ if $type == SYMLINK; 266b39c5158Smillert 267b39c5158Smillert ### otherwise, return from this function -- 268b39c5158Smillert ### anything that's *not* a symlink should be 269b39c5158Smillert ### resolvable 270b39c5158Smillert return; 271b39c5158Smillert } 272b39c5158Smillert 273b39c5158Smillert ### binmode needed to read files properly on win32 ### 274b39c5158Smillert binmode $fh; 275b39c5158Smillert $data = do { local $/; <$fh> }; 276b39c5158Smillert close $fh; 277b39c5158Smillert } 278b39c5158Smillert } 279b39c5158Smillert 280b39c5158Smillert my @items = qw[mode uid gid size mtime]; 281b39c5158Smillert my %hash = map { shift(@items), $_ } (lstat $path)[2,4,5,7,9]; 282b39c5158Smillert 283b39c5158Smillert if (ON_VMS) { 284b39c5158Smillert ### VMS has two UID modes, traditional and POSIX. Normally POSIX is 285b39c5158Smillert ### not used. We currently do not have an easy way to see if we are in 286b39c5158Smillert ### POSIX mode. In traditional mode, the UID is actually the VMS UIC. 287b39c5158Smillert ### The VMS UIC has the upper 16 bits is the GID, which in many cases 288b39c5158Smillert ### the VMS UIC will be larger than 209715, the largest that TAR can 289b39c5158Smillert ### handle. So for now, assume it is traditional if the UID is larger 290b39c5158Smillert ### than 0x10000. 291b39c5158Smillert 292b39c5158Smillert if ($hash{uid} > 0x10000) { 293b39c5158Smillert $hash{uid} = $hash{uid} & 0xFFFF; 294b39c5158Smillert } 295b39c5158Smillert 296b39c5158Smillert ### The file length from stat() is the physical length of the file 297b39c5158Smillert ### However the amount of data read in may be more for some file types. 298b39c5158Smillert ### Fixed length files are read past the logical EOF to end of the block 299b39c5158Smillert ### containing. Other file types get expanded on read because record 300b39c5158Smillert ### delimiters are added. 301b39c5158Smillert 302b39c5158Smillert my $data_len = length $data; 303b39c5158Smillert $hash{size} = $data_len if $hash{size} < $data_len; 304b39c5158Smillert 305b39c5158Smillert } 306b39c5158Smillert ### you *must* set size == 0 on symlinks, or the next entry will be 307b39c5158Smillert ### though of as the contents of the symlink, which is wrong. 308b39c5158Smillert ### this fixes bug #7937 309b39c5158Smillert $hash{size} = 0 if ($type == DIR or $type == SYMLINK); 310b39c5158Smillert $hash{mtime} -= TIME_OFFSET; 311b39c5158Smillert 312b39c5158Smillert ### strip the high bits off the mode, which we don't need to store 313b39c5158Smillert $hash{mode} = STRIP_MODE->( $hash{mode} ); 314b39c5158Smillert 315b39c5158Smillert 316b39c5158Smillert ### probably requires some file path munging here ... ### 317b39c5158Smillert ### name and prefix are set later 318b39c5158Smillert my $obj = { 319b39c5158Smillert %hash, 320b39c5158Smillert name => '', 321b39c5158Smillert chksum => CHECK_SUM, 322b39c5158Smillert type => $type, 323b39c5158Smillert linkname => ($type == SYMLINK and CAN_READLINK) 324b39c5158Smillert ? readlink $path 325b39c5158Smillert : '', 326b39c5158Smillert magic => MAGIC, 327b39c5158Smillert version => TAR_VERSION, 328b39c5158Smillert uname => UNAME->( $hash{uid} ), 329b39c5158Smillert gname => GNAME->( $hash{gid} ), 330b39c5158Smillert devmajor => 0, # not handled 331b39c5158Smillert devminor => 0, # not handled 332b39c5158Smillert prefix => '', 333b39c5158Smillert data => $data, 334b39c5158Smillert }; 335b39c5158Smillert 336b39c5158Smillert bless $obj, $class; 337b39c5158Smillert 338b39c5158Smillert ### fix up the prefix and file from the path 339b39c5158Smillert my($prefix,$file) = $obj->_prefix_and_file( $path ); 340b39c5158Smillert $obj->prefix( $prefix ); 341b39c5158Smillert $obj->name( $file ); 342b39c5158Smillert 343b39c5158Smillert return $obj; 344b39c5158Smillert} 345b39c5158Smillert 346b39c5158Smillertsub _new_from_data { 347b39c5158Smillert my $class = shift; 348b39c5158Smillert my $path = shift; return unless defined $path; 349b39c5158Smillert my $data = shift; return unless defined $data; 350b39c5158Smillert my $opt = shift; 351b39c5158Smillert 352b39c5158Smillert my $obj = { 353b39c5158Smillert data => $data, 354b39c5158Smillert name => '', 355b39c5158Smillert mode => MODE, 356b39c5158Smillert uid => UID, 357b39c5158Smillert gid => GID, 358b39c5158Smillert size => length $data, 359b39c5158Smillert mtime => time - TIME_OFFSET, 360b39c5158Smillert chksum => CHECK_SUM, 361b39c5158Smillert type => FILE, 362b39c5158Smillert linkname => '', 363b39c5158Smillert magic => MAGIC, 364b39c5158Smillert version => TAR_VERSION, 365b39c5158Smillert uname => UNAME->( UID ), 366b39c5158Smillert gname => GNAME->( GID ), 367b39c5158Smillert devminor => 0, 368b39c5158Smillert devmajor => 0, 369b39c5158Smillert prefix => '', 370b39c5158Smillert }; 371b39c5158Smillert 372b39c5158Smillert ### overwrite with user options, if provided ### 373b39c5158Smillert if( $opt and ref $opt eq 'HASH' ) { 374b39c5158Smillert for my $key ( keys %$opt ) { 375b39c5158Smillert 376b39c5158Smillert ### don't write bogus options ### 377b39c5158Smillert next unless exists $obj->{$key}; 378b39c5158Smillert $obj->{$key} = $opt->{$key}; 379b39c5158Smillert } 380b39c5158Smillert } 381b39c5158Smillert 382b39c5158Smillert bless $obj, $class; 383b39c5158Smillert 384b39c5158Smillert ### fix up the prefix and file from the path 385b39c5158Smillert my($prefix,$file) = $obj->_prefix_and_file( $path ); 386b39c5158Smillert $obj->prefix( $prefix ); 387b39c5158Smillert $obj->name( $file ); 388b39c5158Smillert 389b39c5158Smillert return $obj; 390b39c5158Smillert} 391b39c5158Smillert 392b39c5158Smillertsub _prefix_and_file { 393b39c5158Smillert my $self = shift; 394b39c5158Smillert my $path = shift; 395b39c5158Smillert 396b39c5158Smillert my ($vol, $dirs, $file) = File::Spec->splitpath( $path, $self->is_dir ); 3979f11ffb7Safresh1 my @dirs = File::Spec->splitdir( File::Spec->canonpath($dirs) ); 398b39c5158Smillert 399b39c5158Smillert ### if it's a directory, then $file might be empty 400b39c5158Smillert $file = pop @dirs if $self->is_dir and not length $file; 401b39c5158Smillert 402b39c5158Smillert ### splitting ../ gives you the relative path in native syntax 403b46d8ef2Safresh1 ### Remove the root (000000) directory 404b46d8ef2Safresh1 ### The volume from splitpath will also be in native syntax 405b46d8ef2Safresh1 if (ON_VMS) { 406b46d8ef2Safresh1 map { $_ = '..' if $_ eq '-'; $_ = '' if $_ eq '000000' } @dirs; 407b46d8ef2Safresh1 if (length($vol)) { 408b46d8ef2Safresh1 $vol = VMS::Filespec::unixify($vol); 409b46d8ef2Safresh1 unshift @dirs, $vol; 410b46d8ef2Safresh1 } 411b46d8ef2Safresh1 } 412b39c5158Smillert 4139f11ffb7Safresh1 my $prefix = File::Spec::Unix->catdir(@dirs); 414b39c5158Smillert return( $prefix, $file ); 415b39c5158Smillert} 416b39c5158Smillert 417b39c5158Smillertsub _filetype { 418b39c5158Smillert my $self = shift; 419b39c5158Smillert my $file = shift; 420b39c5158Smillert 421b39c5158Smillert return unless defined $file; 422b39c5158Smillert 423b39c5158Smillert return SYMLINK if (-l $file); # Symlink 424b39c5158Smillert 425b39c5158Smillert return FILE if (-f _); # Plain file 426b39c5158Smillert 427b39c5158Smillert return DIR if (-d _); # Directory 428b39c5158Smillert 429b39c5158Smillert return FIFO if (-p _); # Named pipe 430b39c5158Smillert 431b39c5158Smillert return SOCKET if (-S _); # Socket 432b39c5158Smillert 433b39c5158Smillert return BLOCKDEV if (-b _); # Block special 434b39c5158Smillert 435b39c5158Smillert return CHARDEV if (-c _); # Character special 436b39c5158Smillert 437b39c5158Smillert ### shouldn't happen, this is when making archives, not reading ### 438b39c5158Smillert return LONGLINK if ( $file eq LONGLINK_NAME ); 439b39c5158Smillert 440b39c5158Smillert return UNKNOWN; # Something else (like what?) 441b39c5158Smillert 442b39c5158Smillert} 443b39c5158Smillert 444b39c5158Smillert### this method 'downgrades' a file to plain file -- this is used for 445b39c5158Smillert### symlinks when FOLLOW_SYMLINKS is true. 446b39c5158Smillertsub _downgrade_to_plainfile { 447b39c5158Smillert my $entry = shift; 448b39c5158Smillert $entry->type( FILE ); 449b39c5158Smillert $entry->mode( MODE ); 450b39c5158Smillert $entry->linkname(''); 451b39c5158Smillert 452b39c5158Smillert return 1; 453b39c5158Smillert} 454b39c5158Smillert 455b39c5158Smillert=head2 $bool = $file->extract( [ $alternative_name ] ) 456b39c5158Smillert 457b39c5158SmillertExtract this object, optionally to an alternative name. 458b39c5158Smillert 459b39c5158SmillertSee C<< Archive::Tar->extract_file >> for details. 460b39c5158Smillert 461b39c5158SmillertReturns true on success and false on failure. 462b39c5158Smillert 463b39c5158Smillert=cut 464b39c5158Smillert 465b39c5158Smillertsub extract { 466b39c5158Smillert my $self = shift; 467b39c5158Smillert 468b39c5158Smillert local $Carp::CarpLevel += 1; 469b39c5158Smillert 470eac174f2Safresh1 ### avoid circular use, so only require; 471eac174f2Safresh1 require Archive::Tar; 472b39c5158Smillert return Archive::Tar->_extract_file( $self, @_ ); 473b39c5158Smillert} 474b39c5158Smillert 475b39c5158Smillert=head2 $path = $file->full_path 476b39c5158Smillert 477b39c5158SmillertReturns the full path from the tar header; this is basically a 478b39c5158Smillertconcatenation of the C<prefix> and C<name> fields. 479b39c5158Smillert 480b39c5158Smillert=cut 481b39c5158Smillert 482b39c5158Smillertsub full_path { 483b39c5158Smillert my $self = shift; 484b39c5158Smillert 4856fb12b70Safresh1 ### if prefix field is empty 486b39c5158Smillert return $self->name unless defined $self->prefix and length $self->prefix; 487b39c5158Smillert 488b39c5158Smillert ### or otherwise, catfile'd 489*3d61058aSafresh1 my $path = File::Spec::Unix->catfile( $self->prefix, $self->name ); 490*3d61058aSafresh1 $path .= "/" if $self->name =~ m{/$}; # Re-add trailing slash if necessary, as catfile() strips them off. 491*3d61058aSafresh1 return $path; 492b39c5158Smillert} 493b39c5158Smillert 494b39c5158Smillert 495b39c5158Smillert=head2 $bool = $file->validate 496b39c5158Smillert 497b39c5158SmillertDone by Archive::Tar internally when reading the tar file: 498b39c5158Smillertvalidate the header against the checksum to ensure integer tar file. 499b39c5158Smillert 500b39c5158SmillertReturns true on success, false on failure 501b39c5158Smillert 502b39c5158Smillert=cut 503b39c5158Smillert 504b39c5158Smillertsub validate { 505b39c5158Smillert my $self = shift; 506b39c5158Smillert 507b39c5158Smillert my $raw = $self->raw; 508b39c5158Smillert 509b39c5158Smillert ### don't know why this one is different from the one we /write/ ### 510b39c5158Smillert substr ($raw, 148, 8) = " "; 511b39c5158Smillert 512b39c5158Smillert ### bug #43513: [PATCH] Accept wrong checksums from SunOS and HP-UX tar 513b39c5158Smillert ### like GNU tar does. See here for details: 514b39c5158Smillert ### http://www.gnu.org/software/tar/manual/tar.html#SEC139 515b39c5158Smillert ### so we do both a signed AND unsigned validate. if one succeeds, that's 516b39c5158Smillert ### good enough 517b39c5158Smillert return ( (unpack ("%16C*", $raw) == $self->chksum) 518b39c5158Smillert or (unpack ("%16c*", $raw) == $self->chksum)) ? 1 : 0; 519b39c5158Smillert} 520b39c5158Smillert 521b39c5158Smillert=head2 $bool = $file->has_content 522b39c5158Smillert 523b39c5158SmillertReturns a boolean to indicate whether the current object has content. 524b39c5158SmillertSome special files like directories and so on never will have any 525b39c5158Smillertcontent. This method is mainly to make sure you don't get warnings 526b39c5158Smillertfor using uninitialized values when looking at an object's content. 527b39c5158Smillert 528b39c5158Smillert=cut 529b39c5158Smillert 530b39c5158Smillertsub has_content { 531b39c5158Smillert my $self = shift; 532b39c5158Smillert return defined $self->data() && length $self->data() ? 1 : 0; 533b39c5158Smillert} 534b39c5158Smillert 535b39c5158Smillert=head2 $content = $file->get_content 536b39c5158Smillert 537b39c5158SmillertReturns the current content for the in-memory file 538b39c5158Smillert 539b39c5158Smillert=cut 540b39c5158Smillert 541b39c5158Smillertsub get_content { 542b39c5158Smillert my $self = shift; 543b39c5158Smillert $self->data( ); 544b39c5158Smillert} 545b39c5158Smillert 546b39c5158Smillert=head2 $cref = $file->get_content_by_ref 547b39c5158Smillert 548b39c5158SmillertReturns the current content for the in-memory file as a scalar 549b39c5158Smillertreference. Normal users won't need this, but it will save memory if 550b39c5158Smillertyou are dealing with very large data files in your tar archive, since 551b39c5158Smillertit will pass the contents by reference, rather than make a copy of it 552b39c5158Smillertfirst. 553b39c5158Smillert 554b39c5158Smillert=cut 555b39c5158Smillert 556b39c5158Smillertsub get_content_by_ref { 557b39c5158Smillert my $self = shift; 558b39c5158Smillert 559b39c5158Smillert return \$self->{data}; 560b39c5158Smillert} 561b39c5158Smillert 562b39c5158Smillert=head2 $bool = $file->replace_content( $content ) 563b39c5158Smillert 564b39c5158SmillertReplace the current content of the file with the new content. This 565b39c5158Smillertonly affects the in-memory archive, not the on-disk version until 566b39c5158Smillertyou write it. 567b39c5158Smillert 568b39c5158SmillertReturns true on success, false on failure. 569b39c5158Smillert 570b39c5158Smillert=cut 571b39c5158Smillert 572b39c5158Smillertsub replace_content { 573b39c5158Smillert my $self = shift; 574b39c5158Smillert my $data = shift || ''; 575b39c5158Smillert 576b39c5158Smillert $self->data( $data ); 577b39c5158Smillert $self->size( length $data ); 578b39c5158Smillert return 1; 579b39c5158Smillert} 580b39c5158Smillert 581b39c5158Smillert=head2 $bool = $file->rename( $new_name ) 582b39c5158Smillert 583b39c5158SmillertRename the current file to $new_name. 584b39c5158Smillert 585b39c5158SmillertNote that you must specify a Unix path for $new_name, since per tar 586b39c5158Smillertstandard, all files in the archive must be Unix paths. 587b39c5158Smillert 588b39c5158SmillertReturns true on success and false on failure. 589b39c5158Smillert 590b39c5158Smillert=cut 591b39c5158Smillert 592b39c5158Smillertsub rename { 593b39c5158Smillert my $self = shift; 594b39c5158Smillert my $path = shift; 595b39c5158Smillert 596b39c5158Smillert return unless defined $path; 597b39c5158Smillert 598b39c5158Smillert my ($prefix,$file) = $self->_prefix_and_file( $path ); 599b39c5158Smillert 600b39c5158Smillert $self->name( $file ); 601b39c5158Smillert $self->prefix( $prefix ); 602b39c5158Smillert 603b39c5158Smillert return 1; 604b39c5158Smillert} 605b39c5158Smillert 606*3d61058aSafresh1=head2 $bool = $file->chmod( $mode ) 607898184e3Ssthen 608898184e3SsthenChange mode of $file to $mode. The mode can be a string or a number 609898184e3Ssthenwhich is interpreted as octal whether or not a leading 0 is given. 610898184e3Ssthen 611898184e3SsthenReturns true on success and false on failure. 612898184e3Ssthen 613898184e3Ssthen=cut 614898184e3Ssthen 615898184e3Ssthensub chmod { 616898184e3Ssthen my $self = shift; 617898184e3Ssthen my $mode = shift; return unless defined $mode && $mode =~ /^[0-7]{1,4}$/; 618898184e3Ssthen $self->{mode} = oct($mode); 619898184e3Ssthen return 1; 620898184e3Ssthen} 621898184e3Ssthen 622898184e3Ssthen=head2 $bool = $file->chown( $user [, $group]) 623898184e3Ssthen 624898184e3SsthenChange owner of $file to $user. If a $group is given that is changed 625898184e3Ssthenas well. You can also pass a single parameter with a colon separating the 626898184e3Ssthenuse and group as in 'root:wheel'. 627898184e3Ssthen 628898184e3SsthenReturns true on success and false on failure. 629898184e3Ssthen 630898184e3Ssthen=cut 631898184e3Ssthen 632898184e3Ssthensub chown { 633898184e3Ssthen my $self = shift; 634898184e3Ssthen my $uname = shift; 635898184e3Ssthen return unless defined $uname; 636898184e3Ssthen my $gname; 637898184e3Ssthen if (-1 != index($uname, ':')) { 638898184e3Ssthen ($uname, $gname) = split(/:/, $uname); 639898184e3Ssthen } else { 640898184e3Ssthen $gname = shift if @_ > 0; 641898184e3Ssthen } 642898184e3Ssthen 643898184e3Ssthen $self->uname( $uname ); 644898184e3Ssthen $self->gname( $gname ) if $gname; 645898184e3Ssthen return 1; 646898184e3Ssthen} 647898184e3Ssthen 648b39c5158Smillert=head1 Convenience methods 649b39c5158Smillert 650b39c5158SmillertTo quickly check the type of a C<Archive::Tar::File> object, you can 651b39c5158Smillertuse the following methods: 652b39c5158Smillert 653b39c5158Smillert=over 4 654b39c5158Smillert 655b39c5158Smillert=item $file->is_file 656b39c5158Smillert 657b39c5158SmillertReturns true if the file is of type C<file> 658b39c5158Smillert 659b39c5158Smillert=item $file->is_dir 660b39c5158Smillert 661b39c5158SmillertReturns true if the file is of type C<dir> 662b39c5158Smillert 663b39c5158Smillert=item $file->is_hardlink 664b39c5158Smillert 665b39c5158SmillertReturns true if the file is of type C<hardlink> 666b39c5158Smillert 667b39c5158Smillert=item $file->is_symlink 668b39c5158Smillert 669b39c5158SmillertReturns true if the file is of type C<symlink> 670b39c5158Smillert 671b39c5158Smillert=item $file->is_chardev 672b39c5158Smillert 673b39c5158SmillertReturns true if the file is of type C<chardev> 674b39c5158Smillert 675b39c5158Smillert=item $file->is_blockdev 676b39c5158Smillert 677b39c5158SmillertReturns true if the file is of type C<blockdev> 678b39c5158Smillert 679b39c5158Smillert=item $file->is_fifo 680b39c5158Smillert 681b39c5158SmillertReturns true if the file is of type C<fifo> 682b39c5158Smillert 683b39c5158Smillert=item $file->is_socket 684b39c5158Smillert 685b39c5158SmillertReturns true if the file is of type C<socket> 686b39c5158Smillert 687b39c5158Smillert=item $file->is_longlink 688b39c5158Smillert 689b39c5158SmillertReturns true if the file is of type C<LongLink>. 690b39c5158SmillertShould not happen after a successful C<read>. 691b39c5158Smillert 692b39c5158Smillert=item $file->is_label 693b39c5158Smillert 694b39c5158SmillertReturns true if the file is of type C<Label>. 695b39c5158SmillertShould not happen after a successful C<read>. 696b39c5158Smillert 697b39c5158Smillert=item $file->is_unknown 698b39c5158Smillert 699b39c5158SmillertReturns true if the file type is C<unknown> 700b39c5158Smillert 701b39c5158Smillert=back 702b39c5158Smillert 703b39c5158Smillert=cut 704b39c5158Smillert 705b39c5158Smillert#stupid perl5.5.3 needs to warn if it's not numeric 706b39c5158Smillertsub is_file { local $^W; FILE == $_[0]->type } 707b39c5158Smillertsub is_dir { local $^W; DIR == $_[0]->type } 708b39c5158Smillertsub is_hardlink { local $^W; HARDLINK == $_[0]->type } 709b39c5158Smillertsub is_symlink { local $^W; SYMLINK == $_[0]->type } 710b39c5158Smillertsub is_chardev { local $^W; CHARDEV == $_[0]->type } 711b39c5158Smillertsub is_blockdev { local $^W; BLOCKDEV == $_[0]->type } 712b39c5158Smillertsub is_fifo { local $^W; FIFO == $_[0]->type } 713b39c5158Smillertsub is_socket { local $^W; SOCKET == $_[0]->type } 714b39c5158Smillertsub is_unknown { local $^W; UNKNOWN == $_[0]->type } 715b39c5158Smillertsub is_longlink { local $^W; LONGLINK eq $_[0]->type } 716b39c5158Smillertsub is_label { local $^W; LABEL eq $_[0]->type } 717b39c5158Smillert 718b39c5158Smillert1; 719