193
my ( $self, $newMember ) = @_;
230
my $newMember = ( ref( $_[0] ) eq 'HASH' ) ? shift->{member} : shift;
194
231
push( @{ $self->{'members'} }, $newMember ) if $newMember;
195
232
return $newMember;
200
my $fileName = shift;
238
my ( $fileName, $newName, $compressionLevel );
239
if ( ref( $_[0] ) eq 'HASH' ) {
240
$fileName = $_[0]->{filename};
241
$newName = $_[0]->{zipName};
242
$compressionLevel = $_[0]->{compressionLevel};
245
( $fileName, $newName, $compressionLevel ) = @_;
202
248
my $newMember = $self->ZIPMEMBERCLASS->newFromFile( $fileName, $newName );
203
$self->addMember($newMember) if defined($newMember);
249
$newMember->desiredCompressionLevel($compressionLevel);
250
if ( $self->{'storeSymbolicLink'} && -l $fileName ) {
251
my $newMember = $self->ZIPMEMBERCLASS->newFromString(readlink $fileName, $newName);
252
# For symbolic links, External File Attribute is set to 0xA1FF0000 by Info-ZIP
253
$newMember->{'externalFileAttributes'} = 0xA1FF0000;
254
$self->addMember($newMember);
256
$self->addMember($newMember);
204
258
return $newMember;
209
my $newMember = $self->ZIPMEMBERCLASS->newFromString(@_);
264
my ( $stringOrStringRef, $name, $compressionLevel );
265
if ( ref( $_[0] ) eq 'HASH' ) {
266
$stringOrStringRef = $_[0]->{string};
267
$name = $_[0]->{zipName};
268
$compressionLevel = $_[0]->{compressionLevel};
271
( $stringOrStringRef, $name, $compressionLevel ) = @_;;
274
my $newMember = $self->ZIPMEMBERCLASS->newFromString(
275
$stringOrStringRef, $name
277
$newMember->desiredCompressionLevel($compressionLevel);
210
278
return $self->addMember($newMember);
213
281
sub addDirectory {
214
my ( $self, $name, $newName ) = @_;
284
my ( $name, $newName );
285
if ( ref( $_[0] ) eq 'HASH' ) {
286
$name = $_[0]->{directoryName};
287
$newName = $_[0]->{zipName};
290
( $name, $newName ) = @_;
215
293
my $newMember = $self->ZIPMEMBERCLASS->newDirectoryNamed( $name, $newName );
216
$self->addMember($newMember);
294
if ( $self->{'storeSymbolicLink'} && -l $name ) {
295
my $link = readlink $name;
296
( $newName =~ s{/$}{} ) if $newName; # Strip trailing /
297
my $newMember = $self->ZIPMEMBERCLASS->newFromString($link, $newName);
298
# For symbolic links, External File Attribute is set to 0xA1FF0000 by Info-ZIP
299
$newMember->{'externalFileAttributes'} = 0xA1FF0000;
300
$self->addMember($newMember);
302
$self->addMember($newMember);
217
304
return $newMember;
220
307
# add either a file or a directory.
222
309
sub addFileOrDirectory {
223
my ( $self, $name, $newName ) = @_;
312
my ( $name, $newName, $compressionLevel );
313
if ( ref( $_[0] ) eq 'HASH' ) {
314
$name = $_[0]->{name};
315
$newName = $_[0]->{zipName};
316
$compressionLevel = $_[0]->{compressionLevel};
319
( $name, $newName, $compressionLevel ) = @_;
224
328
if ( -f $name ) {
225
( $newName =~ s{/$}{} ) if $newName;
226
return $self->addFile( $name, $newName );
329
return $self->addFile( $name, $newName, $compressionLevel );
228
331
elsif ( -d $name ) {
229
( $newName =~ s{[^/]$}{&/} ) if $newName;
230
332
return $self->addDirectory( $name, $newName );
238
my ( $self, $member, $newContents ) = @_;
342
my ( $member, $newContents );
343
if ( ref( $_[0] ) eq 'HASH' ) {
344
$member = $_[0]->{memberOrZipName};
345
$newContents = $_[0]->{contents};
348
( $member, $newContents ) = @_;
239
351
return _error('No member name given') unless $member;
240
352
$member = $self->memberNamed($member) unless ref($member);
241
353
return undef unless $member;
265
378
# perhaps to make a self-extracting archive.
266
379
sub writeToFileHandle {
267
380
my $self = shift;
382
my ( $fh, $fhIsSeekable );
383
if ( ref( $_[0] ) eq 'HASH' ) {
384
$fh = $_[0]->{fileHandle};
386
exists( $_[0]->{seek} ) ? $_[0]->{seek} : _isSeekable($fh);
390
$fhIsSeekable = @_ ? shift : _isSeekable($fh);
269
393
return _error('No filehandle given') unless $fh;
270
394
return _ioError('filehandle not open') unless $fh->opened();
272
my $fhIsSeekable = @_ ? shift: _isSeekable($fh);
275
397
# Find out where the current position is.
276
398
my $offset = $fhIsSeekable ? $fh->tell() : 0;
277
$offset = 0 if $offset < 0;
399
$offset = 0 if $offset < 0;
279
401
foreach my $member ( $self->members() ) {
280
402
my $retval = $member->_writeToFileHandle( $fh, $fhIsSeekable, $offset );
571
710
my $self = shift;
572
my $root = shift or return _error("root arg missing in call to addTree()");
712
my ( $root, $dest, $pred, $compressionLevel );
713
if ( ref( $_[0] ) eq 'HASH' ) {
714
$root = $_[0]->{root};
715
$dest = $_[0]->{zipName};
716
$pred = $_[0]->{select};
717
$compressionLevel = $_[0]->{compressionLevel};
720
( $root, $dest, $pred, $compressionLevel ) = @_;
723
return _error("root arg missing in call to addTree()")
724
unless defined($root);
574
725
$dest = '' unless defined($dest);
575
my $pred = shift || sub { -r };
726
$pred = sub { -r } unless defined($pred);
577
729
my $startDir = _untaintDir( cwd() );
615
769
sub addTreeMatching {
616
770
my $self = shift;
618
or return _error("root arg missing in call to addTreeMatching()");
772
my ( $root, $dest, $pattern, $pred, $compressionLevel );
773
if ( ref( $_[0] ) eq 'HASH' ) {
774
$root = $_[0]->{root};
775
$dest = $_[0]->{zipName};
776
$pattern = $_[0]->{pattern};
777
$pred = $_[0]->{select};
778
$compressionLevel = $_[0]->{compressionLevel};
781
( $root, $dest, $pattern, $pred, $compressionLevel ) = @_;
784
return _error("root arg missing in call to addTreeMatching()")
785
unless defined($root);
620
786
$dest = '' unless defined($dest);
622
or return _error("pattern missing in call to addTreeMatching()");
787
return _error("pattern missing in call to addTreeMatching()")
788
unless defined($pattern);
625
790
$pred ? sub { m{$pattern} && &$pred } : sub { m{$pattern} && -r };
626
return $self->addTree( $root, $dest, $matcher );
791
return $self->addTree( $root, $dest, $matcher, $compressionLevel );
629
794
# $zip->extractTree( $root, $dest [, $volume] );
634
799
sub extractTree {
635
800
my $self = shift;
636
my $root = shift; # Zip format
802
my ( $root, $dest, $volume );
803
if ( ref( $_[0] ) eq 'HASH' ) {
804
$root = $_[0]->{root};
805
$dest = $_[0]->{zipName};
806
$volume = $_[0]->{volume};
809
( $root, $dest, $volume ) = @_;
637
812
$root = '' unless defined($root);
638
my $dest = shift; # Zip format
639
813
$dest = './' unless defined($dest);
640
my $volume = shift; # optional
641
814
my $pattern = "^\Q$root";
642
815
my @members = $self->membersMatching($pattern);
724
904
my $self = shift;
726
or return _error("root arg missing in call to updateTree()");
906
my ( $root, $dest, $pred, $mirror, $compressionLevel );
907
if ( ref( $_[0] ) eq 'HASH' ) {
908
$root = $_[0]->{root};
909
$dest = $_[0]->{zipName};
910
$pred = $_[0]->{select};
911
$mirror = $_[0]->{mirror};
912
$compressionLevel = $_[0]->{compressionLevel};
915
( $root, $dest, $pred, $mirror, $compressionLevel ) = @_;
918
return _error("root arg missing in call to updateTree()")
919
unless defined($root);
728
920
$dest = '' unless defined($dest);
921
$pred = sub { -r } unless defined($pred);
729
923
$dest = _asZipDirName( $dest, 1 );
730
my $pred = shift || sub { -r };
733
924
my $rootZipName = _asZipDirName( $root, 1 ); # with trailing slash
734
925
my $pattern = $rootZipName eq './' ? '^' : "^\Q$rootZipName\E";