Fixes for ext/compress
[p5sagit/p5-mst-13.2.git] / lib / Archive / Extract.pm
CommitLineData
520c99e2 1package Archive::Extract;
2
3use strict;
4
5use Cwd qw[cwd];
6use Carp qw[carp];
7use IPC::Cmd qw[run can_run];
8use FileHandle;
9use File::Path qw[mkpath];
10use File::Spec;
11use File::Basename qw[dirname basename];
12use Params::Check qw[check];
13use Module::Load::Conditional qw[can_load check_install];
14use Locale::Maketext::Simple Style => 'gettext';
15
16### solaris has silly /bin/tar output ###
17use constant ON_SOLARIS => $^O eq 'solaris' ? 1 : 0;
18use constant FILE_EXISTS => sub { -e $_[0] ? 1 : 0 };
19
4f3b9739 20### VMS may require quoting upper case command options
21use constant ON_VMS => $^O eq 'VMS' ? 1 : 0;
22
e74f3fd4 23### Windows needs special treatment of Tar options
24use constant ON_WIN32 => $^O eq 'MSWin32' ? 1 : 0;
25
83285295 26### we can't use this extraction method, because of missing
27### modules/binaries:
28use constant METHOD_NA => [];
29
520c99e2 30### If these are changed, update @TYPES and the new() POD
31use constant TGZ => 'tgz';
32use constant TAR => 'tar';
33use constant GZ => 'gz';
34use constant ZIP => 'zip';
35use constant BZ2 => 'bz2';
36use constant TBZ => 'tbz';
1dae2fb5 37use constant Z => 'Z';
8d2ac73b 38use constant LZMA => 'lzma';
520c99e2 39
83285295 40use vars qw[$VERSION $PREFER_BIN $PROGRAMS $WARN $DEBUG
41 $_ALLOW_BIN $_ALLOW_PURE_PERL
42 ];
43
7bb74d35 44$VERSION = '0.31_03';
83285295 45$PREFER_BIN = 0;
46$WARN = 1;
47$DEBUG = 0;
48$_ALLOW_PURE_PERL = 1; # allow pure perl extractors
49$_ALLOW_BIN = 1; # allow binary extractors
520c99e2 50
83285295 51# same as all constants
52my @Types = ( TGZ, TAR, GZ, ZIP, BZ2, TBZ, Z, LZMA );
520c99e2 53
54local $Params::Check::VERBOSE = $Params::Check::VERBOSE = 1;
55
56=pod
57
58=head1 NAME
59
60Archive::Extract - A generic archive extracting mechanism
61
62=head1 SYNOPSIS
63
64 use Archive::Extract;
65
66 ### build an Archive::Extract object ###
67 my $ae = Archive::Extract->new( archive => 'foo.tgz' );
68
69 ### extract to cwd() ###
70 my $ok = $ae->extract;
71
72 ### extract to /tmp ###
73 my $ok = $ae->extract( to => '/tmp' );
74
75 ### what if something went wrong?
76 my $ok = $ae->extract or die $ae->error;
77
78 ### files from the archive ###
79 my $files = $ae->files;
80
81 ### dir that was extracted to ###
82 my $outdir = $ae->extract_path;
83
84
85 ### quick check methods ###
86 $ae->is_tar # is it a .tar file?
87 $ae->is_tgz # is it a .tar.gz or .tgz file?
88 $ae->is_gz; # is it a .gz file?
89 $ae->is_zip; # is it a .zip file?
90 $ae->is_bz2; # is it a .bz2 file?
91 $ae->is_tbz; # is it a .tar.bz2 or .tbz file?
8d2ac73b 92 $ae->is_lzma; # is it a .lzma file?
520c99e2 93
94 ### absolute path to the archive you provided ###
95 $ae->archive;
96
97 ### commandline tools, if found ###
98 $ae->bin_tar # path to /bin/tar, if found
99 $ae->bin_gzip # path to /bin/gzip, if found
100 $ae->bin_unzip # path to /bin/unzip, if found
101 $ae->bin_bunzip2 # path to /bin/bunzip2 if found
8d2ac73b 102 $ae->bin_unlzma # path to /bin/unlzma if found
520c99e2 103
104=head1 DESCRIPTION
105
106Archive::Extract is a generic archive extraction mechanism.
107
108It allows you to extract any archive file of the type .tar, .tar.gz,
8d2ac73b 109.gz, .Z, tar.bz2, .tbz, .bz2, .zip or .lzma without having to worry how it
1dae2fb5 110does so, or use different interfaces for each type by using either
111perl modules, or commandline tools on your system.
520c99e2 112
113See the C<HOW IT WORKS> section further down for details.
114
115=cut
116
117
118### see what /bin/programs are available ###
119$PROGRAMS = {};
8d2ac73b 120for my $pgm (qw[tar unzip gzip bunzip2 uncompress unlzma]) {
520c99e2 121 $PROGRAMS->{$pgm} = can_run($pgm);
122}
123
124### mapping from types to extractor methods ###
83285295 125my $Mapping = { # binary program # pure perl module
126 is_tgz => { bin => '_untar_bin', pp => '_untar_at' },
127 is_tar => { bin => '_untar_bin', pp => '_untar_at' },
128 is_gz => { bin => '_gunzip_bin', pp => '_gunzip_cz' },
129 is_zip => { bin => '_unzip_bin', pp => '_unzip_az' },
130 is_tbz => { bin => '_untar_bin', pp => '_untar_at' },
131 is_bz2 => { bin => '_bunzip2_bin', pp => '_bunzip2_bz2'},
132 is_Z => { bin => '_uncompress_bin', pp => '_gunzip_cz' },
133 is_lzma => { bin => '_unlzma_bin', pp => '_unlzma_cz' },
520c99e2 134};
135
83285295 136{ ### use subs so we re-generate array refs etc for the no-overide flags
137 ### if we don't, then we reuse the same arrayref, meaning objects store
138 ### previous errors
520c99e2 139 my $tmpl = {
83285295 140 archive => sub { { required => 1, allow => FILE_EXISTS } },
141 type => sub { { default => '', allow => [ @Types ] } },
142 _error_msg => sub { { no_override => 1, default => [] } },
143 _error_msg_long => sub { { no_override => 1, default => [] } },
520c99e2 144 };
145
146 ### build accesssors ###
147 for my $method( keys %$tmpl,
148 qw[_extractor _gunzip_to files extract_path],
520c99e2 149 ) {
150 no strict 'refs';
151 *$method = sub {
152 my $self = shift;
153 $self->{$method} = $_[0] if @_;
154 return $self->{$method};
155 }
156 }
157
158=head1 METHODS
159
160=head2 $ae = Archive::Extract->new(archive => '/path/to/archive',[type => TYPE])
161
162Creates a new C<Archive::Extract> object based on the archive file you
163passed it. Automatically determines the type of archive based on the
164extension, but you can override that by explicitly providing the
165C<type> argument.
166
167Valid values for C<type> are:
168
169=over 4
170
171=item tar
172
173Standard tar files, as produced by, for example, C</bin/tar>.
174Corresponds to a C<.tar> suffix.
175
176=item tgz
177
178Gzip compressed tar files, as produced by, for example C</bin/tar -z>.
179Corresponds to a C<.tgz> or C<.tar.gz> suffix.
180
181=item gz
182
183Gzip compressed file, as produced by, for example C</bin/gzip>.
184Corresponds to a C<.gz> suffix.
185
1dae2fb5 186=item Z
187
188Lempel-Ziv compressed file, as produced by, for example C</bin/compress>.
189Corresponds to a C<.Z> suffix.
190
520c99e2 191=item zip
192
193Zip compressed file, as produced by, for example C</bin/zip>.
194Corresponds to a C<.zip>, C<.jar> or C<.par> suffix.
195
196=item bz2
197
198Bzip2 compressed file, as produced by, for example, C</bin/bzip2>.
199Corresponds to a C<.bz2> suffix.
200
201=item tbz
202
203Bzip2 compressed tar file, as produced by, for exmample C</bin/tar -j>.
204Corresponds to a C<.tbz> or C<.tar.bz2> suffix.
205
8d2ac73b 206=item lzma
207
208Lzma compressed file, as produced by C</bin/lzma>.
209Corresponds to a C<.lzma> suffix.
210
520c99e2 211=back
212
213Returns a C<Archive::Extract> object on success, or false on failure.
214
215=cut
216
217 ### constructor ###
218 sub new {
219 my $class = shift;
220 my %hash = @_;
83285295 221
222 ### see above why we use subs here and generate the template;
223 ### it's basically to not re-use arrayrefs
224 my %utmpl = map { $_ => $tmpl->{$_}->() } keys %$tmpl;
520c99e2 225
83285295 226 my $parsed = check( \%utmpl, \%hash ) or return;
520c99e2 227
228 ### make sure we have an absolute path ###
229 my $ar = $parsed->{archive} = File::Spec->rel2abs( $parsed->{archive} );
230
231 ### figure out the type, if it wasn't already specified ###
232 unless ( $parsed->{type} ) {
233 $parsed->{type} =
574b415d 234 $ar =~ /.+?\.(?:tar\.gz|tgz)$/i ? TGZ :
520c99e2 235 $ar =~ /.+?\.gz$/i ? GZ :
236 $ar =~ /.+?\.tar$/i ? TAR :
237 $ar =~ /.+?\.(zip|jar|par)$/i ? ZIP :
9e5a0ef9 238 $ar =~ /.+?\.(?:tbz2?|tar\.bz2?)$/i ? TBZ :
520c99e2 239 $ar =~ /.+?\.bz2$/i ? BZ2 :
1dae2fb5 240 $ar =~ /.+?\.Z$/ ? Z :
8d2ac73b 241 $ar =~ /.+?\.lzma$/ ? LZMA :
520c99e2 242 '';
243
244 }
245
83285295 246 bless $parsed, $class;
520c99e2 247
83285295 248 ### don't know what type of file it is
249 ### XXX this *has* to be an object call, not a package call
250 return $parsed->_error(loc("Cannot determine file type for '%1'",
251 $parsed->{archive} )) unless $parsed->{type};
252 return $parsed;
520c99e2 253 }
254}
255
256=head2 $ae->extract( [to => '/output/path'] )
257
258Extracts the archive represented by the C<Archive::Extract> object to
259the path of your choice as specified by the C<to> argument. Defaults to
260C<cwd()>.
261
262Since C<.gz> files never hold a directory, but only a single file; if
263the C<to> argument is an existing directory, the file is extracted
83285295 264there, with its C<.gz> suffix stripped.
520c99e2 265If the C<to> argument is not an existing directory, the C<to> argument
266is understood to be a filename, if the archive type is C<gz>.
267In the case that you did not specify a C<to> argument, the output
83285295 268file will be the name of the archive file, stripped from its C<.gz>
520c99e2 269suffix, in the current working directory.
270
271C<extract> will try a pure perl solution first, and then fall back to
272commandline tools if they are available. See the C<GLOBAL VARIABLES>
273section below on how to alter this behaviour.
274
275It will return true on success, and false on failure.
276
277On success, it will also set the follow attributes in the object:
278
279=over 4
280
281=item $ae->extract_path
282
283This is the directory that the files where extracted to.
284
285=item $ae->files
286
287This is an array ref with the paths of all the files in the archive,
288relative to the C<to> argument you specified.
289To get the full path to an extracted file, you would use:
290
291 File::Spec->catfile( $to, $ae->files->[0] );
292
293Note that all files from a tar archive will be in unix format, as per
294the tar specification.
295
296=back
297
298=cut
299
300sub extract {
301 my $self = shift;
302 my %hash = @_;
303
83285295 304 ### reset error messages
305 $self->_error_msg( [] );
306 $self->_error_msg_long( [] );
307
520c99e2 308 my $to;
309 my $tmpl = {
310 to => { default => '.', store => \$to }
311 };
312
313 check( $tmpl, \%hash ) or return;
314
315 ### so 'to' could be a file or a dir, depending on whether it's a .gz
316 ### file, or basically anything else.
317 ### so, check that, then act accordingly.
318 ### set an accessor specifically so _gunzip can know what file to extract
319 ### to.
320 my $dir;
321 { ### a foo.gz file
8d2ac73b 322 if( $self->is_gz or $self->is_bz2 or $self->is_Z or $self->is_lzma ) {
520c99e2 323
8d2ac73b 324 my $cp = $self->archive; $cp =~ s/\.(?:gz|bz2?|Z|lzma)$//i;
520c99e2 325
326 ### to is a dir?
327 if ( -d $to ) {
328 $dir = $to;
329 $self->_gunzip_to( basename($cp) );
330
331 ### then it's a filename
332 } else {
333 $dir = dirname($to);
334 $self->_gunzip_to( basename($to) );
335 }
336
337 ### not a foo.gz file
338 } else {
339 $dir = $to;
340 }
341 }
342
343 ### make the dir if it doesn't exist ###
344 unless( -d $dir ) {
345 eval { mkpath( $dir ) };
346
347 return $self->_error(loc("Could not create path '%1': %2", $dir, $@))
348 if $@;
349 }
350
351 ### get the current dir, to restore later ###
352 my $cwd = cwd();
353
354 my $ok = 1;
355 EXTRACT: {
356
357 ### chdir to the target dir ###
358 unless( chdir $dir ) {
359 $self->_error(loc("Could not chdir to '%1': %2", $dir, $!));
360 $ok = 0; last EXTRACT;
361 }
362
363 ### set files to an empty array ref, so there's always an array
364 ### ref IN the accessor, to avoid errors like:
365 ### Can't use an undefined value as an ARRAY reference at
366 ### ../lib/Archive/Extract.pm line 742. (rt #19815)
367 $self->files( [] );
368
83285295 369 ### find out the dispatch methods needed for this type of
370 ### archive. Do a $self->is_XXX to figure out the type, then
371 ### get the hashref with bin + pure perl dispatchers.
372 my ($map) = map { $Mapping->{$_} } grep { $self->$_ } keys %$Mapping;
520c99e2 373
83285295 374 ### add pure perl extractor if allowed & add bin extractor if allowed
375 my @methods;
376 push @methods, $map->{'pp'} if $_ALLOW_PURE_PERL;
377 push @methods, $map->{'bin'} if $_ALLOW_BIN;
378
379 ### reverse it if we prefer bin extractors
380 @methods = reverse @methods if $PREFER_BIN;
520c99e2 381
83285295 382 my($na, $fail);
383 for my $method (@methods) {
384 print "# Extracting with ->$method\n" if $DEBUG;
385
386 my $rv = $self->$method;
387
388 ### a positive extraction
389 if( $rv and $rv ne METHOD_NA ) {
390 print "# Extraction succeeded\n" if $DEBUG;
391 $self->_extractor($method);
392 last;
393
394 ### method is not available
395 } elsif ( $rv and $rv eq METHOD_NA ) {
396 print "# Extraction method not available\n" if $DEBUG;
397 $na++;
398 } else {
399 print "# Extraction method failed\n" if $DEBUG;
400 $fail++;
401 }
402 }
520c99e2 403
83285295 404 ### warn something went wrong if we didn't get an extractor
405 unless( $self->_extractor ) {
406 my $diag = $fail ? loc("Extract failed due to errors") :
407 $na ? loc("Extract failed; no extractors available") :
408 '';
409
410 $self->_error($diag);
411 $ok = 0;
412 }
520c99e2 413 }
414
415 ### and chdir back ###
416 unless( chdir $cwd ) {
417 $self->_error(loc("Could not chdir back to start dir '%1': %2'",
418 $cwd, $!));
419 }
420
421 return $ok;
422}
423
424=pod
425
426=head1 ACCESSORS
427
428=head2 $ae->error([BOOL])
429
430Returns the last encountered error as string.
431Pass it a true value to get the C<Carp::longmess()> output instead.
432
433=head2 $ae->extract_path
434
435This is the directory the archive got extracted to.
436See C<extract()> for details.
437
438=head2 $ae->files
439
440This is an array ref holding all the paths from the archive.
441See C<extract()> for details.
442
443=head2 $ae->archive
444
445This is the full path to the archive file represented by this
446C<Archive::Extract> object.
447
448=head2 $ae->type
449
450This is the type of archive represented by this C<Archive::Extract>
451object. See accessors below for an easier way to use this.
452See the C<new()> method for details.
453
454=head2 $ae->types
455
456Returns a list of all known C<types> for C<Archive::Extract>'s
457C<new> method.
458
459=cut
460
461sub types { return @Types }
462
463=head2 $ae->is_tgz
464
465Returns true if the file is of type C<.tar.gz>.
466See the C<new()> method for details.
467
468=head2 $ae->is_tar
469
470Returns true if the file is of type C<.tar>.
471See the C<new()> method for details.
472
473=head2 $ae->is_gz
474
475Returns true if the file is of type C<.gz>.
476See the C<new()> method for details.
477
1dae2fb5 478=head2 $ae->is_Z
479
480Returns true if the file is of type C<.Z>.
481See the C<new()> method for details.
482
520c99e2 483=head2 $ae->is_zip
484
485Returns true if the file is of type C<.zip>.
486See the C<new()> method for details.
487
8d2ac73b 488=head2 $ae->is_lzma
489
490Returns true if the file is of type C<.lzma>.
491See the C<new()> method for details.
492
520c99e2 493=cut
494
495### quick check methods ###
496sub is_tgz { return $_[0]->type eq TGZ }
497sub is_tar { return $_[0]->type eq TAR }
498sub is_gz { return $_[0]->type eq GZ }
499sub is_zip { return $_[0]->type eq ZIP }
500sub is_tbz { return $_[0]->type eq TBZ }
501sub is_bz2 { return $_[0]->type eq BZ2 }
1dae2fb5 502sub is_Z { return $_[0]->type eq Z }
8d2ac73b 503sub is_lzma { return $_[0]->type eq LZMA }
520c99e2 504
505=pod
506
507=head2 $ae->bin_tar
508
509Returns the full path to your tar binary, if found.
510
511=head2 $ae->bin_gzip
512
513Returns the full path to your gzip binary, if found
514
515=head2 $ae->bin_unzip
516
517Returns the full path to your unzip binary, if found
518
8d2ac73b 519=head2 $ae->bin_unlzma
520
521Returns the full path to your unlzma binary, if found
522
520c99e2 523=cut
524
525### paths to commandline tools ###
1dae2fb5 526sub bin_gzip { return $PROGRAMS->{'gzip'} if $PROGRAMS->{'gzip'} }
527sub bin_unzip { return $PROGRAMS->{'unzip'} if $PROGRAMS->{'unzip'} }
528sub bin_tar { return $PROGRAMS->{'tar'} if $PROGRAMS->{'tar'} }
529sub bin_bunzip2 { return $PROGRAMS->{'bunzip2'} if $PROGRAMS->{'bunzip2'} }
530sub bin_uncompress { return $PROGRAMS->{'uncompress'}
531 if $PROGRAMS->{'uncompress'} }
8d2ac73b 532sub bin_unlzma { return $PROGRAMS->{'unlzma'} if $PROGRAMS->{'unlzma'} }
533
9e5a0ef9 534=head2 $bool = $ae->have_old_bunzip2
535
536Older versions of C</bin/bunzip2>, from before the C<bunzip2 1.0> release,
537require all archive names to end in C<.bz2> or it will not extract
538them. This method checks if you have a recent version of C<bunzip2>
539that allows any extension, or an older one that doesn't.
540
541=cut
542
543sub have_old_bunzip2 {
544 my $self = shift;
545
546 ### no bunzip2? no old bunzip2 either :)
547 return unless $self->bin_bunzip2;
548
549 ### if we can't run this, we can't be sure if it's too old or not
550 ### XXX stupid stupid stupid bunzip2 doesn't understand --version
551 ### is not a request to extract data:
552 ### $ bunzip2 --version
553 ### bzip2, a block-sorting file compressor. Version 1.0.2, 30-Dec-2001.
554 ### [...]
555 ### bunzip2: I won't read compressed data from a terminal.
556 ### bunzip2: For help, type: `bunzip2 --help'.
557 ### $ echo $?
558 ### 1
559 ### HATEFUL!
8d2ac73b 560
561 ### double hateful: bunzip2 --version also hangs if input is a pipe
562 ### See #32370: Archive::Extract will hang if stdin is a pipe [+PATCH]
563 ### So, we have to provide *another* argument which is a fake filename,
83285295 564 ### just so it wont try to read from stdin to print its version..
8d2ac73b 565 ### *sigh*
566 ### Even if the file exists, it won't clobber or change it.
9e5a0ef9 567 my $buffer;
8d2ac73b 568 scalar run(
569 command => [$self->bin_bunzip2, '--version', 'NoSuchFile'],
9e5a0ef9 570 verbose => 0,
571 buffer => \$buffer
572 );
573
574 ### no output
575 return unless $buffer;
576
577 my ($version) = $buffer =~ /version \s+ (\d+)/ix;
578
579 return 1 if $version < 1;
580 return;
581}
520c99e2 582
583#################################
584#
585# Untar code
586#
587#################################
588
e74f3fd4 589### annoying issue with (gnu) tar on win32, as illustrated by this
590### bug: https://rt.cpan.org/Ticket/Display.html?id=40138
591### which shows that (gnu) tar will interpret a file name with a :
592### in it as a remote file name, so C:\tmp\foo.txt is interpreted
593### as a remote shell, and the extract fails.
594{ my @ExtraTarFlags;
595 if( ON_WIN32 and my $cmd = __PACKAGE__->bin_tar ) {
520c99e2 596
e74f3fd4 597 ### if this is gnu tar we are running, we need to use --force-local
598 push @ExtraTarFlags, '--force-local' if `$cmd --version` =~ /gnu tar/i;
83285295 599 }
520c99e2 600
520c99e2 601
e74f3fd4 602 ### use /bin/tar to extract ###
603 sub _untar_bin {
604 my $self = shift;
605
606 ### check for /bin/tar ###
607 ### check for /bin/gzip if we need it ###
608 ### if any of the binaries are not available, return NA
609 { my $diag = not $self->bin_tar ?
610 loc("No '%1' program found", '/bin/tar') :
611 $self->is_tgz && !$self->bin_gzip ?
612 loc("No '%1' program found", '/bin/gzip') :
613 $self->is_tbz && !$self->bin_bunzip2 ?
614 loc("No '%1' program found", '/bin/bunzip2') :
615 '';
616
617 if( $diag ) {
618 $self->_error( $diag );
619 return METHOD_NA;
620 }
621 }
622
623 ### XXX figure out how to make IPC::Run do this in one call --
624 ### currently i don't know how to get output of a command after a pipe
625 ### trapped in a scalar. Mailed barries about this 5th of june 2004.
626
627 ### see what command we should run, based on whether
628 ### it's a .tgz or .tar
629
630 ### XXX solaris tar and bsdtar are having different outputs
631 ### depending whether you run with -x or -t
632 ### compensate for this insanity by running -t first, then -x
633 { my $cmd =
634 $self->is_tgz ? [$self->bin_gzip, '-cdf', $self->archive, '|',
635 $self->bin_tar, '-tf', '-'] :
636 $self->is_tbz ? [$self->bin_bunzip2, '-cd', $self->archive, '|',
637 $self->bin_tar, '-tf', '-'] :
638 [$self->bin_tar, @ExtraTarFlags, '-tf', $self->archive];
639
7bb74d35 640 ### run the command
641 ### newer versions of 'tar' (1.21 and up) now print record size
642 ### to STDERR as well if v OR t is given (used to be both). This
643 ### is a 'feature' according to the changelog, so we must now only
644 ### inspect STDOUT, otherwise, failures like these occur:
645 ### nntp.perl.org/group/perl.cpan.testers/2009/02/msg3230366.html
646 my $buffer = '';
647 my @out = run( command => $cmd,
e74f3fd4 648 buffer => \$buffer,
7bb74d35 649 verbose => $DEBUG );
650
651 ### command was unsuccessful
652 unless( $out[0] ) {
e74f3fd4 653 return $self->_error(loc(
654 "Error listing contents of archive '%1': %2",
655 $self->archive, $buffer ));
656 }
657
658 ### no buffers available?
659 if( !IPC::Cmd->can_capture_buffer and !$buffer ) {
660 $self->_error( $self->_no_buffer_files( $self->archive ) );
661
662 } else {
663 ### if we're on solaris we /might/ be using /bin/tar, which has
664 ### a weird output format... we might also be using
665 ### /usr/local/bin/tar, which is gnu tar, which is perfectly
666 ### fine... so we have to do some guessing here =/
667 my @files = map { chomp;
668 !ON_SOLARIS ? $_
669 : (m|^ x \s+ # 'xtract' -- sigh
670 (.+?), # the actual file name
671 \s+ [\d,.]+ \s bytes,
672 \s+ [\d,.]+ \s tape \s blocks
673 |x ? $1 : $_);
674
7bb74d35 675 ### only STDOUT, see above
676 } map { split $/, $_ } @{$out[3]};
e74f3fd4 677
678 ### store the files that are in the archive ###
679 $self->files(\@files);
680 }
520c99e2 681 }
e74f3fd4 682
683 ### now actually extract it ###
684 { my $cmd =
685 $self->is_tgz ? [$self->bin_gzip, '-cdf', $self->archive, '|',
686 $self->bin_tar, '-xf', '-'] :
687 $self->is_tbz ? [$self->bin_bunzip2, '-cd', $self->archive, '|',
688 $self->bin_tar, '-xf', '-'] :
689 [$self->bin_tar, @ExtraTarFlags, '-xf', $self->archive];
690
691 my $buffer = '';
692 unless( scalar run( command => $cmd,
693 buffer => \$buffer,
694 verbose => $DEBUG )
695 ) {
696 return $self->_error(loc("Error extracting archive '%1': %2",
697 $self->archive, $buffer ));
698 }
699
700 ### we might not have them, due to lack of buffers
701 if( $self->files ) {
702 ### now that we've extracted, figure out where we extracted to
703 my $dir = $self->__get_extract_dir( $self->files );
520c99e2 704
e74f3fd4 705 ### store the extraction dir ###
706 $self->extract_path( $dir );
707 }
520c99e2 708 }
520c99e2 709
e74f3fd4 710 ### we got here, no error happened
711 return 1;
520c99e2 712 }
520c99e2 713}
714
e74f3fd4 715
520c99e2 716### use archive::tar to extract ###
717sub _untar_at {
718 my $self = shift;
719
83285295 720 ### Loading Archive::Tar is going to set it to 1, so make it local
721 ### within this block, starting with its initial value. Whatever
722 ### Achive::Tar does will be undone when we return.
723 ###
724 ### Also, later, set $Archive::Tar::WARN to $Archive::Extract::WARN
725 ### so users don't have to even think about this variable. If they
726 ### do, they still get their set value outside of this call.
727 local $Archive::Tar::WARN = $Archive::Tar::WARN;
728
729 ### we definitely need Archive::Tar, so load that first
520c99e2 730 { my $use_list = { 'Archive::Tar' => '0.0' };
731
732 unless( can_load( modules => $use_list ) ) {
733
83285295 734 $self->_error(loc("You do not have '%1' installed - " .
735 "Please install it as soon as possible.",
736 'Archive::Tar'));
737
738 return METHOD_NA;
520c99e2 739 }
740 }
741
742 ### we might pass it a filehandle if it's a .tbz file..
743 my $fh_to_read = $self->archive;
744
745 ### we will need Compress::Zlib too, if it's a tgz... and IO::Zlib
746 ### if A::T's version is 0.99 or higher
747 if( $self->is_tgz ) {
748 my $use_list = { 'Compress::Zlib' => '0.0' };
749 $use_list->{ 'IO::Zlib' } = '0.0'
750 if $Archive::Tar::VERSION >= '0.99';
751
752 unless( can_load( modules => $use_list ) ) {
753 my $which = join '/', sort keys %$use_list;
754
83285295 755 $self->_error(loc(
756 "You do not have '%1' installed - Please ".
757 "install it as soon as possible.", $which)
758 );
759
760 return METHOD_NA;
520c99e2 761 }
83285295 762
520c99e2 763 } elsif ( $self->is_tbz ) {
764 my $use_list = { 'IO::Uncompress::Bunzip2' => '0.0' };
765 unless( can_load( modules => $use_list ) ) {
83285295 766 $self->_error(loc(
767 "You do not have '%1' installed - Please " .
768 "install it as soon as possible.",
769 'IO::Uncompress::Bunzip2')
770 );
771
772 return METHOD_NA;
520c99e2 773 }
774
775 my $bz = IO::Uncompress::Bunzip2->new( $self->archive ) or
776 return $self->_error(loc("Unable to open '%1': %2",
777 $self->archive,
778 $IO::Uncompress::Bunzip2::Bunzip2Error));
779
780 $fh_to_read = $bz;
781 }
782
83285295 783 ### $Archive::Tar::WARN is 1 by default in Archive::Tar, but we've
784 ### localized $Archive::Tar::WARN already.
785 $Archive::Tar::WARN = $Archive::Extract::WARN;
786
520c99e2 787 my $tar = Archive::Tar->new();
788
789 ### only tell it it's compressed if it's a .tgz, as we give it a file
790 ### handle if it's a .tbz
791 unless( $tar->read( $fh_to_read, ( $self->is_tgz ? 1 : 0 ) ) ) {
792 return $self->_error(loc("Unable to read '%1': %2", $self->archive,
793 $Archive::Tar::error));
794 }
795
796 ### workaround to prevent Archive::Tar from setting uid, which
797 ### is a potential security hole. -autrijus
798 ### have to do it here, since A::T needs to be /loaded/ first ###
799 { no strict 'refs'; local $^W;
800
801 ### older versions of archive::tar <= 0.23
802 *Archive::Tar::chown = sub {};
803 }
804
83285295 805 ### for version of Archive::Tar > 1.04
806 local $Archive::Tar::CHOWN = 0;
520c99e2 807
808 { local $^W; # quell 'splice() offset past end of array' warnings
809 # on older versions of A::T
810
811 ### older archive::tar always returns $self, return value slightly
812 ### fux0r3d because of it.
813 $tar->extract()
814 or return $self->_error(loc("Unable to extract '%1': %2",
815 $self->archive, $Archive::Tar::error ));
816 }
817
818 my @files = $tar->list_files;
819 my $dir = $self->__get_extract_dir( \@files );
820
821 ### store the files that are in the archive ###
822 $self->files(\@files);
823
824 ### store the extraction dir ###
825 $self->extract_path( $dir );
826
827 ### check if the dir actually appeared ###
828 return 1 if -d $self->extract_path;
829
830 ### no dir, we failed ###
831 return $self->_error(loc("Unable to extract '%1': %2",
832 $self->archive, $Archive::Tar::error ));
833}
834
835#################################
836#
837# Gunzip code
838#
839#################################
840
520c99e2 841sub _gunzip_bin {
842 my $self = shift;
843
844 ### check for /bin/gzip -- we need it ###
83285295 845 unless( $self->bin_gzip ) {
846 $self->_error(loc("No '%1' program found", '/bin/gzip'));
847 return METHOD_NA;
848 }
520c99e2 849
850 my $fh = FileHandle->new('>'. $self->_gunzip_to) or
851 return $self->_error(loc("Could not open '%1' for writing: %2",
852 $self->_gunzip_to, $! ));
853
854 my $cmd = [ $self->bin_gzip, '-cdf', $self->archive ];
855
856 my $buffer;
857 unless( scalar run( command => $cmd,
858 verbose => $DEBUG,
859 buffer => \$buffer )
860 ) {
861 return $self->_error(loc("Unable to gunzip '%1': %2",
862 $self->archive, $buffer));
863 }
864
865 ### no buffers available?
866 if( !IPC::Cmd->can_capture_buffer and !$buffer ) {
867 $self->_error( $self->_no_buffer_content( $self->archive ) );
868 }
869
870 print $fh $buffer if defined $buffer;
871
872 close $fh;
873
874 ### set what files where extract, and where they went ###
875 $self->files( [$self->_gunzip_to] );
876 $self->extract_path( File::Spec->rel2abs(cwd()) );
877
878 return 1;
879}
880
881sub _gunzip_cz {
882 my $self = shift;
883
884 my $use_list = { 'Compress::Zlib' => '0.0' };
885 unless( can_load( modules => $use_list ) ) {
83285295 886 $self->_error(loc("You do not have '%1' installed - Please " .
887 "install it as soon as possible.", 'Compress::Zlib'));
888 return METHOD_NA;
520c99e2 889 }
890
891 my $gz = Compress::Zlib::gzopen( $self->archive, "rb" ) or
892 return $self->_error(loc("Unable to open '%1': %2",
893 $self->archive, $Compress::Zlib::gzerrno));
894
895 my $fh = FileHandle->new('>'. $self->_gunzip_to) or
896 return $self->_error(loc("Could not open '%1' for writing: %2",
897 $self->_gunzip_to, $! ));
898
899 my $buffer;
900 $fh->print($buffer) while $gz->gzread($buffer) > 0;
901 $fh->close;
902
903 ### set what files where extract, and where they went ###
904 $self->files( [$self->_gunzip_to] );
905 $self->extract_path( File::Spec->rel2abs(cwd()) );
906
907 return 1;
908}
909
910#################################
911#
1dae2fb5 912# Uncompress code
913#
914#################################
915
1dae2fb5 916sub _uncompress_bin {
917 my $self = shift;
918
919 ### check for /bin/gzip -- we need it ###
83285295 920 unless( $self->bin_uncompress ) {
921 $self->_error(loc("No '%1' program found", '/bin/uncompress'));
922 return METHOD_NA;
923 }
1dae2fb5 924
925 my $fh = FileHandle->new('>'. $self->_gunzip_to) or
926 return $self->_error(loc("Could not open '%1' for writing: %2",
927 $self->_gunzip_to, $! ));
928
929 my $cmd = [ $self->bin_uncompress, '-c', $self->archive ];
930
931 my $buffer;
932 unless( scalar run( command => $cmd,
933 verbose => $DEBUG,
934 buffer => \$buffer )
935 ) {
936 return $self->_error(loc("Unable to uncompress '%1': %2",
937 $self->archive, $buffer));
938 }
939
940 ### no buffers available?
941 if( !IPC::Cmd->can_capture_buffer and !$buffer ) {
942 $self->_error( $self->_no_buffer_content( $self->archive ) );
943 }
944
945 print $fh $buffer if defined $buffer;
946
947 close $fh;
948
949 ### set what files where extract, and where they went ###
950 $self->files( [$self->_gunzip_to] );
951 $self->extract_path( File::Spec->rel2abs(cwd()) );
952
953 return 1;
954}
955
956
957#################################
958#
520c99e2 959# Unzip code
960#
961#################################
962
520c99e2 963
964sub _unzip_bin {
965 my $self = shift;
966
967 ### check for /bin/gzip if we need it ###
83285295 968 unless( $self->bin_unzip ) {
969 $self->_error(loc("No '%1' program found", '/bin/unzip'));
970 return METHOD_NA;
971 }
520c99e2 972
973 ### first, get the files.. it must be 2 different commands with 'unzip' :(
9e5a0ef9 974 { ### on VMS, capital letter options have to be quoted. This is
975 ### peported by John Malmberg on P5P Tue 21 Aug 2007 05:05:11
976 ### Subject: [patch@31735]Archive Extract fix on VMS.
977 my $opt = ON_VMS ? '"-Z"' : '-Z';
978 my $cmd = [ $self->bin_unzip, $opt, '-1', $self->archive ];
979
520c99e2 980 my $buffer = '';
981 unless( scalar run( command => $cmd,
982 verbose => $DEBUG,
983 buffer => \$buffer )
984 ) {
985 return $self->_error(loc("Unable to unzip '%1': %2",
986 $self->archive, $buffer));
987 }
988
989 ### no buffers available?
990 if( !IPC::Cmd->can_capture_buffer and !$buffer ) {
991 $self->_error( $self->_no_buffer_files( $self->archive ) );
992
993 } else {
994 $self->files( [split $/, $buffer] );
995 }
996 }
997
998 ### now, extract the archive ###
999 { my $cmd = [ $self->bin_unzip, '-qq', '-o', $self->archive ];
1000
1001 my $buffer;
1002 unless( scalar run( command => $cmd,
1003 verbose => $DEBUG,
1004 buffer => \$buffer )
1005 ) {
1006 return $self->_error(loc("Unable to unzip '%1': %2",
1007 $self->archive, $buffer));
1008 }
1009
1010 if( scalar @{$self->files} ) {
1011 my $files = $self->files;
1012 my $dir = $self->__get_extract_dir( $files );
1013
1014 $self->extract_path( $dir );
1015 }
1016 }
1017
1018 return 1;
1019}
1020
1021sub _unzip_az {
1022 my $self = shift;
1023
1024 my $use_list = { 'Archive::Zip' => '0.0' };
1025 unless( can_load( modules => $use_list ) ) {
83285295 1026 $self->_error(loc("You do not have '%1' installed - Please " .
1027 "install it as soon as possible.", 'Archive::Zip'));
1028 return METHOD_NA;
520c99e2 1029 }
1030
1031 my $zip = Archive::Zip->new();
1032
1033 unless( $zip->read( $self->archive ) == &Archive::Zip::AZ_OK ) {
1034 return $self->_error(loc("Unable to read '%1'", $self->archive));
1035 }
1036
1037 my @files;
e74f3fd4 1038
1039
1040 ### Address: #43278: Explicitly tell Archive::Zip where to put the files:
1041 ### "In my BackPAN indexing, Archive::Zip was extracting things
1042 ### in my script's directory instead of the current working directory.
1043 ### I traced this back through Archive::Zip::_asLocalName which
1044 ### eventually calls File::Spec::Win32::rel2abs which on Windows might
1045 ### call Cwd::getdcwd. getdcwd returns the wrong directory in my
1046 ### case, even though I think I'm on the same drive.
1047 ###
1048 ### To fix this, I pass the optional second argument to
1049 ### extractMember using the cwd from Archive::Extract." --bdfoy
1050
1051 ## store cwd() before looping; calls to cwd() can be expensive, and
1052 ### it won't change during the loop
1053 my $extract_dir = cwd();
1054
1055 ### have to extract every member individually ###
520c99e2 1056 for my $member ($zip->members) {
1057 push @files, $member->{fileName};
1058
e74f3fd4 1059 ### file to extact to, to avoid the above problem
1060 my $to = File::Spec->catfile( $extract_dir, $member->{fileName} );
1061
1062 unless( $zip->extractMember($member, $to) == &Archive::Zip::AZ_OK ) {
520c99e2 1063 return $self->_error(loc("Extraction of '%1' from '%2' failed",
1064 $member->{fileName}, $self->archive ));
1065 }
1066 }
1067
1068 my $dir = $self->__get_extract_dir( \@files );
1069
1070 ### set what files where extract, and where they went ###
1071 $self->files( \@files );
1072 $self->extract_path( File::Spec->rel2abs($dir) );
1073
1074 return 1;
1075}
1076
1077sub __get_extract_dir {
1078 my $self = shift;
1079 my $files = shift || [];
1080
1081 return unless scalar @$files;
1082
1083 my($dir1, $dir2);
1084 for my $aref ( [ \$dir1, 0 ], [ \$dir2, -1 ] ) {
1085 my($dir,$pos) = @$aref;
1086
1087 ### add a catdir(), so that any trailing slashes get
1088 ### take care of (removed)
1089 ### also, a catdir() normalises './dir/foo' to 'dir/foo';
1090 ### which was the problem in bug #23999
1091 my $res = -d $files->[$pos]
1092 ? File::Spec->catdir( $files->[$pos], '' )
1093 : File::Spec->catdir( dirname( $files->[$pos] ) );
1094
1095 $$dir = $res;
1096 }
1097
1098 ### if the first and last dir don't match, make sure the
1099 ### dirname is not set wrongly
1100 my $dir;
1101
1102 ### dirs are the same, so we know for sure what the extract dir is
1103 if( $dir1 eq $dir2 ) {
1104 $dir = $dir1;
1105
1106 ### dirs are different.. do they share the base dir?
1107 ### if so, use that, if not, fall back to '.'
1108 } else {
1109 my $base1 = [ File::Spec->splitdir( $dir1 ) ]->[0];
1110 my $base2 = [ File::Spec->splitdir( $dir2 ) ]->[0];
1111
1112 $dir = File::Spec->rel2abs( $base1 eq $base2 ? $base1 : '.' );
1113 }
1114
1115 return File::Spec->rel2abs( $dir );
1116}
1117
1118#################################
1119#
1120# Bunzip2 code
1121#
1122#################################
1123
520c99e2 1124sub _bunzip2_bin {
1125 my $self = shift;
1126
1127 ### check for /bin/gzip -- we need it ###
83285295 1128 unless( $self->bin_bunzip2 ) {
1129 $self->_error(loc("No '%1' program found", '/bin/bunzip2'));
1130 return METHOD_NA;
1131 }
520c99e2 1132
1133 my $fh = FileHandle->new('>'. $self->_gunzip_to) or
1134 return $self->_error(loc("Could not open '%1' for writing: %2",
1135 $self->_gunzip_to, $! ));
9e5a0ef9 1136
1137 ### guard against broken bunzip2. See ->have_old_bunzip2()
1138 ### for details
1139 if( $self->have_old_bunzip2 and $self->archive !~ /\.bz2$/i ) {
1140 return $self->_error(loc("Your bunzip2 version is too old and ".
1141 "can only extract files ending in '%1'",
1142 '.bz2'));
1143 }
520c99e2 1144
9e5a0ef9 1145 my $cmd = [ $self->bin_bunzip2, '-cd', $self->archive ];
520c99e2 1146
1147 my $buffer;
1148 unless( scalar run( command => $cmd,
1149 verbose => $DEBUG,
1150 buffer => \$buffer )
1151 ) {
1152 return $self->_error(loc("Unable to bunzip2 '%1': %2",
1153 $self->archive, $buffer));
1154 }
1155
1156 ### no buffers available?
1157 if( !IPC::Cmd->can_capture_buffer and !$buffer ) {
1158 $self->_error( $self->_no_buffer_content( $self->archive ) );
1159 }
1160
1161 print $fh $buffer if defined $buffer;
1162
1163 close $fh;
1164
1165 ### set what files where extract, and where they went ###
1166 $self->files( [$self->_gunzip_to] );
1167 $self->extract_path( File::Spec->rel2abs(cwd()) );
1168
1169 return 1;
1170}
1171
1172### using cz2, the compact versions... this we use mainly in archive::tar
1173### extractor..
1174# sub _bunzip2_cz1 {
1175# my $self = shift;
1176#
1177# my $use_list = { 'IO::Uncompress::Bunzip2' => '0.0' };
1178# unless( can_load( modules => $use_list ) ) {
1179# return $self->_error(loc("You do not have '%1' installed - Please " .
1180# "install it as soon as possible.",
1181# 'IO::Uncompress::Bunzip2'));
1182# }
1183#
1184# my $bz = IO::Uncompress::Bunzip2->new( $self->archive ) or
1185# return $self->_error(loc("Unable to open '%1': %2",
1186# $self->archive,
1187# $IO::Uncompress::Bunzip2::Bunzip2Error));
1188#
1189# my $fh = FileHandle->new('>'. $self->_gunzip_to) or
1190# return $self->_error(loc("Could not open '%1' for writing: %2",
1191# $self->_gunzip_to, $! ));
1192#
1193# my $buffer;
1194# $fh->print($buffer) while $bz->read($buffer) > 0;
1195# $fh->close;
1196#
1197# ### set what files where extract, and where they went ###
1198# $self->files( [$self->_gunzip_to] );
1199# $self->extract_path( File::Spec->rel2abs(cwd()) );
1200#
1201# return 1;
1202# }
1203
83285295 1204sub _bunzip2_bz2 {
520c99e2 1205 my $self = shift;
1206
1207 my $use_list = { 'IO::Uncompress::Bunzip2' => '0.0' };
1208 unless( can_load( modules => $use_list ) ) {
83285295 1209 $self->_error(loc("You do not have '%1' installed - Please " .
1210 "install it as soon as possible.",
1211 'IO::Uncompress::Bunzip2'));
1212 return METHOD_NA;
520c99e2 1213 }
1214
1215 IO::Uncompress::Bunzip2::bunzip2($self->archive => $self->_gunzip_to)
1216 or return $self->_error(loc("Unable to uncompress '%1': %2",
1217 $self->archive,
1218 $IO::Uncompress::Bunzip2::Bunzip2Error));
1219
1220 ### set what files where extract, and where they went ###
1221 $self->files( [$self->_gunzip_to] );
1222 $self->extract_path( File::Spec->rel2abs(cwd()) );
1223
1224 return 1;
1225}
1226
1227
1228#################################
1229#
8d2ac73b 1230# unlzma code
1231#
1232#################################
1233
8d2ac73b 1234sub _unlzma_bin {
1235 my $self = shift;
1236
1237 ### check for /bin/unlzma -- we need it ###
83285295 1238 unless( $self->bin_unlzma ) {
1239 $self->_error(loc("No '%1' program found", '/bin/unlzma'));
1240 return METHOD_NA;
1241 }
8d2ac73b 1242
1243 my $fh = FileHandle->new('>'. $self->_gunzip_to) or
1244 return $self->_error(loc("Could not open '%1' for writing: %2",
1245 $self->_gunzip_to, $! ));
1246
1247 my $cmd = [ $self->bin_unlzma, '-c', $self->archive ];
1248
1249 my $buffer;
1250 unless( scalar run( command => $cmd,
1251 verbose => $DEBUG,
1252 buffer => \$buffer )
1253 ) {
1254 return $self->_error(loc("Unable to unlzma '%1': %2",
1255 $self->archive, $buffer));
1256 }
1257
1258 ### no buffers available?
1259 if( !IPC::Cmd->can_capture_buffer and !$buffer ) {
1260 $self->_error( $self->_no_buffer_content( $self->archive ) );
1261 }
1262
1263 print $fh $buffer if defined $buffer;
1264
1265 close $fh;
1266
1267 ### set what files where extract, and where they went ###
1268 $self->files( [$self->_gunzip_to] );
1269 $self->extract_path( File::Spec->rel2abs(cwd()) );
1270
1271 return 1;
1272}
1273
1274sub _unlzma_cz {
1275 my $self = shift;
1276
1277 my $use_list = { 'Compress::unLZMA' => '0.0' };
1278 unless( can_load( modules => $use_list ) ) {
83285295 1279 $self->_error(loc("You do not have '%1' installed - Please " .
1280 "install it as soon as possible.", 'Compress::unLZMA'));
1281 return METHOD_NA;
8d2ac73b 1282 }
1283
1284 my $fh = FileHandle->new('>'. $self->_gunzip_to) or
1285 return $self->_error(loc("Could not open '%1' for writing: %2",
1286 $self->_gunzip_to, $! ));
1287
1288 my $buffer;
1289 $buffer = Compress::unLZMA::uncompressfile( $self->archive );
1290 unless ( defined $buffer ) {
1291 return $self->_error(loc("Could not unlzma '%1': %2",
1292 $self->archive, $@));
1293 }
1294
1295 print $fh $buffer if defined $buffer;
1296
1297 close $fh;
1298
1299 ### set what files where extract, and where they went ###
1300 $self->files( [$self->_gunzip_to] );
1301 $self->extract_path( File::Spec->rel2abs(cwd()) );
1302
1303 return 1;
1304}
1305
1306#################################
1307#
520c99e2 1308# Error code
1309#
1310#################################
1311
1312sub _error {
1313 my $self = shift;
1314 my $error = shift;
83285295 1315 my $lerror = Carp::longmess($error);
1316
1317 push @{$self->_error_msg}, $error;
1318 push @{$self->_error_msg_long}, $lerror;
520c99e2 1319
1320 ### set $Archive::Extract::WARN to 0 to disable printing
1321 ### of errors
1322 if( $WARN ) {
83285295 1323 carp $DEBUG ? $lerror : $error;
520c99e2 1324 }
1325
1326 return;
1327}
1328
1329sub error {
1330 my $self = shift;
83285295 1331
1332 ### make sure we have a fallback aref
1333 my $aref = do {
1334 shift()
1335 ? $self->_error_msg_long
1336 : $self->_error_msg
1337 } || [];
1338
1339 return join $/, @$aref;
520c99e2 1340}
1341
1342sub _no_buffer_files {
1343 my $self = shift;
1344 my $file = shift or return;
1345 return loc("No buffer captured, unable to tell ".
1346 "extracted files or extraction dir for '%1'", $file);
1347}
1348
1349sub _no_buffer_content {
1350 my $self = shift;
1351 my $file = shift or return;
1352 return loc("No buffer captured, unable to get content for '%1'", $file);
1353}
13541;
1355
1356=pod
1357
1358=head1 HOW IT WORKS
1359
1360C<Archive::Extract> tries first to determine what type of archive you
1361are passing it, by inspecting its suffix. It does not do this by using
1362Mime magic, or something related. See C<CAVEATS> below.
1363
1364Once it has determined the file type, it knows which extraction methods
1365it can use on the archive. It will try a perl solution first, then fall
1366back to a commandline tool if that fails. If that also fails, it will
1367return false, indicating it was unable to extract the archive.
1368See the section on C<GLOBAL VARIABLES> to see how to alter this order.
1369
1370=head1 CAVEATS
1371
1372=head2 File Extensions
1373
1374C<Archive::Extract> trusts on the extension of the archive to determine
1375what type it is, and what extractor methods therefore can be used. If
1376your archives do not have any of the extensions as described in the
1377C<new()> method, you will have to specify the type explicitly, or
1378C<Archive::Extract> will not be able to extract the archive for you.
1379
9e5a0ef9 1380=head2 Supporting Very Large Files
1381
1382C<Archive::Extract> can use either pure perl modules or command line
1383programs under the hood. Some of the pure perl modules (like
8d2ac73b 1384C<Archive::Tar> and Compress::unLZMA) take the entire contents of the archive into memory,
9e5a0ef9 1385which may not be feasible on your system. Consider setting the global
1386variable C<$Archive::Extract::PREFER_BIN> to C<1>, which will prefer
1387the use of command line programs and won't consume so much memory.
1388
1389See the C<GLOBAL VARIABLES> section below for details.
1390
1391=head2 Bunzip2 support of arbitrary extensions.
1392
1393Older versions of C</bin/bunzip2> do not support arbitrary file
1394extensions and insist on a C<.bz2> suffix. Although we do our best
1395to guard against this, if you experience a bunzip2 error, it may
1396be related to this. For details, please see the C<have_old_bunzip2>
1397method.
1398
520c99e2 1399=head1 GLOBAL VARIABLES
1400
1401=head2 $Archive::Extract::DEBUG
1402
1403Set this variable to C<true> to have all calls to command line tools
1404be printed out, including all their output.
1405This also enables C<Carp::longmess> errors, instead of the regular
1406C<carp> errors.
1407
1408Good for tracking down why things don't work with your particular
1409setup.
1410
1411Defaults to C<false>.
1412
1413=head2 $Archive::Extract::WARN
1414
1415This variable controls whether errors encountered internally by
1416C<Archive::Extract> should be C<carp>'d or not.
1417
1418Set to false to silence warnings. Inspect the output of the C<error()>
1419method manually to see what went wrong.
1420
1421Defaults to C<true>.
1422
1423=head2 $Archive::Extract::PREFER_BIN
1424
1425This variables controls whether C<Archive::Extract> should prefer the
1426use of perl modules, or commandline tools to extract archives.
1427
1428Set to C<true> to have C<Archive::Extract> prefer commandline tools.
1429
1430Defaults to C<false>.
1431
1432=head1 TODO
1433
1434=over 4
1435
1436=item Mime magic support
1437
1438Maybe this module should use something like C<File::Type> to determine
1439the type, rather than blindly trust the suffix.
1440
1dae2fb5 1441=back
1442
574b415d 1443=head1 BUG REPORTS
520c99e2 1444
574b415d 1445Please report bugs or other issues to E<lt>bug-archive-extract@rt.cpan.org<gt>.
520c99e2 1446
574b415d 1447=head1 AUTHOR
1448
1449This module by Jos Boumans E<lt>kane@cpan.orgE<gt>.
520c99e2 1450
574b415d 1451=head1 COPYRIGHT
520c99e2 1452
574b415d 1453This library is free software; you may redistribute and/or modify it
1454under the same terms as Perl itself.
520c99e2 1455
1456=cut
1457
1458# Local variables:
1459# c-indentation-style: bsd
1460# c-basic-offset: 4
1461# indent-tabs-mode: nil
1462# End:
1463# vim: expandtab shiftwidth=4:
1464