Blame lib/Archive/Zip.pm

Packit 0bf95d
package Archive::Zip;
Packit 0bf95d
Packit 0bf95d
use 5.006;
Packit 0bf95d
use strict;
Packit 0bf95d
use Carp                ();
Packit 0bf95d
use Cwd                 ();
Packit 0bf95d
use IO::File            ();
Packit 0bf95d
use IO::Seekable        ();
Packit 0bf95d
use Compress::Raw::Zlib ();
Packit 0bf95d
use File::Spec          ();
Packit 0bf95d
use File::Temp          ();
Packit 0bf95d
use FileHandle          ();
Packit 0bf95d
Packit 0bf95d
use vars qw( $VERSION @ISA );
Packit 0bf95d
Packit 0bf95d
BEGIN {
Packit 0bf95d
    $VERSION = '1.60';
Packit 0bf95d
Packit 0bf95d
    require Exporter;
Packit 0bf95d
    @ISA = qw( Exporter );
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
use vars qw( $ChunkSize $ErrorHandler );
Packit 0bf95d
Packit 0bf95d
BEGIN {
Packit 0bf95d
    # This is the size we'll try to read, write, and (de)compress.
Packit 0bf95d
    # You could set it to something different if you had lots of memory
Packit 0bf95d
    # and needed more speed.
Packit 0bf95d
    $ChunkSize ||= 32768;
Packit 0bf95d
Packit 0bf95d
    $ErrorHandler = \&Carp::carp;
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
# BEGIN block is necessary here so that other modules can use the constants.
Packit 0bf95d
use vars qw( @EXPORT_OK %EXPORT_TAGS );
Packit 0bf95d
Packit 0bf95d
BEGIN {
Packit 0bf95d
    @EXPORT_OK   = ('computeCRC32');
Packit 0bf95d
    %EXPORT_TAGS = (
Packit 0bf95d
        CONSTANTS => [
Packit 0bf95d
            qw(
Packit 0bf95d
              FA_MSDOS
Packit 0bf95d
              FA_UNIX
Packit 0bf95d
              GPBF_ENCRYPTED_MASK
Packit 0bf95d
              GPBF_DEFLATING_COMPRESSION_MASK
Packit 0bf95d
              GPBF_HAS_DATA_DESCRIPTOR_MASK
Packit 0bf95d
              COMPRESSION_STORED
Packit 0bf95d
              COMPRESSION_DEFLATED
Packit 0bf95d
              COMPRESSION_LEVEL_NONE
Packit 0bf95d
              COMPRESSION_LEVEL_DEFAULT
Packit 0bf95d
              COMPRESSION_LEVEL_FASTEST
Packit 0bf95d
              COMPRESSION_LEVEL_BEST_COMPRESSION
Packit 0bf95d
              IFA_TEXT_FILE_MASK
Packit 0bf95d
              IFA_TEXT_FILE
Packit 0bf95d
              IFA_BINARY_FILE
Packit 0bf95d
              )
Packit 0bf95d
        ],
Packit 0bf95d
Packit 0bf95d
        MISC_CONSTANTS => [
Packit 0bf95d
            qw(
Packit 0bf95d
              FA_AMIGA
Packit 0bf95d
              FA_VAX_VMS
Packit 0bf95d
              FA_VM_CMS
Packit 0bf95d
              FA_ATARI_ST
Packit 0bf95d
              FA_OS2_HPFS
Packit 0bf95d
              FA_MACINTOSH
Packit 0bf95d
              FA_Z_SYSTEM
Packit 0bf95d
              FA_CPM
Packit 0bf95d
              FA_TOPS20
Packit 0bf95d
              FA_WINDOWS_NTFS
Packit 0bf95d
              FA_QDOS
Packit 0bf95d
              FA_ACORN
Packit 0bf95d
              FA_VFAT
Packit 0bf95d
              FA_MVS
Packit 0bf95d
              FA_BEOS
Packit 0bf95d
              FA_TANDEM
Packit 0bf95d
              FA_THEOS
Packit 0bf95d
              GPBF_IMPLODING_8K_SLIDING_DICTIONARY_MASK
Packit 0bf95d
              GPBF_IMPLODING_3_SHANNON_FANO_TREES_MASK
Packit 0bf95d
              GPBF_IS_COMPRESSED_PATCHED_DATA_MASK
Packit 0bf95d
              COMPRESSION_SHRUNK
Packit 0bf95d
              DEFLATING_COMPRESSION_NORMAL
Packit 0bf95d
              DEFLATING_COMPRESSION_MAXIMUM
Packit 0bf95d
              DEFLATING_COMPRESSION_FAST
Packit 0bf95d
              DEFLATING_COMPRESSION_SUPER_FAST
Packit 0bf95d
              COMPRESSION_REDUCED_1
Packit 0bf95d
              COMPRESSION_REDUCED_2
Packit 0bf95d
              COMPRESSION_REDUCED_3
Packit 0bf95d
              COMPRESSION_REDUCED_4
Packit 0bf95d
              COMPRESSION_IMPLODED
Packit 0bf95d
              COMPRESSION_TOKENIZED
Packit 0bf95d
              COMPRESSION_DEFLATED_ENHANCED
Packit 0bf95d
              COMPRESSION_PKWARE_DATA_COMPRESSION_LIBRARY_IMPLODED
Packit 0bf95d
              )
Packit 0bf95d
        ],
Packit 0bf95d
Packit 0bf95d
        ERROR_CODES => [
Packit 0bf95d
            qw(
Packit 0bf95d
              AZ_OK
Packit 0bf95d
              AZ_STREAM_END
Packit 0bf95d
              AZ_ERROR
Packit 0bf95d
              AZ_FORMAT_ERROR
Packit 0bf95d
              AZ_IO_ERROR
Packit 0bf95d
              )
Packit 0bf95d
        ],
Packit 0bf95d
Packit 0bf95d
        # For Internal Use Only
Packit 0bf95d
        PKZIP_CONSTANTS => [
Packit 0bf95d
            qw(
Packit 0bf95d
              SIGNATURE_FORMAT
Packit 0bf95d
              SIGNATURE_LENGTH
Packit 0bf95d
Packit 0bf95d
              LOCAL_FILE_HEADER_SIGNATURE
Packit 0bf95d
              LOCAL_FILE_HEADER_FORMAT
Packit 0bf95d
              LOCAL_FILE_HEADER_LENGTH
Packit 0bf95d
Packit 0bf95d
              DATA_DESCRIPTOR_SIGNATURE
Packit 0bf95d
              DATA_DESCRIPTOR_FORMAT
Packit 0bf95d
              DATA_DESCRIPTOR_LENGTH
Packit 0bf95d
Packit 0bf95d
              DATA_DESCRIPTOR_FORMAT_NO_SIG
Packit 0bf95d
              DATA_DESCRIPTOR_LENGTH_NO_SIG
Packit 0bf95d
Packit 0bf95d
              CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE
Packit 0bf95d
              CENTRAL_DIRECTORY_FILE_HEADER_FORMAT
Packit 0bf95d
              CENTRAL_DIRECTORY_FILE_HEADER_LENGTH
Packit 0bf95d
Packit 0bf95d
              ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIGNATURE
Packit 0bf95d
              ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_FORMAT
Packit 0bf95d
              ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_LENGTH
Packit 0bf95d
Packit 0bf95d
              ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE
Packit 0bf95d
              ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_FORMAT
Packit 0bf95d
              ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_LENGTH
Packit 0bf95d
Packit 0bf95d
              END_OF_CENTRAL_DIRECTORY_SIGNATURE
Packit 0bf95d
              END_OF_CENTRAL_DIRECTORY_FORMAT
Packit 0bf95d
              END_OF_CENTRAL_DIRECTORY_LENGTH
Packit 0bf95d
Packit 0bf95d
              END_OF_CENTRAL_DIRECTORY_SIGNATURE_STRING
Packit 0bf95d
              )
Packit 0bf95d
        ],
Packit 0bf95d
Packit 0bf95d
        # For Internal Use Only
Packit 0bf95d
        UTILITY_METHODS => [
Packit 0bf95d
            qw(
Packit 0bf95d
              _error
Packit 0bf95d
              _printError
Packit 0bf95d
              _ioError
Packit 0bf95d
              _formatError
Packit 0bf95d
              _subclassResponsibility
Packit 0bf95d
              _binmode
Packit 0bf95d
              _isSeekable
Packit 0bf95d
              _newFileHandle
Packit 0bf95d
              _readSignature
Packit 0bf95d
              _asZipDirName
Packit 0bf95d
              )
Packit 0bf95d
        ],
Packit 0bf95d
    );
Packit 0bf95d
Packit 0bf95d
    # Add all the constant names and error code names to @EXPORT_OK
Packit 0bf95d
    Exporter::export_ok_tags(
Packit 0bf95d
        qw(
Packit 0bf95d
          CONSTANTS
Packit 0bf95d
          ERROR_CODES
Packit 0bf95d
          PKZIP_CONSTANTS
Packit 0bf95d
          UTILITY_METHODS
Packit 0bf95d
          MISC_CONSTANTS
Packit 0bf95d
          ));
Packit 0bf95d
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
# Error codes
Packit 0bf95d
use constant AZ_OK           => 0;
Packit 0bf95d
use constant AZ_STREAM_END   => 1;
Packit 0bf95d
use constant AZ_ERROR        => 2;
Packit 0bf95d
use constant AZ_FORMAT_ERROR => 3;
Packit 0bf95d
use constant AZ_IO_ERROR     => 4;
Packit 0bf95d
Packit 0bf95d
# File types
Packit 0bf95d
# Values of Archive::Zip::Member->fileAttributeFormat()
Packit 0bf95d
Packit 0bf95d
use constant FA_MSDOS        => 0;
Packit 0bf95d
use constant FA_AMIGA        => 1;
Packit 0bf95d
use constant FA_VAX_VMS      => 2;
Packit 0bf95d
use constant FA_UNIX         => 3;
Packit 0bf95d
use constant FA_VM_CMS       => 4;
Packit 0bf95d
use constant FA_ATARI_ST     => 5;
Packit 0bf95d
use constant FA_OS2_HPFS     => 6;
Packit 0bf95d
use constant FA_MACINTOSH    => 7;
Packit 0bf95d
use constant FA_Z_SYSTEM     => 8;
Packit 0bf95d
use constant FA_CPM          => 9;
Packit 0bf95d
use constant FA_TOPS20       => 10;
Packit 0bf95d
use constant FA_WINDOWS_NTFS => 11;
Packit 0bf95d
use constant FA_QDOS         => 12;
Packit 0bf95d
use constant FA_ACORN        => 13;
Packit 0bf95d
use constant FA_VFAT         => 14;
Packit 0bf95d
use constant FA_MVS          => 15;
Packit 0bf95d
use constant FA_BEOS         => 16;
Packit 0bf95d
use constant FA_TANDEM       => 17;
Packit 0bf95d
use constant FA_THEOS        => 18;
Packit 0bf95d
Packit 0bf95d
# general-purpose bit flag masks
Packit 0bf95d
# Found in Archive::Zip::Member->bitFlag()
Packit 0bf95d
Packit 0bf95d
use constant GPBF_ENCRYPTED_MASK             => 1 << 0;
Packit 0bf95d
use constant GPBF_DEFLATING_COMPRESSION_MASK => 3 << 1;
Packit 0bf95d
use constant GPBF_HAS_DATA_DESCRIPTOR_MASK   => 1 << 3;
Packit 0bf95d
Packit 0bf95d
# deflating compression types, if compressionMethod == COMPRESSION_DEFLATED
Packit 0bf95d
# ( Archive::Zip::Member->bitFlag() & GPBF_DEFLATING_COMPRESSION_MASK )
Packit 0bf95d
Packit 0bf95d
use constant DEFLATING_COMPRESSION_NORMAL     => 0 << 1;
Packit 0bf95d
use constant DEFLATING_COMPRESSION_MAXIMUM    => 1 << 1;
Packit 0bf95d
use constant DEFLATING_COMPRESSION_FAST       => 2 << 1;
Packit 0bf95d
use constant DEFLATING_COMPRESSION_SUPER_FAST => 3 << 1;
Packit 0bf95d
Packit 0bf95d
# compression method
Packit 0bf95d
Packit 0bf95d
# these two are the only ones supported in this module
Packit 0bf95d
use constant COMPRESSION_STORED        => 0;   # file is stored (no compression)
Packit 0bf95d
use constant COMPRESSION_DEFLATED      => 8;   # file is Deflated
Packit 0bf95d
use constant COMPRESSION_LEVEL_NONE    => 0;
Packit 0bf95d
use constant COMPRESSION_LEVEL_DEFAULT => -1;
Packit 0bf95d
use constant COMPRESSION_LEVEL_FASTEST => 1;
Packit 0bf95d
use constant COMPRESSION_LEVEL_BEST_COMPRESSION => 9;
Packit 0bf95d
Packit 0bf95d
# internal file attribute bits
Packit 0bf95d
# Found in Archive::Zip::Member::internalFileAttributes()
Packit 0bf95d
Packit 0bf95d
use constant IFA_TEXT_FILE_MASK => 1;
Packit 0bf95d
use constant IFA_TEXT_FILE      => 1;
Packit 0bf95d
use constant IFA_BINARY_FILE    => 0;
Packit 0bf95d
Packit 0bf95d
# PKZIP file format miscellaneous constants (for internal use only)
Packit 0bf95d
use constant SIGNATURE_FORMAT => "V";
Packit 0bf95d
use constant SIGNATURE_LENGTH => 4;
Packit 0bf95d
Packit 0bf95d
# these lengths are without the signature.
Packit 0bf95d
use constant LOCAL_FILE_HEADER_SIGNATURE => 0x04034b50;
Packit 0bf95d
use constant LOCAL_FILE_HEADER_FORMAT    => "v3 V4 v2";
Packit 0bf95d
use constant LOCAL_FILE_HEADER_LENGTH    => 26;
Packit 0bf95d
Packit 0bf95d
# PKZIP docs don't mention the signature, but Info-Zip writes it.
Packit 0bf95d
use constant DATA_DESCRIPTOR_SIGNATURE => 0x08074b50;
Packit 0bf95d
use constant DATA_DESCRIPTOR_FORMAT    => "V3";
Packit 0bf95d
use constant DATA_DESCRIPTOR_LENGTH    => 12;
Packit 0bf95d
Packit 0bf95d
# but the signature is apparently optional.
Packit 0bf95d
use constant DATA_DESCRIPTOR_FORMAT_NO_SIG => "V2";
Packit 0bf95d
use constant DATA_DESCRIPTOR_LENGTH_NO_SIG => 8;
Packit 0bf95d
Packit 0bf95d
use constant CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE => 0x02014b50;
Packit 0bf95d
use constant CENTRAL_DIRECTORY_FILE_HEADER_FORMAT    => "C2 v3 V4 v5 V2";
Packit 0bf95d
use constant CENTRAL_DIRECTORY_FILE_HEADER_LENGTH    => 42;
Packit 0bf95d
Packit 0bf95d
# zip64 support
Packit 0bf95d
use constant ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIGNATURE => 0x06064b50;
Packit 0bf95d
use constant ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_FORMAT => 0;
Packit 0bf95d
use constant ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_LENGTH => 0;
Packit 0bf95d
Packit 0bf95d
use constant ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE => 0x07064b50;
Packit 0bf95d
use constant ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_FORMAT => 0;
Packit 0bf95d
use constant ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_LENGTH => 0;
Packit 0bf95d
Packit 0bf95d
Packit 0bf95d
use constant END_OF_CENTRAL_DIRECTORY_SIGNATURE => 0x06054b50;
Packit 0bf95d
use constant END_OF_CENTRAL_DIRECTORY_SIGNATURE_STRING =>
Packit 0bf95d
  pack("V", END_OF_CENTRAL_DIRECTORY_SIGNATURE);
Packit 0bf95d
use constant END_OF_CENTRAL_DIRECTORY_FORMAT => "v4 V2 v";
Packit 0bf95d
use constant END_OF_CENTRAL_DIRECTORY_LENGTH => 18;
Packit 0bf95d
Packit 0bf95d
use constant GPBF_IMPLODING_8K_SLIDING_DICTIONARY_MASK => 1 << 1;
Packit 0bf95d
use constant GPBF_IMPLODING_3_SHANNON_FANO_TREES_MASK  => 1 << 2;
Packit 0bf95d
use constant GPBF_IS_COMPRESSED_PATCHED_DATA_MASK      => 1 << 5;
Packit 0bf95d
Packit 0bf95d
# the rest of these are not supported in this module
Packit 0bf95d
use constant COMPRESSION_SHRUNK    => 1;    # file is Shrunk
Packit 0bf95d
use constant COMPRESSION_REDUCED_1 => 2;    # file is Reduced CF=1
Packit 0bf95d
use constant COMPRESSION_REDUCED_2 => 3;    # file is Reduced CF=2
Packit 0bf95d
use constant COMPRESSION_REDUCED_3 => 4;    # file is Reduced CF=3
Packit 0bf95d
use constant COMPRESSION_REDUCED_4 => 5;    # file is Reduced CF=4
Packit 0bf95d
use constant COMPRESSION_IMPLODED  => 6;    # file is Imploded
Packit 0bf95d
use constant COMPRESSION_TOKENIZED => 7;    # reserved for Tokenizing compr.
Packit 0bf95d
use constant COMPRESSION_DEFLATED_ENHANCED => 9;   # reserved for enh. Deflating
Packit 0bf95d
use constant COMPRESSION_PKWARE_DATA_COMPRESSION_LIBRARY_IMPLODED => 10;
Packit 0bf95d
Packit 0bf95d
# Load the various required classes
Packit 0bf95d
require Archive::Zip::Archive;
Packit 0bf95d
require Archive::Zip::Member;
Packit 0bf95d
require Archive::Zip::FileMember;
Packit 0bf95d
require Archive::Zip::DirectoryMember;
Packit 0bf95d
require Archive::Zip::ZipFileMember;
Packit 0bf95d
require Archive::Zip::NewFileMember;
Packit 0bf95d
require Archive::Zip::StringMember;
Packit 0bf95d
Packit 0bf95d
# Convenience functions
Packit 0bf95d
Packit 0bf95d
sub _ISA ($$) {
Packit 0bf95d
Packit 0bf95d
    # Can't rely on Scalar::Util, so use the next best way
Packit 0bf95d
    local $@;
Packit 0bf95d
    !!eval { ref $_[0] and $_[0]->isa($_[1]) };
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
sub _CAN ($$) {
Packit 0bf95d
    local $@;
Packit 0bf95d
    !!eval { ref $_[0] and $_[0]->can($_[1]) };
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
#####################################################################
Packit 0bf95d
# Methods
Packit 0bf95d
Packit 0bf95d
sub new {
Packit 0bf95d
    my $class = shift;
Packit 0bf95d
    return Archive::Zip::Archive->new(@_);
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
sub computeCRC32 {
Packit 0bf95d
    my ($data, $crc);
Packit 0bf95d
Packit 0bf95d
    if (ref($_[0]) eq 'HASH') {
Packit 0bf95d
        $data = $_[0]->{string};
Packit 0bf95d
        $crc  = $_[0]->{checksum};
Packit 0bf95d
    } else {
Packit 0bf95d
        $data = shift;
Packit 0bf95d
        $data = shift if ref($data);
Packit 0bf95d
        $crc  = shift;
Packit 0bf95d
    }
Packit 0bf95d
Packit 0bf95d
    return Compress::Raw::Zlib::crc32($data, $crc);
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
# Report or change chunk size used for reading and writing.
Packit 0bf95d
# Also sets Zlib's default buffer size (eventually).
Packit 0bf95d
sub setChunkSize {
Packit 0bf95d
    shift if ref($_[0]) eq 'Archive::Zip::Archive';
Packit 0bf95d
    my $chunkSize = (ref($_[0]) eq 'HASH') ? shift->{chunkSize} : shift;
Packit 0bf95d
    my $oldChunkSize = $Archive::Zip::ChunkSize;
Packit 0bf95d
    $Archive::Zip::ChunkSize = $chunkSize if ($chunkSize);
Packit 0bf95d
    return $oldChunkSize;
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
sub chunkSize {
Packit 0bf95d
    return $Archive::Zip::ChunkSize;
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
sub setErrorHandler {
Packit 0bf95d
    my $errorHandler = (ref($_[0]) eq 'HASH') ? shift->{subroutine} : shift;
Packit 0bf95d
    $errorHandler = \&Carp::carp unless defined($errorHandler);
Packit 0bf95d
    my $oldErrorHandler = $Archive::Zip::ErrorHandler;
Packit 0bf95d
    $Archive::Zip::ErrorHandler = $errorHandler;
Packit 0bf95d
    return $oldErrorHandler;
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
######################################################################
Packit 0bf95d
# Private utility functions (not methods).
Packit 0bf95d
Packit 0bf95d
sub _printError {
Packit 0bf95d
    my $string = join(' ', @_, "\n");
Packit 0bf95d
    my $oldCarpLevel = $Carp::CarpLevel;
Packit 0bf95d
    $Carp::CarpLevel += 2;
Packit 0bf95d
    &{$ErrorHandler}($string);
Packit 0bf95d
    $Carp::CarpLevel = $oldCarpLevel;
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
# This is called on format errors.
Packit 0bf95d
sub _formatError {
Packit 0bf95d
    shift if ref($_[0]);
Packit 0bf95d
    _printError('format error:', @_);
Packit 0bf95d
    return AZ_FORMAT_ERROR;
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
# This is called on IO errors.
Packit 0bf95d
sub _ioError {
Packit 0bf95d
    shift if ref($_[0]);
Packit 0bf95d
    _printError('IO error:', @_, ':', $!);
Packit 0bf95d
    return AZ_IO_ERROR;
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
# This is called on generic errors.
Packit 0bf95d
sub _error {
Packit 0bf95d
    shift if ref($_[0]);
Packit 0bf95d
    _printError('error:', @_);
Packit 0bf95d
    return AZ_ERROR;
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
# Called when a subclass should have implemented
Packit 0bf95d
# something but didn't
Packit 0bf95d
sub _subclassResponsibility {
Packit 0bf95d
    Carp::croak("subclass Responsibility\n");
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
# Try to set the given file handle or object into binary mode.
Packit 0bf95d
sub _binmode {
Packit 0bf95d
    my $fh = shift;
Packit 0bf95d
    return _CAN($fh, 'binmode') ? $fh->binmode() : binmode($fh);
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
# Attempt to guess whether file handle is seekable.
Packit 0bf95d
# Because of problems with Windows, this only returns true when
Packit 0bf95d
# the file handle is a real file.
Packit 0bf95d
sub _isSeekable {
Packit 0bf95d
    my $fh = shift;
Packit 0bf95d
    return 0 unless ref $fh;
Packit 0bf95d
    _ISA($fh, "IO::Scalar")    # IO::Scalar objects are brokenly-seekable
Packit 0bf95d
      and return 0;
Packit 0bf95d
    _ISA($fh, "IO::String")
Packit 0bf95d
      and return 1;
Packit 0bf95d
    if (_ISA($fh, "IO::Seekable")) {
Packit 0bf95d
Packit 0bf95d
        # Unfortunately, some things like FileHandle objects
Packit 0bf95d
        # return true for Seekable, but AREN'T!!!!!
Packit 0bf95d
        _ISA($fh, "FileHandle")
Packit 0bf95d
          and return 0;
Packit 0bf95d
        return 1;
Packit 0bf95d
    }
Packit 0bf95d
Packit 0bf95d
    # open my $fh, "+<", \$data;
Packit 0bf95d
    ref $fh eq "GLOB" && eval { seek $fh, 0, 1 } and return 1;
Packit 0bf95d
    _CAN($fh, "stat")
Packit 0bf95d
      and return -f $fh;
Packit 0bf95d
    return (_CAN($fh, "seek") and _CAN($fh, "tell")) ? 1 : 0;
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
# Print to the filehandle, while making sure the pesky Perl special global
Packit 0bf95d
# variables don't interfere.
Packit 0bf95d
sub _print {
Packit 0bf95d
    my ($self, $fh, @data) = @_;
Packit 0bf95d
Packit 0bf95d
    local $\;
Packit 0bf95d
Packit 0bf95d
    return $fh->print(@data);
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
# Return an opened IO::Handle
Packit 0bf95d
# my ( $status, fh ) = _newFileHandle( 'fileName', 'w' );
Packit 0bf95d
# Can take a filename, file handle, or ref to GLOB
Packit 0bf95d
# Or, if given something that is a ref but not an IO::Handle,
Packit 0bf95d
# passes back the same thing.
Packit 0bf95d
sub _newFileHandle {
Packit 0bf95d
    my $fd     = shift;
Packit 0bf95d
    my $status = 1;
Packit 0bf95d
    my $handle;
Packit 0bf95d
Packit 0bf95d
    if (ref($fd)) {
Packit 0bf95d
        if (_ISA($fd, 'IO::Scalar') or _ISA($fd, 'IO::String')) {
Packit 0bf95d
            $handle = $fd;
Packit 0bf95d
        } elsif (_ISA($fd, 'IO::Handle') or ref($fd) eq 'GLOB') {
Packit 0bf95d
            $handle = IO::File->new;
Packit 0bf95d
            $status = $handle->fdopen($fd, @_);
Packit 0bf95d
        } else {
Packit 0bf95d
            $handle = $fd;
Packit 0bf95d
        }
Packit 0bf95d
    } else {
Packit 0bf95d
        $handle = IO::File->new;
Packit 0bf95d
        $status = $handle->open($fd, @_);
Packit 0bf95d
    }
Packit 0bf95d
Packit 0bf95d
    return ($status, $handle);
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
# Returns next signature from given file handle, leaves
Packit 0bf95d
# file handle positioned afterwards.
Packit 0bf95d
# In list context, returns ($status, $signature)
Packit 0bf95d
# ( $status, $signature) = _readSignature( $fh, $fileName );
Packit 0bf95d
Packit 0bf95d
sub _readSignature {
Packit 0bf95d
    my $fh                = shift;
Packit 0bf95d
    my $fileName          = shift;
Packit 0bf95d
    my $expectedSignature = shift;    # optional
Packit 0bf95d
Packit 0bf95d
    my $signatureData;
Packit 0bf95d
    my $bytesRead = $fh->read($signatureData, SIGNATURE_LENGTH);
Packit 0bf95d
    if ($bytesRead != SIGNATURE_LENGTH) {
Packit 0bf95d
        return _ioError("reading header signature");
Packit 0bf95d
    }
Packit 0bf95d
    my $signature = unpack(SIGNATURE_FORMAT, $signatureData);
Packit 0bf95d
    my $status = AZ_OK;
Packit 0bf95d
Packit 0bf95d
    # compare with expected signature, if any, or any known signature.
Packit 0bf95d
    if (
Packit 0bf95d
        (defined($expectedSignature) && $signature != $expectedSignature)
Packit 0bf95d
        || (   !defined($expectedSignature)
Packit 0bf95d
            && $signature != CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE
Packit 0bf95d
            && $signature != LOCAL_FILE_HEADER_SIGNATURE
Packit 0bf95d
            && $signature != END_OF_CENTRAL_DIRECTORY_SIGNATURE
Packit 0bf95d
            && $signature != DATA_DESCRIPTOR_SIGNATURE
Packit 0bf95d
            && $signature != ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIGNATURE
Packit 0bf95d
            && $signature != ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE
Packit 0bf95d
        )
Packit 0bf95d
      ) {
Packit 0bf95d
        my $errmsg = sprintf("bad signature: 0x%08x", $signature);
Packit 0bf95d
        if (_isSeekable($fh)) {
Packit 0bf95d
            $errmsg .= sprintf(" at offset %d", $fh->tell() - SIGNATURE_LENGTH);
Packit 0bf95d
        }
Packit 0bf95d
Packit 0bf95d
        $status = _formatError("$errmsg in file $fileName");
Packit 0bf95d
    }
Packit 0bf95d
Packit 0bf95d
    return ($status, $signature);
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
# Utility method to make and open a temp file.
Packit 0bf95d
# Will create $temp_dir if it does not exist.
Packit 0bf95d
# Returns file handle and name:
Packit 0bf95d
#
Packit 0bf95d
# my ($fh, $name) = Archive::Zip::tempFile();
Packit 0bf95d
# my ($fh, $name) = Archive::Zip::tempFile('mytempdir');
Packit 0bf95d
#
Packit 0bf95d
Packit 0bf95d
sub tempFile {
Packit 0bf95d
    my $dir = (ref($_[0]) eq 'HASH') ? shift->{tempDir} : shift;
Packit 0bf95d
    my ($fh, $filename) = File::Temp::tempfile(
Packit 0bf95d
        SUFFIX => '.zip',
Packit 0bf95d
        UNLINK => 1,
Packit 0bf95d
        $dir ? (DIR => $dir) : ());
Packit 0bf95d
    return (undef, undef) unless $fh;
Packit 0bf95d
    my ($status, $newfh) = _newFileHandle($fh, 'w+');
Packit 0bf95d
    $fh->close();
Packit 0bf95d
    return ($newfh, $filename);
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
# Return the normalized directory name as used in a zip file (path
Packit 0bf95d
# separators become slashes, etc.).
Packit 0bf95d
# Will translate internal slashes in path components (i.e. on Macs) to
Packit 0bf95d
# underscores.  Discards volume names.
Packit 0bf95d
# When $forceDir is set, returns paths with trailing slashes (or arrays
Packit 0bf95d
# with trailing blank members).
Packit 0bf95d
#
Packit 0bf95d
# If third argument is a reference, returns volume information there.
Packit 0bf95d
#
Packit 0bf95d
# input         output
Packit 0bf95d
# .             ('.')   '.'
Packit 0bf95d
# ./a           ('a')   a
Packit 0bf95d
# ./a/b         ('a','b')   a/b
Packit 0bf95d
# ./a/b/        ('a','b')   a/b
Packit 0bf95d
# a/b/          ('a','b')   a/b
Packit 0bf95d
# /a/b/         ('','a','b')    a/b
Packit 0bf95d
# c:\a\b\c.doc  ('','a','b','c.doc')    a/b/c.doc      # on Windows
Packit 0bf95d
# "i/o maps:whatever"   ('i_o maps', 'whatever')  "i_o maps/whatever"   # on Macs
Packit 0bf95d
sub _asZipDirName {
Packit 0bf95d
    my $name      = shift;
Packit 0bf95d
    my $forceDir  = shift;
Packit 0bf95d
    my $volReturn = shift;
Packit 0bf95d
    my ($volume, $directories, $file) =
Packit 0bf95d
      File::Spec->splitpath(File::Spec->canonpath($name), $forceDir);
Packit 0bf95d
    $$volReturn = $volume if (ref($volReturn));
Packit 0bf95d
    my @dirs = map { $_ =~ s{/}{_}g; $_ } File::Spec->splitdir($directories);
Packit 0bf95d
    if (@dirs > 0) { pop(@dirs) unless $dirs[-1] }    # remove empty component
Packit 0bf95d
    push(@dirs, defined($file) ? $file : '');
Packit 0bf95d
Packit 0bf95d
    #return wantarray ? @dirs : join ( '/', @dirs );
Packit 0bf95d
Packit 0bf95d
    my $normalised_path = join '/', @dirs;
Packit 0bf95d
Packit 0bf95d
    # Leading directory separators should not be stored in zip archives.
Packit 0bf95d
    # Example:
Packit 0bf95d
    #   C:\a\b\c\      a/b/c
Packit 0bf95d
    #   C:\a\b\c.txt   a/b/c.txt
Packit 0bf95d
    #   /a/b/c/        a/b/c
Packit 0bf95d
    #   /a/b/c.txt     a/b/c.txt
Packit 0bf95d
    $normalised_path =~ s{^/}{};    # remove leading separator
Packit 0bf95d
Packit 0bf95d
    return $normalised_path;
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
# Return an absolute local name for a zip name.
Packit 0bf95d
# Assume a directory if zip name has trailing slash.
Packit 0bf95d
# Takes an optional volume name in FS format (like 'a:').
Packit 0bf95d
#
Packit 0bf95d
sub _asLocalName {
Packit 0bf95d
    my $name   = shift;    # zip format
Packit 0bf95d
    my $volume = shift;
Packit 0bf95d
    $volume = '' unless defined($volume);    # local FS format
Packit 0bf95d
Packit 0bf95d
    my @paths = split(/\//, $name);
Packit 0bf95d
    my $filename = pop(@paths);
Packit 0bf95d
    $filename = '' unless defined($filename);
Packit 0bf95d
    my $localDirs = @paths ? File::Spec->catdir(@paths) : '';
Packit 0bf95d
    my $localName = File::Spec->catpath($volume, $localDirs, $filename);
Packit 0bf95d
    unless ($volume) {
Packit 0bf95d
        $localName = File::Spec->rel2abs($localName, Cwd::getcwd());
Packit 0bf95d
    }
Packit 0bf95d
    return $localName;
Packit 0bf95d
}
Packit 0bf95d
Packit 0bf95d
1;
Packit 0bf95d
Packit 0bf95d
__END__
Packit 0bf95d
Packit 0bf95d
=pod
Packit 0bf95d
Packit 0bf95d
=encoding utf8
Packit 0bf95d
Packit 0bf95d
=head1 NAME
Packit 0bf95d
Packit 0bf95d
Archive::Zip - Provide an interface to ZIP archive files.
Packit 0bf95d
Packit 0bf95d
=head1 SYNOPSIS
Packit 0bf95d
Packit 0bf95d
   # Create a Zip file
Packit 0bf95d
   use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
Packit 0bf95d
   my $zip = Archive::Zip->new();
Packit 0bf95d
Packit 0bf95d
   # Add a directory
Packit 0bf95d
   my $dir_member = $zip->addDirectory( 'dirname/' );
Packit 0bf95d
Packit 0bf95d
   # Add a file from a string with compression
Packit 0bf95d
   my $string_member = $zip->addString( 'This is a test', 'stringMember.txt' );
Packit 0bf95d
   $string_member->desiredCompressionMethod( COMPRESSION_DEFLATED );
Packit 0bf95d
Packit 0bf95d
   # Add a file from disk
Packit 0bf95d
   my $file_member = $zip->addFile( 'xyz.pl', 'AnotherName.pl' );
Packit 0bf95d
Packit 0bf95d
   # Save the Zip file
Packit 0bf95d
   unless ( $zip->writeToFileNamed('someZip.zip') == AZ_OK ) {
Packit 0bf95d
       die 'write error';
Packit 0bf95d
   }
Packit 0bf95d
Packit 0bf95d
   # Read a Zip file
Packit 0bf95d
   my $somezip = Archive::Zip->new();
Packit 0bf95d
   unless ( $somezip->read( 'someZip.zip' ) == AZ_OK ) {
Packit 0bf95d
       die 'read error';
Packit 0bf95d
   }
Packit 0bf95d
Packit 0bf95d
   # Change the compression type for a file in the Zip
Packit 0bf95d
   my $member = $somezip->memberNamed( 'stringMember.txt' );
Packit 0bf95d
   $member->desiredCompressionMethod( COMPRESSION_STORED );
Packit 0bf95d
   unless ( $zip->writeToFileNamed( 'someOtherZip.zip' ) == AZ_OK ) {
Packit 0bf95d
       die 'write error';
Packit 0bf95d
   }
Packit 0bf95d
Packit 0bf95d
=head1 DESCRIPTION
Packit 0bf95d
Packit 0bf95d
The Archive::Zip module allows a Perl program to create, manipulate, read,
Packit 0bf95d
and write Zip archive files.
Packit 0bf95d
Packit 0bf95d
Zip archives can be created, or you can read from existing zip files.
Packit 0bf95d
Packit 0bf95d
Once created, they can be written to files, streams, or strings. Members
Packit 0bf95d
can be added, removed, extracted, replaced, rearranged, and enumerated.
Packit 0bf95d
They can also be renamed or have their dates, comments, or other attributes
Packit 0bf95d
queried or modified. Their data can be compressed or uncompressed as needed.
Packit 0bf95d
Packit 0bf95d
Members can be created from members in existing Zip files, or from existing
Packit 0bf95d
directories, files, or strings.
Packit 0bf95d
Packit 0bf95d
This module uses the L<Compress::Raw::Zlib> library to read and write the
Packit 0bf95d
compressed streams inside the files.
Packit 0bf95d
Packit 0bf95d
One can use L<Archive::Zip::MemberRead> to read the zip file archive members
Packit 0bf95d
as if they were files.
Packit 0bf95d
Packit 0bf95d
=head2 File Naming
Packit 0bf95d
Packit 0bf95d
Regardless of what your local file system uses for file naming, names in a
Packit 0bf95d
Zip file are in Unix format (I<forward> slashes (/) separating directory
Packit 0bf95d
names, etc.).
Packit 0bf95d
Packit 0bf95d
C<Archive::Zip> tries to be consistent with file naming conventions, and will
Packit 0bf95d
translate back and forth between native and Zip file names.
Packit 0bf95d
Packit 0bf95d
However, it can't guess which format names are in. So two rules control what
Packit 0bf95d
kind of file name you must pass various routines:
Packit 0bf95d
Packit 0bf95d
=over 4
Packit 0bf95d
Packit 0bf95d
=item Names of files are in local format.
Packit 0bf95d
Packit 0bf95d
C<File::Spec> and C<File::Basename> are used for various file
Packit 0bf95d
operations. When you're referring to a file on your system, use its
Packit 0bf95d
file naming conventions.
Packit 0bf95d
Packit 0bf95d
=item Names of archive members are in Unix format.
Packit 0bf95d
Packit 0bf95d
This applies to every method that refers to an archive member, or
Packit 0bf95d
provides a name for new archive members. The C<extract()> methods
Packit 0bf95d
that can take one or two names will convert from local to zip names
Packit 0bf95d
if you call them with a single name.
Packit 0bf95d
Packit 0bf95d
=back
Packit 0bf95d
Packit 0bf95d
=head2 Archive::Zip Object Model
Packit 0bf95d
Packit 0bf95d
=head3 Overview
Packit 0bf95d
Packit 0bf95d
Archive::Zip::Archive objects are what you ordinarily deal with.
Packit 0bf95d
These maintain the structure of a zip file, without necessarily
Packit 0bf95d
holding data. When a zip is read from a disk file, the (possibly
Packit 0bf95d
compressed) data still lives in the file, not in memory. Archive
Packit 0bf95d
members hold information about the individual members, but not
Packit 0bf95d
(usually) the actual member data. When the zip is written to a
Packit 0bf95d
(different) file, the member data is compressed or copied as needed.
Packit 0bf95d
It is possible to make archive members whose data is held in a string
Packit 0bf95d
in memory, but this is not done when a zip file is read. Directory
Packit 0bf95d
members don't have any data.
Packit 0bf95d
Packit 0bf95d
=head2 Inheritance
Packit 0bf95d
Packit 0bf95d
  Exporter
Packit 0bf95d
   Archive::Zip                            Common base class, has defs.
Packit 0bf95d
       Archive::Zip::Archive               A Zip archive.
Packit 0bf95d
       Archive::Zip::Member                Abstract superclass for all members.
Packit 0bf95d
           Archive::Zip::StringMember      Member made from a string
Packit 0bf95d
           Archive::Zip::FileMember        Member made from an external file
Packit 0bf95d
               Archive::Zip::ZipFileMember Member that lives in a zip file
Packit 0bf95d
               Archive::Zip::NewFileMember Member whose data is in a file
Packit 0bf95d
           Archive::Zip::DirectoryMember   Member that is a directory
Packit 0bf95d
Packit 0bf95d
=head1 EXPORTS
Packit 0bf95d
Packit 0bf95d
=over 4
Packit 0bf95d
Packit 0bf95d
=item :CONSTANTS
Packit 0bf95d
Packit 0bf95d
Exports the following constants:
Packit 0bf95d
Packit 0bf95d
FA_MSDOS FA_UNIX GPBF_ENCRYPTED_MASK
Packit 0bf95d
GPBF_DEFLATING_COMPRESSION_MASK GPBF_HAS_DATA_DESCRIPTOR_MASK
Packit 0bf95d
COMPRESSION_STORED COMPRESSION_DEFLATED IFA_TEXT_FILE_MASK
Packit 0bf95d
IFA_TEXT_FILE IFA_BINARY_FILE COMPRESSION_LEVEL_NONE
Packit 0bf95d
COMPRESSION_LEVEL_DEFAULT COMPRESSION_LEVEL_FASTEST
Packit 0bf95d
COMPRESSION_LEVEL_BEST_COMPRESSION
Packit 0bf95d
Packit 0bf95d
=item :MISC_CONSTANTS
Packit 0bf95d
Packit 0bf95d
Exports the following constants (only necessary for extending the
Packit 0bf95d
module):
Packit 0bf95d
Packit 0bf95d
FA_AMIGA FA_VAX_VMS FA_VM_CMS FA_ATARI_ST FA_OS2_HPFS
Packit 0bf95d
FA_MACINTOSH FA_Z_SYSTEM FA_CPM FA_WINDOWS_NTFS
Packit 0bf95d
GPBF_IMPLODING_8K_SLIDING_DICTIONARY_MASK
Packit 0bf95d
GPBF_IMPLODING_3_SHANNON_FANO_TREES_MASK
Packit 0bf95d
GPBF_IS_COMPRESSED_PATCHED_DATA_MASK COMPRESSION_SHRUNK
Packit 0bf95d
DEFLATING_COMPRESSION_NORMAL DEFLATING_COMPRESSION_MAXIMUM
Packit 0bf95d
DEFLATING_COMPRESSION_FAST DEFLATING_COMPRESSION_SUPER_FAST
Packit 0bf95d
COMPRESSION_REDUCED_1 COMPRESSION_REDUCED_2 COMPRESSION_REDUCED_3
Packit 0bf95d
COMPRESSION_REDUCED_4 COMPRESSION_IMPLODED COMPRESSION_TOKENIZED
Packit 0bf95d
COMPRESSION_DEFLATED_ENHANCED
Packit 0bf95d
COMPRESSION_PKWARE_DATA_COMPRESSION_LIBRARY_IMPLODED
Packit 0bf95d
Packit 0bf95d
=item :ERROR_CODES
Packit 0bf95d
Packit 0bf95d
Explained below. Returned from most methods.
Packit 0bf95d
Packit 0bf95d
AZ_OK AZ_STREAM_END AZ_ERROR AZ_FORMAT_ERROR AZ_IO_ERROR
Packit 0bf95d
Packit 0bf95d
=back
Packit 0bf95d
Packit 0bf95d
=head1 ERROR CODES
Packit 0bf95d
Packit 0bf95d
Many of the methods in Archive::Zip return error codes. These are implemented
Packit 0bf95d
as inline subroutines, using the C<use constant> pragma. They can be imported
Packit 0bf95d
into your namespace using the C<:ERROR_CODES> tag:
Packit 0bf95d
Packit 0bf95d
  use Archive::Zip qw( :ERROR_CODES );
Packit 0bf95d
Packit 0bf95d
  ...
Packit 0bf95d
Packit 0bf95d
  unless ( $zip->read( 'myfile.zip' ) == AZ_OK ) {
Packit 0bf95d
      die "whoops!";
Packit 0bf95d
  }
Packit 0bf95d
Packit 0bf95d
=over 4
Packit 0bf95d
Packit 0bf95d
=item AZ_OK (0)
Packit 0bf95d
Packit 0bf95d
Everything is fine.
Packit 0bf95d
Packit 0bf95d
=item AZ_STREAM_END (1)
Packit 0bf95d
Packit 0bf95d
The read stream (or central directory) ended normally.
Packit 0bf95d
Packit 0bf95d
=item AZ_ERROR (2)
Packit 0bf95d
Packit 0bf95d
There was some generic kind of error.
Packit 0bf95d
Packit 0bf95d
=item AZ_FORMAT_ERROR (3)
Packit 0bf95d
Packit 0bf95d
There is a format error in a ZIP file being read.
Packit 0bf95d
Packit 0bf95d
=item AZ_IO_ERROR (4)
Packit 0bf95d
Packit 0bf95d
There was an IO error.
Packit 0bf95d
Packit 0bf95d
=back
Packit 0bf95d
Packit 0bf95d
=head2 Compression
Packit 0bf95d
Packit 0bf95d
Archive::Zip allows each member of a ZIP file to be compressed (using the
Packit 0bf95d
Deflate algorithm) or uncompressed.
Packit 0bf95d
Packit 0bf95d
Other compression algorithms that some versions of ZIP have been able to
Packit 0bf95d
produce are not supported. Each member has two compression methods: the
Packit 0bf95d
one it's stored as (this is always COMPRESSION_STORED for string and external
Packit 0bf95d
file members), and the one you desire for the member in the zip file.
Packit 0bf95d
Packit 0bf95d
These can be different, of course, so you can make a zip member that is not
Packit 0bf95d
compressed out of one that is, and vice versa.
Packit 0bf95d
Packit 0bf95d
You can inquire about the current compression and set the desired
Packit 0bf95d
compression method:
Packit 0bf95d
Packit 0bf95d
  my $member = $zip->memberNamed( 'xyz.txt' );
Packit 0bf95d
  $member->compressionMethod();    # return current compression
Packit 0bf95d
Packit 0bf95d
  # set to read uncompressed
Packit 0bf95d
  $member->desiredCompressionMethod( COMPRESSION_STORED );
Packit 0bf95d
Packit 0bf95d
  # set to read compressed
Packit 0bf95d
  $member->desiredCompressionMethod( COMPRESSION_DEFLATED );
Packit 0bf95d
Packit 0bf95d
There are two different compression methods:
Packit 0bf95d
Packit 0bf95d
=over 4
Packit 0bf95d
Packit 0bf95d
=item COMPRESSION_STORED
Packit 0bf95d
Packit 0bf95d
File is stored (no compression)
Packit 0bf95d
Packit 0bf95d
=item COMPRESSION_DEFLATED
Packit 0bf95d
Packit 0bf95d
File is Deflated
Packit 0bf95d
Packit 0bf95d
=back
Packit 0bf95d
Packit 0bf95d
=head2 Compression Levels
Packit 0bf95d
Packit 0bf95d
If a member's desiredCompressionMethod is COMPRESSION_DEFLATED, you
Packit 0bf95d
can choose different compression levels. This choice may affect the
Packit 0bf95d
speed of compression and decompression, as well as the size of the
Packit 0bf95d
compressed member data.
Packit 0bf95d
Packit 0bf95d
  $member->desiredCompressionLevel( 9 );
Packit 0bf95d
Packit 0bf95d
The levels given can be:
Packit 0bf95d
Packit 0bf95d
=over 4
Packit 0bf95d
Packit 0bf95d
=item * 0 or COMPRESSION_LEVEL_NONE
Packit 0bf95d
Packit 0bf95d
This is the same as saying
Packit 0bf95d
Packit 0bf95d
  $member->desiredCompressionMethod( COMPRESSION_STORED );
Packit 0bf95d
Packit 0bf95d
=item * 1 .. 9
Packit 0bf95d
Packit 0bf95d
1 gives the best speed and worst compression, and 9 gives the
Packit 0bf95d
best compression and worst speed.
Packit 0bf95d
Packit 0bf95d
=item * COMPRESSION_LEVEL_FASTEST
Packit 0bf95d
Packit 0bf95d
This is a synonym for level 1.
Packit 0bf95d
Packit 0bf95d
=item * COMPRESSION_LEVEL_BEST_COMPRESSION
Packit 0bf95d
Packit 0bf95d
This is a synonym for level 9.
Packit 0bf95d
Packit 0bf95d
=item * COMPRESSION_LEVEL_DEFAULT
Packit 0bf95d
Packit 0bf95d
This gives a good compromise between speed and compression,
Packit 0bf95d
and is currently equivalent to 6 (this is in the zlib code).
Packit 0bf95d
This is the level that will be used if not specified.
Packit 0bf95d
Packit 0bf95d
=back
Packit 0bf95d
Packit 0bf95d
=head1 Archive::Zip Methods
Packit 0bf95d
Packit 0bf95d
The Archive::Zip class (and its invisible subclass Archive::Zip::Archive)
Packit 0bf95d
implement generic zip file functionality. Creating a new Archive::Zip object
Packit 0bf95d
actually makes an Archive::Zip::Archive object, but you don't have to worry
Packit 0bf95d
about this unless you're subclassing.
Packit 0bf95d
Packit 0bf95d
=head2 Constructor
Packit 0bf95d
Packit 0bf95d
=over 4
Packit 0bf95d
Packit 0bf95d
=item new( [$fileName] )
Packit 0bf95d
Packit 0bf95d
=item new( { filename => $fileName } )
Packit 0bf95d
Packit 0bf95d
Make a new, empty zip archive.
Packit 0bf95d
Packit 0bf95d
    my $zip = Archive::Zip->new();
Packit 0bf95d
Packit 0bf95d
If an additional argument is passed, new() will call read()
Packit 0bf95d
to read the contents of an archive:
Packit 0bf95d
Packit 0bf95d
    my $zip = Archive::Zip->new( 'xyz.zip' );
Packit 0bf95d
Packit 0bf95d
If a filename argument is passed and the read fails for any
Packit 0bf95d
reason, new will return undef. For this reason, it may be
Packit 0bf95d
better to call read separately.
Packit 0bf95d
Packit 0bf95d
=back
Packit 0bf95d
Packit 0bf95d
=head2 Zip Archive Utility Methods
Packit 0bf95d
Packit 0bf95d
These Archive::Zip methods may be called as functions or as object
Packit 0bf95d
methods. Do not call them as class methods:
Packit 0bf95d
Packit 0bf95d
    $zip = Archive::Zip->new();
Packit 0bf95d
    $crc = Archive::Zip::computeCRC32( 'ghijkl' );    # OK
Packit 0bf95d
    $crc = $zip->computeCRC32( 'ghijkl' );            # also OK
Packit 0bf95d
    $crc = Archive::Zip->computeCRC32( 'ghijkl' );    # NOT OK
Packit 0bf95d
Packit 0bf95d
=over 4
Packit 0bf95d
Packit 0bf95d
=item Archive::Zip::computeCRC32( $string [, $crc] )
Packit 0bf95d
Packit 0bf95d
=item Archive::Zip::computeCRC32( { string => $string [, checksum => $crc ] } )
Packit 0bf95d
Packit 0bf95d
This is a utility function that uses the Compress::Raw::Zlib CRC
Packit 0bf95d
routine to compute a CRC-32. You can get the CRC of a string:
Packit 0bf95d
Packit 0bf95d
    $crc = Archive::Zip::computeCRC32( $string );
Packit 0bf95d
Packit 0bf95d
Or you can compute the running CRC:
Packit 0bf95d
Packit 0bf95d
    $crc = 0;
Packit 0bf95d
    $crc = Archive::Zip::computeCRC32( 'abcdef', $crc );
Packit 0bf95d
    $crc = Archive::Zip::computeCRC32( 'ghijkl', $crc );
Packit 0bf95d
Packit 0bf95d
=item Archive::Zip::setChunkSize( $number )
Packit 0bf95d
Packit 0bf95d
=item Archive::Zip::setChunkSize( { chunkSize => $number } )
Packit 0bf95d
Packit 0bf95d
Report or change chunk size used for reading and writing.
Packit 0bf95d
This can make big differences in dealing with large files.
Packit 0bf95d
Currently, this defaults to 32K. This also changes the chunk
Packit 0bf95d
size used for Compress::Raw::Zlib. You must call setChunkSize()
Packit 0bf95d
before reading or writing. This is not exportable, so you
Packit 0bf95d
must call it like:
Packit 0bf95d
Packit 0bf95d
    Archive::Zip::setChunkSize( 4096 );
Packit 0bf95d
Packit 0bf95d
or as a method on a zip (though this is a global setting).
Packit 0bf95d
Returns old chunk size.
Packit 0bf95d
Packit 0bf95d
=item Archive::Zip::chunkSize()
Packit 0bf95d
Packit 0bf95d
Returns the current chunk size:
Packit 0bf95d
Packit 0bf95d
    my $chunkSize = Archive::Zip::chunkSize();
Packit 0bf95d
Packit 0bf95d
=item Archive::Zip::setErrorHandler( \&subroutine )
Packit 0bf95d
Packit 0bf95d
=item Archive::Zip::setErrorHandler( { subroutine => \&subroutine } )
Packit 0bf95d
Packit 0bf95d
Change the subroutine called with error strings. This
Packit 0bf95d
defaults to \&Carp::carp, but you may want to change it to
Packit 0bf95d
get the error strings. This is not exportable, so you must
Packit 0bf95d
call it like:
Packit 0bf95d
Packit 0bf95d
    Archive::Zip::setErrorHandler( \&myErrorHandler );
Packit 0bf95d
Packit 0bf95d
If myErrorHandler is undef, resets handler to default.
Packit 0bf95d
Returns old error handler. Note that if you call Carp::carp
Packit 0bf95d
or a similar routine or if you're chaining to the default
Packit 0bf95d
error handler from your error handler, you may want to
Packit 0bf95d
increment the number of caller levels that are skipped (do
Packit 0bf95d
not just set it to a number):
Packit 0bf95d
Packit 0bf95d
    $Carp::CarpLevel++;
Packit 0bf95d
Packit 0bf95d
=item Archive::Zip::tempFile( [ $tmpdir ] )
Packit 0bf95d
Packit 0bf95d
=item Archive::Zip::tempFile( { tempDir => $tmpdir } )
Packit 0bf95d
Packit 0bf95d
Create a uniquely named temp file. It will be returned open
Packit 0bf95d
for read/write. If C<$tmpdir> is given, it is used as the
Packit 0bf95d
name of a directory to create the file in. If not given,
Packit 0bf95d
creates the file using C<File::Spec::tmpdir()>. Generally, you can
Packit 0bf95d
override this choice using the
Packit 0bf95d
Packit 0bf95d
    $ENV{TMPDIR}
Packit 0bf95d
Packit 0bf95d
environment variable. But see the L<File::Spec|File::Spec>
Packit 0bf95d
documentation for your system. Note that on many systems, if you're
Packit 0bf95d
running in taint mode, then you must make sure that C<$ENV{TMPDIR}> is
Packit 0bf95d
untainted for it to be used.
Packit 0bf95d
Will I<NOT> create C<$tmpdir> if it does not exist (this is a change
Packit 0bf95d
from prior versions!). Returns file handle and name:
Packit 0bf95d
Packit 0bf95d
    my ($fh, $name) = Archive::Zip::tempFile();
Packit 0bf95d
    my ($fh, $name) = Archive::Zip::tempFile('myTempDir');
Packit 0bf95d
    my $fh = Archive::Zip::tempFile();  # if you don't need the name
Packit 0bf95d
Packit 0bf95d
=back
Packit 0bf95d
Packit 0bf95d
=head2 Zip Archive Accessors
Packit 0bf95d
Packit 0bf95d
=over 4
Packit 0bf95d
Packit 0bf95d
=item members()
Packit 0bf95d
Packit 0bf95d
Return a copy of the members array
Packit 0bf95d
Packit 0bf95d
    my @members = $zip->members();
Packit 0bf95d
Packit 0bf95d
=item numberOfMembers()
Packit 0bf95d
Packit 0bf95d
Return the number of members I have
Packit 0bf95d
Packit 0bf95d
=item memberNames()
Packit 0bf95d
Packit 0bf95d
Return a list of the (internal) file names of the zip members
Packit 0bf95d
Packit 0bf95d
=item memberNamed( $string )
Packit 0bf95d
Packit 0bf95d
=item memberNamed( { zipName => $string } )
Packit 0bf95d
Packit 0bf95d
Return ref to member whose filename equals given filename or
Packit 0bf95d
undef. C<$string> must be in Zip (Unix) filename format.
Packit 0bf95d
Packit 0bf95d
=item membersMatching( $regex )
Packit 0bf95d
Packit 0bf95d
=item membersMatching( { regex => $regex } )
Packit 0bf95d
Packit 0bf95d
Return array of members whose filenames match given regular
Packit 0bf95d
expression in list context. Returns number of matching
Packit 0bf95d
members in scalar context.
Packit 0bf95d
Packit 0bf95d
    my @textFileMembers = $zip->membersMatching( '.*\.txt' );
Packit 0bf95d
    # or
Packit 0bf95d
    my $numberOfTextFiles = $zip->membersMatching( '.*\.txt' );
Packit 0bf95d
Packit 0bf95d
=item diskNumber()
Packit 0bf95d
Packit 0bf95d
Return the disk that I start on. Not used for writing zips,
Packit 0bf95d
but might be interesting if you read a zip in. This should be
Packit 0bf95d
0, as Archive::Zip does not handle multi-volume archives.
Packit 0bf95d
Packit 0bf95d
=item diskNumberWithStartOfCentralDirectory()
Packit 0bf95d
Packit 0bf95d
Return the disk number that holds the beginning of the
Packit 0bf95d
central directory. Not used for writing zips, but might be
Packit 0bf95d
interesting if you read a zip in. This should be 0, as
Packit 0bf95d
Archive::Zip does not handle multi-volume archives.
Packit 0bf95d
Packit 0bf95d
=item numberOfCentralDirectoriesOnThisDisk()
Packit 0bf95d
Packit 0bf95d
Return the number of CD structures in the zipfile last read in.
Packit 0bf95d
Not used for writing zips, but might be interesting if you read a zip
Packit 0bf95d
in.
Packit 0bf95d
Packit 0bf95d
=item numberOfCentralDirectories()
Packit 0bf95d
Packit 0bf95d
Return the number of CD structures in the zipfile last read in.
Packit 0bf95d
Not used for writing zips, but might be interesting if you read a zip
Packit 0bf95d
in.
Packit 0bf95d
Packit 0bf95d
=item centralDirectorySize()
Packit 0bf95d
Packit 0bf95d
Returns central directory size, as read from an external zip
Packit 0bf95d
file. Not used for writing zips, but might be interesting if
Packit 0bf95d
you read a zip in.
Packit 0bf95d
Packit 0bf95d
=item centralDirectoryOffsetWRTStartingDiskNumber()
Packit 0bf95d
Packit 0bf95d
Returns the offset into the zip file where the CD begins. Not
Packit 0bf95d
used for writing zips, but might be interesting if you read a
Packit 0bf95d
zip in.
Packit 0bf95d
Packit 0bf95d
=item zipfileComment( [ $string ] )
Packit 0bf95d
Packit 0bf95d
=item zipfileComment( [ { comment => $string } ] )
Packit 0bf95d
Packit 0bf95d
Get or set the zipfile comment. Returns the old comment.
Packit 0bf95d
Packit 0bf95d
    print $zip->zipfileComment();
Packit 0bf95d
    $zip->zipfileComment( 'New Comment' );
Packit 0bf95d
Packit 0bf95d
=item eocdOffset()
Packit 0bf95d
Packit 0bf95d
Returns the (unexpected) number of bytes between where the
Packit 0bf95d
EOCD was found and where it expected to be. This is normally
Packit 0bf95d
0, but would be positive if something (a virus, perhaps) had
Packit 0bf95d
added bytes somewhere before the EOCD. Not used for writing
Packit 0bf95d
zips, but might be interesting if you read a zip in. Here is
Packit 0bf95d
an example of how you can diagnose this:
Packit 0bf95d
Packit 0bf95d
  my $zip = Archive::Zip->new('somefile.zip');
Packit 0bf95d
  if ($zip->eocdOffset())
Packit 0bf95d
  {
Packit 0bf95d
    warn "A virus has added ", $zip->eocdOffset, " bytes of garbage\n";
Packit 0bf95d
  }
Packit 0bf95d
Packit 0bf95d
The C<eocdOffset()> is used to adjust the starting position of member
Packit 0bf95d
headers, if necessary.
Packit 0bf95d
Packit 0bf95d
=item fileName()
Packit 0bf95d
Packit 0bf95d
Returns the name of the file last read from. If nothing has
Packit 0bf95d
been read yet, returns an empty string; if read from a file
Packit 0bf95d
handle, returns the handle in string form.
Packit 0bf95d
Packit 0bf95d
=back
Packit 0bf95d
Packit 0bf95d
=head2 Zip Archive Member Operations
Packit 0bf95d
Packit 0bf95d
Various operations on a zip file modify members. When a member is
Packit 0bf95d
passed as an argument, you can either use a reference to the member
Packit 0bf95d
itself, or the name of a member. Of course, using the name requires
Packit 0bf95d
that names be unique within a zip (this is not enforced).
Packit 0bf95d
Packit 0bf95d
=over 4
Packit 0bf95d
Packit 0bf95d
=item removeMember( $memberOrName )
Packit 0bf95d
Packit 0bf95d
=item removeMember( { memberOrZipName => $memberOrName } )
Packit 0bf95d
Packit 0bf95d
Remove and return the given member, or match its name and
Packit 0bf95d
remove it. Returns undef if member or name does not exist in this
Packit 0bf95d
Zip. No-op if member does not belong to this zip.
Packit 0bf95d
Packit 0bf95d
=item replaceMember( $memberOrName, $newMember )
Packit 0bf95d
Packit 0bf95d
=item replaceMember( { memberOrZipName => $memberOrName,
Packit 0bf95d
    newMember => $newMember } )
Packit 0bf95d
Packit 0bf95d
Remove and return the given member, or match its name and
Packit 0bf95d
remove it. Replace with new member. Returns undef if member or
Packit 0bf95d
name does not exist in this Zip, or if C<$newMember> is undefined.
Packit 0bf95d
Packit 0bf95d
It is an (undiagnosed) error to provide a C<$newMember> that is a
Packit 0bf95d
member of the zip being modified.
Packit 0bf95d
Packit 0bf95d
    my $member1 = $zip->removeMember( 'xyz' );
Packit 0bf95d
    my $member2 = $zip->replaceMember( 'abc', $member1 );
Packit 0bf95d
    # now, $member2 (named 'abc') is not in $zip,
Packit 0bf95d
    # and $member1 (named 'xyz') is, having taken $member2's place.
Packit 0bf95d
Packit 0bf95d
=item extractMember( $memberOrName [, $extractedName ] )
Packit 0bf95d
Packit 0bf95d
=item extractMember( { memberOrZipName => $memberOrName
Packit 0bf95d
    [, name => $extractedName ] } )
Packit 0bf95d
Packit 0bf95d
Extract the given member, or match its name and extract it.
Packit 0bf95d
Returns undef if member does not exist in this Zip. If
Packit 0bf95d
optional second arg is given, use it as the name of the
Packit 0bf95d
extracted member. Otherwise, the internal filename of the
Packit 0bf95d
member is used as the name of the extracted file or
Packit 0bf95d
directory.
Packit 0bf95d
If you pass C<$extractedName>, it should be in the local file
Packit 0bf95d
system's format.
Packit 0bf95d
All necessary directories will be created. Returns C<AZ_OK>
Packit 0bf95d
on success.
Packit 0bf95d
Packit 0bf95d
=item extractMemberWithoutPaths( $memberOrName [, $extractedName ] )
Packit 0bf95d
Packit 0bf95d
=item extractMemberWithoutPaths( { memberOrZipName => $memberOrName
Packit 0bf95d
    [, name => $extractedName ] } )
Packit 0bf95d
Packit 0bf95d
Extract the given member, or match its name and extract it.
Packit 0bf95d
Does not use path information (extracts into the current
Packit 0bf95d
directory). Returns undef if member does not exist in this
Packit 0bf95d
Zip.
Packit 0bf95d
If optional second arg is given, use it as the name of the
Packit 0bf95d
extracted member (its paths will be deleted too). Otherwise,
Packit 0bf95d
the internal filename of the member (minus paths) is used as
Packit 0bf95d
the name of the extracted file or directory. Returns C<AZ_OK>
Packit 0bf95d
on success.
Packit 0bf95d
Packit 0bf95d
=item addMember( $member )
Packit 0bf95d
Packit 0bf95d
=item addMember( { member => $member } )
Packit 0bf95d
Packit 0bf95d
Append a member (possibly from another zip file) to the zip
Packit 0bf95d
file. Returns the new member. Generally, you will use
Packit 0bf95d
addFile(), addDirectory(), addFileOrDirectory(), addString(),
Packit 0bf95d
or read() to add members.
Packit 0bf95d
Packit 0bf95d
    # Move member named 'abc' to end of zip:
Packit 0bf95d
    my $member = $zip->removeMember( 'abc' );
Packit 0bf95d
    $zip->addMember( $member );
Packit 0bf95d
Packit 0bf95d
=item updateMember( $memberOrName, $fileName )
Packit 0bf95d
Packit 0bf95d
=item updateMember( { memberOrZipName => $memberOrName, name => $fileName } )
Packit 0bf95d
Packit 0bf95d
Update a single member from the file or directory named C<$fileName>.
Packit 0bf95d
Returns the (possibly added or updated) member, if any; C<undef> on
Packit 0bf95d
errors.
Packit 0bf95d
The comparison is based on C<lastModTime()> and (in the case of a
Packit 0bf95d
non-directory) the size of the file.
Packit 0bf95d
Packit 0bf95d
=item addFile( $fileName [, $newName, $compressionLevel ] )
Packit 0bf95d
Packit 0bf95d
=item addFile( { filename => $fileName
Packit 0bf95d
    [, zipName => $newName, compressionLevel => $compressionLevel } ] )
Packit 0bf95d
Packit 0bf95d
Append a member whose data comes from an external file,
Packit 0bf95d
returning the member or undef. The member will have its file
Packit 0bf95d
name set to the name of the external file, and its
Packit 0bf95d
desiredCompressionMethod set to COMPRESSION_DEFLATED. The
Packit 0bf95d
file attributes and last modification time will be set from
Packit 0bf95d
the file.
Packit 0bf95d
If the name given does not represent a readable plain file or
Packit 0bf95d
symbolic link, undef will be returned. C<$fileName> must be
Packit 0bf95d
in the format required for the local file system.
Packit 0bf95d
The optional C<$newName> argument sets the internal file name
Packit 0bf95d
to something different than the given $fileName. C<$newName>,
Packit 0bf95d
if given, must be in Zip name format (i.e. Unix).
Packit 0bf95d
The text mode bit will be set if the contents appears to be
Packit 0bf95d
text (as returned by the C<-T> perl operator).
Packit 0bf95d
Packit 0bf95d
Packit 0bf95d
I<NOTE> that you should not (generally) use absolute path names
Packit 0bf95d
in zip member names, as this will cause problems with some zip
Packit 0bf95d
tools as well as introduce a security hole and make the zip
Packit 0bf95d
harder to use.
Packit 0bf95d
Packit 0bf95d
=item addDirectory( $directoryName [, $fileName ] )
Packit 0bf95d
Packit 0bf95d
=item addDirectory( { directoryName => $directoryName
Packit 0bf95d
    [, zipName => $fileName ] } )
Packit 0bf95d
Packit 0bf95d
Packit 0bf95d
Append a member created from the given directory name. The
Packit 0bf95d
directory name does not have to name an existing directory.
Packit 0bf95d
If the named directory exists, the file modification time and
Packit 0bf95d
permissions are set from the existing directory, otherwise
Packit 0bf95d
they are set to now and permissive default permissions.
Packit 0bf95d
C<$directoryName> must be in local file system format.
Packit 0bf95d
The optional second argument sets the name of the archive
Packit 0bf95d
member (which defaults to C<$directoryName>). If given, it
Packit 0bf95d
must be in Zip (Unix) format.
Packit 0bf95d
Returns the new member.
Packit 0bf95d
Packit 0bf95d
=item addFileOrDirectory( $name [, $newName, $compressionLevel ] )
Packit 0bf95d
Packit 0bf95d
=item addFileOrDirectory( { name => $name [, zipName => $newName,
Packit 0bf95d
    compressionLevel => $compressionLevel ] } )
Packit 0bf95d
Packit 0bf95d
Packit 0bf95d
Append a member from the file or directory named $name. If
Packit 0bf95d
$newName is given, use it for the name of the new member.
Packit 0bf95d
Will add or remove trailing slashes from $newName as needed.
Packit 0bf95d
C<$name> must be in local file system format.
Packit 0bf95d
The optional second argument sets the name of the archive
Packit 0bf95d
member (which defaults to C<$name>). If given, it must be in
Packit 0bf95d
Zip (Unix) format.
Packit 0bf95d
Packit 0bf95d
=item addString( $stringOrStringRef, $name, [$compressionLevel] )
Packit 0bf95d
Packit 0bf95d
=item addString( { string => $stringOrStringRef [, zipName => $name,
Packit 0bf95d
    compressionLevel => $compressionLevel ] } )
Packit 0bf95d
Packit 0bf95d
Append a member created from the given string or string
Packit 0bf95d
reference. The name is given by the second argument.
Packit 0bf95d
Returns the new member. The last modification time will be
Packit 0bf95d
set to now, and the file attributes will be set to permissive
Packit 0bf95d
defaults.
Packit 0bf95d
Packit 0bf95d
    my $member = $zip->addString( 'This is a test', 'test.txt' );
Packit 0bf95d
Packit 0bf95d
=item contents( $memberOrMemberName [, $newContents ] )
Packit 0bf95d
Packit 0bf95d
=item contents( { memberOrZipName => $memberOrMemberName
Packit 0bf95d
    [, contents => $newContents ] } )
Packit 0bf95d
Packit 0bf95d
Packit 0bf95d
Returns the uncompressed data for a particular member, or
Packit 0bf95d
undef.
Packit 0bf95d
Packit 0bf95d
    print "xyz.txt contains " . $zip->contents( 'xyz.txt' );
Packit 0bf95d
Packit 0bf95d
Also can change the contents of a member:
Packit 0bf95d
Packit 0bf95d
    $zip->contents( 'xyz.txt', 'This is the new contents' );
Packit 0bf95d
Packit 0bf95d
If called expecting an array as the return value, it will include
Packit 0bf95d
the status as the second value in the array.
Packit 0bf95d
Packit 0bf95d
    ($content, $status) = $zip->contents( 'xyz.txt');
Packit 0bf95d
Packit 0bf95d
=back
Packit 0bf95d
Packit 0bf95d
=head2 Zip Archive I/O operations
Packit 0bf95d
Packit 0bf95d
Packit 0bf95d
A Zip archive can be written to a file or file handle, or read from
Packit 0bf95d
one.
Packit 0bf95d
Packit 0bf95d
=over 4
Packit 0bf95d
Packit 0bf95d
=item writeToFileNamed( $fileName )
Packit 0bf95d
Packit 0bf95d
=item writeToFileNamed( { fileName => $fileName } )
Packit 0bf95d
Packit 0bf95d
Write a zip archive to named file. Returns C<AZ_OK> on
Packit 0bf95d
success.
Packit 0bf95d
Packit 0bf95d
    my $status = $zip->writeToFileNamed( 'xx.zip' );
Packit 0bf95d
    die "error somewhere" if $status != AZ_OK;
Packit 0bf95d
Packit 0bf95d
Note that if you use the same name as an existing zip file
Packit 0bf95d
that you read in, you will clobber ZipFileMembers. So
Packit 0bf95d
instead, write to a different file name, then delete the
Packit 0bf95d
original.
Packit 0bf95d
If you use the C<overwrite()> or C<overwriteAs()> methods, you can
Packit 0bf95d
re-write the original zip in this way.
Packit 0bf95d
C<$fileName> should be a valid file name on your system.
Packit 0bf95d
Packit 0bf95d
=item writeToFileHandle( $fileHandle [, $seekable] )
Packit 0bf95d
Packit 0bf95d
Write a zip archive to a file handle. Return AZ_OK on
Packit 0bf95d
success. The optional second arg tells whether or not to try
Packit 0bf95d
to seek backwards to re-write headers. If not provided, it is
Packit 0bf95d
set if the Perl C<-f> test returns true. This could fail on
Packit 0bf95d
some operating systems, though.
Packit 0bf95d
Packit 0bf95d
    my $fh = IO::File->new( 'someFile.zip', 'w' );
Packit 0bf95d
    unless ( $zip->writeToFileHandle( $fh ) == AZ_OK ) {
Packit 0bf95d
        # error handling
Packit 0bf95d
    }
Packit 0bf95d
Packit 0bf95d
If you pass a file handle that is not seekable (like if
Packit 0bf95d
you're writing to a pipe or a socket), pass a false second
Packit 0bf95d
argument:
Packit 0bf95d
Packit 0bf95d
    my $fh = IO::File->new( '| cat > somefile.zip', 'w' );
Packit 0bf95d
    $zip->writeToFileHandle( $fh, 0 );   # fh is not seekable
Packit 0bf95d
Packit 0bf95d
If this method fails during the write of a member, that
Packit 0bf95d
member and all following it will return false from
Packit 0bf95d
C<wasWritten()>. See writeCentralDirectory() for a way to
Packit 0bf95d
deal with this.
Packit 0bf95d
If you want, you can write data to the file handle before
Packit 0bf95d
passing it to writeToFileHandle(); this could be used (for
Packit 0bf95d
instance) for making self-extracting archives. However, this
Packit 0bf95d
only works reliably when writing to a real file (as opposed
Packit 0bf95d
to STDOUT or some other possible non-file).
Packit 0bf95d
Packit 0bf95d
See examples/selfex.pl for how to write a self-extracting
Packit 0bf95d
archive.
Packit 0bf95d
Packit 0bf95d
=item writeCentralDirectory( $fileHandle [, $offset ] )
Packit 0bf95d
Packit 0bf95d
=item writeCentralDirectory( { fileHandle => $fileHandle
Packit 0bf95d
    [, offset => $offset ] } )
Packit 0bf95d
Packit 0bf95d
Writes the central directory structure to the given file
Packit 0bf95d
handle.
Packit 0bf95d
Packit 0bf95d
Returns AZ_OK on success. If given an $offset, will
Packit 0bf95d
seek to that point before writing. This can be used for
Packit 0bf95d
recovery in cases where writeToFileHandle or writeToFileNamed
Packit 0bf95d
returns an IO error because of running out of space on the
Packit 0bf95d
destination file.
Packit 0bf95d
Packit 0bf95d
You can truncate the zip by seeking backwards and then writing the
Packit 0bf95d
directory:
Packit 0bf95d
Packit 0bf95d
    my $fh = IO::File->new( 'someFile.zip', 'w' );
Packit 0bf95d
        my $retval = $zip->writeToFileHandle( $fh );
Packit 0bf95d
    if ( $retval == AZ_IO_ERROR ) {
Packit 0bf95d
        my @unwritten = grep { not $_->wasWritten() } $zip->members();
Packit 0bf95d
        if (@unwritten) {
Packit 0bf95d
            $zip->removeMember( $member ) foreach my $member ( @unwritten );
Packit 0bf95d
            $zip->writeCentralDirectory( $fh,
Packit 0bf95d
            $unwritten[0]->writeLocalHeaderRelativeOffset());
Packit 0bf95d
        }
Packit 0bf95d
    }
Packit 0bf95d
Packit 0bf95d
=item overwriteAs( $newName )
Packit 0bf95d
Packit 0bf95d
=item overwriteAs( { filename => $newName } )
Packit 0bf95d
Packit 0bf95d
Write the zip to the specified file, as safely as possible.
Packit 0bf95d
This is done by first writing to a temp file, then renaming
Packit 0bf95d
the original if it exists, then renaming the temp file, then
Packit 0bf95d
deleting the renamed original if it exists. Returns AZ_OK if
Packit 0bf95d
successful.
Packit 0bf95d
Packit 0bf95d
=item overwrite()
Packit 0bf95d
Packit 0bf95d
Write back to the original zip file. See overwriteAs() above.
Packit 0bf95d
If the zip was not ever read from a file, this generates an
Packit 0bf95d
error.
Packit 0bf95d
Packit 0bf95d
=item read( $fileName )
Packit 0bf95d
Packit 0bf95d
=item read( { filename => $fileName } )
Packit 0bf95d
Packit 0bf95d
Read zipfile headers from a zip file, appending new members.
Packit 0bf95d
Returns C<AZ_OK> or error code.
Packit 0bf95d
Packit 0bf95d
    my $zipFile = Archive::Zip->new();
Packit 0bf95d
    my $status = $zipFile->read( '/some/FileName.zip' );
Packit 0bf95d
Packit 0bf95d
=item readFromFileHandle( $fileHandle, $filename )
Packit 0bf95d
Packit 0bf95d
=item readFromFileHandle( { fileHandle => $fileHandle, filename => $filename } )
Packit 0bf95d
Packit 0bf95d
Read zipfile headers from an already-opened file handle,
Packit 0bf95d
appending new members. Does not close the file handle.
Packit 0bf95d
Returns C<AZ_OK> or error code. Note that this requires a
Packit 0bf95d
seekable file handle; reading from a stream is not yet
Packit 0bf95d
supported, but using in-memory data is.
Packit 0bf95d
Packit 0bf95d
    my $fh = IO::File->new( '/some/FileName.zip', 'r' );
Packit 0bf95d
    my $zip1 = Archive::Zip->new();
Packit 0bf95d
    my $status = $zip1->readFromFileHandle( $fh );
Packit 0bf95d
    my $zip2 = Archive::Zip->new();
Packit 0bf95d
    $status = $zip2->readFromFileHandle( $fh );
Packit 0bf95d
Packit 0bf95d
Read zip using in-memory data (recursable):
Packit 0bf95d
Packit 0bf95d
    open my $fh, "<", "archive.zip" or die $!;
Packit 0bf95d
    my $zip_data = do { local $.; <$fh> };
Packit 0bf95d
    my $zip = Archive::Zip->new;
Packit 0bf95d
    open my $dh, "+<", \$zip_data;
Packit 0bf95d
    $zip->readFromFileHandle ($dh);
Packit 0bf95d
Packit 0bf95d
=back
Packit 0bf95d
Packit 0bf95d
=head2 Zip Archive Tree operations
Packit 0bf95d
Packit 0bf95d
These used to be in Archive::Zip::Tree but got moved into
Packit 0bf95d
Archive::Zip. They enable operation on an entire tree of members or
Packit 0bf95d
files.
Packit 0bf95d
A usage example:
Packit 0bf95d
Packit 0bf95d
  use Archive::Zip;
Packit 0bf95d
  my $zip = Archive::Zip->new();
Packit 0bf95d
Packit 0bf95d
  # add all readable files and directories below . as xyz/*
Packit 0bf95d
  $zip->addTree( '.', 'xyz' );
Packit 0bf95d
Packit 0bf95d
  # add all readable plain files below /abc as def/*
Packit 0bf95d
  $zip->addTree( '/abc', 'def', sub { -f && -r } );
Packit 0bf95d
Packit 0bf95d
  # add all .c files below /tmp as stuff/*
Packit 0bf95d
  $zip->addTreeMatching( '/tmp', 'stuff', '\.c$' );
Packit 0bf95d
Packit 0bf95d
  # add all .o files below /tmp as stuff/* if they aren't writable
Packit 0bf95d
  $zip->addTreeMatching( '/tmp', 'stuff', '\.o$', sub { ! -w } );
Packit 0bf95d
Packit 0bf95d
  # add all .so files below /tmp that are smaller than 200 bytes as stuff/*
Packit 0bf95d
  $zip->addTreeMatching( '/tmp', 'stuff', '\.o$', sub { -s < 200 } );
Packit 0bf95d
Packit 0bf95d
  # and write them into a file
Packit 0bf95d
  $zip->writeToFileNamed('xxx.zip');
Packit 0bf95d
Packit 0bf95d
  # now extract the same files into /tmpx
Packit 0bf95d
  $zip->extractTree( 'stuff', '/tmpx' );
Packit 0bf95d
Packit 0bf95d
=over 4
Packit 0bf95d
Packit 0bf95d
=item $zip->addTree( $root, $dest [, $pred, $compressionLevel ] ) -- Add tree of files to a zip
Packit 0bf95d
Packit 0bf95d
=item $zip->addTree( { root => $root, zipName => $dest [, select => $pred,
Packit 0bf95d
    compressionLevel => $compressionLevel ] )
Packit 0bf95d
Packit 0bf95d
C<$root> is the root of the tree of files and directories to be
Packit 0bf95d
added. It is a valid directory name on your system. C<$dest> is
Packit 0bf95d
the name for the root in the zip file (undef or blank means
Packit 0bf95d
to use relative pathnames). It is a valid ZIP directory name
Packit 0bf95d
(that is, it uses forward slashes (/) for separating
Packit 0bf95d
directory components). C<$pred> is an optional subroutine
Packit 0bf95d
reference to select files: it is passed the name of the
Packit 0bf95d
prospective file or directory using C<$_>, and if it returns
Packit 0bf95d
true, the file or directory will be included. The default is
Packit 0bf95d
to add all readable files and directories. For instance,
Packit 0bf95d
using
Packit 0bf95d
Packit 0bf95d
  my $pred = sub { /\.txt/ };
Packit 0bf95d
  $zip->addTree( '.', '', $pred );
Packit 0bf95d
Packit 0bf95d
will add all the .txt files in and below the current
Packit 0bf95d
directory, using relative names, and making the names
Packit 0bf95d
identical in the zipfile:
Packit 0bf95d
Packit 0bf95d
  original name           zip member name
Packit 0bf95d
  ./xyz                   xyz
Packit 0bf95d
  ./a/                    a/
Packit 0bf95d
  ./a/b                   a/b
Packit 0bf95d
Packit 0bf95d
To translate absolute to relative pathnames, just pass them
Packit 0bf95d
in: $zip->addTree( '/c/d', 'a' );
Packit 0bf95d
Packit 0bf95d
  original name           zip member name
Packit 0bf95d
  /c/d/xyz                a/xyz
Packit 0bf95d
  /c/d/a/                 a/a/
Packit 0bf95d
  /c/d/a/b                a/a/b
Packit 0bf95d
Packit 0bf95d
Returns AZ_OK on success. Note that this will not follow
Packit 0bf95d
symbolic links to directories. Note also that this does not
Packit 0bf95d
check for the validity of filenames.
Packit 0bf95d
Packit 0bf95d
Note that you generally I<don't> want to make zip archive member names
Packit 0bf95d
absolute.
Packit 0bf95d
Packit 0bf95d
=item $zip->addTreeMatching( $root, $dest, $pattern [, $pred, $compressionLevel ] )
Packit 0bf95d
Packit 0bf95d
=item $zip->addTreeMatching( { root => $root, zipName => $dest, pattern =>
Packit 0bf95d
    $pattern [, select => $pred, compressionLevel => $compressionLevel ] } )
Packit 0bf95d
Packit 0bf95d
$root is the root of the tree of files and directories to be
Packit 0bf95d
added $dest is the name for the root in the zip file (undef
Packit 0bf95d
means to use relative pathnames) $pattern is a (non-anchored)
Packit 0bf95d
regular expression for filenames to match $pred is an
Packit 0bf95d
optional subroutine reference to select files: it is passed
Packit 0bf95d
the name of the prospective file or directory in C<$_>, and
Packit 0bf95d
if it returns true, the file or directory will be included.
Packit 0bf95d
The default is to add all readable files and directories. To
Packit 0bf95d
add all files in and below the current directory whose names
Packit 0bf95d
end in C<.pl>, and make them extract into a subdirectory
Packit 0bf95d
named C<xyz>, do this:
Packit 0bf95d
Packit 0bf95d
  $zip->addTreeMatching( '.', 'xyz', '\.pl$' )
Packit 0bf95d
Packit 0bf95d
To add all I<writable> files in and below the directory named
Packit 0bf95d
C</abc> whose names end in C<.pl>, and make them extract into
Packit 0bf95d
a subdirectory named C<xyz>, do this:
Packit 0bf95d
Packit 0bf95d
  $zip->addTreeMatching( '/abc', 'xyz', '\.pl$', sub { -w } )
Packit 0bf95d
Packit 0bf95d
Returns AZ_OK on success. Note that this will not follow
Packit 0bf95d
symbolic links to directories.
Packit 0bf95d
Packit 0bf95d
=item $zip->updateTree( $root [, $dest , $pred , $mirror, $compressionLevel ] );
Packit 0bf95d
Packit 0bf95d
=item $zip->updateTree( { root => $root [, zipName => $dest, select => $pred,
Packit 0bf95d
    mirror => $mirror, compressionLevel => $compressionLevel ] } );
Packit 0bf95d
Packit 0bf95d
Update a zip file from a directory tree.
Packit 0bf95d
Packit 0bf95d
C<updateTree()> takes the same arguments as C<addTree()>, but first
Packit 0bf95d
checks to see whether the file or directory already exists in the zip
Packit 0bf95d
file, and whether it has been changed.
Packit 0bf95d
Packit 0bf95d
If the fourth argument C<$mirror> is true, then delete all my members
Packit 0bf95d
if corresponding files were not found.
Packit 0bf95d
Packit 0bf95d
Returns an error code or AZ_OK if all is well.
Packit 0bf95d
Packit 0bf95d
=item $zip->extractTree( [ $root, $dest, $volume } ] )
Packit 0bf95d
Packit 0bf95d
=item $zip->extractTree( [ { root => $root, zipName => $dest, volume => $volume } ] )
Packit 0bf95d
Packit 0bf95d
If you don't give any arguments at all, will extract all the
Packit 0bf95d
files in the zip with their original names.
Packit 0bf95d
Packit 0bf95d
If you supply one argument for C<$root>, C<extractTree> will extract
Packit 0bf95d
all the members whose names start with C<$root> into the current
Packit 0bf95d
directory, stripping off C<$root> first.
Packit 0bf95d
C<$root> is in Zip (Unix) format.
Packit 0bf95d
For instance,
Packit 0bf95d
Packit 0bf95d
  $zip->extractTree( 'a' );
Packit 0bf95d
Packit 0bf95d
when applied to a zip containing the files:
Packit 0bf95d
a/x a/b/c ax/d/e d/e will extract:
Packit 0bf95d
Packit 0bf95d
a/x as ./x
Packit 0bf95d
Packit 0bf95d
a/b/c as ./b/c
Packit 0bf95d
Packit 0bf95d
If you give two arguments, C<extractTree> extracts all the members
Packit 0bf95d
whose names start with C<$root>. It will translate C<$root> into
Packit 0bf95d
C<$dest> to construct the destination file name.
Packit 0bf95d
C<$root> and C<$dest> are in Zip (Unix) format.
Packit 0bf95d
For instance,
Packit 0bf95d
Packit 0bf95d
   $zip->extractTree( 'a', 'd/e' );
Packit 0bf95d
Packit 0bf95d
when applied to a zip containing the files:
Packit 0bf95d
a/x a/b/c ax/d/e d/e will extract:
Packit 0bf95d
Packit 0bf95d
a/x to d/e/x
Packit 0bf95d
Packit 0bf95d
a/b/c to d/e/b/c and ignore ax/d/e and d/e
Packit 0bf95d
Packit 0bf95d
If you give three arguments, C<extractTree> extracts all the members
Packit 0bf95d
whose names start with C<$root>. It will translate C<$root> into
Packit 0bf95d
C<$dest> to construct the destination file name, and then it will
Packit 0bf95d
convert to local file system format, using C<$volume> as the name of
Packit 0bf95d
the destination volume.
Packit 0bf95d
Packit 0bf95d
C<$root> and C<$dest> are in Zip (Unix) format.
Packit 0bf95d
Packit 0bf95d
C<$volume> is in local file system format.
Packit 0bf95d
Packit 0bf95d
For instance, under Windows,
Packit 0bf95d
Packit 0bf95d
   $zip->extractTree( 'a', 'd/e', 'f:' );
Packit 0bf95d
Packit 0bf95d
when applied to a zip containing the files:
Packit 0bf95d
a/x a/b/c ax/d/e d/e will extract:
Packit 0bf95d
Packit 0bf95d
a/x to f:d/e/x
Packit 0bf95d
Packit 0bf95d
a/b/c to f:d/e/b/c and ignore ax/d/e and d/e
Packit 0bf95d
Packit 0bf95d
If you want absolute paths (the prior example used paths relative to
Packit 0bf95d
the current directory on the destination volume, you can specify these
Packit 0bf95d
in C<$dest>:
Packit 0bf95d
Packit 0bf95d
   $zip->extractTree( 'a', '/d/e', 'f:' );
Packit 0bf95d
Packit 0bf95d
when applied to a zip containing the files:
Packit 0bf95d
a/x a/b/c ax/d/e d/e will extract:
Packit 0bf95d
Packit 0bf95d
a/x to f:\d\e\x
Packit 0bf95d
Packit 0bf95d
a/b/c to f:\d\e\b\c and ignore ax/d/e and d/e
Packit 0bf95d
Packit 0bf95d
Returns an error code or AZ_OK if everything worked OK.
Packit 0bf95d
Packit 0bf95d
=back
Packit 0bf95d
Packit 0bf95d
=head1 Archive::Zip Global Variables
Packit 0bf95d
Packit 0bf95d
=over 4
Packit 0bf95d
Packit 0bf95d
=item $Archive::Zip::UNICODE
Packit 0bf95d
Packit 0bf95d
This variable governs how Unicode file and directory names are added
Packit 0bf95d
to or extracted from an archive. If set, file and directory names are considered
Packit 0bf95d
to be UTF-8 encoded. This is I
Packit 0bf95d
on Win32)>. Please report problems.
Packit 0bf95d
Packit 0bf95d
    {
Packit 0bf95d
        local $Archive::Zip::UNICODE = 1;
Packit 0bf95d
        $zip->addFile('Déjà vu.txt');
Packit 0bf95d
    }
Packit 0bf95d
Packit 0bf95d
=back
Packit 0bf95d
Packit 0bf95d
=head1 MEMBER OPERATIONS
Packit 0bf95d
Packit 0bf95d
=head2 Member Class Methods
Packit 0bf95d
Packit 0bf95d
Several constructors allow you to construct members without adding
Packit 0bf95d
them to a zip archive. These work the same as the addFile(),
Packit 0bf95d
addDirectory(), and addString() zip instance methods described above,
Packit 0bf95d
but they don't add the new members to a zip.
Packit 0bf95d
Packit 0bf95d
=over 4
Packit 0bf95d
Packit 0bf95d
=item Archive::Zip::Member->newFromString( $stringOrStringRef [, $fileName ] )
Packit 0bf95d
Packit 0bf95d
=item Archive::Zip::Member->newFromString( { string => $stringOrStringRef
Packit 0bf95d
    [, zipName => $fileName ] )
Packit 0bf95d
Packit 0bf95d
Construct a new member from the given string. Returns undef
Packit 0bf95d
on error.
Packit 0bf95d
Packit 0bf95d
    my $member = Archive::Zip::Member->newFromString( 'This is a test',
Packit 0bf95d
Packit 0bf95d
=item newFromFile( $fileName [, $zipName ] )
Packit 0bf95d
Packit 0bf95d
=item newFromFile( { filename => $fileName [, zipName => $zipName ] } )
Packit 0bf95d
Packit 0bf95d
Construct a new member from the given file. Returns undef on
Packit 0bf95d
error.
Packit 0bf95d
Packit 0bf95d
    my $member = Archive::Zip::Member->newFromFile( 'xyz.txt' );
Packit 0bf95d
Packit 0bf95d
=item newDirectoryNamed( $directoryName [, $zipname ] )
Packit 0bf95d
Packit 0bf95d
=item newDirectoryNamed( { directoryName => $directoryName
Packit 0bf95d
    [, zipName => $zipname ] } )
Packit 0bf95d
Packit 0bf95d
Construct a new member from the given directory.
Packit 0bf95d
C<$directoryName> must be a valid name on your file system; it does not
Packit 0bf95d
have to exist.
Packit 0bf95d
Packit 0bf95d
If given, C<$zipname> will be the name of the zip member; it must be a
Packit 0bf95d
valid Zip (Unix) name. If not given, it will be converted from
Packit 0bf95d
C<$directoryName>.
Packit 0bf95d
Packit 0bf95d
Returns undef on error.
Packit 0bf95d
Packit 0bf95d
    my $member = Archive::Zip::Member->newDirectoryNamed( 'CVS/' );
Packit 0bf95d
Packit 0bf95d
=back
Packit 0bf95d
Packit 0bf95d
=head2 Member Simple accessors
Packit 0bf95d
Packit 0bf95d
These methods get (and/or set) member attribute values.
Packit 0bf95d
Packit 0bf95d
=over 4
Packit 0bf95d
Packit 0bf95d
=item versionMadeBy()
Packit 0bf95d
Packit 0bf95d
Gets the field from the member header.
Packit 0bf95d
Packit 0bf95d
=item fileAttributeFormat( [ $format ] )
Packit 0bf95d
Packit 0bf95d
=item fileAttributeFormat( [ { format => $format ] } )
Packit 0bf95d
Packit 0bf95d
Gets or sets the field from the member header. These are
Packit 0bf95d
C<FA_*> values.
Packit 0bf95d
Packit 0bf95d
=item versionNeededToExtract()
Packit 0bf95d
Packit 0bf95d
Gets the field from the member header.
Packit 0bf95d
Packit 0bf95d
=item bitFlag()
Packit 0bf95d
Packit 0bf95d
Gets the general purpose bit field from the member header.
Packit 0bf95d
This is where the C<GPBF_*> bits live.
Packit 0bf95d
Packit 0bf95d
=item compressionMethod()
Packit 0bf95d
Packit 0bf95d
Returns the member compression method. This is the method
Packit 0bf95d
that is currently being used to compress the member data.
Packit 0bf95d
This will be COMPRESSION_STORED for added string or file
Packit 0bf95d
members, or any of the C<COMPRESSION_*> values for members
Packit 0bf95d
from a zip file. However, this module can only handle members
Packit 0bf95d
whose data is in COMPRESSION_STORED or COMPRESSION_DEFLATED
Packit 0bf95d
format.
Packit 0bf95d
Packit 0bf95d
=item desiredCompressionMethod( [ $method ] )
Packit 0bf95d
Packit 0bf95d
=item desiredCompressionMethod( [ { compressionMethod => $method } ] )
Packit 0bf95d
Packit 0bf95d
Get or set the member's C<desiredCompressionMethod>. This is
Packit 0bf95d
the compression method that will be used when the member is
Packit 0bf95d
written. Returns prior desiredCompressionMethod. Only
Packit 0bf95d
COMPRESSION_DEFLATED or COMPRESSION_STORED are valid
Packit 0bf95d
arguments. Changing to COMPRESSION_STORED will change the
Packit 0bf95d
member desiredCompressionLevel to 0; changing to
Packit 0bf95d
COMPRESSION_DEFLATED will change the member
Packit 0bf95d
desiredCompressionLevel to COMPRESSION_LEVEL_DEFAULT.
Packit 0bf95d
Packit 0bf95d
=item desiredCompressionLevel( [ $level ] )
Packit 0bf95d
Packit 0bf95d
=item desiredCompressionLevel( [ { compressionLevel => $level } ] )
Packit 0bf95d
Packit 0bf95d
Get or set the member's desiredCompressionLevel This is the
Packit 0bf95d
method that will be used to write. Returns prior
Packit 0bf95d
desiredCompressionLevel. Valid arguments are 0 through 9,
Packit 0bf95d
COMPRESSION_LEVEL_NONE, COMPRESSION_LEVEL_DEFAULT,
Packit 0bf95d
COMPRESSION_LEVEL_BEST_COMPRESSION, and
Packit 0bf95d
COMPRESSION_LEVEL_FASTEST. 0 or COMPRESSION_LEVEL_NONE will
Packit 0bf95d
change the desiredCompressionMethod to COMPRESSION_STORED.
Packit 0bf95d
All other arguments will change the desiredCompressionMethod
Packit 0bf95d
to COMPRESSION_DEFLATED.
Packit 0bf95d
Packit 0bf95d
=item externalFileName()
Packit 0bf95d
Packit 0bf95d
Return the member's external file name, if any, or undef.
Packit 0bf95d
Packit 0bf95d
=item fileName()
Packit 0bf95d
Packit 0bf95d
Get or set the member's internal filename. Returns the
Packit 0bf95d
(possibly new) filename. Names will have backslashes
Packit 0bf95d
converted to forward slashes, and will have multiple
Packit 0bf95d
consecutive slashes converted to single ones.
Packit 0bf95d
Packit 0bf95d
=item lastModFileDateTime()
Packit 0bf95d
Packit 0bf95d
Return the member's last modification date/time stamp in
Packit 0bf95d
MS-DOS format.
Packit 0bf95d
Packit 0bf95d
=item lastModTime()
Packit 0bf95d
Packit 0bf95d
Return the member's last modification date/time stamp,
Packit 0bf95d
converted to unix localtime format.
Packit 0bf95d
Packit 0bf95d
    print "Mod Time: " . scalar( localtime( $member->lastModTime() ) );
Packit 0bf95d
Packit 0bf95d
=item setLastModFileDateTimeFromUnix()
Packit 0bf95d
Packit 0bf95d
Set the member's lastModFileDateTime from the given unix
Packit 0bf95d
time.
Packit 0bf95d
Packit 0bf95d
    $member->setLastModFileDateTimeFromUnix( time() );
Packit 0bf95d
Packit 0bf95d
=item internalFileAttributes()
Packit 0bf95d
Packit 0bf95d
Return the internal file attributes field from the zip
Packit 0bf95d
header. This is only set for members read from a zip file.
Packit 0bf95d
Packit 0bf95d
=item externalFileAttributes()
Packit 0bf95d
Packit 0bf95d
Return member attributes as read from the ZIP file. Note that
Packit 0bf95d
these are NOT UNIX!
Packit 0bf95d
Packit 0bf95d
=item unixFileAttributes( [ $newAttributes ] )
Packit 0bf95d
Packit 0bf95d
=item unixFileAttributes( [ { attributes => $newAttributes } ] )
Packit 0bf95d
Packit 0bf95d
Get or set the member's file attributes using UNIX file
Packit 0bf95d
attributes. Returns old attributes.
Packit 0bf95d
Packit 0bf95d
    my $oldAttribs = $member->unixFileAttributes( 0666 );
Packit 0bf95d
Packit 0bf95d
Note that the return value has more than just the file
Packit 0bf95d
permissions, so you will have to mask off the lowest bits for
Packit 0bf95d
comparisons.
Packit 0bf95d
Packit 0bf95d
=item localExtraField( [ $newField ] )
Packit 0bf95d
Packit 0bf95d
=item localExtraField( [ { field => $newField } ] )
Packit 0bf95d
Packit 0bf95d
Gets or sets the extra field that was read from the local
Packit 0bf95d
header. This is not set for a member from a zip file until
Packit 0bf95d
after the member has been written out. The extra field must
Packit 0bf95d
be in the proper format.
Packit 0bf95d
Packit 0bf95d
=item cdExtraField( [ $newField ] )
Packit 0bf95d
Packit 0bf95d
=item cdExtraField( [ { field => $newField } ] )
Packit 0bf95d
Packit 0bf95d
Gets or sets the extra field that was read from the central
Packit 0bf95d
directory header. The extra field must be in the proper
Packit 0bf95d
format.
Packit 0bf95d
Packit 0bf95d
=item extraFields()
Packit 0bf95d
Packit 0bf95d
Return both local and CD extra fields, concatenated.
Packit 0bf95d
Packit 0bf95d
=item fileComment( [ $newComment ] )
Packit 0bf95d
Packit 0bf95d
=item fileComment( [ { comment => $newComment } ] )
Packit 0bf95d
Packit 0bf95d
Get or set the member's file comment.
Packit 0bf95d
Packit 0bf95d
=item hasDataDescriptor()
Packit 0bf95d
Packit 0bf95d
Get or set the data descriptor flag. If this is set, the
Packit 0bf95d
local header will not necessarily have the correct data
Packit 0bf95d
sizes. Instead, a small structure will be stored at the end
Packit 0bf95d
of the member data with these values. This should be
Packit 0bf95d
transparent in normal operation.
Packit 0bf95d
Packit 0bf95d
=item crc32()
Packit 0bf95d
Packit 0bf95d
Return the CRC-32 value for this member. This will not be set
Packit 0bf95d
for members that were constructed from strings or external
Packit 0bf95d
files until after the member has been written.
Packit 0bf95d
Packit 0bf95d
=item crc32String()
Packit 0bf95d
Packit 0bf95d
Return the CRC-32 value for this member as an 8 character
Packit 0bf95d
printable hex string. This will not be set for members that
Packit 0bf95d
were constructed from strings or external files until after
Packit 0bf95d
the member has been written.
Packit 0bf95d
Packit 0bf95d
=item compressedSize()
Packit 0bf95d
Packit 0bf95d
Return the compressed size for this member. This will not be
Packit 0bf95d
set for members that were constructed from strings or
Packit 0bf95d
external files until after the member has been written.
Packit 0bf95d
Packit 0bf95d
=item uncompressedSize()
Packit 0bf95d
Packit 0bf95d
Return the uncompressed size for this member.
Packit 0bf95d
Packit 0bf95d
=item password( [ $password ] )
Packit 0bf95d
Packit 0bf95d
Returns the password for this member to be used on decryption.
Packit 0bf95d
If $password is given, it will set the password for the decryption.
Packit 0bf95d
Packit 0bf95d
=item isEncrypted()
Packit 0bf95d
Packit 0bf95d
Return true if this member is encrypted. The Archive::Zip
Packit 0bf95d
module does not currently support creation of encrypted
Packit 0bf95d
members. Decryption works more or less like this:
Packit 0bf95d
Packit 0bf95d
  my $zip = Archive::Zip->new;
Packit 0bf95d
  $zip->read ("encrypted.zip");
Packit 0bf95d
  for my $m (map { $zip->memberNamed ($_) } $zip->memberNames) {
Packit 0bf95d
      $m->password ("secret");
Packit 0bf95d
      $m->contents;  # is "" when password was wrong
Packit 0bf95d
Packit 0bf95d
That shows that the password has to be set per member, and not per
Packit 0bf95d
archive. This might change in the future.
Packit 0bf95d
Packit 0bf95d
=item isTextFile( [ $flag ] )
Packit 0bf95d
Packit 0bf95d
=item isTextFile( [ { flag => $flag } ] )
Packit 0bf95d
Packit 0bf95d
Returns true if I am a text file. Also can set the status if
Packit 0bf95d
given an argument (then returns old state). Note that this
Packit 0bf95d
module does not currently do anything with this flag upon
Packit 0bf95d
extraction or storage. That is, bytes are stored in native
Packit 0bf95d
format whether or not they came from a text file.
Packit 0bf95d
Packit 0bf95d
=item isBinaryFile()
Packit 0bf95d
Packit 0bf95d
Returns true if I am a binary file. Also can set the status
Packit 0bf95d
if given an argument (then returns old state). Note that this
Packit 0bf95d
module does not currently do anything with this flag upon
Packit 0bf95d
extraction or storage. That is, bytes are stored in native
Packit 0bf95d
format whether or not they came from a text file.
Packit 0bf95d
Packit 0bf95d
=item extractToFileNamed( $fileName )
Packit 0bf95d
Packit 0bf95d
=item extractToFileNamed( { name => $fileName } )
Packit 0bf95d
Packit 0bf95d
Extract me to a file with the given name. The file will be
Packit 0bf95d
created with default modes. Directories will be created as
Packit 0bf95d
needed.
Packit 0bf95d
The C<$fileName> argument should be a valid file name on your
Packit 0bf95d
file system.
Packit 0bf95d
Returns AZ_OK on success.
Packit 0bf95d
Packit 0bf95d
=item isDirectory()
Packit 0bf95d
Packit 0bf95d
Returns true if I am a directory.
Packit 0bf95d
Packit 0bf95d
=item writeLocalHeaderRelativeOffset()
Packit 0bf95d
Packit 0bf95d
Returns the file offset in bytes the last time I was written.
Packit 0bf95d
Packit 0bf95d
=item wasWritten()
Packit 0bf95d
Packit 0bf95d
Returns true if I was successfully written. Reset at the
Packit 0bf95d
beginning of a write attempt.
Packit 0bf95d
Packit 0bf95d
=back
Packit 0bf95d
Packit 0bf95d
=head2 Low-level member data reading
Packit 0bf95d
Packit 0bf95d
It is possible to use lower-level routines to access member data
Packit 0bf95d
streams, rather than the extract* methods and contents(). For
Packit 0bf95d
instance, here is how to print the uncompressed contents of a member
Packit 0bf95d
in chunks using these methods:
Packit 0bf95d
Packit 0bf95d
    my ( $member, $status, $bufferRef );
Packit 0bf95d
    $member = $zip->memberNamed( 'xyz.txt' );
Packit 0bf95d
    $member->desiredCompressionMethod( COMPRESSION_STORED );
Packit 0bf95d
    $status = $member->rewindData();
Packit 0bf95d
    die "error $status" unless $status == AZ_OK;
Packit 0bf95d
    while ( ! $member->readIsDone() )
Packit 0bf95d
    {
Packit 0bf95d
    ( $bufferRef, $status ) = $member->readChunk();
Packit 0bf95d
    die "error $status"
Packit 0bf95d
                if $status != AZ_OK && $status != AZ_STREAM_END;
Packit 0bf95d
    # do something with $bufferRef:
Packit 0bf95d
    print $$bufferRef;
Packit 0bf95d
    }
Packit 0bf95d
    $member->endRead();
Packit 0bf95d
Packit 0bf95d
=over 4
Packit 0bf95d
Packit 0bf95d
=item readChunk( [ $chunkSize ] )
Packit 0bf95d
Packit 0bf95d
=item readChunk( [ { chunkSize => $chunkSize } ] )
Packit 0bf95d
Packit 0bf95d
This reads the next chunk of given size from the member's
Packit 0bf95d
data stream and compresses or uncompresses it as necessary,
Packit 0bf95d
returning a reference to the bytes read and a status. If size
Packit 0bf95d
argument is not given, defaults to global set by
Packit 0bf95d
Archive::Zip::setChunkSize. Status is AZ_OK on success until
Packit 0bf95d
the last chunk, where it returns AZ_STREAM_END. Returns C<(
Packit 0bf95d
\$bytes, $status)>.
Packit 0bf95d
Packit 0bf95d
    my ( $outRef, $status ) = $self->readChunk();
Packit 0bf95d
    print $$outRef if $status != AZ_OK && $status != AZ_STREAM_END;
Packit 0bf95d
Packit 0bf95d
=item rewindData()
Packit 0bf95d
Packit 0bf95d
Rewind data and set up for reading data streams or writing
Packit 0bf95d
zip files. Can take options for C<inflateInit()> or
Packit 0bf95d
C<deflateInit()>, but this is not likely to be necessary.
Packit 0bf95d
Subclass overrides should call this method. Returns C<AZ_OK>
Packit 0bf95d
on success.
Packit 0bf95d
Packit 0bf95d
=item endRead()
Packit 0bf95d
Packit 0bf95d
Reset the read variables and free the inflater or deflater.
Packit 0bf95d
Must be called to close files, etc. Returns AZ_OK on success.
Packit 0bf95d
Packit 0bf95d
=item readIsDone()
Packit 0bf95d
Packit 0bf95d
Return true if the read has run out of data or encountered an error.
Packit 0bf95d
Packit 0bf95d
=item contents()
Packit 0bf95d
Packit 0bf95d
Return the entire uncompressed member data or undef in scalar
Packit 0bf95d
context. When called in array context, returns C<( $string,
Packit 0bf95d
$status )>; status will be AZ_OK on success:
Packit 0bf95d
Packit 0bf95d
    my $string = $member->contents();
Packit 0bf95d
    # or
Packit 0bf95d
    my ( $string, $status ) = $member->contents();
Packit 0bf95d
    die "error $status" unless $status == AZ_OK;
Packit 0bf95d
Packit 0bf95d
Can also be used to set the contents of a member (this may
Packit 0bf95d
change the class of the member):
Packit 0bf95d
Packit 0bf95d
    $member->contents( "this is my new contents" );
Packit 0bf95d
Packit 0bf95d
=item extractToFileHandle( $fh )
Packit 0bf95d
Packit 0bf95d
=item extractToFileHandle( { fileHandle => $fh } )
Packit 0bf95d
Packit 0bf95d
Extract (and uncompress, if necessary) the member's contents
Packit 0bf95d
to the given file handle. Return AZ_OK on success.
Packit 0bf95d
Packit 0bf95d
=back
Packit 0bf95d
Packit 0bf95d
=head1 Archive::Zip::FileMember methods
Packit 0bf95d
Packit 0bf95d
The Archive::Zip::FileMember class extends Archive::Zip::Member. It is the
Packit 0bf95d
base class for both ZipFileMember and NewFileMember classes. This class adds
Packit 0bf95d
an C<externalFileName> and an C<fh> member to keep track of the external
Packit 0bf95d
file.
Packit 0bf95d
Packit 0bf95d
=over 4
Packit 0bf95d
Packit 0bf95d
=item externalFileName()
Packit 0bf95d
Packit 0bf95d
Return the member's external filename.
Packit 0bf95d
Packit 0bf95d
=item fh()
Packit 0bf95d
Packit 0bf95d
Return the member's read file handle. Automatically opens file if
Packit 0bf95d
necessary.
Packit 0bf95d
Packit 0bf95d
=back
Packit 0bf95d
Packit 0bf95d
=head1 Archive::Zip::ZipFileMember methods
Packit 0bf95d
Packit 0bf95d
The Archive::Zip::ZipFileMember class represents members that have been read
Packit 0bf95d
from external zip files.
Packit 0bf95d
Packit 0bf95d
=over 4
Packit 0bf95d
Packit 0bf95d
=item diskNumberStart()
Packit 0bf95d
Packit 0bf95d
Returns the disk number that the member's local header resides in.
Packit 0bf95d
Should be 0.
Packit 0bf95d
Packit 0bf95d
=item localHeaderRelativeOffset()
Packit 0bf95d
Packit 0bf95d
Returns the offset into the zip file where the member's local header
Packit 0bf95d
is.
Packit 0bf95d
Packit 0bf95d
=item dataOffset()
Packit 0bf95d
Packit 0bf95d
Returns the offset from the beginning of the zip file to the member's
Packit 0bf95d
data.
Packit 0bf95d
Packit 0bf95d
=back
Packit 0bf95d
Packit 0bf95d
=head1 REQUIRED MODULES
Packit 0bf95d
Packit 0bf95d
L<Archive::Zip> requires several other modules:
Packit 0bf95d
Packit 0bf95d
L<Carp>
Packit 0bf95d
Packit 0bf95d
L<Compress::Raw::Zlib>
Packit 0bf95d
Packit 0bf95d
L<Cwd>
Packit 0bf95d
Packit 0bf95d
L<File::Basename>
Packit 0bf95d
Packit 0bf95d
L<File::Copy>
Packit 0bf95d
Packit 0bf95d
L<File::Find>
Packit 0bf95d
Packit 0bf95d
L<File::Path>
Packit 0bf95d
Packit 0bf95d
L<File::Spec>
Packit 0bf95d
Packit 0bf95d
L<IO::File>
Packit 0bf95d
Packit 0bf95d
L<IO::Seekable>
Packit 0bf95d
Packit 0bf95d
L<Time::Local>
Packit 0bf95d
Packit 0bf95d
=head1 BUGS AND CAVEATS
Packit 0bf95d
Packit 0bf95d
=head2 When not to use Archive::Zip
Packit 0bf95d
Packit 0bf95d
If you are just going to be extracting zips (and/or other archives) you
Packit 0bf95d
are recommended to look at using L<Archive::Extract> instead, as it is much
Packit 0bf95d
easier to use and factors out archive-specific functionality.
Packit 0bf95d
Packit 0bf95d
=head2 Try to avoid IO::Scalar
Packit 0bf95d
Packit 0bf95d
One of the most common ways to use Archive::Zip is to generate Zip files
Packit 0bf95d
in-memory. Most people use L<IO::Scalar> for this purpose.
Packit 0bf95d
Packit 0bf95d
Unfortunately, as of 1.11 this module no longer works with L<IO::Scalar>
Packit 0bf95d
as it incorrectly implements seeking.
Packit 0bf95d
Packit 0bf95d
Anybody using L<IO::Scalar> should consider porting to L<IO::String>,
Packit 0bf95d
which is smaller, lighter, and is implemented to be perfectly compatible
Packit 0bf95d
with regular seekable filehandles.
Packit 0bf95d
Packit 0bf95d
Support for L<IO::Scalar> most likely will B<not> be restored in the
Packit 0bf95d
future, as L<IO::Scalar> itself cannot change the way it is implemented
Packit 0bf95d
due to back-compatibility issues.
Packit 0bf95d
Packit 0bf95d
=head2 Wrong password for encrypted members
Packit 0bf95d
Packit 0bf95d
When an encrypted member is read using the wrong password, you currently
Packit 0bf95d
have to re-read the entire archive to try again with the correct password.
Packit 0bf95d
Packit 0bf95d
=head1 TO DO
Packit 0bf95d
Packit 0bf95d
* auto-choosing storing vs compression
Packit 0bf95d
Packit 0bf95d
* extra field hooks (see notes.txt)
Packit 0bf95d
Packit 0bf95d
* check for duplicates on addition/renaming?
Packit 0bf95d
Packit 0bf95d
* Text file extraction (line end translation)
Packit 0bf95d
Packit 0bf95d
* Reading zip files from non-seekable inputs
Packit 0bf95d
  (Perhaps by proxying through IO::String?)
Packit 0bf95d
Packit 0bf95d
* separate unused constants into separate module
Packit 0bf95d
Packit 0bf95d
* cookbook style docs
Packit 0bf95d
Packit 0bf95d
* Handle tainted paths correctly
Packit 0bf95d
Packit 0bf95d
* Work on better compatibility with other IO:: modules
Packit 0bf95d
Packit 0bf95d
* Support encryption
Packit 0bf95d
Packit 0bf95d
* More user-friendly decryption
Packit 0bf95d
Packit 0bf95d
=head1 SUPPORT
Packit 0bf95d
Packit 0bf95d
Bugs should be reported via the CPAN bug tracker
Packit 0bf95d
Packit 0bf95d
L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Archive-Zip>
Packit 0bf95d
Packit 0bf95d
For other issues contact the maintainer
Packit 0bf95d
Packit 0bf95d
=head1 AUTHOR
Packit 0bf95d
Packit 0bf95d
Currently maintained by Fred Moyer <fred@redhotpenguin.com>
Packit 0bf95d
Packit 0bf95d
Previously maintained by Adam Kennedy <adamk@cpan.org>
Packit 0bf95d
Packit 0bf95d
Previously maintained by Steve Peters E<lt>steve@fisharerojo.orgE<gt>.
Packit 0bf95d
Packit 0bf95d
File attributes code by Maurice Aubrey E<lt>maurice@lovelyfilth.comE<gt>.
Packit 0bf95d
Packit 0bf95d
Originally by Ned Konz E<lt>nedkonz@cpan.orgE<gt>.
Packit 0bf95d
Packit 0bf95d
=head1 COPYRIGHT
Packit 0bf95d
Packit 0bf95d
Some parts copyright 2006 - 2012 Adam Kennedy.
Packit 0bf95d
Packit 0bf95d
Some parts copyright 2005 Steve Peters.
Packit 0bf95d
Packit 0bf95d
Original work copyright 2000 - 2004 Ned Konz.
Packit 0bf95d
Packit 0bf95d
This program is free software; you can redistribute it and/or modify
Packit 0bf95d
it under the same terms as Perl itself.
Packit 0bf95d
Packit 0bf95d
=head1 SEE ALSO
Packit 0bf95d
Packit 0bf95d
Look at L<Archive::Zip::MemberRead> which is a wrapper that allows one to
Packit 0bf95d
read Zip archive members as if they were files.
Packit 0bf95d
Packit 0bf95d
L<Compress::Raw::Zlib>, L<Archive::Tar>, L<Archive::Extract>
Packit 0bf95d
Packit 0bf95d
=cut