5 use version
; our $VERSION = qv
('0.1.2');
7 use Pod
::Usage
qw( pod2usage );
8 use Getopt
::Long
qw( :config gnu_getopt );
9 use English
qw( -no_match_vars );
10 use File
::Basename
qw( basename dirname );
11 use File
::Spec
::Functions
qw( file_name_is_absolute catfile );
12 use File
::Temp
qw( tempfile );
13 use POSIX
qw( strftime );
14 use Cwd
qw( cwd realpath );
18 # __MOBUNDLE_INCLUSION__
26 'Archive/Tar.pm' => <<'END_OF_FILE',
27 ### the gnu tar specification:
28 ### http://www.gnu.org/software/tar/manual/tar.html
30 ### and the pax format spec, which tar derives from:
31 ### http://www.opengroup.org/onlinepubs/007904975/utilities/pax.html
39 use Carp qw(carp croak);
41 use File
::Spec
::Unix
();
44 use Archive
::Tar
::File
;
45 use Archive
::Tar
::Constant
;
50 use vars qw
[$DEBUG $error $VERSION $WARN $FOLLOW_SYMLINK $CHOWN $CHMOD
51 $DO_NOT_USE_PREFIX $HAS_PERLIO $HAS_IO_STRING $SAME_PERMISSIONS
52 $INSECURE_EXTRACT_MODE $ZERO_PAD_NUMBERS @ISA @EXPORT $RESOLVE_SYMLINK
56 @EXPORT = qw
[ COMPRESS_GZIP COMPRESS_BZIP
];
63 $SAME_PERMISSIONS = $> == 0 ?
1 : 0;
64 $DO_NOT_USE_PREFIX = 0;
65 $INSECURE_EXTRACT_MODE = 0;
66 $ZERO_PAD_NUMBERS = 0;
67 $RESOLVE_SYMLINK = $ENV{'PERL5_AT_RESOLVE_SYMLINK'} || 'speed';
71 $HAS_PERLIO = $Config::Config
{useperlio
};
73 ### try and load IO::String anyway, so you can dynamically
74 ### switch between perlio and IO::String
75 $HAS_IO_STRING = eval {
84 Archive
::Tar
- module
for manipulations of tar archives
89 my $tar = Archive
::Tar
->new;
91 $tar->read('origin.tgz');
94 $tar->add_files('file/foo.pl', 'docs/README');
95 $tar->add_data('file/baz.txt', 'This is the contents now');
97 $tar->rename('oldname', 'new/file/name');
98 $tar->chown('/', 'root');
99 $tar->chown('/', 'root:root');
100 $tar->chmod('/tmp', '1777');
102 $tar->write('files.tar'); # plain tar
103 $tar->write('files.tgz', COMPRESS_GZIP
); # gzip compressed
104 $tar->write('files.tbz', COMPRESS_BZIP
); # bzip2 compressed
108 Archive
::Tar provides an object oriented mechanism
for handling tar
109 files
. It provides
class methods
for quick
and easy files handling
110 while also allowing
for the creation of tar file objects
for custom
111 manipulation
. If you have the IO
::Zlib module installed
,
112 Archive
::Tar will also support compressed
or gzipped tar files
.
114 An object of
class Archive
::Tar represents a
.tar
(.gz
) archive full
117 =head1 Object Methods
119 =head2 Archive
::Tar
->new( [$file, $compressed] )
121 Returns a new Tar object
. If
given any arguments
, C
<new
()> calls the
122 C
<read()> method automatically
, passing on the arguments provided to
123 the C
<read()> method
.
125 If C
<new
()> is invoked with arguments
and the C
<read()> method fails
126 for any reason
, C
<new
()> returns
undef.
135 ### install get/set accessors for this object.
136 for my $key ( keys %$tmpl ) {
138 *{__PACKAGE__
."::$key"} = sub {
140 $self->{$key} = $_[0] if @_;
141 return $self->{$key};
147 $class = ref $class if ref $class;
149 ### copying $tmpl here since a shallow copy makes it use the
150 ### same aref, causing for files to remain in memory always.
151 my $obj = bless { _data
=> [ ], _file
=> 'Unknown', _error
=> '' }, $class;
154 unless ( $obj->read( @_ ) ) {
155 $obj->_error(qq[No data could be
read from file
]);
163 =head2
$tar->read ( $filename|$handle, [$compressed, {opt
=> 'val'}] )
165 Read the
given tar file into memory
.
166 The first argument can either be the name of a file
or a reference to
167 an already
open filehandle
(or an IO
::Zlib object
if it
's compressed)
169 The C<read> will I<replace> any previous content in C<$tar>!
171 The second argument may be considered optional, but remains for
172 backwards compatibility. Archive::Tar now looks at the file
173 magic to determine what class should be used to open the file
174 and will transparently Do The Right Thing.
176 Archive::Tar will warn if you try to pass a bzip2 compressed file and the
177 IO::Zlib / IO::Uncompress::Bunzip2 modules are not available and simply return.
179 Note that you can currently B<not> pass a C<gzip> compressed
180 filehandle, which is not opened with C<IO::Zlib>, a C<bzip2> compressed
181 filehandle, which is not opened with C<IO::Uncompress::Bunzip2>, nor a string
182 containing the full archive information (either compressed or
183 uncompressed). These are worth while features, but not currently
184 implemented. See the C<TODO> section.
186 The third argument can be a hash reference with options. Note that
187 all options are case-sensitive.
193 Do not read more than C<limit> files. This is useful if you have
194 very big archives, and are only interested in the first few files.
198 Can be set to a regular expression. Only files with names that match
199 the expression will be read.
203 Set to 1 and the md5sum of files will be returned (instead of file data)
204 my $iter = Archive::Tar->iter( $file, 1, {md5 => 1} );
205 while( my $f = $iter->() ) {
206 print $f->data . "\t" . $f->full_path . $/;
211 If set to true, immediately extract entries when reading them. This
212 gives you the same memory break as the C<extract_archive> function.
213 Note however that entries will not be read into memory, but written
214 straight to disk. This means no C<Archive::Tar::File> objects are
215 created for you to inspect.
219 All files are stored internally as C<Archive::Tar::File> objects.
220 Please consult the L<Archive::Tar::File> documentation for details.
222 Returns the number of files read in scalar context, and a list of
223 C<Archive::Tar::File> objects in list context.
230 my $gzip = shift || 0;
231 my $opts = shift || {};
233 unless( defined $file ) {
234 $self->_error( qq[No file to read from!] );
237 $self->_file( $file );
240 my $handle = $self->_get_handle($file, $gzip, READ_ONLY->( ZLIB ) )
243 my $data = $self->_read_tar( $handle, $opts ) or return;
245 $self->_data( $data );
247 return wantarray ? @$data : scalar @$data;
252 my $file = shift; return unless defined $file;
253 my $compress = shift || 0;
254 my $mode = shift || READ_ONLY->( ZLIB ); # default to read only
256 ### Check if file is a file handle or IO glob
258 return $file if eval{ *$file{IO} };
259 return $file if eval{ $file->isa(q{IO::Handle}) };
263 ### get a FH opened to the right class, so we can use it transparently
264 ### throughout the program
266 { ### reading magic only makes sense if we're opening a file for
267 ### reading. otherwise, just use what the user requested.
269 if( MODE_READ
->($mode) ) {
270 open my $tmp, $file or do {
271 $self->_error( qq[Could
not open '$file' for reading
: $!] );
275 ### read the first 4 bites of the file to figure out which class to
276 ### use to open the file.
277 sysread( $tmp, $magic, 4 );
282 ### if you asked specifically for bzip compression, or if we're in
283 ### read mode and the magic numbers add up, use bzip
285 ($compress eq COMPRESS_BZIP
) or
286 ( MODE_READ
->($mode) and $magic =~ BZIP_MAGIC_NUM
)
290 ### different reader/writer modules, different error vars... sigh
291 if( MODE_READ
->($mode) ) {
292 $fh = IO
::Uncompress
::Bunzip2
->new( $file ) or do {
293 $self->_error( qq[Could
not read '$file': ] .
294 $IO::Uncompress
::Bunzip2
::Bunzip2Error
300 $fh = IO
::Compress
::Bzip2
->new( $file ) or do {
301 $self->_error( qq[Could
not write to
'$file': ] .
302 $IO::Compress
::Bzip2
::Bzip2Error
309 ### if you asked for compression, if you wanted to read or the gzip
310 ### magic number is present (redundant with read)
312 $compress or MODE_READ
->($mode) or $magic =~ GZIP_MAGIC_NUM
317 unless( $fh->open( $file, $mode ) ) {
318 $self->_error(qq[Could
not create filehandle
for '$file': $!]);
326 unless( $fh->open( $file, $mode ) ) {
327 $self->_error(qq[Could
not create filehandle
for '$file': $!]);
331 ### enable bin mode on tar archives
342 my $handle = shift or return;
343 my $opts = shift || {};
345 my $count = $opts->{limit
} || 0;
346 my $filter = $opts->{filter
};
347 my $md5 = $opts->{md5
} || 0; # cdrake
348 my $filter_cb = $opts->{filter_cb
};
349 my $extract = $opts->{extract
} || 0;
351 ### set a cap on the amount of files to extract ###
353 $limit = 1 if $count > 0;
358 my $real_name; # to set the name of a file when
359 # we're encountering @longlink
363 while( $handle->read( $chunk, HEAD
) ) {
364 ### IO::Zlib doesn't support this yet
366 if ( ref($handle) ne 'IO::Zlib' ) {
368 $offset = eval { tell $handle } || 'unknown';
376 my $gzip = GZIP_MAGIC_NUM
;
377 if( $chunk =~ /$gzip/ ) {
378 $self->_error( qq[Cannot
read compressed format
in tar
-mode
] );
382 ### size is < HEAD, which means a corrupted file, as the minimum
383 ### length is _at least_ HEAD
384 if (length $chunk != HEAD
) {
385 $self->_error( qq[Cannot
read enough bytes from the tarfile
] );
390 ### if we can't read in all bytes... ###
391 last if length $chunk != HEAD
;
393 ### Apparently this should really be two blocks of 512 zeroes,
394 ### but GNU tar sometimes gets it wrong. See comment in the
395 ### source code (tar.c) to GNU cpio.
396 next if $chunk eq TAR_END
;
398 ### according to the posix spec, the last 12 bytes of the header are
399 ### null bytes, to pad it to a 512 byte block. That means if these
400 ### bytes are NOT null bytes, it's a corrupt header. See:
401 ### www.koders.com/c/fidCE473AD3D9F835D690259D60AD5654591D91D5BA.aspx
403 { my $nulls = join '', "\0" x
12;
404 unless( $nulls eq substr( $chunk, 500, 12 ) ) {
405 $self->_error( qq[Invalid header block at offset
$offset] );
410 ### pass the realname, so we can set it 'proper' right away
411 ### some of the heuristics are done on the name, so important
414 { my %extra_args = ();
415 $extra_args{'name'} = $$real_name if defined $real_name;
417 unless( $entry = Archive
::Tar
::File
->new( chunk
=> $chunk,
420 $self->_error( qq[Couldn
't read chunk at offset $offset] );
426 ### http://www.gnu.org/software/tar/manual/html_chapter/Media.html#SEC159
427 next if $entry->is_label;
429 if( length $entry->type and ($entry->is_file || $entry->is_longlink) ) {
431 if ( $entry->is_file && !$entry->validate ) {
432 ### sometimes the chunk is rather fux0r3d and a whole 512
433 ### bytes ends up in the ->name area.
434 ### clean it up, if need be
435 my $name = $entry->name;
436 $name = substr($name, 0, 100) if length $name > 100;
439 $self->_error( $name . qq[: checksum error] );
443 my $block = BLOCK_SIZE->( $entry->size );
445 $data = $entry->get_content_by_ref;
449 ### skip this entry if we're filtering
452 $ctx = Digest
::MD5
->new; # cdrake
455 } elsif ($filter && $entry->name !~ $filter) {
458 } elsif ($filter_cb && ! $filter_cb->($entry)) {
461 ### skip this entry if it's a pax header. This is a special file added
462 ### by, among others, git-generated tarballs. It holds comments and is
463 ### not meant for extracting. See #38932: pax_global_header extracted
464 } elsif ( $entry->name eq PAX_HEADER
or $entry->type =~ /^(x|g)$/ ) {
470 # Since we're skipping, do not allocate memory for the
471 # whole file. Read it 64 BLOCKS at a time. Do not
472 # complete the skip yet because maybe what we read is a
473 # longlink and it won't get skipped after all
476 my $fsz=$entry->size; # cdrake
479 my $this = 64 * BLOCK
;
480 $this = $amt if $this > $amt;
481 if( $handle->read( $$data, $this ) < $this ) {
482 $self->_error( qq[Read error on tarfile
(missing data
) '].
483 $entry->full_path ."' at offset
$offset" );
487 $fsz -= $this; # cdrake
488 substr ($$data, $fsz) = "" if ($fsz<0); # remove external junk prior to md5 # cdrake
489 $ctx->add($$data) if($skip==5); # cdrake
491 $$data = $ctx->hexdigest if($skip==5 && !$entry->is_longlink && !$entry->is_unknown && !$entry->is_label ) ; # cdrake
494 ### just read everything into memory
495 ### can't do lazy loading since IO::Zlib doesn't support 'seek'
496 ### this is because Compress::Zlib doesn't support it =/
497 ### this reads in the whole data in one read() call.
498 if ( $handle->read( $$data, $block ) < $block ) {
499 $self->_error( qq[Read error on tarfile (missing data) '].
500 $entry->full_path ."' at offset $offset" );
503 ### throw away trailing garbage ###
504 substr ($$data, $entry->size) = "" if defined $$data;
507 ### part II of the @LongLink munging -- need to do /after/
508 ### the checksum check.
509 if( $entry->is_longlink ) {
510 ### weird thing in tarfiles -- if the file is actually a
511 ### @LongLink, the data part seems to have a trailing ^@
512 ### (unprintable) char. to display, pipe output through less.
513 ### but that doesn't
*always
* happen
.. so check
if the
last
514 ### character is a control character, and if so remove it
515 ### at any rate, we better remove that character here, or tests
516 ### like 'eq' and hash lookups based on names will SO not work
517 ### remove it by calculating the proper size, and then
518 ### tossing out everything that's longer than that size.
520 ### count number of nulls
521 my $nulls = $$data =~ tr/\0/\0/;
523 ### cut data + size by that many bytes
524 $entry->size( $entry->size - $nulls );
525 substr ($$data, $entry->size) = "";
529 ### clean up of the entries.. posix tar /apparently/ has some
530 ### weird 'feature' that allows for filenames > 255 characters
531 ### they'll put a header in with as name '././@LongLink' and the
532 ### contents will be the name of the /next/ file in the archive
533 ### pretty crappy and kludgy if you ask me
535 ### set the name for the next entry if this is a @LongLink;
536 ### this is one ugly hack =/ but needed for direct extraction
537 if( $entry->is_longlink ) {
540 } elsif ( defined $real_name ) {
541 $entry->name( $$real_name );
546 if ($filter && $entry->name !~ $filter) {
549 } elsif ($filter_cb && ! $filter_cb->($entry)) {
552 ### skip this entry if it's a pax header. This is a special file added
553 ### by, among others, git-generated tarballs. It holds comments and is
554 ### not meant for extracting. See #38932: pax_global_header extracted
555 } elsif ( $entry->name eq PAX_HEADER
or $entry->type =~ /^(x|g)$/ ) {
559 if ( $extract && !$entry->is_longlink
560 && !$entry->is_unknown
561 && !$entry->is_label ) {
562 $self->_extract_file( $entry ) or return;
565 ### Guard against tarfiles with garbage at the end
566 last LOOP
if $entry->name eq '';
568 ### push only the name on the rv if we're extracting
569 ### -- for extract_archive
570 push @
$tarfile, ($extract ?
$entry->name : $entry);
573 $count-- unless $entry->is_longlink || $entry->is_dir;
574 last LOOP
unless $count;
583 =head2
$tar->contains_file( $filename )
585 Check
if the archive contains a certain file
.
586 It will
return true
if the file is
in the archive
, false otherwise
.
588 Note however
, that this function does an exact match using C
<eq>
589 on the full path
. So it cannot compensate
for case
-insensitive file
-
590 systems
or compare
2 paths to see
if they would point to the same
599 return unless defined $full;
601 ### don't warn if the entry isn't there.. that's what this function
602 ### is for after all.
604 return 1 if $self->_find_entry($full);
608 =head2
$tar->extract( [@filenames] )
610 Write files whose names are equivalent to any of the names
in
611 C
<@filenames> to disk
, creating subdirectories as necessary
. This
612 might
not work too well under VMS
.
613 Under MacPerl
, the file
's modification time will be converted to the
614 MacOS zero of time, and appropriate conversions will be done to the
615 path. However, the length of each element of the path is not
616 inspected to see whether it's longer than MacOS currently allows
(32
619 If C
<extract
> is called without a list of file names
, the entire
620 contents of the archive are extracted
.
622 Returns a list of filenames extracted
.
631 # use the speed optimization for all extracted files
632 local($self->{cwd
}) = cwd
() unless $self->{cwd
};
634 ### you requested the extraction of only certain files
636 for my $file ( @args ) {
638 ### it's already an object?
639 if( UNIVERSAL
::isa
( $file, 'Archive::Tar::File' ) ) {
647 for my $entry ( @
{$self->_data} ) {
648 next unless $file eq $entry->full_path;
650 ### we found the file you're looking for
656 return $self->_error(
657 qq[Could
not find
'$file' in archive
] );
662 ### just grab all the file items
664 @files = $self->get_files;
667 ### nothing found? that's an error
668 unless( scalar @files ) {
669 $self->_error( qq[No files found
for ] . $self->_file );
674 for my $entry ( @files ) {
675 unless( $self->_extract_file( $entry ) ) {
676 $self->_error(q
[Could
not extract
']. $entry->full_path .q['] );
684 =head2
$tar->extract_file( $file, [$extract_path] )
686 Write an entry
, whose name is equivalent to the file name provided to
687 disk
. Optionally takes a second parameter
, which is the full native
688 path
(including filename
) the entry will be written to
.
692 $tar->extract_file( 'name/in/archive', 'name/i/want/to/give/it' );
694 $tar->extract_file( $at_file_object, 'name/i/want/to/give/it' );
696 Returns true on success
, false on failure
.
702 my $file = shift; return unless defined $file;
705 my $entry = $self->_find_entry( $file )
706 or $self->_error( qq[Could
not find an entry
for '$file'] ), return;
708 return $self->_extract_file( $entry, $alt );
713 my $entry = shift or return;
716 ### you wanted an alternate extraction location ###
717 my $name = defined $alt ?
$alt : $entry->full_path;
719 ### splitpath takes a bool at the end to indicate
720 ### that it's splitting a dir
721 my ($vol,$dirs,$file);
722 if ( defined $alt ) { # It's a local-OS path
723 ($vol,$dirs,$file) = File
::Spec
->splitpath( $alt,
726 ($vol,$dirs,$file) = File
::Spec
::Unix
->splitpath( $name,
731 ### is $name an absolute path? ###
732 if( $vol || File
::Spec
->file_name_is_absolute( $dirs ) ) {
734 ### absolute names are not allowed to be in tarballs under
735 ### strict mode, so only allow it if a user tells us to do it
736 if( not defined $alt and not $INSECURE_EXTRACT_MODE ) {
738 q
[Entry
']. $entry->full_path .q[' is an absolute path
. ].
739 q
[Not extracting absolute paths under SECURE EXTRACT MODE
]
744 ### user asked us to, it's fine.
745 $dir = File
::Spec
->catpath( $vol, $dirs, "" );
747 ### it's a relative path ###
749 my $cwd = (ref $self and defined $self->{cwd
})
753 my @dirs = defined $alt
754 ? File
::Spec
->splitdir( $dirs ) # It's a local-OS path
755 : File
::Spec
::Unix
->splitdir( $dirs ); # it's UNIX-style, likely
756 # straight from the tarball
758 if( not defined $alt and
759 not $INSECURE_EXTRACT_MODE
762 ### paths that leave the current directory are not allowed under
763 ### strict mode, so only allow it if a user tells us to do this.
764 if( grep { $_ eq '..' } @dirs ) {
767 q
[Entry
']. $entry->full_path .q[' is attempting to leave
].
768 q
[the current working directory
. Not extracting under
].
769 q
[SECURE EXTRACT MODE
]
774 ### the archive may be asking us to extract into a symlink. This
775 ### is not sane and a possible security issue, as outlined here:
776 ### https://rt.cpan.org/Ticket/Display.html?id=30380
777 ### https://bugzilla.redhat.com/show_bug.cgi?id=295021
778 ### https://issues.rpath.com/browse/RPL-1716
779 my $full_path = $cwd;
780 for my $d ( @dirs ) {
781 $full_path = File
::Spec
->catdir( $full_path, $d );
783 ### we've already checked this one, and it's safe. Move on.
784 next if ref $self and $self->{_link_cache
}->{$full_path};
786 if( -l
$full_path ) {
787 my $to = readlink $full_path;
788 my $diag = "symlinked directory ($full_path => $to)";
791 q
[Entry
']. $entry->full_path .q[' is attempting to
].
792 qq[extract to a
$diag. This is considered a security
].
793 q
[vulnerability
and not allowed under SECURE EXTRACT
].
799 ### XXX keep a cache if possible, so the stats become cheaper:
800 $self->{_link_cache
}->{$full_path} = 1 if ref $self;
804 ### '.' is the directory delimiter on VMS, which has to be escaped
805 ### or changed to '_' on vms. vmsify is used, because older versions
806 ### of vmspath do not handle this properly.
807 ### Must not add a '/' to an empty directory though.
808 map { length() ? VMS
::Filespec
::vmsify
($_.'/') : $_ } @dirs if ON_VMS
;
810 my ($cwd_vol,$cwd_dir,$cwd_file)
811 = File
::Spec
->splitpath( $cwd );
812 my @cwd = File
::Spec
->splitdir( $cwd_dir );
813 push @cwd, $cwd_file if length $cwd_file;
815 ### We need to pass '' as the last element to catpath. Craig Berry
816 ### explains why (msgid <p0624083dc311ae541393@[172.16.52.1]>):
817 ### The root problem is that splitpath on UNIX always returns the
818 ### final path element as a file even if it is a directory, and of
819 ### course there is no way it can know the difference without checking
820 ### against the filesystem, which it is documented as not doing. When
821 ### you turn around and call catpath, on VMS you have to know which bits
822 ### are directory bits and which bits are file bits. In this case we
823 ### know the result should be a directory. I had thought you could omit
824 ### the file argument to catpath in such a case, but apparently on UNIX
826 $dir = File
::Spec
->catpath(
827 $cwd_vol, File
::Spec
->catdir( @cwd, @dirs ), ''
830 ### catdir() returns undef if the path is longer than 255 chars on
831 ### older VMS systems.
832 unless ( defined $dir ) {
833 $^W
&& $self->_error( qq[Could
not compose a path
for '$dirs'\n] );
839 if( -e
$dir && !-d _
) {
840 $^W
&& $self->_error( qq['$dir' exists, but it
's not a directory!\n] );
845 eval { File::Path::mkpath( $dir, 0, 0777 ) };
847 my $fp = $entry->full_path;
848 $self->_error(qq[Could not create directory '$dir' for '$fp': $@]);
852 ### XXX chown here? that might not be the same as in the archive
853 ### as we're only
chown'ing to the owner of the file we're extracting
854 ### not to the owner of the directory itself, which may or may not
855 ### be another entry in the archive
856 ### Answer: no, gnu tar doesn't do it either, it'd be the wrong
858 #if( $CHOWN && CAN_CHOWN ) {
859 # chown $entry->uid, $entry->gid, $dir or
860 # $self->_error( qq[Could not set uid/gid on '$dir'] );
864 ### we're done if we just needed to create a dir ###
865 return 1 if $entry->is_dir;
867 my $full = File
::Spec
->catfile( $dir, $file );
869 if( $entry->is_unknown ) {
870 $self->_error( qq[Unknown file type
for file
'$full'] );
874 if( length $entry->type && $entry->is_file ) {
875 my $fh = IO
::File
->new;
876 $fh->open( '>' . $full ) or (
877 $self->_error( qq[Could
not open file
'$full': $!] ),
883 syswrite $fh, $entry->data or (
884 $self->_error( qq[Could
not write data to
'$full'] ),
890 $self->_error( qq[Could
not close file
'$full'] ),
895 $self->_make_special_file( $entry, $full ) or return;
898 ### only update the timestamp if it's not a symlink; that will change the
899 ### timestamp of the original. This addresses bug #33669: Could not update
900 ### timestamp warning on symlinks
902 utime time, $entry->mtime - TIME_OFFSET
, $full or
903 $self->_error( qq[Could
not update timestamp
] );
906 if( $CHOWN && CAN_CHOWN
->() and not -l
$full ) {
907 chown $entry->uid, $entry->gid, $full or
908 $self->_error( qq[Could
not set uid
/gid on
'$full'] );
911 ### only chmod if we're allowed to, but never chmod symlinks, since they'll
912 ### change the perms on the file they're linking too...
913 if( $CHMOD and not -l
$full ) {
914 my $mode = $entry->mode;
915 unless ($SAME_PERMISSIONS) {
916 $mode &= ~(oct(7000) | umask);
918 chmod $mode, $full or
919 $self->_error( qq[Could
not chown '$full' to
] . $entry->mode );
925 sub _make_special_file
{
927 my $entry = shift or return;
928 my $file = shift; return unless defined $file;
932 if( $entry->is_symlink ) {
935 symlink( $entry->linkname, $file ) or $fail++;
938 $self->_extract_special_file_as_plain_file( $entry, $file )
942 $err = qq[Making symbolic
link '$file' to
'] .
943 $entry->linkname .q[' failed
] if $fail;
945 } elsif ( $entry->is_hardlink ) {
948 link( $entry->linkname, $file ) or $fail++;
951 $self->_extract_special_file_as_plain_file( $entry, $file )
955 $err = qq[Making hard
link from
'] . $entry->linkname .
956 qq[' to
'$file' failed
] if $fail;
958 } elsif ( $entry->is_fifo ) {
959 ON_UNIX
&& !system('mknod', $file, 'p') or
960 $err = qq[Making fifo
']. $entry->name .qq[' failed
];
962 } elsif ( $entry->is_blockdev or $entry->is_chardev ) {
963 my $mode = $entry->is_blockdev ?
'b' : 'c';
965 ON_UNIX
&& !system('mknod', $file, $mode,
966 $entry->devmajor, $entry->devminor) or
967 $err = qq[Making block device
']. $entry->name .qq[' (maj
=] .
968 $entry->devmajor . qq[ min
=] . $entry->devminor .
971 } elsif ( $entry->is_socket ) {
972 ### the original doesn't do anything special for sockets.... ###
976 return $err ?
$self->_error( $err ) : 1;
979 ### don't know how to make symlinks, let's just extract the file as
981 sub _extract_special_file_as_plain_file
{
983 my $entry = shift or return;
984 my $file = shift; return unless defined $file;
988 my $orig = $self->_find_entry( $entry->linkname, $entry );
991 $err = qq[Could
not find file
'] . $entry->linkname .
996 ### clone the entry, make it appear as a normal file ###
997 my $clone = $orig->clone;
998 $clone->_downgrade_to_plainfile;
999 $self->_extract_file( $clone, $file ) or last TRY
;
1004 return $self->_error($err);
1007 =head2
$tar->list_files( [\
@properties] )
1009 Returns a list of the names of all the files
in the archive
.
1011 If C
<list_files
()> is passed an array reference as its first argument
1012 it returns a list of hash references containing the requested
1013 properties of
each file
. The following list of properties is
1014 supported
: name
, size
, mtime
(last modified date
), mode
, uid
, gid
,
1015 linkname
, uname
, gname
, devmajor
, devminor
, prefix
.
1017 Passing an array reference containing only one element
, 'name', is
1018 special cased to
return a list of names rather than a list of hash
1019 references
, making it equivalent to calling C
<list_files
> without
1026 my $aref = shift || [ ];
1028 unless( $self->_data ) {
1029 $self->read() or return;
1032 if( @
$aref == 0 or ( @
$aref == 1 and $aref->[0] eq 'name' ) ) {
1033 return map { $_->full_path } @
{$self->_data};
1037 #for my $obj ( @{$self->_data} ) {
1038 # push @rv, { map { $_ => $obj->$_() } @$aref };
1042 ### this does the same as the above.. just needs a +{ }
1043 ### to make sure perl doesn't confuse it for a block
1044 return map { my $o=$_;
1045 +{ map { $_ => $o->$_() } @
$aref }
1054 unless( defined $file ) {
1055 $self->_error( qq[No file specified
] );
1059 ### it's an object already
1060 return $file if UNIVERSAL
::isa
( $file, 'Archive::Tar::File' );
1064 for my $entry ( @
{$self->_data} ) {
1065 my $path = $entry->full_path;
1066 return $entry if $path eq $file;
1070 if($Archive::Tar
::RESOLVE_SYMLINK
!~/none/){
1071 if(my $link_entry = shift()){#fallback mode when symlinks are using relative notations ( ../a/./b/text.bin )
1072 $file = _symlinks_resolver
( $link_entry->name, $file );
1073 goto seach_entry
if $self->_data;
1075 #this will be slower than never, but won't failed!
1077 my $iterargs = $link_entry->{'_archive'};
1078 if($Archive::Tar
::RESOLVE_SYMLINK
=~/speed/ && @
$iterargs==3){
1079 #faster but whole archive will be read in memory
1080 #read whole archive and share data
1081 my $archive = Archive
::Tar
->new;
1082 $archive->read( @
$iterargs );
1083 push @
$iterargs, $archive; #take a trace for destruction
1084 if($archive->_data){
1085 $self->_data( $archive->_data );
1090 {#slower but lower memory usage
1091 # $iterargs = [$filename, $compressed, $opts];
1092 my $next = Archive
::Tar
->iter( @
$iterargs );
1093 while(my $e = $next->()){
1094 if($e->full_path eq $file){
1103 $self->_error( qq[No such file
in archive
: '$file'] );
1107 =head2
$tar->get_files( [@filenames] )
1109 Returns the C
<Archive
::Tar
::File
> objects matching the filenames
1110 provided
. If
no filename list was passed
, all C
<Archive
::Tar
::File
>
1111 objects
in the current Tar object are returned
.
1113 Please refer to the C
<Archive
::Tar
::File
> documentation on how to
1114 handle these objects
.
1121 return @
{ $self->_data } unless @_;
1124 for my $file ( @_ ) {
1125 push @list, grep { defined } $self->_find_entry( $file );
1131 =head2
$tar->get_content( $file )
1133 Return the content of the named file
.
1139 my $entry = $self->_find_entry( shift ) or return;
1141 return $entry->data;
1144 =head2
$tar->replace_content( $file, $content )
1146 Make the string
$content be the content
for the file named
$file.
1150 sub replace_content
{
1152 my $entry = $self->_find_entry( shift ) or return;
1154 return $entry->replace_content( shift );
1157 =head2
$tar->rename( $file, $new_name )
1159 Rename the file of the
in-memory archive to
$new_name.
1161 Note that you must specify a Unix path
for $new_name, since per tar
1162 standard
, all files
in the archive must be Unix paths
.
1164 Returns true on success
and false on failure
.
1170 my $file = shift; return unless defined $file;
1171 my $new = shift; return unless defined $new;
1173 my $entry = $self->_find_entry( $file ) or return;
1175 return $entry->rename( $new );
1178 =head2
$tar->chmod( $file, $mode )
1180 Change mode of
$file to
$mode.
1182 Returns true on success
and false on failure
.
1188 my $file = shift; return unless defined $file;
1189 my $mode = shift; return unless defined $mode && $mode =~ /^[0-7]{1,4}$/;
1190 my @args = ("$mode");
1192 my $entry = $self->_find_entry( $file ) or return;
1193 my $x = $entry->chmod( @args );
1197 =head2
$tar->chown( $file, $uname [, $gname] )
1199 Change owner
$file to
$uname and $gname.
1201 Returns true on success
and false on failure
.
1207 my $file = shift; return unless defined $file;
1208 my $uname = shift; return unless defined $uname;
1209 my @args = ($uname);
1212 my $entry = $self->_find_entry( $file ) or return;
1213 my $x = $entry->chown( @args );
1217 =head2
$tar->remove (@filenamelist)
1219 Removes any entries with names matching any of the
given filenames
1220 from the
in-memory archive
. Returns a list of C
<Archive
::Tar
::File
>
1221 objects that remain
.
1229 my %seen = map { $_->full_path => $_ } @
{$self->_data};
1230 delete $seen{ $_ } for @list;
1232 $self->_data( [values %seen] );
1234 return values %seen;
1239 C
<clear
> clears the current
in-memory archive
. This effectively gives
1240 you a
'blank' object
, ready to be filled again
. Note that C
<clear
>
1241 only has effect on the object
, not the underlying tarfile
.
1246 my $self = shift or return;
1255 =head2
$tar->write ( [$file, $compressed, $prefix] )
1257 Write the
in-memory archive to disk
. The first argument can either
1258 be the name of a file
or a reference to an already
open filehandle
(a
1261 The second argument is used to indicate compression
. You can either
1262 compress using C
<gzip
> or C
<bzip2
>. If you pass a digit
, it
's assumed
1263 to be the C<gzip> compression level (between 1 and 9), but the use of
1264 constants is preferred:
1266 # write a gzip compressed file
1267 $tar->write( 'out
.tgz
', COMPRESS_GZIP );
1269 # write a bzip compressed file
1270 $tar->write( 'out
.tbz
', COMPRESS_BZIP );
1272 Note that when you pass in a filehandle, the compression argument
1273 is ignored, as all files are printed verbatim to your filehandle.
1274 If you wish to enable compression with filehandles, use an
1275 C<IO::Zlib> or C<IO::Compress::Bzip2> filehandle instead.
1277 The third argument is an optional prefix. All files will be tucked
1278 away in the directory you specify as prefix. So if you have files
1279 'a
' and 'b
' in your archive, and you specify 'foo
' as prefix, they
1280 will be written to the archive as 'foo
/a' and 'foo/b
'.
1282 If no arguments are given, C<write> returns the entire formatted
1283 archive as a string, which could be useful if you'd like to stuff the
1284 archive into a
socket or a
pipe to gzip
or something
.
1291 my $file = shift; $file = '' unless defined $file;
1292 my $gzip = shift || 0;
1293 my $ext_prefix = shift; $ext_prefix = '' unless defined $ext_prefix;
1296 ### only need a handle if we have a file to print to ###
1297 my $handle = length($file)
1298 ?
( $self->_get_handle($file, $gzip, WRITE_ONLY
->($gzip) )
1300 : $HAS_PERLIO ?
do { open my $h, '>', \
$dummy; $h }
1301 : $HAS_IO_STRING ? IO
::String
->new
1302 : __PACKAGE__
->no_string_support();
1304 ### Addresses: #41798: Nonempty $\ when writing a TAR file produces a
1305 ### corrupt TAR file. Must clear out $\ to make sure no garbage is
1306 ### printed to the archive
1309 for my $entry ( @
{$self->_data} ) {
1310 ### entries to be written to the tarfile ###
1313 ### only now will we change the object to reflect the current state
1314 ### of the name and prefix fields -- this needs to be limited to
1316 my $clone = $entry->clone;
1319 ### so, if you don't want use to use the prefix, we'll stuff
1320 ### everything in the name field instead
1321 if( $DO_NOT_USE_PREFIX ) {
1323 ### you might have an extended prefix, if so, set it in the clone
1324 ### XXX is ::Unix right?
1325 $clone->name( length $ext_prefix
1326 ? File
::Spec
::Unix
->catdir( $ext_prefix,
1328 : $clone->full_path );
1329 $clone->prefix( '' );
1331 ### otherwise, we'll have to set it properly -- prefix part in the
1332 ### prefix and name part in the name field.
1335 ### split them here, not before!
1336 my ($prefix,$name) = $clone->_prefix_and_file( $clone->full_path );
1338 ### you might have an extended prefix, if so, set it in the clone
1339 ### XXX is ::Unix right?
1340 $prefix = File
::Spec
::Unix
->catdir( $ext_prefix, $prefix )
1341 if length $ext_prefix;
1343 $clone->prefix( $prefix );
1344 $clone->name( $name );
1347 ### names are too long, and will get truncated if we don't add a
1348 ### '@LongLink' file...
1349 my $make_longlink = ( length($clone->name) > NAME_LENGTH
or
1350 length($clone->prefix) > PREFIX_LENGTH
1353 ### perhaps we need to make a longlink file?
1354 if( $make_longlink ) {
1355 my $longlink = Archive
::Tar
::File
->new(
1356 data
=> LONGLINK_NAME
,
1358 { type
=> LONGLINK
}
1361 unless( $longlink ) {
1362 $self->_error( qq[Could
not create
'LongLink' entry
for ] .
1363 qq[oversize file
'] . $clone->full_path ."'" );
1367 push @write_me, $longlink;
1370 push @write_me, $clone;
1372 ### write the one, optionally 2 a::t::file objects to the handle
1373 for my $clone (@write_me) {
1375 ### if the file is a symlink, there are 2 options:
1376 ### either we leave the symlink intact, but then we don't write any
1377 ### data OR we follow the symlink, which means we actually make a
1378 ### copy. if we do the latter, we have to change the TYPE of the
1380 my $link_ok = $clone->is_symlink && $Archive::Tar::FOLLOW_SYMLINK;
1381 my $data_ok = !$clone->is_symlink && $clone->has_content;
1383 ### downgrade to a 'normal' file if it's a symlink we're going to
1384 ### treat as a regular file
1385 $clone->_downgrade_to_plainfile if $link_ok;
1387 ### get the header for this block
1388 my $header = $self->_format_tar_entry( $clone );
1390 $self->_error(q[Could not format header for: ] .
1391 $clone->full_path );
1395 unless( print $handle $header ) {
1396 $self->_error(q[Could not write header for: ] .
1401 if( $link_ok or $data_ok ) {
1402 unless( print $handle $clone->data ) {
1403 $self->_error(q[Could not write data for: ] .
1408 ### pad the end of the clone if required ###
1409 print $handle TAR_PAD->( $clone->size ) if $clone->size % BLOCK
1412 } ### done writing these entries
1415 ### write the end markers ###
1416 print $handle TAR_END x 2 or
1417 return $self->_error( qq[Could not write tar end markers] );
1419 ### did you want it written to a file, or returned as a string? ###
1420 my $rv = length($file) ? 1
1421 : $HAS_PERLIO ? $dummy
1422 : do { seek $handle, 0, 0; local $/; <$handle> };
1424 ### make sure to close the handle if we created it
1425 if ( $file ne $handle ) {
1426 unless( close $handle ) {
1427 $self->_error( qq[Could not write tar] );
1435 sub _format_tar_entry {
1437 my $entry = shift or return;
1438 my $ext_prefix = shift; $ext_prefix = '' unless defined $ext_prefix;
1439 my $no_prefix = shift || 0;
1441 my $file = $entry->name;
1442 my $prefix = $entry->prefix; $prefix = '' unless defined $prefix;
1444 ### remove the prefix from the file name
1445 ### not sure if this is still needed --kane
1446 ### no it's not -- Archive::Tar::File->_new_from_file will take care of
1447 ### this for us. Even worse, this would break if we tried to add a file
1449 #if( length $prefix ) {
1450 # $file =~ s/^$match//;
1453 $prefix = File::Spec::Unix->catdir($ext_prefix, $prefix)
1454 if length $ext_prefix;
1456 ### not sure why this is... ###
1457 my $l = PREFIX_LENGTH; # is ambiguous otherwise...
1458 substr ($prefix, 0, -$l) = "" if length $prefix >= PREFIX_LENGTH;
1460 my $f1 = "%06o"; my $f2 = $ZERO_PAD_NUMBERS ? "%011o" : "%11o";
1462 ### this might be optimizable with a 'changed' flag in the file objects ###
1467 (map { sprintf( $f1, $entry->$_() ) } qw[mode uid gid]),
1468 (map { sprintf( $f2, $entry->$_() ) } qw[size mtime]),
1470 "", # checksum field - space padded a bit down
1472 (map { $entry->$_() } qw[type linkname magic]),
1474 $entry->version || TAR_VERSION,
1476 (map { $entry->$_() } qw[uname gname]),
1477 (map { sprintf( $f1, $entry->$_() ) } qw[devmajor devminor]),
1479 ($no_prefix ? '' : $prefix)
1482 ### add the checksum ###
1483 my $checksum_fmt = $ZERO_PAD_NUMBERS ? "%06o\
0" : "%06o\
0";
1484 substr($tar,148,7) = sprintf("%6o\
0", unpack("%16C*",$tar));
1489 =head2 $tar->add_files( @filenamelist )
1491 Takes a list of filenames and adds them to the in-memory archive.
1493 The path to the file is automatically converted to a Unix like
1494 equivalent for use in the archive, and, if on MacOS, the file's
1495 modification time is converted from the MacOS epoch to the Unix epoch.
1496 So tar archives created on MacOS with B<Archive::Tar> can be read
1497 both with I<tar> on Unix and applications like I<suntar> or
1498 I<Stuffit Expander> on MacOS.
1500 Be aware that the file's type/creator and resource fork will be lost,
1501 which is usually what you want in cross-platform archives.
1503 Instead of a filename, you can also pass it an existing C<Archive::Tar::File>
1504 object from, for example, another archive. The object will be clone, and
1505 effectively be a copy of the original, not an alias.
1507 Returns a list of C<Archive::Tar::File> objects that were just added.
1513 my @files = @_ or return;
1516 for my $file ( @files ) {
1518 ### you passed an Archive::Tar::File object
1519 ### clone it so we don't accidentally have a reference to
1520 ### an object from another archive
1521 if( UNIVERSAL::isa( $file,'Archive::Tar::File' ) ) {
1522 push @rv, $file->clone;
1527 if( utf8::is_utf8( $file )) {
1528 utf8::encode( $file );
1532 unless( -e $file || -l $file ) {
1533 $self->_error( qq[No such file: '$file'] );
1537 my $obj = Archive::Tar::File->new( file => $file );
1539 $self->_error( qq[Unable to add file: '$file'] );
1546 push @{$self->{_data}}, @rv;
1551 =head2 $tar->add_data ( $filename, $data, [$opthashref] )
1553 Takes a filename, a scalar full of data and optionally a reference to
1554 a hash with specific options.
1556 Will add a file to the in-memory archive, with name C<$filename> and
1557 content C<$data>. Specific properties can be set using C<$opthashref>.
1558 The following list of properties is supported: name, size, mtime
1559 (last modified date), mode, uid, gid, linkname, uname, gname,
1560 devmajor, devminor, prefix, type. (On MacOS, the file's path and
1561 modification times are converted to Unix equivalents.)
1563 Valid values for the file type are the following constants defined by
1564 Archive::Tar::Constant:
1576 Hard and symbolic ("soft
") links; linkname should specify target.
1582 Character and block devices. devmajor and devminor should specify the major
1583 and minor device numbers.
1599 Returns the C<Archive::Tar::File> object that was just added, or
1600 C<undef> on failure.
1606 my ($file, $data, $opt) = @_;
1608 my $obj = Archive::Tar::File->new( data => $file, $data, $opt );
1610 $self->_error( qq[Unable to add file: '$file'] );
1614 push @{$self->{_data}}, $obj;
1619 =head2 $tar->error( [$BOOL] )
1621 Returns the current error string (usually, the last error reported).
1622 If a true value was specified, it will give the C<Carp::longmess>
1623 equivalent of the error, in effect giving you a stacktrace.
1625 For backwards compatibility, this error is also available as
1626 C<$Archive::Tar::error> although it is much recommended you use the
1627 method call instead.
1637 my $msg = $error = shift;
1638 $longmess = Carp::longmess($error);
1640 $self->{_error} = $error;
1641 $self->{_longmess} = $longmess;
1644 ### set Archive::Tar::WARN to 0 to disable printing
1647 carp $DEBUG ? $longmess : $msg;
1656 return shift() ? $self->{_longmess} : $self->{_error};
1658 return shift() ? $longmess : $error;
1663 =head2 $tar->setcwd( $cwd );
1665 C<Archive::Tar> needs to know the current directory, and it will run
1666 C<Cwd::cwd()> I<every> time it extracts a I<relative> entry from the
1667 tarfile and saves it in the file system. (As of version 1.30, however,
1668 C<Archive::Tar> will use the speed optimization described below
1669 automatically, so it's only relevant if you're using C<extract_file()>).
1671 Since C<Archive::Tar> doesn't change the current directory internally
1672 while it is extracting the items in a tarball, all calls to C<Cwd::cwd()>
1673 can be avoided if we can guarantee that the current directory doesn't
1674 get changed externally.
1676 To use this performance boost, set the current directory via
1679 $tar->setcwd( cwd() );
1681 once before calling a function like C<extract_file> and
1682 C<Archive::Tar> will use the current directory setting from then on
1683 and won't call C<Cwd::cwd()> internally.
1685 To switch back to the default behaviour, use
1687 $tar->setcwd( undef );
1689 and C<Archive::Tar> will call C<Cwd::cwd()> internally again.
1691 If you're using C<Archive::Tar>'s C<extract()> method, C<setcwd()> will
1700 $self->{cwd} = $cwd;
1703 =head1 Class Methods
1705 =head2 Archive::Tar->create_archive($file, $compressed, @filelist)
1707 Creates a tar file from the list of files provided. The first
1708 argument can either be the name of the tar file to create or a
1709 reference to an open file handle (e.g. a GLOB reference).
1711 The second argument is used to indicate compression. You can either
1712 compress using C<gzip> or C<bzip2>. If you pass a digit, it's assumed
1713 to be the C<gzip> compression level (between 1 and 9), but the use of
1714 constants is preferred:
1716 # write a gzip compressed file
1717 Archive::Tar->create_archive( 'out.tgz', COMPRESS_GZIP, @filelist );
1719 # write a bzip compressed file
1720 Archive::Tar->create_archive( 'out.tbz', COMPRESS_BZIP, @filelist );
1722 Note that when you pass in a filehandle, the compression argument
1723 is ignored, as all files are printed verbatim to your filehandle.
1724 If you wish to enable compression with filehandles, use an
1725 C<IO::Zlib> or C<IO::Compress::Bzip2> filehandle instead.
1727 The remaining arguments list the files to be included in the tar file.
1728 These files must all exist. Any files which don't exist or can't be
1729 read are silently ignored.
1731 If the archive creation fails for any reason, C<create_archive> will
1732 return false. Please use the C<error> method to find the cause of the
1735 Note that this method does not write C<on the fly> as it were; it
1736 still reads all the files into memory before writing out the archive.
1737 Consult the FAQ below if this is a problem.
1741 sub create_archive {
1744 my $file = shift; return unless defined $file;
1745 my $gzip = shift || 0;
1749 return $class->_error( qq[Cowardly refusing to create empty archive!] );
1752 my $tar = $class->new;
1753 $tar->add_files( @files );
1754 return $tar->write( $file, $gzip );
1757 =head2 Archive::Tar->iter( $filename, [ $compressed, {opt => $val} ] )
1759 Returns an iterator function that reads the tar file without loading
1760 it all in memory. Each time the function is called it will return the
1761 next file in the tarball. The files are returned as
1762 C<Archive::Tar::File> objects. The iterator function returns the
1763 empty list once it has exhausted the files contained.
1765 The second argument can be a hash reference with options, which are
1766 identical to the arguments passed to C<read()>.
1770 my $next = Archive::Tar->iter( "example
.tar
.gz
", 1, {filter => qr/\.pm$/} );
1772 while( my $f = $next->() ) {
1773 print $f->name, "\n";
1775 $f->extract or warn "Extraction failed
";
1785 my $filename = shift or return;
1786 my $compressed = shift || 0;
1787 my $opts = shift || {};
1789 ### get a handle to read from.
1790 my $handle = $class->_get_handle(
1797 my $CONSTRUCT_ARGS = [ $filename, $compressed, $opts ];
1799 return shift(@data) if @data; # more than one file returned?
1800 return unless $handle; # handle exhausted?
1802 ### read data, should only return file
1803 my $tarfile = $class->_read_tar($handle, { %$opts, limit => 1 });
1804 @data = @$tarfile if ref $tarfile && ref $tarfile eq 'ARRAY';
1805 if($Archive::Tar::RESOLVE_SYMLINK!~/none/){
1807 #may refine this heuristic for ON_UNIX?
1809 #is there a better slot to store/share it ?
1810 $_->{'_archive'} = $CONSTRUCT_ARGS;
1815 ### return one piece of data
1816 return shift(@data) if @data;
1818 ### data is exhausted, free the filehandle
1820 if(@$CONSTRUCT_ARGS == 4){
1821 #free archive in memory
1822 undef $CONSTRUCT_ARGS->[-1];
1828 =head2 Archive::Tar->list_archive($file, $compressed, [\@properties])
1830 Returns a list of the names of all the files in the archive. The
1831 first argument can either be the name of the tar file to list or a
1832 reference to an open file handle (e.g. a GLOB reference).
1834 If C<list_archive()> is passed an array reference as its third
1835 argument it returns a list of hash references containing the requested
1836 properties of each file. The following list of properties is
1837 supported: full_path, name, size, mtime (last modified date), mode,
1838 uid, gid, linkname, uname, gname, devmajor, devminor, prefix, type.
1840 See C<Archive::Tar::File> for details about supported properties.
1842 Passing an array reference containing only one element, 'name', is
1843 special cased to return a list of names rather than a list of hash
1850 my $file = shift; return unless defined $file;
1851 my $gzip = shift || 0;
1853 my $tar = $class->new($file, $gzip);
1856 return $tar->list_files( @_ );
1859 =head2 Archive::Tar->extract_archive($file, $compressed)
1861 Extracts the contents of the tar file. The first argument can either
1862 be the name of the tar file to create or a reference to an open file
1863 handle (e.g. a GLOB reference). All relative paths in the tar file will
1864 be created underneath the current working directory.
1866 C<extract_archive> will return a list of files it extracted.
1867 If the archive extraction fails for any reason, C<extract_archive>
1868 will return false. Please use the C<error> method to find the cause
1873 sub extract_archive {
1875 my $file = shift; return unless defined $file;
1876 my $gzip = shift || 0;
1878 my $tar = $class->new( ) or return;
1880 return $tar->read( $file, $gzip, { extract => 1 } );
1883 =head2 $bool = Archive::Tar->has_io_string
1885 Returns true if we currently have C<IO::String> support loaded.
1887 Either C<IO::String> or C<perlio> support is needed to support writing
1888 stringified archives. Currently, C<perlio> is the preferred method, if
1891 See the C<GLOBAL VARIABLES> section to see how to change this preference.
1895 sub has_io_string { return $HAS_IO_STRING; }
1897 =head2 $bool = Archive::Tar->has_perlio
1899 Returns true if we currently have C<perlio> support loaded.
1901 This requires C<perl-5.8> or higher, compiled with C<perlio>
1903 Either C<IO::String> or C<perlio> support is needed to support writing
1904 stringified archives. Currently, C<perlio> is the preferred method, if
1907 See the C<GLOBAL VARIABLES> section to see how to change this preference.
1911 sub has_perlio { return $HAS_PERLIO; }
1913 =head2 $bool = Archive::Tar->has_zlib_support
1915 Returns true if C<Archive::Tar> can extract C<zlib> compressed archives
1919 sub has_zlib_support { return ZLIB }
1921 =head2 $bool = Archive::Tar->has_bzip2_support
1923 Returns true if C<Archive::Tar> can extract C<bzip2> compressed archives
1927 sub has_bzip2_support { return BZIP }
1929 =head2 Archive::Tar->can_handle_compressed_files
1931 A simple checking routine, which will return true if C<Archive::Tar>
1932 is able to uncompress compressed archives on the fly with C<IO::Zlib>
1933 and C<IO::Compress::Bzip2> or false if not both are installed.
1935 You can use this as a shortcut to determine whether C<Archive::Tar>
1936 will do what you think before passing compressed archives to its
1941 sub can_handle_compressed_files { return ZLIB && BZIP ? 1 : 0 }
1943 sub no_string_support {
1944 croak("You have to install IO
::String to support writing archives to strings
");
1947 sub _symlinks_resolver{
1948 my ($src, $trg) = @_;
1949 my @src = split /[\/\\]/, $src;
1950 my @trg = split /[\/\\]/, $trg;
1951 pop @src; #strip out current object name
1952 if(@trg and $trg[0] eq ''){
1954 #restart path from scratch
1957 foreach my $part ( @trg ){
1958 next if $part eq '.'; #ignore current
1968 my $path = join('/', @src);
1969 warn "_symlinks_resolver
('$src','$trg') = $path" if $DEBUG;
1977 =head1 GLOBAL VARIABLES
1979 =head2 $Archive::Tar::FOLLOW_SYMLINK
1981 Set this variable to C<1> to make C<Archive::Tar> effectively make a
1982 copy of the file when extracting. Default is C<0>, which
1983 means the symlink stays intact. Of course, you will have to pack the
1984 file linked to as well.
1986 This option is checked when you write out the tarfile using C<write>
1987 or C<create_archive>.
1989 This works just like C</bin/tar>'s C<-h> option.
1991 =head2 $Archive::Tar::CHOWN
1993 By default, C<Archive::Tar> will try to C<chown> your files if it is
1994 able to. In some cases, this may not be desired. In that case, set
1995 this variable to C<0> to disable C<chown>-ing, even if it were
1998 The default is C<1>.
2000 =head2 $Archive::Tar::CHMOD
2002 By default, C<Archive::Tar> will try to C<chmod> your files to
2003 whatever mode was specified for the particular file in the archive.
2004 In some cases, this may not be desired. In that case, set this
2005 variable to C<0> to disable C<chmod>-ing.
2007 The default is C<1>.
2009 =head2 $Archive::Tar::SAME_PERMISSIONS
2011 When, C<$Archive::Tar::CHMOD> is enabled, this setting controls whether
2012 the permissions on files from the archive are used without modification
2013 of if they are filtered by removing any setid bits and applying the
2016 The default is C<1> for the root user and C<0> for normal users.
2018 =head2 $Archive::Tar::DO_NOT_USE_PREFIX
2020 By default, C<Archive::Tar> will try to put paths that are over
2021 100 characters in the C<prefix> field of your tar header, as
2022 defined per POSIX-standard. However, some (older) tar programs
2023 do not implement this spec. To retain compatibility with these older
2024 or non-POSIX compliant versions, you can set the C<$DO_NOT_USE_PREFIX>
2025 variable to a true value, and C<Archive::Tar> will use an alternate
2026 way of dealing with paths over 100 characters by using the
2027 C<GNU Extended Header> feature.
2029 Note that clients who do not support the C<GNU Extended Header>
2030 feature will not be able to read these archives. Such clients include
2031 tars on C<Solaris>, C<Irix> and C<AIX>.
2033 The default is C<0>.
2035 =head2 $Archive::Tar::DEBUG
2037 Set this variable to C<1> to always get the C<Carp::longmess> output
2038 of the warnings, instead of the regular C<carp>. This is the same
2039 message you would get by doing:
2045 =head2 $Archive::Tar::WARN
2047 Set this variable to C<0> if you do not want any warnings printed.
2048 Personally I recommend against doing this, but people asked for the
2049 option. Also, be advised that this is of course not threadsafe.
2053 =head2 $Archive::Tar::error
2055 Holds the last reported error. Kept for historical reasons, but its
2056 use is very much discouraged. Use the C<error()> method instead:
2058 warn $tar->error unless $tar->extract;
2060 Note that in older versions of this module, the C<error()> method
2061 would return an effectively global value even when called an instance
2062 method as above. This has since been fixed, and multiple instances of
2063 C<Archive::Tar> now have separate error strings.
2065 =head2 $Archive::Tar::INSECURE_EXTRACT_MODE
2067 This variable indicates whether C<Archive::Tar> should allow
2068 files to be extracted outside their current working directory.
2070 Allowing this could have security implications, as a malicious
2071 tar archive could alter or replace any file the extracting user
2072 has permissions to. Therefor, the default is to not allow
2073 insecure extractions.
2075 If you trust the archive, or have other reasons to allow the
2076 archive to write files outside your current working directory,
2077 set this variable to C<true>.
2079 Note that this is a backwards incompatible change from version
2082 =head2 $Archive::Tar::HAS_PERLIO
2084 This variable holds a boolean indicating if we currently have
2085 C<perlio> support loaded. This will be enabled for any perl
2086 greater than C<5.8> compiled with C<perlio>.
2088 If you feel strongly about disabling it, set this variable to
2089 C<false>. Note that you will then need C<IO::String> installed
2090 to support writing stringified archives.
2092 Don't change this variable unless you B<really> know what you're
2095 =head2 $Archive::Tar::HAS_IO_STRING
2097 This variable holds a boolean indicating if we currently have
2098 C<IO::String> support loaded. This will be enabled for any perl
2099 that has a loadable C<IO::String> module.
2101 If you feel strongly about disabling it, set this variable to
2102 C<false>. Note that you will then need C<perlio> support from
2103 your perl to be able to write stringified archives.
2105 Don't change this variable unless you B<really> know what you're
2108 =head2 $Archive::Tar::ZERO_PAD_NUMBERS
2110 This variable holds a boolean indicating if we will create
2111 zero padded numbers for C<size>, C<mtime> and C<checksum>.
2112 The default is C<0>, indicating that we will create space padded
2113 numbers. Added for compatibility with C<busybox> implementations.
2115 =head2 Tuning the way RESOLVE_SYMLINK will works
2117 You can tune the behaviour by setting the $Archive::Tar::RESOLVE_SYMLINK variable,
2118 or $ENV{PERL5_AT_RESOLVE_SYMLINK} before loading the module Archive::Tar.
2120 Values can be one of the following:
2123 Disable this mechanism and failed as it was in previous version (<1.88)
2127 this will read again the whole archive using read() so all entries
2131 If you prefer memory
2135 It won't work for terminal, pipe or sockets or every non seekable source.
2143 =item What's the minimum perl version required to run Archive::Tar?
2145 You will need perl version 5.005_03 or newer.
2147 =item Isn't Archive::Tar slow?
2149 Yes it is. It's pure perl, so it's a lot slower then your C</bin/tar>
2150 However, it's very portable. If speed is an issue, consider using
2151 C</bin/tar> instead.
2153 =item Isn't Archive::Tar heavier on memory than /bin/tar?
2155 Yes it is, see previous answer. Since C<Compress::Zlib> and therefore
2156 C<IO::Zlib> doesn't support C<seek> on their filehandles, there is little
2157 choice but to read the archive into memory.
2158 This is ok if you want to do in-memory manipulation of the archive.
2160 If you just want to extract, use the C<extract_archive> class method
2161 instead. It will optimize and write to disk immediately.
2163 Another option is to use the C<iter> class method to iterate over
2164 the files in the tarball without reading them all in memory at once.
2166 =item Can you lazy-load data instead?
2168 In some cases, yes. You can use the C<iter> class method to iterate
2169 over the files in the tarball without reading them all in memory at once.
2171 =item How much memory will an X kb tar file need?
2173 Probably more than X kb, since it will all be read into memory. If
2174 this is a problem, and you don't need to do in memory manipulation
2175 of the archive, consider using the C<iter> class method, or C</bin/tar>
2178 =item What do you do with unsupported filetypes in an archive?
2180 C<Unix> has a few filetypes that aren't supported on other platforms,
2181 like C<Win32>. If we encounter a C<hardlink> or C<symlink> we'll just
2182 try to make a copy of the original file, rather than throwing an error.
2184 This does require you to read the entire archive in to memory first,
2185 since otherwise we wouldn't know what data to fill the copy with.
2186 (This means that you cannot use the class methods, including C<iter>
2187 on archives that have incompatible filetypes and still expect things
2190 For other filetypes, like C<chardevs> and C<blockdevs> we'll warn that
2191 the extraction of this particular item didn't work.
2193 =item I'm using WinZip, or some other non-POSIX client, and files are not being extracted properly!
2195 By default, C<Archive::Tar> is in a completely POSIX-compatible
2196 mode, which uses the POSIX-specification of C<tar> to store files.
2197 For paths greater than 100 characters, this is done using the
2198 C<POSIX header prefix>. Non-POSIX-compatible clients may not support
2199 this part of the specification, and may only support the C<GNU Extended
2200 Header> functionality. To facilitate those clients, you can set the
2201 C<$Archive::Tar::DO_NOT_USE_PREFIX> variable to C<true>. See the
2202 C<GLOBAL VARIABLES> section for details on this variable.
2204 Note that GNU tar earlier than version 1.14 does not cope well with
2205 the C<POSIX header prefix>. If you use such a version, consider setting
2206 the C<$Archive::Tar::DO_NOT_USE_PREFIX> variable to C<true>.
2208 =item How do I extract only files that have property X from an archive?
2210 Sometimes, you might not wish to extract a complete archive, just
2211 the files that are relevant to you, based on some criteria.
2213 You can do this by filtering a list of C<Archive::Tar::File> objects
2214 based on your criteria. For example, to extract only files that have
2215 the string C<foo> in their title, you would use:
2218 grep { $_->full_path =~ /foo/ } $tar->get_files
2221 This way, you can filter on any attribute of the files in the archive.
2222 Consult the C<Archive::Tar::File> documentation on how to use these
2225 =item How do I access .tar.Z files?
2227 The C<Archive::Tar> module can optionally use C<Compress::Zlib> (via
2228 the C<IO::Zlib> module) to access tar files that have been compressed
2229 with C<gzip>. Unfortunately tar files compressed with the Unix C<compress>
2230 utility cannot be read by C<Compress::Zlib> and so cannot be directly
2231 accesses by C<Archive::Tar>.
2233 If the C<uncompress> or C<gunzip> programs are available, you can use
2234 one of these workarounds to read C<.tar.Z> files from C<Archive::Tar>
2236 Firstly with C<uncompress>
2240 open F, "uncompress
-c
$filename |";
2241 my $tar = Archive::Tar->new(*F);
2244 and this with C<gunzip>
2248 open F, "gunzip
-c
$filename |";
2249 my $tar = Archive::Tar->new(*F);
2252 Similarly, if the C<compress> program is available, you can use this to
2253 write a C<.tar.Z> file
2258 my $fh = new IO::File "| compress
-c
>$filename";
2259 my $tar = Archive::Tar->new();
2264 =item How do I handle Unicode strings?
2266 C<Archive::Tar> uses byte semantics for any files it reads from or writes
2267 to disk. This is not a problem if you only deal with files and never
2268 look at their content or work solely with byte strings. But if you use
2269 Unicode strings with character semantics, some additional steps need
2272 For example, if you add a Unicode string like
2275 $tar->add_data('file.txt', "Euro
: \x
{20AC
}");
2277 then there will be a problem later when the tarfile gets written out
2278 to disk via C<$tar->write()>:
2280 Wide character in print at .../Archive/Tar.pm line 1014.
2282 The data was added as a Unicode string and when writing it out to disk,
2283 the C<:utf8> line discipline wasn't set by C<Archive::Tar>, so Perl
2284 tried to convert the string to ISO-8859 and failed. The written file
2285 now contains garbage.
2287 For this reason, Unicode strings need to be converted to UTF-8-encoded
2288 bytestrings before they are handed off to C<add_data()>:
2291 my $data = "Accented character
: \x
{20AC
}";
2292 $data = encode('utf8', $data);
2294 $tar->add_data('file.txt', $data);
2296 A opposite problem occurs if you extract a UTF8-encoded file from a
2297 tarball. Using C<get_content()> on the C<Archive::Tar::File> object
2298 will return its content as a bytestring, not as a Unicode string.
2300 If you want it to be a Unicode string (because you want character
2301 semantics with operations like regular expression matching), you need
2302 to decode the UTF8-encoded content and have Perl convert it into
2306 my $data = $tar->get_content();
2308 # Make it a Unicode string
2309 $data = decode('utf8', $data);
2311 There is no easy way to provide this functionality in C<Archive::Tar>,
2312 because a tarball can contain many files, and each of which could be
2313 encoded in a different way.
2319 The AIX tar does not fill all unused space in the tar archive with 0x00.
2320 This sometimes leads to warning messages from C<Archive::Tar>.
2322 Invalid header block at offset nnn
2324 A fix for that problem is scheduled to be released in the following levels
2325 of AIX, all of which should be coming out in the 4th quarter of 2009:
2337 The IBM APAR number for this problem is IZ50240 (Reported component ID:
2338 5765G0300 / AIX 5.3). It is possible to get an ifix for that problem.
2339 If you need an ifix please contact your local IBM AIX support.
2345 =item Check if passed in handles are open for read/write
2347 Currently I don't know of any portable pure perl way to do this.
2348 Suggestions welcome.
2350 =item Allow archives to be passed in as string
2352 Currently, we only allow opened filehandles or filenames, but
2353 not strings. The internals would need some reworking to facilitate
2354 stringified archives.
2356 =item Facilitate processing an opened filehandle of a compressed archive
2358 Currently, we only support this if the filehandle is an IO::Zlib object.
2359 Environments, like apache, will present you with an opened filehandle
2360 to an uploaded file, which might be a compressed archive.
2368 =item The GNU tar specification
2370 C<http://www.gnu.org/software/tar/manual/tar.html>
2372 =item The PAX format specification
2374 The specification which tar derives from; C< http://www.opengroup.org/onlinepubs/007904975/utilities/pax.html>
2376 =item A comparison of GNU and POSIX tar standards; C<http://www.delorie.com/gnu/docs/tar/tar_114.html>
2378 =item GNU tar intends to switch to POSIX compatibility
2380 GNU Tar authors have expressed their intention to become completely
2381 POSIX-compatible; C<http://www.gnu.org/software/tar/manual/html_node/Formats.html>
2383 =item A Comparison between various tar implementations
2385 Lists known issues and incompatibilities; C<http://gd.tuwien.ac.at/utils/archivers/star/README.otherbugs>
2391 This module by Jos Boumans E<lt>kane@cpan.orgE<gt>.
2393 Please reports bugs to E<lt>bug-archive-tar@rt.cpan.orgE<gt>.
2395 =head1 ACKNOWLEDGEMENTS
2397 Thanks to Sean Burke, Chris Nandor, Chip Salzenberg, Tim Heaney, Gisle Aas,
2398 Rainer Tammer and especially Andrew Savige for their help and suggestions.
2402 This module is copyright (c) 2002 - 2009 Jos Boumans
2403 E<lt>kane@cpan.orgE<gt>. All rights reserved.
2405 This library is free software; you may redistribute and/or modify
2406 it under the same terms as Perl itself.
2415 'Archive/Tar/Constant.pm' => <<'END_OF_FILE',
2416 package Archive::Tar::Constant;
2421 $VERSION = '2.04_01';
2422 @ISA = qw[Exporter];
2424 require Time::Local if $^O eq "MacOS
";
2427 @EXPORT = Archive::Tar::Constant->_list_consts( __PACKAGE__ );
2429 use constant FILE => 0;
2430 use constant HARDLINK => 1;
2431 use constant SYMLINK => 2;
2432 use constant CHARDEV => 3;
2433 use constant BLOCKDEV => 4;
2434 use constant DIR => 5;
2435 use constant FIFO => 6;
2436 use constant SOCKET => 8;
2437 use constant UNKNOWN => 9;
2438 use constant LONGLINK => 'L';
2439 use constant LABEL => 'V';
2441 use constant BUFFER => 4096;
2442 use constant HEAD => 512;
2443 use constant BLOCK => 512;
2445 use constant COMPRESS_GZIP => 9;
2446 use constant COMPRESS_BZIP => 'bzip2';
2448 use constant BLOCK_SIZE => sub { my $n = int($_[0]/BLOCK); $n++ if $_[0] % BLOCK; $n * BLOCK };
2449 use constant TAR_PAD => sub { my $x = shift || return; return "\
0" x (BLOCK - ($x % BLOCK) ) };
2450 use constant TAR_END => "\
0" x BLOCK;
2452 use constant READ_ONLY => sub { shift() ? 'rb' : 'r' };
2453 use constant WRITE_ONLY => sub { $_[0] ? 'wb' . shift : 'w' };
2454 use constant MODE_READ => sub { $_[0] =~ /^r/ ? 1 : 0 };
2456 # Pointless assignment to make -w shut up
2457 my $getpwuid; $getpwuid = 'unknown' unless eval { my $f = getpwuid (0); };
2458 my $getgrgid; $getgrgid = 'unknown' unless eval { my $f = getgrgid (0); };
2459 use constant UNAME => sub { $getpwuid || scalar getpwuid( shift() ) || '' };
2460 use constant GNAME => sub { $getgrgid || scalar getgrgid( shift() ) || '' };
2461 use constant UID => $>;
2462 use constant GID => (split ' ', $) )[0];
2464 use constant MODE => do { 0666 & (0777 & ~umask) };
2465 use constant STRIP_MODE => sub { shift() & 0777 };
2466 use constant CHECK_SUM => " ";
2468 use constant UNPACK => 'A100 A8 A8 A8 a12 A12 A8 A1 A100 A6 A2 A32 A32 A8 A8 A155 x12'; # cdrake - size must be a12 - not A12 - or else screws up huge file sizes (>8gb)
2469 use constant PACK => 'a100 a8 a8 a8 a12 a12 A8 a1 a100 a6 a2 a32 a32 a8 a8 a155 x12';
2470 use constant NAME_LENGTH => 100;
2471 use constant PREFIX_LENGTH => 155;
2473 use constant TIME_OFFSET => ($^O eq "MacOS
") ? Time::Local::timelocal(0,0,0,1,0,70) : 0;
2474 use constant MAGIC => "ustar
";
2475 use constant TAR_VERSION => "00";
2476 use constant LONGLINK_NAME => '././@LongLink';
2477 use constant PAX_HEADER => 'pax_global_header';
2479 ### allow ZLIB to be turned off using ENV: DEBUG only
2480 use constant ZLIB => do { !$ENV{'PERL5_AT_NO_ZLIB'} and
2481 eval { require IO::Zlib };
2482 $ENV{'PERL5_AT_NO_ZLIB'} || $@ ? 0 : 1
2485 ### allow BZIP to be turned off using ENV: DEBUG only
2486 use constant BZIP => do { !$ENV{'PERL5_AT_NO_BZIP'} and
2487 eval { require IO::Uncompress::Bunzip2;
2488 require IO::Compress::Bzip2; };
2489 $ENV{'PERL5_AT_NO_BZIP'} || $@ ? 0 : 1
2492 use constant GZIP_MAGIC_NUM => qr/^(?:\037\213|\037\235)/;
2493 use constant BZIP_MAGIC_NUM => qr/^BZh\d/;
2495 use constant CAN_CHOWN => sub { ($> == 0 and $^O ne "MacOS
" and $^O ne "MSWin32
") };
2496 use constant CAN_READLINK => ($^O ne 'MSWin32' and $^O !~ /RISC(?:[ _])?OS/i and $^O ne 'VMS');
2497 use constant ON_UNIX => ($^O ne 'MSWin32' and $^O ne 'MacOS' and $^O ne 'VMS');
2498 use constant ON_VMS => $^O eq 'VMS';
2503 return unless defined $pkg; # some joker might use '0' as a pkg...
2507 my $stash = $pkg . '::';
2509 for my $name (sort keys %$stash ) {
2511 ### is it a subentry?
2512 my $sub = $pkg->can( $name );
2513 next unless defined $sub;
2515 next unless defined prototype($sub) and
2516 not length prototype($sub);
2532 'Archive/Tar/File.pm' => <<'END_OF_FILE',
2533 package Archive::Tar::File;
2538 use File::Spec::Unix ();
2540 use File::Basename ();
2542 ### avoid circular use, so only require;
2543 require Archive::Tar;
2544 use Archive::Tar::Constant;
2546 use vars qw[@ISA $VERSION];
2547 #@ISA = qw[Archive::Tar];
2548 $VERSION = '2.04_01';
2550 ### set value to 1 to oct() it during the unpack ###
2553 name => 0, # string A100
2554 mode => 1, # octal A8
2555 uid => 1, # octal A8
2556 gid => 1, # octal A8
2557 size => 0, # octal # cdrake - not *always* octal.. A12
2558 mtime => 1, # octal A12
2559 chksum => 1, # octal A8
2560 type => 0, # character A1
2561 linkname => 0, # string A100
2562 magic => 0, # string A6
2563 version => 0, # 2 bytes A2
2564 uname => 0, # string A32
2565 gname => 0, # string A32
2566 devmajor => 1, # octal A8
2567 devminor => 1, # octal A8
2568 prefix => 0, # A155 x 12
2570 ### end UNPACK items ###
2571 raw => 0, # the raw data chunk
2572 data => 0, # the data associated with the file --
2573 # This might be very memory intensive
2576 ### install get/set accessors for this object.
2577 for ( my $i=0; $i<scalar @$tmpl ; $i+=2 ) {
2578 my $key = $tmpl->[$i];
2580 *{__PACKAGE__."::$key"} = sub {
2582 $self->{$key} = $_[0] if @_;
2584 ### just in case the key is not there or undef or something ###
2586 return $self->{$key};
2593 Archive::Tar::File - a subclass for in-memory extracted file from Archive::Tar
2597 my @items = $tar->get_files;
2599 print $_->name, ' ', $_->size, "\n" for @items;
2601 print $object->get_content;
2602 $object->replace_content('new content');
2604 $object->rename( 'new/full/path/to/file.c' );
2608 Archive::Tar::Files provides a neat little object layer for in-memory
2609 extracted files. It's mostly used internally in Archive::Tar to tidy
2610 up the code, but there's no reason users shouldn't use this API as
2615 A lot of the methods in this package are accessors to the various
2616 fields in the tar header:
2630 The user id owning the file
2634 The group id owning the file
2642 Modification time. Adjusted to mac-time on MacOS if required
2646 Checksum field for the tar header
2650 File type -- numeric, but comparable to exported constants -- see
2651 Archive::Tar's documentation
2655 If the file is a symlink, the file it's pointing to
2659 Tar magic string -- not useful for most users
2663 Tar version string -- not useful for most users
2667 The user name that owns the file
2671 The group name that owns the file
2675 Device major number in case of a special file
2679 Device minor number in case of a special file
2683 Any directory to prefix to the extraction path, if any
2687 Raw tar header -- not useful for most users
2693 =head2 Archive::Tar::File->new( file => $path )
2695 Returns a new Archive::Tar::File object from an existing file.
2697 Returns undef on failure.
2699 =head2 Archive::Tar::File->new( data => $path, $data, $opt )
2701 Returns a new Archive::Tar::File object from data.
2703 C<$path> defines the file name (which need not exist), C<$data> the
2704 file contents, and C<$opt> is a reference to a hash of attributes
2705 which may be used to override the default attributes (fields in the
2706 tar header), which are described above in the Accessors section.
2708 Returns undef on failure.
2710 =head2 Archive::Tar::File->new( chunk => $chunk )
2712 Returns a new Archive::Tar::File object from a raw 512-byte tar
2715 Returns undef on failure.
2723 my $obj = ($what eq 'chunk') ? __PACKAGE__->_new_from_chunk( @_ ) :
2724 ($what eq 'file' ) ? __PACKAGE__->_new_from_file( @_ ) :
2725 ($what eq 'data' ) ? __PACKAGE__->_new_from_data( @_ ) :
2731 ### copies the data, creates a clone ###
2734 return bless { %$self }, ref $self;
2737 sub _new_from_chunk {
2739 my $chunk = shift or return; # 512 bytes of tar header
2742 ### filter any arguments on defined-ness of values.
2743 ### this allows overriding from what the tar-header is saying
2744 ### about this tar-entry. Particularly useful for @LongLink files
2745 my %args = map { $_ => $hash{$_} } grep { defined $hash{$_} } keys %hash;
2747 ### makes it start at 0 actually... :) ###
2750 my ($s,$v)=($tmpl->[++$i],$tmpl->[++$i]); # cdrake
2751 ($_)=($_=~/^([^\0]*)/) unless($s eq 'size'); # cdrake
2752 $s=> $v ? oct $_ : $_ # cdrake
2753 # $tmpl->[++$i] => $tmpl->[++$i] ? oct $_ : $_ # removed by cdrake - mucks up binary sizes >8gb
2754 } unpack( UNPACK, $chunk ); # cdrake
2755 # } map { /^([^\0]*)/ } unpack( UNPACK, $chunk ); # old - replaced now by cdrake
2758 if(substr($entry{'size'}, 0, 1) eq "\x80") { # binary size extension for files >8gigs (> octal 77777777777777) # cdrake
2759 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
2761 ($entry{'size'})=($entry{'size'}=~/^([^\0]*)/); $entry{'size'}=oct $entry{'size'}; # cdrake
2765 my $obj = bless { %entry, %args }, $class;
2767 ### magic is a filetype string.. it should have something like 'ustar' or
2768 ### something similar... if the chunk is garbage, skip it
2769 return unless $obj->magic !~ /\W/;
2771 ### store the original chunk ###
2772 $obj->raw( $chunk );
2774 $obj->type(FILE) if ( (!length $obj->type) or ($obj->type =~ /\W/) );
2775 $obj->type(DIR) if ( ($obj->is_file) && ($obj->name =~ m|/$|) );
2782 sub _new_from_file {
2786 ### path has to at least exist
2787 return unless defined $path;
2789 my $type = __PACKAGE__->_filetype($path);
2793 unless ($type == DIR ) {
2794 my $fh = IO::File->new;
2796 unless( $fh->open($path) ) {
2797 ### dangling symlinks are fine, stop reading but continue
2798 ### creating the object
2799 last READ if $type == SYMLINK;
2801 ### otherwise, return from this function --
2802 ### anything that's *not* a symlink should be
2807 ### binmode needed to read files properly on win32 ###
2809 $data = do { local $/; <$fh> };
2814 my @items = qw[mode uid gid size mtime];
2815 my %hash = map { shift(@items), $_ } (lstat $path)[2,4,5,7,9];
2818 ### VMS has two UID modes, traditional and POSIX. Normally POSIX is
2819 ### not used. We currently do not have an easy way to see if we are in
2820 ### POSIX mode. In traditional mode, the UID is actually the VMS UIC.
2821 ### The VMS UIC has the upper 16 bits is the GID, which in many cases
2822 ### the VMS UIC will be larger than 209715, the largest that TAR can
2823 ### handle. So for now, assume it is traditional if the UID is larger
2826 if ($hash{uid} > 0x10000) {
2827 $hash{uid} = $hash{uid} & 0xFFFF;
2830 ### The file length from stat() is the physical length of the file
2831 ### However the amount of data read in may be more for some file types.
2832 ### Fixed length files are read past the logical EOF to end of the block
2833 ### containing. Other file types get expanded on read because record
2834 ### delimiters are added.
2836 my $data_len = length $data;
2837 $hash{size} = $data_len if $hash{size} < $data_len;
2840 ### you *must* set size == 0 on symlinks, or the next entry will be
2841 ### though of as the contents of the symlink, which is wrong.
2842 ### this fixes bug #7937
2843 $hash{size} = 0 if ($type == DIR or $type == SYMLINK);
2844 $hash{mtime} -= TIME_OFFSET;
2846 ### strip the high bits off the mode, which we don't need to store
2847 $hash{mode} = STRIP_MODE->( $hash{mode} );
2850 ### probably requires some file path munging here ... ###
2851 ### name and prefix are set later
2855 chksum => CHECK_SUM,
2857 linkname => ($type == SYMLINK and CAN_READLINK)
2861 version => TAR_VERSION,
2862 uname => UNAME->( $hash{uid} ),
2863 gname => GNAME->( $hash{gid} ),
2864 devmajor => 0, # not handled
2865 devminor => 0, # not handled
2872 ### fix up the prefix and file from the path
2873 my($prefix,$file) = $obj->_prefix_and_file( $path );
2874 $obj->prefix( $prefix );
2875 $obj->name( $file );
2880 sub _new_from_data {
2882 my $path = shift; return unless defined $path;
2883 my $data = shift; return unless defined $data;
2892 size => length $data,
2893 mtime => time - TIME_OFFSET,
2894 chksum => CHECK_SUM,
2898 version => TAR_VERSION,
2899 uname => UNAME->( UID ),
2900 gname => GNAME->( GID ),
2906 ### overwrite with user options, if provided ###
2907 if( $opt and ref $opt eq 'HASH' ) {
2908 for my $key ( keys %$opt ) {
2910 ### don't write bogus options ###
2911 next unless exists $obj->{$key};
2912 $obj->{$key} = $opt->{$key};
2918 ### fix up the prefix and file from the path
2919 my($prefix,$file) = $obj->_prefix_and_file( $path );
2920 $obj->prefix( $prefix );
2921 $obj->name( $file );
2926 sub _prefix_and_file {
2930 my ($vol, $dirs, $file) = File::Spec->splitpath( $path, $self->is_dir );
2931 my @dirs = File::Spec->splitdir( $dirs );
2933 ### so sometimes the last element is '' -- probably when trailing
2934 ### dir slashes are encountered... this is of course pointless,
2936 pop @dirs while @dirs and not length $dirs[-1];
2938 ### if it's a directory, then $file might be empty
2939 $file = pop @dirs if $self->is_dir and not length $file;
2941 ### splitting ../ gives you the relative path in native syntax
2942 map { $_ = '..' if $_ eq '-' } @dirs if ON_VMS;
2944 my $prefix = File::Spec::Unix->catdir(
2945 grep { length } $vol, @dirs
2947 return( $prefix, $file );
2954 return unless defined $file;
2956 return SYMLINK if (-l $file); # Symlink
2958 return FILE if (-f _); # Plain file
2960 return DIR if (-d _); # Directory
2962 return FIFO if (-p _); # Named pipe
2964 return SOCKET if (-S _); # Socket
2966 return BLOCKDEV if (-b _); # Block special
2968 return CHARDEV if (-c _); # Character special
2970 ### shouldn't happen, this is when making archives, not reading ###
2971 return LONGLINK if ( $file eq LONGLINK_NAME );
2973 return UNKNOWN; # Something else (like what?)
2977 ### this method 'downgrades' a file to plain file -- this is used for
2978 ### symlinks when FOLLOW_SYMLINKS is true.
2979 sub _downgrade_to_plainfile {
2981 $entry->type( FILE );
2982 $entry->mode( MODE );
2983 $entry->linkname('');
2988 =head2 $bool = $file->extract( [ $alternative_name ] )
2990 Extract this object, optionally to an alternative name.
2992 See C<< Archive::Tar->extract_file >> for details.
2994 Returns true on success and false on failure.
3001 local $Carp::CarpLevel += 1;
3003 return Archive::Tar->_extract_file( $self, @_ );
3006 =head2 $path = $file->full_path
3008 Returns the full path from the tar header; this is basically a
3009 concatenation of the C<prefix> and C<name> fields.
3016 ### if prefix field is empty
3017 return $self->name unless defined $self->prefix and length $self->prefix;
3019 ### or otherwise, catfile'd
3020 return File::Spec::Unix->catfile( $self->prefix, $self->name );
3024 =head2 $bool = $file->validate
3026 Done by Archive::Tar internally when reading the tar file:
3027 validate the header against the checksum to ensure integer tar file.
3029 Returns true on success, false on failure
3036 my $raw = $self->raw;
3038 ### don't know why this one is different from the one we /write/ ###
3039 substr ($raw, 148, 8) = " ";
3041 ### bug #43513: [PATCH] Accept wrong checksums from SunOS and HP-UX tar
3042 ### like GNU tar does. See here for details:
3043 ### http://www.gnu.org/software/tar/manual/tar.html#SEC139
3044 ### so we do both a signed AND unsigned validate. if one succeeds, that's
3046 return ( (unpack ("%16C*", $raw) == $self->chksum)
3047 or (unpack ("%16c*", $raw) == $self->chksum)) ? 1 : 0;
3050 =head2 $bool = $file->has_content
3052 Returns a boolean to indicate whether the current object has content.
3053 Some special files like directories and so on never will have any
3054 content. This method is mainly to make sure you don't get warnings
3055 for using uninitialized values when looking at an object's content.
3061 return defined $self->data() && length $self->data() ? 1 : 0;
3064 =head2 $content = $file->get_content
3066 Returns the current content for the in-memory file
3075 =head2 $cref = $file->get_content_by_ref
3077 Returns the current content for the in-memory file as a scalar
3078 reference. Normal users won't need this, but it will save memory if
3079 you are dealing with very large data files in your tar archive, since
3080 it will pass the contents by reference, rather than make a copy of it
3085 sub get_content_by_ref {
3088 return \$self->{data};
3091 =head2 $bool = $file->replace_content( $content )
3093 Replace the current content of the file with the new content. This
3094 only affects the in-memory archive, not the on-disk version until
3097 Returns true on success, false on failure.
3101 sub replace_content {
3103 my $data = shift || '';
3105 $self->data( $data );
3106 $self->size( length $data );
3110 =head2 $bool = $file->rename( $new_name )
3112 Rename the current file to $new_name.
3114 Note that you must specify a Unix path for $new_name, since per tar
3115 standard, all files in the archive must be Unix paths.
3117 Returns true on success and false on failure.
3125 return unless defined $path;
3127 my ($prefix,$file) = $self->_prefix_and_file( $path );
3129 $self->name( $file );
3130 $self->prefix( $prefix );
3135 =head2 $bool = $file->chmod $mode)
3137 Change mode of $file to $mode. The mode can be a string or a number
3138 which is interpreted as octal whether or not a leading 0 is given.
3140 Returns true on success and false on failure.
3146 my $mode = shift; return unless defined $mode && $mode =~ /^[0-7]{1,4}$/;
3147 $self->{mode} = oct($mode);
3151 =head2 $bool = $file->chown( $user [, $group])
3153 Change owner of $file to $user. If a $group is given that is changed
3154 as well. You can also pass a single parameter with a colon separating the
3155 use and group as in 'root:wheel'.
3157 Returns true on success and false on failure.
3164 return unless defined $uname;
3166 if (-1 != index($uname, ':')) {
3167 ($uname, $gname) = split(/:/, $uname);
3169 $gname = shift if @_ > 0;
3172 $self->uname( $uname );
3173 $self->gname( $gname ) if $gname;
3177 =head1 Convenience methods
3179 To quickly check the type of a C<Archive::Tar::File> object, you can
3180 use the following methods:
3184 =item $file->is_file
3186 Returns true if the file is of type C<file>
3190 Returns true if the file is of type C<dir>
3192 =item $file->is_hardlink
3194 Returns true if the file is of type C<hardlink>
3196 =item $file->is_symlink
3198 Returns true if the file is of type C<symlink>
3200 =item $file->is_chardev
3202 Returns true if the file is of type C<chardev>
3204 =item $file->is_blockdev
3206 Returns true if the file is of type C<blockdev>
3208 =item $file->is_fifo
3210 Returns true if the file is of type C<fifo>
3212 =item $file->is_socket
3214 Returns true if the file is of type C<socket>
3216 =item $file->is_longlink
3218 Returns true if the file is of type C<LongLink>.
3219 Should not happen after a successful C<read>.
3221 =item $file->is_label
3223 Returns true if the file is of type C<Label>.
3224 Should not happen after a successful C<read>.
3226 =item $file->is_unknown
3228 Returns true if the file type is C<unknown>
3234 #stupid perl5.5.3 needs to warn if it's not numeric
3235 sub is_file { local $^W; FILE == $_[0]->type }
3236 sub is_dir { local $^W; DIR == $_[0]->type }
3237 sub is_hardlink { local $^W; HARDLINK == $_[0]->type }
3238 sub is_symlink { local $^W; SYMLINK == $_[0]->type }
3239 sub is_chardev { local $^W; CHARDEV == $_[0]->type }
3240 sub is_blockdev { local $^W; BLOCKDEV == $_[0]->type }
3241 sub is_fifo { local $^W; FIFO == $_[0]->type }
3242 sub is_socket { local $^W; SOCKET == $_[0]->type }
3243 sub is_unknown { local $^W; UNKNOWN == $_[0]->type }
3244 sub is_longlink { local $^W; LONGLINK eq $_[0]->type }
3245 sub is_label { local $^W; LABEL eq $_[0]->type }
3254 'File/Find/Rule.pm' => <<'END_OF_FILE',
3257 package File::Find::Rule;
3260 use Text::Glob 'glob_to_regex';
3261 use Number::Compare;
3263 use File::Find (); # we're only wrapping for now
3265 our $VERSION = '0.34';
3267 # we'd just inherit from Exporter, but I want the colon
3271 for my $sym ( qw( find rule ) ) {
3273 *{"$to\::$sym"} = \
&{$sym};
3275 for (grep /^:/, @_) {
3276 my ($extension) = /^:(.*)/;
3277 eval "require File::Find::Rule::$extension";
3278 croak
"couldn't bootstrap File::Find::Rule::$extension: $@" if $@
;
3284 File
::Find
::Rule
- Alternative interface to File
::Find
3288 use File
::Find
::Rule
;
3289 # find all the subdirectories of a given directory
3290 my @subdirs = File
::Find
::Rule
->directory->in( $directory );
3292 # find all the .pm files in @INC
3293 my @files = File
::Find
::Rule
->file()
3297 # as above, but without method chaining
3298 my $rule = File
::Find
::Rule
->new;
3300 $rule->name( '*.pm' );
3301 my @files = $rule->in( @INC );
3305 File
::Find
::Rule is a friendlier interface to File
::Find
. It allows
3306 you to build rules which specify the desired files
and directories
.
3310 # the procedural shim
3314 my $object = __PACKAGE__
->new();
3321 if ($method =~ s/^\!//) {
3322 # jinkies, we're really negating this
3323 unshift @_, $method;
3327 unless (defined prototype $method) {
3329 @args = ref $args eq 'ARRAY' ? @
$args : $args;
3333 @args = $object->new->$method(@args);
3337 my @return = $object->$method(@args);
3338 return @return if $method eq 'in';
3350 A constructor
. You need
not invoke C
<new
> manually
unless you wish
3351 to
, as
each of the rule
-making methods will auto
-create a suitable
3352 object
if called as
class methods
.
3357 my $referent = shift;
3358 my $class = ref $referent || $referent;
3371 $object = $object->new()
3378 =head2 Matching Rules
3382 =item C
<name
( @patterns )>
3384 Specifies names that should match
. May be globs
or regular
3387 $set->name( '*.mp3', '*.ogg' ); # mp3s or oggs
3388 $set->name( qr/\.(mp3|ogg)$/ ); # the same as a regex
3389 $set->name( 'foo.bar' ); # just things named foo.bar
3397 ref $item eq 'ARRAY' ?
push @_, @
{ $item } : push @flat, $item;
3403 my $self = _force_object
shift;
3404 my @names = map { ref $_ eq "Regexp" ?
$_ : glob_to_regex
$_ } _flatten
( @_ );
3406 push @
{ $self->{rules
} }, {
3408 code
=> join( ' || ', map { "m{$_}" } @names ),
3417 Synonyms are provided
for each of the
-X tests
. See L
<perlfunc
/-X
> for
3418 details
. None of these methods take arguments
.
3420 Test
| Method Test
| Method
3421 ------|------------- ------|----------------
3422 -r
| readable
-R
| r_readable
3423 -w
| writeable
-W
| r_writeable
3424 -w
| writable
-W
| r_writable
3425 -x
| executable
-X
| r_executable
3426 -o
| owned
-O
| r_owned
3428 -e
| exists -f
| file
3429 -z
| empty
-d
| directory
3430 -s
| nonempty
-l
| symlink
3432 -u
| setuid
-S
| socket
3433 -g
| setgid
-b
| block
3434 -k
| sticky
-c
| character
3437 -A
| accessed
-T
| ascii
3438 -C
| changed
-B
| binary
3440 Though some tests are fairly meaningless as binary flags
(C
<modified
>,
3441 C
<accessed
>, C
<changed
>), they have been included
for completeness
.
3443 # find nonempty files
3449 use vars
qw( %X_tests );
3451 -r => readable => -R => r_readable =>
3452 -w => writeable => -W => r_writeable =>
3453 -w => writable => -W => r_writable =>
3454 -x => executable => -X => r_executable =>
3455 -o => owned => -O => r_owned =>
3457 -e => exists => -f => file =>
3458 -z => empty => -d => directory =>
3459 -s => nonempty => -l => symlink =>
3461 -u => setuid => -S => socket =>
3462 -g => setgid => -b => block =>
3463 -k => sticky => -c => character =>
3466 -A => accessed => -T => ascii =>
3467 -C => changed => -B => binary =>
3470 for my $test (keys %X_tests) {
3471 my $sub = eval 'sub () {
3472 my $self = _force_object shift;
3473 push @{ $self->{rules} }, {
3474 code => "' . $test . ' \$_",
3475 rule => "'.$X_tests{$test}.'",
3480 *{ $X_tests{$test} } = $sub;
3486 The following C<stat> based methods are provided: C<dev>, C<ino>,
3487 C<mode>, C<nlink>, C<uid>, C<gid>, C<rdev>, C<size>, C<atime>,
3488 C<mtime>, C<ctime>, C<blksize>, and C<blocks>. See L<perlfunc/stat>
3491 Each of these can take a number of targets, which will follow
3492 L<Number::Compare> semantics.
3494 $rule->size( 7 ); # exactly 7
3495 $rule->size( ">7Ki" ); # larger than 7 * 1024 * 1024 bytes
3496 $rule->size( ">=7" )
3497 ->size( "<=90" ); # between 7 and 90, inclusive
3498 $rule->size( 7, 9, 42 ); # 7, 9 or 42
3502 use vars qw( @stat_tests );
3503 @stat_tests = qw( dev ino mode nlink uid gid rdev
3504 size atime mtime ctime blksize blocks );
3507 for my $test (@stat_tests) {
3508 my $index = $i++; # to close over
3510 my $self = _force_object
shift;
3512 my @tests = map { Number
::Compare
->parse_to_perl($_) } @_;
3514 push @
{ $self->{rules
} }, {
3517 code
=> 'do { my $val = (stat $_)['.$index.'] || 0;'.
3518 join ('||', map { "(\$val $_)" } @tests ).' }',
3527 =item C
<any
( @rules )>
3529 =item C
<or( @rules )>
3531 Allows shortcircuiting boolean evaluation as an alternative to the
3532 default and-like nature of combined rules
. C
<any
> and C
<or> are
3535 # find avis, movs, things over 200M and empty files
3536 $rule->any( File
::Find
::Rule
->name( '*.avi', '*.mov' ),
3537 File
::Find
::Rule
->size( '>200M' ),
3538 File
::Find
::Rule
->file->empty,
3544 my $self = _force_object
shift;
3545 # compile all the subrules to code fragments
3546 push @
{ $self->{rules
} }, {
3548 code
=> '(' . join( ' || ', map '( ' . $_->_compile . ' )', @_ ). ')',
3552 # merge all the subs hashes of the kids into ourself
3553 %{ $self->{subs
} } = map { %{ $_->{subs
} } } $self, @_;
3559 =item C
<none
( @rules )>
3561 =item C
<not( @rules )>
3563 Negates a rule
. (The inverse of C
<any
>.) C
<none
> and C
<not> are
3566 # files that aren't 8.3 safe
3568 ->not( $rule->new->name( qr/^[^.]{1,8}(\.[^.]{0,3})?$/ ) );
3573 my $self = _force_object
shift;
3575 push @
{ $self->{rules
} }, {
3578 code
=> '(' . join ( ' && ', map { "!(". $_->_compile . ")" } @_ ) . ")",
3581 # merge all the subs hashes into us
3582 %{ $self->{subs
} } = map { %{ $_->{subs
} } } $self, @_;
3590 Traverse
no further
. This rule always matches
.
3595 my $self = _force_object
shift;
3597 push @
{ $self->{rules
} },
3600 code
=> '$File::Find::prune = 1'
3607 Don
't keep this file. This rule always matches.
3612 my $self = _force_object shift;
3614 push @{ $self->{rules} }, {
3616 code => '$discarded = 1',
3621 =item C<exec( \&subroutine( $shortname, $path, $fullname ) )>
3623 Allows user-defined rules. Your subroutine will be invoked with C<$_>
3624 set to the current short name, and with parameters of the name, the
3625 path you're
in, and the full relative filename
.
3627 Return a true value
if your rule matched
.
3629 # get things with long names
3630 $rules->exec( sub { length > 20 } );
3635 my $self = _force_object
shift;
3638 push @
{ $self->{rules
} }, {
3645 =item C
<grep( @specifiers )>
3647 Opens a file
and tests it
each line at a
time.
3649 For
each line it evaluates
each of the specifiers
, stopping at the
3650 first successful match
. A specifier may be a regular expression
or a
3651 subroutine
. The subroutine will be invoked with the same parameters
3652 as an
->exec subroutine
.
3654 It is possible to provide a set of negative specifiers by enclosing
3655 them
in anonymous arrays
. Should a negative specifier match the
3656 iteration is aborted
and the clause is failed
. For example
:
3658 $rule->grep( qr/^#!.*\bperl/, [ sub { 1 } ] );
3660 Is a passing clause
if the first line of a file looks like a perl
3666 my $self = _force_object
shift;
3670 ?
map { [ ( ref $_ ?
$_ : qr/$_/ ) => 0 ] } @
$_
3677 open FILE
, $_ or return;
3680 for my $p (@pattern) {
3681 my ($rule, $ret) = @
$p;
3683 if ref $rule eq 'Regexp'
3692 =item C
<maxdepth
( $level )>
3694 Descend at most C
<$level> (a non
-negative integer
) levels of directories
3695 below the starting point
.
3697 May be invoked many
times per rule
, but only the most recent value is
3700 =item C
<mindepth
( $level )>
3702 Do
not apply any tests at levels less than C
<$level> (a non
-negative
3705 =item C
<extras
( \
%extras )>
3707 Specifies extra
values to pass through to C
<File
::File
::find
> as part
3708 of the options hash
.
3710 For example this allows you to specify following of symlinks like so
:
3712 my $rule = File
::Find
::Rule
->extras({ follow
=> 1 });
3714 May be invoked many
times per rule
, but only the most recent value is
3719 for my $setter (qw( maxdepth mindepth extras )) {
3721 my $self = _force_object
shift;
3722 $self->{$setter} = shift;
3732 Trim the leading portion of any path found
3737 my $self = _force_object
shift;
3738 $self->{relative
} = 1;
3744 Normalize paths found using C
<File
::Spec
->canonpath>. This will
return paths
3745 with a file
-seperator that is native to your OS
(as determined by L
<File
::Spec
>),
3746 instead of the
default C
</>.
3748 For example
, this will
return C
<tmp
/foobar
> on Unix
-ish OSes
3749 and C
<tmp
\foobar
> on Win32
.
3754 my $self = _force_object
shift;
3755 $self->{canonpath
} = 1;
3761 Negated version of the rule
. An effective shortand related to
! in
3762 the procedural interface
.
3764 $foo->not_name('*.pl');
3766 $foo->not( $foo->new->name('*.pl' ) );
3773 $AUTOLOAD =~ /::not_([^:]*)$/
3774 or croak
"Can't locate method $AUTOLOAD";
3778 my $self = _force_object
shift;
3779 $self->not( $self->new->$method(@_) );
3790 =head2 Query Methods
3794 =item C
<in( @directories )>
3796 Evaluates the rule
, returns a list of paths to matching files
and
3802 my $self = _force_object
shift;
3805 my $fragment = $self->_compile;
3806 my %subs = %{ $self->{subs
} };
3808 warn "relative mode handed multiple paths - that's a bit silly\n"
3809 if $self->{relative
} && @_ > 1;
3813 (my $path = $File::Find::name) =~ s#^(?:\./+)+##;
3814 my @args = ($_, $File::Find::dir, $path);
3815 my $maxdepth = $self->{maxdepth};
3816 my $mindepth = $self->{mindepth};
3817 my $relative = $self->{relative};
3818 my $canonpath = $self->{canonpath};
3820 # figure out the relative path and depth
3821 my $relpath = $File::Find::name;
3822 $relpath =~ s{^\Q$topdir\E/?}{};
3823 my $depth = scalar File::Spec->splitdir($relpath);
3824 #print "name: \'$File::Find::name\' ";
3825 #print "relpath: \'$relpath\' depth: $depth relative: $relative\n";
3827 defined $maxdepth && $depth >= $maxdepth
3828 and $File::Find::prune = 1;
3830 defined $mindepth && $depth < $mindepth
3833 #print "Testing \'$_\'\n";
3836 return unless ' . $fragment . ';
3837 return if $discarded;
3839 if ($relpath ne "") {
3840 push @found, $canonpath ? File::Spec->canonpath($relpath) : $relpath;
3844 push @found, $canonpath ? File::Spec->canonpath($path) : $path;
3849 #print Dumper \%subs;
3850 #warn "Compiled sub: '$code'\n";
3852 my $sub = eval "$code" or die "compile error '$code' $@";
3854 # $topdir is used for relative and maxdepth
3856 # slice off the trailing slash if there is one (the
3857 # maxdepth/mindepth code is fussy)
3859 unless $topdir eq '/';
3860 $self->_call_find( { %{ $self->{extras
} }, wanted
=> $sub }, $path );
3868 File
::Find
::find
( @_ );
3874 return '1' unless @
{ $self->{rules
} };
3875 my $code = join " && ", map {
3876 if (ref $_->{code
}) {
3877 my $key = "$_->{code}";
3878 $self->{subs
}{$key} = $_->{code
};
3879 "\$subs{'$key'}->(\@args) # $_->{rule}\n";
3882 "( $_->{code} ) # $_->{rule}\n";
3884 } @
{ $self->{rules
} };
3890 =item C
<start
( @directories )>
3892 Starts a find across the specified directories
. Matching items may
3893 then be queried using L
</match
>. This allows you to
use a rule as an
3896 my $rule = File
::Find
::Rule
->file->name("*.jpeg")->start( "/web" );
3897 while ( defined ( my $image = $rule->match ) ) {
3904 my $self = _force_object
shift;
3906 $self->{iterator
} = [ $self->in( @_ ) ];
3912 Returns the
next file which matches
, false
if there are
no more
.
3917 my $self = _force_object
shift;
3919 return shift @
{ $self->{iterator
} };
3930 Extension modules are available from CPAN
in the File
::Find
::Rule
3931 namespace
. In order to
use these extensions either
use them directly
:
3933 use File
::Find
::Rule
::ImageSize
;
3934 use File
::Find
::Rule
::MMagic
;
3936 # now your rules can use the clauses supplied by the ImageSize and
3939 or, specify that File
::Find
::Rule should load them
for you
:
3941 use File
::Find
::Rule
qw( :ImageSize :MMagic );
3943 For notes on implementing your own extensions
, consult
3944 L
<File
::Find
::Rule
::Extending
>
3946 =head2 Further examples
3950 =item Finding perl scripts
3952 my $finder = File
::Find
::Rule
->or
3954 File
::Find
::Rule
->name( '*.pl' ),
3955 File
::Find
::Rule
->exec(
3957 if (open my $fh, $_) {
3958 my $shebang = <$fh>;
3960 return $shebang =~ /^#!.*\bperl/;
3966 Based upon this message http
://use
.perl
.org
/comments
.pl?sid
=7052&cid
=10842
3968 =item ignore CVS directories
3970 my $rule = File
::Find
::Rule
->new;
3971 $rule->or($rule->new
3978 Note here the
use of a null rule
. Null rules match anything they see
,
3979 so the effect is to match
(and discard
) directories called
'CVS' or to
3984 =head1 TWO FOR THE PRICE OF ONE
3986 File
::Find
::Rule also gives you a procedural interface
. This is
3987 documented
in L
<File
::Find
::Rule
::Procedural
>
3993 =head1 TAINT MODE INTERACTION
3995 As of
0.32 File
::Find
::Rule doesn
't capture the current working directory in
3996 a taint-unsafe manner. File::Find itself still does operations that the taint
3997 system will flag as insecure but you can use the L</extras> feature to ask
3998 L<File::Find> to internally C<untaint> file paths with a regex like so:
4000 my $rule = File::Find::Rule->extras({ untaint => 1 });
4002 Please consult L<File::Find>'s documentation
for C
<untaint
>,
4003 C
<untaint_pattern
>, and C
<untaint_skip
> for more information
.
4007 The code makes
use of the C
<our> keyword
and as such requires perl version
4010 Currently it isn
't possible to remove a clause from a rule object. If
4011 this becomes a significant issue it will be addressed.
4015 Richard Clamp <richardc@unixbeard.net> with input gained from this
4016 use.perl discussion: http://use.perl.org/~richardc/journal/6467
4018 Additional proofreading and input provided by Kake, Greg McCarroll,
4019 and Andy Lester andy@petdance.com.
4023 Copyright (C) 2002, 2003, 2004, 2006, 2009, 2011 Richard Clamp. All Rights Reserved.
4025 This module is free software; you can redistribute it and/or modify it
4026 under the same terms as Perl itself.
4030 L<File::Find>, L<Text::Glob>, L<Number::Compare>, find(1)
4032 If you want to know about the procedural interface, see
4033 L<File::Find::Rule::Procedural>, and if you have an idea for a neat
4034 extension L<File::Find::Rule::Extending>
4038 Implementation notes:
4040 $self->rules is an array of hashrefs. it may be a code fragment or a call
4043 Anonymous subroutines are stored in the $self->subs hashref keyed on the
4044 stringfied version of the coderef.
4046 When one File::Find::Rule object is combined with another, such as in the any
4047 and not operations, this entire hash is merged.
4049 The _compile method walks the rules element and simply glues the code
4050 fragments together so they can be compiled into an anyonymous File::Find
4054 [*] There's probably a win to be made with the current model
in making
4055 stat calls
use C
<_
>. For
4057 find
( file
=> size
=> "> 20M" => size
=> "< 400M" );
4059 up to
3 stats will happen
for each candidate
. Adding a priming _
4060 would be a bit blind
if the first operation was C
< name
=> 'foo' >,
4061 since that can be tested by a single regex
. Simply checking what the
4062 next type of operation doesn
't work since any arbritary exec sub may
4063 or may not stat. Potentially worse, they could stat something else
4066 # extract from the worlds stupidest make(1)
4067 find( exec => sub { my $f = $_; $f =~ s/\.c$/.o/ && !-e $f } );
4069 Maybe the best way is to treat C<_> as invalid after calling an exec,
4070 and doc that C<_> will only be meaningful after stat and -X tests if
4071 they're wanted
in exec blocks
.
4078 'Number/Compare.pm' => <<'END_OF_FILE',
4079 package Number::Compare;
4082 use vars qw
/$VERSION/;
4086 my $referent = shift;
4087 my $class = ref $referent || $referent;
4088 my $expr = $class->parse_to_perl( shift );
4090 bless eval "sub { \$_[0] $expr }", $class;
4098 ([<>]=?
)?
# comparison
4100 ([kmg
]i?
)?
# magnitude
4102 or croak
"don't understand '$test' as a test";
4104 my $comparison = $1 || '==';
4106 my $magnitude = $3 || '';
4107 $target *= 1000 if lc $magnitude eq 'k';
4108 $target *= 1024 if lc $magnitude eq 'ki';
4109 $target *= 1000000 if lc $magnitude eq 'm';
4110 $target *= 1024*1024 if lc $magnitude eq 'mi';
4111 $target *= 1000000000 if lc $magnitude eq 'g';
4112 $target *= 1024*1024*1024 if lc $magnitude eq 'gi';
4114 return "$comparison $target";
4117 sub test
{ $_[0]->( $_[1] ) }
4125 Number
::Compare
- numeric comparisons
4129 Number
::Compare
->new(">1Ki")->test(1025); # is 1025 > 1024
4131 my $c = Number
::Compare
->new(">1M");
4132 $c->(1_200_000
); # slightly terser invocation
4136 Number
::Compare compiles a simple comparison to an anonymous
4137 subroutine
, which you can call with a value to be tested again
.
4139 Now this would be very pointless
, if Number
::Compare didn
't understand
4142 The target value may use magnitudes of kilobytes (C<k>, C<ki>),
4143 megabytes (C<m>, C<mi>), or gigabytes (C<g>, C<gi>). Those suffixed
4144 with an C<i> use the appropriate 2**n version in accordance with the
4145 IEC standard: http://physics.nist.gov/cuu/Units/binary.html
4149 =head2 ->new( $test )
4151 Returns a new object that compares the specified test.
4153 =head2 ->test( $value )
4155 A longhanded version of $compare->( $value ). Predates blessed
4156 subroutine reference implementation.
4158 =head2 ->parse_to_perl( $test )
4160 Returns a perl code fragment equivalent to the test.
4164 Richard Clamp <richardc@unixbeard.net>
4168 Copyright (C) 2002,2011 Richard Clamp. All Rights Reserved.
4170 This module is free software; you can redistribute it and/or modify it
4171 under the same terms as Perl itself.
4175 http://physics.nist.gov/cuu/Units/binary.html
4184 'Text
/Glob
.pm
' => <<'END_OF_FILE',
4188 use vars qw
/$VERSION @ISA @EXPORT_OK
4189 $strict_leading_dot $strict_wildcard_slash/;
4192 @EXPORT_OK = qw( glob_to_regex glob_to_regex_string match_glob );
4194 $strict_leading_dot = 1;
4195 $strict_wildcard_slash = 1;
4197 use constant debug
=> 0;
4201 my $regex = glob_to_regex_string
($glob);
4202 return qr/^$regex$/;
4205 sub glob_to_regex_string
4209 my $seperator = $Text::Glob
::seperator
;
4210 $seperator = "/" unless defined $seperator;
4211 $seperator = quotemeta($seperator);
4213 my ($regex, $in_curlies, $escaping);
4216 for ($glob =~ m/(.)/gs) {
4218 if ($strict_leading_dot) {
4219 $regex .= '(?=[^\.])' unless $_ eq '.';
4226 if ($_ eq '.' || $_ eq '(' || $_ eq ')' || $_ eq '|' ||
4227 $_ eq '+' || $_ eq '^' || $_ eq '$' || $_ eq '@' || $_ eq '%' ) {
4231 $regex .= $escaping ?
"\\*" :
4232 $strict_wildcard_slash ?
"(?:(?!$seperator).)*" : ".*";
4235 $regex .= $escaping ?
"\\?" :
4236 $strict_wildcard_slash ?
"(?!$seperator)." : ".";
4239 $regex .= $escaping ?
"\\{" : "(";
4240 ++$in_curlies unless $escaping;
4242 elsif ($_ eq '}' && $in_curlies) {
4243 $regex .= $escaping ?
"}" : ")";
4244 --$in_curlies unless $escaping;
4246 elsif ($_ eq ',' && $in_curlies) {
4247 $regex .= $escaping ?
"," : "|";
4249 elsif ($_ eq "\\") {
4265 print "# $glob $regex\n" if debug
;
4271 print "# ", join(', ', map { "'$_'" } @_), "\n" if debug
;
4273 my $regex = glob_to_regex
$glob;
4275 grep { $_ =~ $regex } @_;
4283 Text
::Glob
- match globbing patterns against text
4287 use Text
::Glob
qw( match_glob glob_to_regex );
4289 print "matched\n" if match_glob
( "foo.*", "foo.bar" );
4291 # prints foo.bar and foo.baz
4292 my $regex = glob_to_regex
( "foo.*" );
4293 for ( qw( foo.bar foo.baz foo bar ) ) {
4294 print "matched: $_\n" if /$regex/;
4299 Text
::Glob implements
glob(3) style matching that can be used to match
4300 against text
, rather than fetching names from a filesystem
. If you
4301 want to
do full file globbing
use the File
::Glob module instead
.
4307 =item match_glob
( $glob, @things_to_test )
4309 Returns the list of things which match the
glob from the source list
.
4311 =item glob_to_regex
( $glob )
4313 Returns a compiled regex which is the equivalent of the globbing
4316 =item glob_to_regex_string
( $glob )
4318 Returns a regex string which is the equivalent of the globbing
4325 The following metacharacters
and rules are respected
.
4329 =item C
<*> - match zero
or more characters
4331 C
<a
*> matches C
<a
>, C
<aa
>, C
<aaaa
> and many many more
.
4333 =item C
<?
> - match exactly one character
4335 C
<a?
> matches C
<aa
>, but
not C
<a
>, or C
<aaa
>
4337 =item Character sets
/ranges
4339 C
<example
.[ch
]> matches C
<example
.c
> and C
<example
.h
>
4341 C
<demo
.[a
-c
]> matches C
<demo
.a
>, C
<demo
.b
>, and C
<demo
.c
>
4345 C
<example
.{foo
,bar
,baz
}> matches C
<example
.foo
>, C
<example
.bar
>, and
4348 =item leading
. must be explicitly matched
4350 C
<*.foo
> does
not match C
<.bar
.foo
>. For this you must either specify
4351 the leading
. in the
glob pattern
(C
<.*.foo
>), or set
4352 C
<$Text::Glob
::strict_leading_dot
> to a false value
while compiling
4355 =item C
<*> and C
<?
> do not match the seperator
(i
.e
. do not match C
</>)
4357 C
<*.foo
> does
not match C
<bar
/baz
.foo
>. For this you must either
4358 explicitly match the
/ in the glob (C<*/*.foo
>), or set
4359 C
<$Text::Glob
::strict_wildcard_slash
> to a false value
while compiling
4360 the regex
, or change the seperator that Text
::Glob uses by setting
4361 C
<$Text::Glob
::seperator
> to an alternative value
while compiling the
4368 The code uses
qr// to produce compiled regexes
, therefore this module
4369 requires perl version
5.005_03
or newer
.
4373 Richard Clamp
<richardc
@unixbeard.net
>
4377 Copyright
(C
) 2002, 2003, 2006, 2007 Richard Clamp
. All Rights Reserved
.
4379 This module is free software
; you can redistribute it
and/or modify it
4380 under the same terms as Perl itself
.
4384 L
<File
::Glob
>, glob(3)
4395 my ($me, $packfile) = @_;
4396 return unless exists $file_for{$packfile};
4397 (my $text = $file_for{$packfile}) =~ s/^\ //gmxs;
4398 chop($text); # added \n at the end
4399 open my $fh, '<', \
$text or die "open(): $!\n";
4403 # __MOBUNDLE_INCLUSION__
4405 use File
::Find
::Rule
;
4410 remote
=> catfile
(dirname
(realpath
(__FILE__
)), 'remote'),
4424 usage! help! man! version!
4432 include-archive-tar|T!
4437 rootdir|in-root|R=s@
4442 workdir|work-directory|deploy-directory|w=s
4444 ) or pod2usage
(message
=> "invalid command line", -verbose
=> 99, -sections
=> ' ', -noperldoc
=> 1);
4445 pod2usage
(message
=> "$0 $VERSION", -verbose
=> 99, -sections
=> ' ', -noperldoc
=> 1)
4446 if $config{version
};
4447 pod2usage
(-verbose
=> 99, -sections
=> 'USAGE', -noperldoc
=> 1) if $config{usage
};
4448 pod2usage
(-verbose
=> 99, -sections
=> 'USAGE|EXAMPLES|OPTIONS', -noperldoc
=> 1)
4450 pod2usage
(-verbose
=> 2, -noperldoc
=> 1) if $config{man
};
4453 message
=> 'working directory must be an absolute path',
4457 ) if exists $config{workdir
} && !file_name_is_absolute
($config{workdir
});
4459 if (@
{$config{xform
}}) {
4460 $config{'no-tar'} = 1; # force internal stuff
4461 for my $xform (@
{$config{xform
}}) {
4462 my ($src, $filename) =
4463 $xform =~ m{\A((?:[^\\:]|\\.)*) : (.*)}mxs;
4464 s{\\(.)}{$1}gmxs for $src, $filename;
4465 my $array_name = file_name_is_absolute
($filename) ?
'rootfile'
4467 push @
{$config{$array_name}}, [$src, $filename];
4471 if ($config{'include-archive-tar'}) {
4472 $config{remote
} = catfile
(dirname
(realpath
(__FILE__
)), 'remote-at');
4473 if (!-e
$config{remote
}) { # "make" it
4474 print {*STDERR
} "### Making remote-at...\n";
4475 my $startdir = cwd
();
4476 chdir dirname realpath __FILE__
;
4477 system {'make'} qw( make remote-at );
4479 } ## end if (!-e $config{remote...})
4480 } ## end if ($config{'include-archive-tar'...})
4482 # Establish output channel
4483 my $out_fh = \
*STDOUT
;
4484 if ($config{output
} ne '-') {
4485 open my $fh, '>', $config{output
} ## no critic
4486 or croak
"open('$config{output}'): $OS_ERROR";
4491 # Emit script code to be executed remotely. It is guaranteed to end
4492 # with __END__, so that all what comes next is data
4493 print {$out_fh} get_remote_script
();
4495 # Where all the data will be kept
4496 print_configuration
($out_fh, \
%config);
4498 print_here_stuff
($out_fh, \
%config, @ARGV);
4499 print_root_stuff
($out_fh, \
%config);
4504 if ($config{output
} ne '-') {
4505 chmod oct(755), $config{output
}
4506 or carp
"chmod(0755, '$config{output}'): $OS_ERROR";
4511 my $namesize = length $params{name
};
4512 return "$namesize $params{size}\n$params{name}";
4515 sub print_configuration
{ # FIXME
4516 my ($fh, $config) = @_;
4517 my %general_configuration;
4519 qw( workdir cleanup bundle deploy
4520 gzip bzip2 passthrough tempdir-mode )
4523 $general_configuration{$name} = $config->{$name}
4524 if exists $config->{$name};
4525 } ## end for my $name (qw( workdir cleanup bundle deploy...))
4526 my $configuration = Dumper \
%general_configuration;
4527 print {$fh} header
(name
=> 'config.pl', size
=> length($configuration)),
4528 "\n", $configuration, "\n\n";
4529 } ## end sub print_configuration
4531 # Process files and directories. All these will be reported in the
4532 # extraction directory, i.e. basename() will be applied to them. For
4533 # directories, they will be re-created
4534 sub print_here_stuff
{
4539 my $ai = Deployable
::Tar
->new($config);
4542 '.' => $config->{herefile
},
4543 map { $_ => ['.'] } @
{$config->{heredir
}}
4546 print {$fh} header
(name
=> 'here', size
=> $ai->size()), "\n";
4551 } ## end sub print_here_stuff
4553 sub print_root_stuff
{
4554 my ($fh, $config) = @_;
4556 my $ai = Deployable
::Tar
->new($config);
4558 '.' => $config->{rootdir
},
4559 '.' => $config->{rootfile
},
4560 (undef, $config->{tarfile
}),
4561 map { $_ => ['.'] } @
{$config->{root
}},
4564 print {$fh} header
(name
=> 'root', size
=> $ai->size()), "\n";
4569 } ## end sub print_root_stuff
4571 sub get_remote_script
{
4573 if (-e
$config{remote
}) {
4574 open $fh, '<', $config{remote
}
4575 or croak
"open('$config{remote}'): $OS_ERROR";
4583 last if /\A __END__ \s*\z/mxs;
4587 return join '', @lines, "__END__\n";
4588 } ## end sub get_remote_script
4590 package Deployable
::Tar
;
4593 my $package = shift;
4594 my $self = {ref $_[0] ?
%{$_[0]} : @_};
4595 $package = 'Deployable::Tar::Internal';
4596 if (!$self->{'no-tar'}) {
4597 if ((exists $self->{tar
}) || (open my $fh, '-|', 'tar', '--help')) {
4598 $package = 'Deployable::Tar::External';
4599 $self->{tar
} ||= 'tar';
4601 } ## end if (!$self->{'no-tar'})
4602 bless $self, $package;
4603 $self->initialise();
4607 package Deployable
::Tar
::External
;
4608 use File
::Temp
qw( :seekable );
4609 use English
qw( -no_match_vars );
4612 our @ISA = qw( Deployable::Tar );
4616 $self->{_temp
} = File
::Temp
->new();
4617 $self->{_filename
} = Cwd
::abs_path
($self->{_temp
}->filename());
4619 } ## end sub initialise
4623 my $tar = $self->{tar
};
4624 delete $self->{_compressed
};
4626 my ($directory, $stuff) = splice @_, 0, 2;
4627 my @stuff = @
$stuff;
4628 if (defined $directory) {
4630 my @chunk = splice @stuff, 0, 50;
4631 system {$tar} $tar, 'rvf', $self->{_filename
},
4632 '-C', $directory, '--', @chunk;
4634 } ## end if (defined $directory)
4635 else { # it's another TAR file, concatenate
4637 my @chunk = splice @stuff, 0, 50;
4638 system {$tar} $tar, 'Avf', $self->{_filename
}, '--', @chunk;
4640 } ## end else [ if (defined $directory)]
4647 return if exists $self->{_compressed
};
4649 $self->{_temp
}->sysseek(0, SEEK_SET
);
4650 if ($self->{bzip2
}) {
4651 require IO
::Compress
::Bzip2
;
4652 $self->{_compressed
} = File
::Temp
->new();
4654 # double-quotes needed to force usage of filename
4655 # instead of filehandle
4656 IO
::Compress
::Bzip2
::bzip2
($self->{_temp
}, "$self->{_compressed}");
4657 } ## end if ($self->{bzip2})
4658 elsif ($self->{gzip
}) {
4659 require IO
::Compress
::Gzip
;
4660 $self->{_compressed
} = File
::Temp
->new();
4662 # double-quotes needed to force usage of filename
4663 # instead of filehandle
4664 IO
::Compress
::Gzip
::gzip
($self->{_temp
}, "$self->{_compressed}");
4665 } ## end elsif ($self->{gzip})
4667 $self->{_compressed
} = $self->{_temp
};
4671 } ## end sub _compress
4676 return (stat $self->{_compressed
})[7];
4680 my ($self, $out_fh) = @_;
4682 my $in_fh = $self->{_compressed
};
4683 $in_fh->sysseek(0, SEEK_SET
);
4685 my $nread = $in_fh->sysread(my $buffer, 4096);
4686 croak
"sysread(): $OS_ERROR" unless defined $nread;
4688 print {$out_fh} $buffer;
4689 } ## end while ('true')
4691 } ## end sub copy_to
4693 package Deployable
::Tar
::Internal
;
4694 use Archive
::Tar
();
4696 use File
::Find
::Rule
();
4697 use Carp qw
< croak
>;
4698 our @ISA = qw( Deployable::Tar );
4702 $self->{_tar
} = Archive
::Tar
->new();
4708 delete $self->{_string
};
4709 my $tar = $self->{_tar
};
4710 my $cwd = Cwd
::getcwd
();
4712 my ($directory, $stuff) = splice @_, 0, 2;
4713 if (defined $directory) {
4715 for my $item (@
$stuff) {
4717 my ($src, $filename) = @
$item;
4718 my $src_len = length $src;
4719 for my $input (File
::Find
::Rule
->in($src)) {
4720 my ($atf) = $tar->add_files($input);
4721 my $name = $filename . substr $input, $src_len;
4722 $atf->rename($name);
4726 $tar->add_files($_) for File
::Find
::Rule
->in($item);
4730 } ## end if (defined $directory)
4731 else { # It's another TAR file to be concatenated
4732 for my $item (@
$stuff) {
4733 my $iterator = Archive
::Tar
->iter($item);
4734 while (my $f = $iterator->()) {
4735 $tar->add_files($f);
4745 $self->{_string
} = $self->{_tar
}->write()
4746 unless exists $self->{_string
};
4747 return length $self->{_string
};
4751 my ($self, $out_fh) = @_;
4752 $self->{_string
} = $self->{_tar
}->write()
4753 unless exists $self->{_string
};
4754 print {$out_fh} $self->{_string
};
4755 } ## end sub copy_to
4759 deployable - create a deploy script for some files/scripts
4763 See version at beginning of script, variable $VERSION, or call
4765 shell$ deployable --version
4769 deployable [--usage] [--help] [--man] [--version]
4771 deployable [--bundle|--all-exec|-X]
4774 [--deploy|--exec|d <program>]
4776 [--heredir|-H <dirname>]
4777 [--include-archive-tar|-T]
4779 [--output|-o <filename>]
4780 [--root|-r <dirname>]
4781 [--rootdir|--in-root|-R <dirname>]
4782 [--tar|-t <program-path>]
4783 [--tarfile|-F <filename>]
4784 [--tempdir-mode|-m <mode>]
4785 [--xform|-x src:filename]
4786 [--workdir|-w <path>]
4787 [ files or directories... ]
4791 # pack some files and a deploy script together.
4792 shell$ deployable script.sh file.txt some/directory -d script.sh
4794 # Use a directory's contents as elements for the target root
4795 shell$ ls -1 /path/to/target/root
4800 # The above will be deployed as /etc, /opt, /usr and /var
4801 shell$ deployable -o dep.pl --root /path/to/target/root
4803 # Include sub-directory etc/ for inclusion and extraction
4805 shell$ deployable -o dep.pl --in-root etc/
4809 This is a meta-script to create deploy scripts. The latter ones are
4810 suitable to be distributed in order to deploy something.
4812 You basically have to provide two things: files to install and programs
4813 to be executed. Files can be put directly into the deployed script, or
4814 can be included in gzipped tar archives.
4816 When called, this script creates a deploy script for you. This script
4817 includes all the specified files, and when executed it will extract
4818 those files and execute the given programs. In this way, you can ship
4819 both files and logic needed to correctly install those files, but this
4820 is of course of of scope.
4822 All files and archives will be extracted under a configured path
4823 (see L<--workdir> below), which we'll call I<workdir> from now on. Under
4824 the I<workdir> a temporary directory will be created, and the files
4825 will be put in the temporary directory. You can specify if you want to
4826 clean up this temporary directory or keep it, at your choice. (You're able
4827 to both set a default for this cleanup when invoking deployable, or when
4828 invoking the deploy script itself). The temporary directory will be
4829 called I<tmpdir> in the following.
4831 There are several ways to embed files to be shipped:
4837 pass the name of an already-prepared tar file via L</--tarfile>. The
4838 contents of this file will be assumed to be referred to the root
4843 specify the file name directly on the command line. A file given in this
4844 way will always be extracted into the I<tmpdir>, whatever its initial path
4849 specify the name of a directory on the command line. In this case,
4850 C<tar> will be used to archive the directory, with the usual option to
4851 turn absolute paths into relative ones; this means that directories will
4852 be re-created under I<tmpdir> when extraction is performed;
4856 give the name of a directory to be used as a "here directory", using
4857 the C<--heredir|-H> option. This is much the same as giving the directory
4858 name (see above), but in this case C<tar> will be told to change into the
4859 directory first, and archive '.'. This means that the contents of the
4860 "here-directory" will be extracted directly into I<tmpdir>.
4864 =head2 Extended Example
4866 Suppose you have a few server which have the same configuration, apart
4867 from some specific stuff (e.g. the hostname, the IP addresses, etc.).
4868 You'd like to perform changes to all with the minimum work possible...
4869 so you know you should script something.
4871 For example, suppose you want to update a few files in /etc, setting these
4872 files equal for all hosts. You would typically do the following:
4875 shell$ mkdir -p /tmp/newfiles/etc
4876 shell$ cd /tmp/newfiles/etc
4877 # Craft the new files
4879 shell$ tar cvzf newetc.tar.gz etc
4881 # Now, for each server:
4882 shell$ scp newetc.tar.gz $server:/tmp
4883 shell$ ssh $server tar xvzf /tmp/newetc.tar.gz -C /
4886 So far, so good. But what if you need to kick in a little more logic?
4887 For example, if you update some configuration files, you'll most likey
4888 want to restart some services. So you could do the following:
4890 shell$ mkdir -p /tmp/newfiles/tmp
4891 shell$ cd /tmp/newfiles/tmp
4892 # craft a shell script to be executed remotely and set the exec bit
4893 # Suppose it's called deploy.sh
4895 shell$ tar cvzf newetc.tar.gz etc tmp
4897 # Now, for each server:
4898 shell$ scp newetc.tar.gz $server:/tmp
4899 shell$ ssh $server tar xvzf /tmp/newetc.tar.gz -C /
4900 shell$ ssh $server /tmp/deploy.sh
4902 And what if you want to install files depending on the particular machine?
4903 Or you have a bundle of stuff to deploy and a bunch of scripts to execute?
4904 You can use deployable. In this case, you can do the following:
4906 shell$ mkdir -p /tmp/newfiles/etc
4907 shell$ cd /tmp/newfiles/etc
4908 # Craft the new files
4910 # craft a shell script to be executed remotely and set the exec bit
4911 # Suppose it's called deploy.sh
4912 shell$ deployable -o deploy.pl -R etc deploy.sh -d deploy.sh
4914 # Now, for each server
4915 shell$ scp deploy.pl $server:/tmp
4916 shell$ ssh $server /tmp/deploy.pl
4918 And you're done. This can be particularly useful if you have another
4919 layer of deployment, e.g. if you have to run a script to decide which
4920 of a group of archives should be deployed. For example, you could craft
4921 a different new "etc" for each server (which is particularly true if
4922 network configurations are in the package), and produce a simple script
4923 to choose which file to use based on the MAC address of the machine. In
4924 this case you could have:
4928 =item newetc.*.tar.gz
4930 a bunch of tar files with the configurations for each different server
4934 a list file with the association between the MAC addresses and the
4935 real tar file to deploy from the bunch in the previous bullet
4937 =item deploy-the-right-stuff.sh
4939 a script to get the real MAC address of the machine, select the right
4940 tar file and do the deployment.
4944 So, you can do the following:
4946 shell$ deployable -o deploy.pl newetc.*.tar.gz newetc.list \
4947 deploy-the-right-stuff.sh --exec deploy-the-right-stuff.sh
4949 # Now, for each server:
4950 shell$ scp deploy.pl $server:/tmp
4951 shell$ ssh $server /tmp/deploy.pl
4953 So, once you have the deploy script on the target machine all you need
4954 to do is to execute it. This can come handy when you cannot access the
4955 machines from the network, but you have to go there physically: you
4956 can prepare all in advance, and just call the deploy script.
4967 print a somewhat more verbose help, showing usage, this description of
4968 the options and some examples from the synopsis.
4972 print out the full documentation for the script.
4976 print a concise usage line and exit.
4980 print the version of the script.
4988 =item B<< --bundle | --all-exec | -X >>
4990 Set bundle flag in the produced script. If the bundle flag is set, the
4991 I<deploy script> will treat all executables in the main deployment
4992 directory as scripts to be executed.
4994 By default the flag is not set.
4996 =item B<< --bzip2 | --bz2 | -j >>
4998 Compress tar archives with bzip2.
5000 =item B<< --cleanup | -c >>
5002 Set cleanup flag in the produced script. If the cleanup flag is set, the
5003 I<deploy script> will clean up after having performed all operations.
5005 You can set this flag to C<0> by using C<--no-cleanup>.
5007 =item B<< --deploy | --exec | -d <filename> >>
5009 Set the name of a program to execute after extraction. You can provide
5010 multiple program names, they will be executed in the same order.
5012 =item B<< --gzip | --gz | -z >>
5014 Compress tar archives with gzip.
5016 =item B<< --heredir | -H <path> >>
5018 Set the name of a "here directory" (see L<DESCRIPTION>). You can use this
5019 option multiple times to provide multiple directories.
5021 =item B<< --include-archive-tar | -T >>
5023 Embed L<Archive::Tar> (with its dependencies L<Archive::Tar::Constant> and
5024 L<Archive::Tar::File>) inside the final script. Use this when you know (or
5025 aren't sure) that L<Archive::Tar> will not be available in the target
5028 =item B<< --no-tar >>
5030 Don't use system C<tar>.
5032 =item B<< --output | -o <filename> >>
5034 Set the output file name. By default the I<deploy script> will be given
5035 out on the standard output; if you provide a filename (different from
5036 C<->, of course!) the script will be saved there and the permissions will
5039 =item B<< --root | -r <dirname> >>
5041 Include C<dirname> contents for deployment under root directory. The
5042 actual production procedure is: hop into C<dirname> and grab a tarball
5043 of C<.>. During deployment, hop into C</> and extract the tarball.
5045 This is useful if you're already building up the absolute deployment
5046 layout under a given directory: just treat that directory as if it were
5047 the root of the target system.
5049 =item B<< --rootdir | --in-root | -R <filename> >>
5051 Include C<filename> as an item that will be extracted under root
5052 directory. The actual production procedure is: grab a tarball of
5053 C<filename>. During deployment, hop into C</> and extract the tarball.
5055 This is useful e.g. if you have a directory (or a group of directories)
5056 that you want to deploy directly under the root.
5058 Note that the C<--rootdir> alias is kept for backwards compatibility
5059 but is not 100% correct - you can specify both a dirname (like it was
5060 previously stated) or a single file with this option. This is why it's
5061 more readably to use C<--in-root> instead.
5063 =item B<< --tar | -t <program-path> >>
5065 Set the system C<tar> program to use.
5067 =item B<< --tempdir-mode | -m >>
5069 set default permissions for temporary directory of deployable script
5071 =item B<< --workdir | --deploy-directory | -w <path> >>
5073 Set the working directory for the deploy.
5077 =head1 ROOT OR ROOTDIR?
5079 There are two options that allow you to specify things to be deployed
5080 in C</>, so what should you use? Thing is... whatever you want!
5082 If you have a bunch of directories that have to appear under root, probably
5083 your best bet is to put them all inside a directory called C<myroot> and
5084 use option C<--root>:
5086 shell$ mkdir -p myroot/{etc,opt,var,lib,usr,whatever}
5087 # Now put stuff in the directories created above...
5088 shell$ deployable --root myroot ...
5090 On the other hand, if you just want to put stuff starting from one or
5091 two directories that have to show up in C</>, you can avoid creating
5092 the extra C<myroot> directory and use C<--in-root> instead:
5094 shell$ mkdir -p etc/whatever
5095 # Now put stuff in etc/whatever...
5096 shell$ deployable --in-root etc ...
5098 They are indeed somehow equivalent, the first avoiding you much typing
5099 when you have many directories to be deployed starting from root (just
5100 put them into the same subdirectory), the second allowing you to avoid
5101 putting an extra directory layer.
5103 There is indeed an additional catch that makes them quite different. When
5104 you use C<root>, the whole content of the directory specified will be
5105 used as a base, so you will end up with a listing like this:
5109 opt/local/application/
5110 opt/local/application/myfile.txt
5111 opt/local/application/otherfile.txt
5113 i.e. all intermediate directories will be saved. On the other hand, when
5114 you specify a directory with C<--in-root>, you're not limited to provide
5115 a "single-step" directory, so for example:
5117 shell$ deployable --in-root opt/local/application
5119 will result in the following list of files/directories to be stored:
5121 opt/local/application/
5122 opt/local/application/myfile.txt
5123 opt/local/application/otherfile.txt
5125 i.e. the upper level directories will not be included. What is better for
5126 you is for you to judge.
5128 =head1 THE DEPLOY SCRIPT
5130 The net result of calling this script is to produce another script,
5131 that we call the I<deploy script>. This script is made of two parts: the
5132 code, which is fixed, and the configurations/files, which is what is
5133 actually produced. The latter part is put after the C<__END__> marker,
5136 Stuff in the configuration part is always hexified in order to prevent
5137 strange tricks or errors. Comments will help you devise what's inside the
5138 configurations themselves.
5140 The I<deploy script> has options itself, even if they are quite minimal.
5141 In particular, it supports the same options C<--workdir|-w> and
5142 C<--cleanup> described above, allowing the final user to override the
5143 configured values. By default, the I<workdir> is set to C</tmp>
5144 and the script will clean up after itself.
5146 The following options are supported in the I<deploy script>:
5150 =item B<--usage | --man | --help>
5152 print a minimal help and exit
5156 print script version and exit
5158 =item B<--bundle | --all-exec | -X>
5160 treat all executables in the main deployment directory as scripts
5163 =item B<--cleanup | --no-cleanup>
5165 perform / don't perform temporary directory cleanup after work done
5167 =item B<< --deploy | --no-deploy >>
5169 deploy scripts are executed by default (same as specifying '--deploy')
5170 but you can prevent it.
5172 =item B<--dryrun | --dry-run>
5174 print final options and exit
5176 =item B<< --filelist | --list | -l >>
5178 print a list of files that are shipped in the deploy script
5180 =item B<< --heretar | --here-tar | -H >>
5182 print out the tar file that contains all the files that would be
5183 extracted in the temporary directory, useful to redirect to file or
5184 pipe to the tar program
5186 =item B<< --inspect <dirname> >>
5188 just extract all the stuff into <dirname> for inspection. Implies
5189 C<--no-deploy>, C<--no-tempdir>, ignores C<--bundle> (as a consequence of
5190 C<--no-deploy>), disables C<--cleanup> and sets the working directory
5193 =item B<< --no-tar >>
5195 don't use system C<tar>
5197 =item B<< --rootar | --root-tar | -R >>
5199 print out the tar file that contains all the files that would be
5200 extracted in the root directory, useful to redirect to file or
5201 pipe to the tar program
5203 =item B<--show | --show-options | -s>
5205 print configured options and exit
5207 =item B<< --tar | -t <program-path> >>
5209 set the system C<tar> program to use.
5211 =item B<< --tarfile | -F <filename> >>
5213 add the specified C<filename> (assumed to be an uncompressed
5214 TAR file) to the lot for root extraction. This can come handy
5215 when you already have all the files backed up in a TAR archive
5216 and you're not willing to expand them (e.g. because your
5217 filesystem is case-insensitive...).
5219 =item B<< --tempdir | --no-tempdir >>
5221 by default a temporary directory is created (same as specifying
5222 C<--tempdir>), but you can execute directly in the workdir (see below)
5223 without creating it.
5225 =item B<< --tempdir-mode | -m >>
5227 temporary directories (see C<--tempdir>) created by File::Temp have
5228 permission 600 that prevents group/others from even looking at the
5229 contents. You might want to invoke some of the internal scripts
5230 from another user (e.g. via C<su>), so you can pass a mode to be
5231 set on the temporary directory.
5233 Works only if C<--tempdir> is active.
5235 =item B<< --xform | -x <src:filename> >>
5237 include file or directory C<src> as path C<filename>. The latter can be
5238 either an absolute path (included in C<root>) or a relative one
5239 (included in the working directory).
5241 =item B<--workdir | --work-directory | --deploy-directory | -w>
5243 working base directory (a temporary subdirectory will be created
5248 Note the difference between C<--show> and C<--dryrun>: the former will
5249 give you the options that are "embedded" in the I<deploy script> without
5250 taking into account other options given on the command line, while the
5251 latter will give you the final options that would be used if the script
5252 were called without C<--dryrun>.
5254 =head2 Deploy Script Example Usage
5256 In the following, we'll assume that the I<deploy script> is called
5259 To execute the script with the already configured options, you just have
5264 If you just want to see which configurations are in the I<deploy script>:
5266 shell$ ./deploy.pl --show
5268 To see which files are included, you have two options. One is asking the
5271 shell$ ./deploy.pl --filelist
5273 the other is piping to tar:
5275 shell$ ./deploy.pl --tar | tar tvf -
5277 Extract contents of the script in a temp directory and simply inspect
5280 # extract stuff into subdirectory 'inspect' for... inspection
5281 shell$ ./deploy.pl --no-tempdir --no-deploy --workdir inspect
5283 =head2 Deploy Script Requirements
5285 You'll need a working Perl with version at least 5.6.2.
5287 If you specify L</--include-archive-tar>, the module L<Archive::Tar> will
5288 be included as well. This should ease your life and avoid you to have
5289 B<tar> on the target machine. On the other hand, if you already know
5290 that B<tar> will be available, you can avoid including C<Archive::Tar>
5291 and have the generated script use it (it could be rather slower anyway).
5295 Each error message should be enough explicit to be understood without the
5296 need for furter explainations. Which is another way to say that I'm way
5297 too lazy to list all possible ways that this script has to fail.
5300 =head1 CONFIGURATION AND ENVIRONMENT
5302 deployable requires no configuration files or environment variables.
5304 Please note that deployable B<needs> to find its master B<remote> file
5305 to produce the final script. This must be put in the same directory where
5306 deployable is put. You should be able to B<symlink> deployable where you
5307 think it's better, anyway - it will go search for the original file
5308 and look for B<remote> inside the same directory. This does not apply to
5309 hard links, of course.
5314 All core modules, apart the following:
5318 =item B<< Archive::Tar >>
5320 =item B<< File::Find::Rule >>
5324 =head1 BUGS AND LIMITATIONS
5326 No bugs have been reported.
5328 Please report any bugs or feature requests to the AUTHOR below.
5330 Be sure to read L<CONFIGURATION AND ENVIRONMENT> for a slight limitation
5331 about the availability of the B<remote> script.
5335 Flavio Poletti C<flavio [AT] polettix.it>
5338 =head1 LICENSE AND COPYRIGHT
5340 Copyright (c) 2008, Flavio Poletti C<flavio [AT] polettix.it>. All rights reserved.
5342 This script is free software; you can redistribute it and/or
5343 modify it under the same terms as Perl itself. See L<perlartistic>
5346 =head1 DISCLAIMER OF WARRANTY
5348 BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
5349 FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
5350 OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
5351 PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
5352 EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5353 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
5354 ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
5355 YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
5356 NECESSARY SERVICING, REPAIR, OR CORRECTION.
5358 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
5359 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
5360 REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE
5361 LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
5362 OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
5363 THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
5364 RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
5365 FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
5366 SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
5371 package main
; # ensure DATA is main::DATA
5374 # *** NOTE *** LEAVE THIS MODULE LIST AS A PARAGRAPH
5378 our $VERSION = '0.2.0';
5379 use English
qw( -no_match_vars );
5380 use Fatal
qw( close chdir opendir closedir );
5381 use File
::Temp
qw( tempdir );
5382 use File
::Path
qw( mkpath );
5383 use File
::Spec
::Functions
qw( file_name_is_absolute catfile );
5384 use File
::Basename
qw( basename dirname );
5385 use POSIX
qw( strftime );
5386 use Getopt
::Long
qw( :config gnu_getopt );
5387 use Cwd
qw( getcwd );
5388 use Fcntl
qw( :seek );
5390 # *** NOTE *** LEAVE EMPTY LINE ABOVE
5391 my %default_config = ( # default values
5400 my $DATA_POSITION = tell DATA
; # GLOBAL VARIABLE
5401 my %script_config = (%default_config, get_config
());
5403 my %config = %script_config;
5404 if ($ENV{DEPLOYABLE_DISABLE_PASSTHROUGH
} || (!$config{passthrough
})) {
5421 show|show-options|s!
5426 workdir|work-directory|deploy-directory|w=s
5429 %config = (%config, %cmdline_config);
5430 } ## end if ($ENV{DEPLOYABLE_DISABLE_PASSTHROUGH...})
5432 usage
() if $config{usage
};
5433 version
() if $config{version
};
5435 if ($config{roottar
}) {
5437 my ($fh, $size) = locate_file
('root');
5438 copy
($fh, \
*STDOUT
, $size);
5440 } ## end if ($config{roottar})
5442 if ($config{heretar
}) {
5444 my ($fh, $size) = locate_file
('here');
5445 copy
($fh, \
*STDOUT
, $size);
5447 } ## end if ($config{heretar})
5449 if ($config{show
}) {
5450 require Data
::Dumper
;
5451 print {*STDOUT
} Data
::Dumper
::Dumper
(\
%script_config);
5455 if ($config{inspect
}) {
5456 $config{cleanup
} = 0;
5457 $config{'no-exec'} = 1;
5458 $config{'tempdir'} = 0;
5459 $config{workdir
} = $config{inspect
};
5460 } ## end if ($config{inspect})
5462 if ($config{dryrun
}) {
5463 require Data
::Dumper
;
5464 print {*STDOUT
} Data
::Dumper
::Dumper
(\
%config);
5468 if ($config{filelist
}) {
5469 my $root_tar = get_sub_tar
('root');
5471 $root_tar->print_filelist();
5472 my $here_tar = get_sub_tar
('here');
5474 $here_tar->print_filelist();
5476 } ## end if ($config{filelist})
5478 # here we have to do things for real... probably, so save the current
5479 # working directory for consumption by the scripts
5480 $ENV{OLD_PWD
} = getcwd
();
5482 # go into the working directory, creating any intermediate if needed
5483 mkpath
($config{workdir
});
5484 chdir($config{workdir
});
5485 print {*STDERR
} "### Got into working directory '$config{workdir}'\n\n"
5486 if $config{verbose
};
5489 if ($config{'tempdir'}) { # Only if allowed
5490 my $me = basename
(__FILE__
) || 'deploy';
5491 my $now = strftime
('%Y-%m-%d_%H-%M-%S', localtime);
5493 join('-', $me, $now, ('X' x
10)),
5495 CLEANUP
=> $config{cleanup
}
5498 if ($config{'tempdir-mode'}) {
5499 chmod oct($config{'tempdir-mode'}), $tempdir
5500 or die "chmod('$tempdir'): $OS_ERROR\n";
5504 or die "chdir('$tempdir'): $OS_ERROR\n";
5506 if ($config{verbose
}) {
5508 "### Created and got into temporary directory '$tempdir'\n";
5509 print {*STDERR
} "### (will clean it up later)\n" if $config{cleanup
};
5510 print {*STDERR
} "\n";
5511 } ## end if ($config{verbose})
5512 } ## end if ($config{'tempdir'})
5514 eval { # Not really needed, but you know...
5515 $ENV{PATH
} = '/bin:/usr/bin:/sbin:/usr/sbin';
5517 execute_deploy_programs
() unless $config{'no-exec'};
5519 warn "$EVAL_ERROR\n" if $EVAL_ERROR;
5521 # Get back so that cleanup can successfully happen, if requested
5522 chdir '..' if defined $tempdir;
5525 my ($filename) = @_;
5527 seek $fh, $DATA_POSITION, SEEK_SET
;
5529 chomp(my $sizes = <$fh>);
5530 my ($name_size, $file_size) = split /\s+/, $sizes;
5531 my $name = full_read
($fh, $name_size);
5532 full_read
($fh, 1); # "\n"
5533 return ($fh, $file_size) if $name eq $filename;
5534 seek $fh, $file_size + 2, SEEK_CUR
; # includes "\n\n"
5535 } ## end while (!eof $fh)
5536 die "could not find '$filename'";
5537 } ## end sub locate_file
5540 my ($fh, $size) = @_;
5544 my $nread = read $fh, $buffer, $size;
5545 die "read(): $OS_ERROR" unless defined $nread;
5546 die "unexpected end of file" unless $nread;
5549 } ## end while ($size)
5551 } ## end sub full_read
5554 my ($ifh, $ofh, $size) = @_;
5557 my $nread = read $ifh, $buffer, ($size < 4096 ?
$size : 4096);
5558 die "read(): $OS_ERROR" unless defined $nread;
5559 die "unexpected end of file" unless $nread;
5560 print {$ofh} $buffer;
5562 } ## end while ($size)
5567 my ($filename) = @_;
5568 my ($fh, $size) = locate_file
($filename);
5569 return Deployable
::Tar
->new(%config, fh
=> $fh, size
=> $size);
5573 my ($fh, $size) = locate_file
('config.pl');
5574 my $config_text = full_read
($fh, $size);
5575 my $config = eval 'my ' . $config_text or return;
5576 return $config unless wantarray;
5578 } ## end sub get_config
5581 my $here_tar = get_sub_tar
('here');
5582 $here_tar->extract();
5584 my $root_dir = $config{inspect
} ?
'root' : '/';
5585 mkpath
$root_dir unless -d
$root_dir;
5588 my $root_tar = get_sub_tar
('root');
5589 $root_tar->extract();
5593 } ## end sub save_files
5595 sub execute_deploy_programs
{
5596 my @deploy_programs = @
{$config{deploy
} || []};
5598 if ($config{bundle
}) { # add all executable scripts in current directory
5599 print {*STDERR
} "### Auto-deploying all executables in main dir\n\n"
5600 if $config{verbose
};
5601 my %flag_for = map { $_ => 1 } @deploy_programs;
5602 opendir my $dh, '.';
5603 for my $item (sort readdir $dh) {
5604 next if $flag_for{$item};
5605 next unless ((-f
$item) || (-l
$item)) && (-x
$item);
5606 $flag_for{$item} = 1;
5607 push @deploy_programs, $item;
5608 } ## end for my $item (sort readdir...)
5610 } ## end if ($config{bundle})
5613 for my $deploy (@deploy_programs) {
5614 $deploy = catfile
('.', $deploy)
5615 unless file_name_is_absolute
($deploy);
5617 print {*STDERR
} "### Skipping '$deploy', not executable\n\n"
5618 if $config{verbose
};
5621 print {*STDERR
} "### Executing '$deploy'...\n"
5622 if $config{verbose
};
5623 system {$deploy} $deploy, @ARGV;
5624 print {*STDERR
} "\n"
5625 if $config{verbose
};
5626 } ## end DEPLOY: for my $deploy (@deploy_programs)
5629 } ## end sub execute_deploy_programs
5632 my $progname = basename
($0);
5633 print {*STDOUT
} <<"END_OF_USAGE" ;
5635 $progname version $VERSION - for help on calling and options, run:
5640 } ## end sub short_usage
5643 my $progname = basename($0);
5644 print {*STDOUT} <<"END_OF_USAGE
" ;
5645 $progname version $VERSION
5647 More or less, this script is intended to be launched without parameters.
5648 Anyway, you can also set the following options, which will override any
5649 present configuration (except in "--show
-options
"):
5651 * --usage | --man | --help
5652 print these help lines and exit
5655 print script version and exit
5657 * --bundle | --all-exec | -X
5658 treat all executables in the main deployment directory as scripts
5661 * --cleanup | -c | --no-cleanup
5662 perform / don't perform temporary directory cleanup after work done
5664 * --deploy | --no-deploy
5665 deploy scripts are executed by default (same as specifying '--deploy')
5666 but you can prevent it.
5668 * --dryrun | --dry-run
5669 print final options and exit
5671 * --filelist | --list | -l
5672 print a list of files that are shipped in the deploy script
5674 * --heretar | --here-tar | -H
5675 print out the tar file that contains all the files that would be
5676 extracted in the temporary directory, useful to redirect to file or
5677 pipe to the tar program
5679 * --inspect | -i <dirname>
5680 just extract all the stuff into <dirname> for inspection. Implies
5681 --no-deploy, --no-tempdir, ignores --bundle (as a consequence of
5682 --no-deploy), disables --cleanup and sets the working directory
5686 don't use system "tar
"
5688 * --roottar | --root-tar | -R
5689 print out the tar file that contains all the files that would be
5690 extracted in the root directory, useful to redirect to file or
5691 pipe to the tar program
5693 * --show | --show-options | -s
5694 print configured options and exit
5696 * --tar | -t <program-path>
5697 set the system "tar
" program to use.
5699 * --tempdir | --no-tempdir
5700 by default a temporary directory is created (same as specifying
5701 '--tempdir'), but you can execute directly in the workdir (see below)
5702 without creating it.
5704 * --tempdir-mode | -m
5705 set permissions of temporary directory (octal string)
5707 * --workdir | --work-directory | --deploy-directory | -w
5708 working base directory (a temporary subdirectory will be created
5716 print "$0 version
$VERSION\n";
5720 package Deployable::Tar;
5723 my $package = shift;
5724 my $self = {ref $_[0] ? %{$_[0]} : @_};
5725 $package = 'Deployable::Tar::Internal';
5726 if (!$self->{'no-tar'}) {
5727 if ((exists $self->{tar}) || (open my $fh, '-|', 'tar', '--help')) {
5728 $package = 'Deployable::Tar::External';
5729 $self->{tar} ||= 'tar';
5731 } ## end if (!$self->{'no-tar'})
5732 bless $self, $package;
5733 $self->initialise() if $self->can('initialise');
5737 package Deployable::Tar::External;
5738 use English qw( -no_match_vars );
5743 $self->{bzip2
} ?
'j'
5744 : $self->{gzip
} ?
'z'
5746 $self->{_list_command
} = 'tv' . $compression . 'f';
5747 $self->{_extract_command
} = 'x' . $compression . 'f';
5748 } ## end sub initialise
5750 sub print_filelist
{
5752 if ($self->{size
}) {
5753 open my $tfh, '|-', $self->{tar
}, $self->{_list_command
}, '-'
5754 or die "open() on pipe to tar: $OS_ERROR";
5755 main
::copy
($self->{fh
}, $tfh, $self->{size
});
5758 } ## end sub print_filelist
5762 if ($self->{size
}) {
5763 open my $tfh, '|-', $self->{tar
}, $self->{_extract_command
}, '-'
5764 or die "open() on pipe to tar: $OS_ERROR";
5765 main
::copy
($self->{fh
}, $tfh, $self->{size
});
5768 } ## end sub extract
5770 package Deployable
::Tar
::Internal
;
5771 use English
qw( -no_match_vars );
5776 if ($self->{size
}) {
5777 my $data = main
::full_read
($self->{fh
}, $self->{size
});
5778 open my $fh, '<', \
$data
5779 or die "open() on internal variable: $OS_ERROR";
5781 require Archive
::Tar
;
5782 $self->{_tar
} = Archive
::Tar
->new();
5783 $self->{_tar
}->read($fh);
5784 } ## end if ($self->{size})
5787 } ## end sub initialise
5789 sub print_filelist
{
5791 if ($self->{size
}) {
5792 print {*STDOUT
} " $_\n" for $self->{_tar
}->list_files();
5795 } ## end sub print_filelist
5799 if ($self->{size
}) {
5800 $self->{_tar
}->extract();
5803 } ## end sub extract