⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 archive.pm

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 PM
📖 第 1 页 / 共 2 页
字号:
package Archive::Zip::Archive;# Represents a generic ZIP archiveuse strict;use File::Path;use File::Find ();use File::Spec ();use File::Copy ();use File::Basename;use Cwd;use vars qw( $VERSION @ISA );BEGIN {    $VERSION = '1.23';    @ISA     = qw( Archive::Zip );}use Archive::Zip qw(  :CONSTANTS  :ERROR_CODES  :PKZIP_CONSTANTS  :UTILITY_METHODS);# Note that this returns undef on read errors, else new zip object.sub new {    my $class = shift;    my $self  = bless(        {            'diskNumber'                            => 0,            'diskNumberWithStartOfCentralDirectory' => 0,            'numberOfCentralDirectoriesOnThisDisk'  => 0, # shld be # of members            'numberOfCentralDirectories'            => 0, # shld be # of members            'centralDirectorySize' => 0,    # must re-compute on write            'centralDirectoryOffsetWRTStartingDiskNumber' =>              0,                            # must re-compute            'writeEOCDOffset'             => 0,            'writeCentralDirectoryOffset' => 0,            'zipfileComment'              => '',            'eocdOffset'                  => 0,            'fileName'                    => ''        },        $class    );    $self->{'members'} = [];    if (@_) {        my $status = $self->read(@_);        return $status == AZ_OK ? $self : undef;    }    return $self;}sub members {    @{ shift->{'members'} };}sub numberOfMembers {    scalar( shift->members() );}sub memberNames {    my $self = shift;    return map { $_->fileName() } $self->members();}# return ref to member with given name or undefsub memberNamed {    my ( $self, $fileName ) = @_;    foreach my $member ( $self->members() ) {        return $member if $member->fileName() eq $fileName;    }    return undef;}sub membersMatching {    my ( $self, $pattern ) = @_;    return grep { $_->fileName() =~ /$pattern/ } $self->members();}sub diskNumber {    shift->{'diskNumber'};}sub diskNumberWithStartOfCentralDirectory {    shift->{'diskNumberWithStartOfCentralDirectory'};}sub numberOfCentralDirectoriesOnThisDisk {    shift->{'numberOfCentralDirectoriesOnThisDisk'};}sub numberOfCentralDirectories {    shift->{'numberOfCentralDirectories'};}sub centralDirectorySize {    shift->{'centralDirectorySize'};}sub centralDirectoryOffsetWRTStartingDiskNumber {    shift->{'centralDirectoryOffsetWRTStartingDiskNumber'};}sub zipfileComment {    my $self    = shift;    my $comment = $self->{'zipfileComment'};    if (@_) {        $self->{'zipfileComment'} = pack( 'C0a*', shift() );    # avoid unicode    }    return $comment;}sub eocdOffset {    shift->{'eocdOffset'};}# Return the name of the file last read.sub fileName {    shift->{'fileName'};}sub removeMember {    my ( $self, $member ) = @_;    $member = $self->memberNamed($member) unless ref($member);    return undef unless $member;    my @newMembers = grep { $_ != $member } $self->members();    $self->{'members'} = \@newMembers;    return $member;}sub replaceMember {    my ( $self, $oldMember, $newMember ) = @_;    $oldMember = $self->memberNamed($oldMember) unless ref($oldMember);    return undef unless $oldMember;    return undef unless $newMember;    my @newMembers =      map { ( $_ == $oldMember ) ? $newMember : $_ } $self->members();    $self->{'members'} = \@newMembers;    return $oldMember;}sub extractMember {    my $self   = shift;    my $member = shift;    $member = $self->memberNamed($member) unless ref($member);    return _error('member not found') unless $member;    my $originalSize = $member->compressedSize();    my $name         = shift;                       # local FS name if given    my ( $volumeName, $dirName, $fileName );    if ( defined($name) ) {        ( $volumeName, $dirName, $fileName ) = File::Spec->splitpath($name);        $dirName = File::Spec->catpath( $volumeName, $dirName, '' );    }    else {        $name = $member->fileName();        ( $dirName = $name ) =~ s{[^/]*$}{};        $dirName = Archive::Zip::_asLocalName($dirName);        $name    = Archive::Zip::_asLocalName($name);    }    if ( $dirName && !-d $dirName ) {        mkpath($dirName);        return _ioError("can't create dir $dirName") if ( !-d $dirName );    }    my $rc = $member->extractToFileNamed( $name, @_ );    # TODO refactor this fix into extractToFileNamed()    $member->{'compressedSize'} = $originalSize;    return $rc;}sub extractMemberWithoutPaths {    my $self   = shift;    my $member = shift;    $member = $self->memberNamed($member) unless ref($member);    return _error('member not found') unless $member;    my $originalSize = $member->compressedSize();    return AZ_OK if $member->isDirectory();    my $name = shift;    unless ($name) {        $name = $member->fileName();        $name =~ s{.*/}{};    # strip off directories, if any        $name = Archive::Zip::_asLocalName($name);    }    my $rc = $member->extractToFileNamed( $name, @_ );    $member->{'compressedSize'} = $originalSize;    return $rc;}sub addMember {    my ( $self, $newMember ) = @_;    push( @{ $self->{'members'} }, $newMember ) if $newMember;    return $newMember;}sub addFile {    my $self      = shift;    my $fileName  = shift;    my $newName   = shift;    my $newMember = $self->ZIPMEMBERCLASS->newFromFile( $fileName, $newName );    $self->addMember($newMember) if defined($newMember);    return $newMember;}sub addString {    my $self      = shift;    my $newMember = $self->ZIPMEMBERCLASS->newFromString(@_);    return $self->addMember($newMember);}sub addDirectory {    my ( $self, $name, $newName ) = @_;    my $newMember = $self->ZIPMEMBERCLASS->newDirectoryNamed( $name, $newName );    $self->addMember($newMember);    return $newMember;}# add either a file or a directory.sub addFileOrDirectory {    my ( $self, $name, $newName ) = @_;    if ( -f $name ) {        ( $newName =~ s{/$}{} ) if $newName;        return $self->addFile( $name, $newName );    }    elsif ( -d $name ) {        ( $newName =~ s{[^/]$}{&/} ) if $newName;        return $self->addDirectory( $name, $newName );    }    else {        return _error("$name is neither a file nor a directory");    }}sub contents {    my ( $self, $member, $newContents ) = @_;    return _error('No member name given') unless $member;    $member = $self->memberNamed($member) unless ref($member);    return undef unless $member;    return $member->contents($newContents);}sub writeToFileNamed {    my $self     = shift;    my $fileName = shift;    # local FS format    foreach my $member ( $self->members() ) {        if ( $member->_usesFileNamed($fileName) ) {            return _error( "$fileName is needed by member "                  . $member->fileName()                  . "; consider using overwrite() or overwriteAs() instead." );        }    }    my ( $status, $fh ) = _newFileHandle( $fileName, 'w' );    return _ioError("Can't open $fileName for write") unless $status;    my $retval = $self->writeToFileHandle( $fh, 1 );    $fh->close();    $fh = undef;    return $retval;}# It is possible to write data to the FH before calling this,# perhaps to make a self-extracting archive.sub writeToFileHandle {    my $self = shift;    my $fh   = shift;    return _error('No filehandle given')   unless $fh;    return _ioError('filehandle not open') unless $fh->opened();    my $fhIsSeekable = @_ ? shift: _isSeekable($fh);    _binmode($fh);    # Find out where the current position is.    my $offset = $fhIsSeekable ? $fh->tell() : 0;    $offset = 0 if $offset < 0;    foreach my $member ( $self->members() ) {        my $retval = $member->_writeToFileHandle( $fh, $fhIsSeekable, $offset );        $member->endRead();        return $retval if $retval != AZ_OK;        $offset += $member->_localHeaderSize() + $member->_writeOffset();        $offset +=          $member->hasDataDescriptor()          ? DATA_DESCRIPTOR_LENGTH + SIGNATURE_LENGTH          : 0;        # changed this so it reflects the last successful position        $self->{'writeCentralDirectoryOffset'} = $offset;    }    return $self->writeCentralDirectory($fh);}# Write zip back to the original file,# as safely as possible.# Returns AZ_OK if successful.sub overwrite {    my $self = shift;    return $self->overwriteAs( $self->{'fileName'} );}# Write zip to the specified file,# as safely as possible.# Returns AZ_OK if successful.sub overwriteAs {    my $self    = shift;    my $zipName = shift;    return _error("no filename in overwriteAs()") unless defined($zipName);    my ( $fh, $tempName ) = Archive::Zip::tempFile();    return _error( "Can't open temp file", $! ) unless $fh;    ( my $backupName = $zipName ) =~ s{(\.[^.]*)?$}{.zbk};    my $status = $self->writeToFileHandle($fh);    $fh->close();    $fh = undef;    if ( $status != AZ_OK ) {        unlink($tempName);        _printError("Can't write to $tempName");        return $status;    }    my $err;    # rename the zip    if ( -f $zipName && !rename( $zipName, $backupName ) ) {        $err = $!;        unlink($tempName);        return _error( "Can't rename $zipName as $backupName", $err );    }    # move the temp to the original name (possibly copying)    unless ( File::Copy::move( $tempName, $zipName ) ) {        $err = $!;        rename( $backupName, $zipName );        unlink($tempName);        return _error( "Can't move $tempName to $zipName", $err );    }    # unlink the backup    if ( -f $backupName && !unlink($backupName) ) {        $err = $!;        return _error( "Can't unlink $backupName", $err );    }    return AZ_OK;}# Used only during writingsub _writeCentralDirectoryOffset {    shift->{'writeCentralDirectoryOffset'};}sub _writeEOCDOffset {    shift->{'writeEOCDOffset'};}# Expects to have _writeEOCDOffset() setsub _writeEndOfCentralDirectory {    my ( $self, $fh ) = @_;    $fh->print(END_OF_CENTRAL_DIRECTORY_SIGNATURE_STRING)      or return _ioError('writing EOCD Signature');    my $zipfileCommentLength = length( $self->zipfileComment() );    my $header = pack(        END_OF_CENTRAL_DIRECTORY_FORMAT,        0,                          # {'diskNumber'},        0,                          # {'diskNumberWithStartOfCentralDirectory'},        $self->numberOfMembers(),   # {'numberOfCentralDirectoriesOnThisDisk'},        $self->numberOfMembers(),   # {'numberOfCentralDirectories'},        $self->_writeEOCDOffset() - $self->_writeCentralDirectoryOffset(),        $self->_writeCentralDirectoryOffset(),        $zipfileCommentLength    );    $fh->print($header)      or return _ioError('writing EOCD header');    if ($zipfileCommentLength) {        $fh->print( $self->zipfileComment() )          or return _ioError('writing zipfile comment');    }    return AZ_OK;}# $offset can be specified to truncate a zip file.sub writeCentralDirectory {    my ( $self, $fh, $offset ) = @_;    if ( defined($offset) ) {        $self->{'writeCentralDirectoryOffset'} = $offset;        $fh->seek( $offset, IO::Seekable::SEEK_SET )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -