use strict; # Shared defs for test programs # Paths. Must make case-insensitive. use File::Temp qw(tempfile tempdir); use File::Spec; BEGIN { mkdir 'testdir' } use constant TESTDIR => do { my $tmpdir = File::Spec->abs2rel(tempdir(DIR => 'testdir', CLEANUP => 1)); $tmpdir =~ s!\\!/!g if $^O eq 'MSWin32'; $tmpdir }; use constant INPUTZIP => (tempfile('testin-XXXXX', SUFFIX => '.zip', TMPDIR => 1, $^O eq 'MSWin32' ? () : (UNLINK => 1)))[1]; use constant OUTPUTZIP => (tempfile('testout-XXXXX', SUFFIX => '.zip', TMPDIR => 1, $^O eq 'MSWin32' ? () : (UNLINK => 1)))[1]; # Do we have the 'zip' and 'unzip' programs? # Embed a copy of the module, rather than adding a dependency BEGIN { package File::Which; use File::Spec; my $Is_VMS = ($^O eq 'VMS'); my $Is_MacOS = ($^O eq 'MacOS'); my $Is_DOSish = (($^O eq 'MSWin32') or ($^O eq 'dos') or ($^O eq 'os2')); # For Win32 systems, stores the extensions used for # executable files # For others, the empty string is used # because 'perl' . '' eq 'perl' => easier my @path_ext = (''); if ($Is_DOSish) { if ($ENV{PATHEXT} and $Is_DOSish) { # WinNT. PATHEXT might be set on Cygwin, but not used. push @path_ext, split ';', $ENV{PATHEXT}; } else { push @path_ext, qw(.com .exe .bat) ; # Win9X or other: doesn't have PATHEXT, so needs hardcoded. } } elsif ($Is_VMS) { push @path_ext, qw(.exe .com); } sub which { my ($exec) = @_; return undef unless $exec; my $all = wantarray; my @results = (); # check for aliases first if ($Is_VMS) { my $symbol = `SHOW SYMBOL $exec`; chomp($symbol); if (!$?) { return $symbol unless $all; push @results, $symbol; } } if ($Is_MacOS) { my @aliases = split /\,/, $ENV{Aliases}; foreach my $alias (@aliases) { # This has not been tested!! # PPT which says MPW-Perl cannot resolve `Alias $alias`, # let's just hope it's fixed if (lc($alias) eq lc($exec)) { chomp(my $file = `Alias $alias`); last unless $file; # if it failed, just go on the normal way return $file unless $all; push @results, $file; # we can stop this loop as if it finds more aliases matching, # it'll just be the same result anyway last; } } } my @path = File::Spec->path(); unshift @path, File::Spec->curdir if $Is_DOSish or $Is_VMS or $Is_MacOS; for my $base (map { File::Spec->catfile($_, $exec) } @path) { for my $ext (@path_ext) { my $file = $base . $ext; # print STDERR "$file\n"; if ( ( -x $file or # executable, normal case ( $Is_MacOS || # MacOS doesn't mark as executable so we check -e ( $Is_DOSish and grep { $file =~ /$_$/i } @path_ext[1 .. $#path_ext]) # DOSish systems don't pass -x on non-exe/bat/com files. # so we check -e. However, we don't want to pass -e on files # that aren't in PATHEXT, like README. and -e _)) and !-d _) { # and finally, we don't want dirs to pass (as they are -x) # print STDERR "-x: ", -x $file, " -e: ", -e _, " -d: ", -d _, "\n"; return $file unless $all; push @results, $file; # Make list to return later } } } if ($all) { return @results; } else { return undef; } } } use constant HAVEZIP => !!File::Which::which('zip'); use constant HAVEUNZIP => !!File::Which::which('unzip'); use constant ZIP => 'zip '; use constant ZIPTEST => 'unzip -t '; # 300-character test string use constant TESTSTRING => join("\n", 1 .. 102) . "\n"; use constant TESTSTRINGLENGTH => length(TESTSTRING); use Archive::Zip (); # CRC-32 should be ac373f32 use constant TESTSTRINGCRC => Archive::Zip::computeCRC32(TESTSTRING); # This is so that it will work on other systems. use constant CAT => $^X . ' -pe "BEGIN{binmode(STDIN);binmode(STDOUT)}"'; use constant CATPIPE => '| ' . CAT . ' >'; use vars qw($zipWorks $testZipDoesntWork $catWorks); # Run ZIPTEST to test a zip file. sub testZip { my $zipName = shift || OUTPUTZIP; if ($testZipDoesntWork) { return wantarray ? (0, '') : 0; } my $cmd = ZIPTEST . $zipName . ($^O eq 'MSWin32' ? '' : ' 2>&1'); my $zipout = `$cmd`; return wantarray ? ($?, $zipout) : $?; } # Return the crc-32 of the given file (0 if empty or error) sub fileCRC { my $fileName = shift; local $/ = undef; my $fh = IO::File->new($fileName, "r"); binmode($fh); return 0 if not defined($fh); my $contents = <$fh>; return Archive::Zip::computeCRC32($contents); } #--------- check to see if cat works sub testCat { my $fh = IO::File->new(CATPIPE . OUTPUTZIP); binmode($fh); my $testString = pack('C256', 0 .. 255); my $testCrc = Archive::Zip::computeCRC32($testString); $fh->write($testString, length($testString)) or return 0; $fh->close(); (-f OUTPUTZIP) or return 0; my @stat = stat(OUTPUTZIP); $stat[7] == length($testString) or return 0; fileCRC(OUTPUTZIP) == $testCrc or return 0; unlink(OUTPUTZIP); return 1; } BEGIN { $catWorks = testCat(); unless ($catWorks) { warn('warning: ', CAT, " doesn't seem to work, may skip some tests"); } } #--------- check to see if zip works (and make INPUTZIP) BEGIN { unlink(INPUTZIP); # Do we have zip installed? if (HAVEZIP) { my $cmd = ZIP . INPUTZIP . ' *' . ($^O eq 'MSWin32' ? '' : ' 2>&1'); my $zipout = `$cmd`; $zipWorks = not $?; unless ($zipWorks) { warn('warning: ', ZIP, " doesn't seem to work, may skip some tests"); } } } #--------- check to see if unzip -t works BEGIN { $testZipDoesntWork = 1; if (HAVEUNZIP) { my ($status, $zipout) = do { local $testZipDoesntWork = 0; testZip(INPUTZIP) }; # 9 * 256 = 2304 - the specified zipfiles were not found $testZipDoesntWork = (($status == 0 || $status == 2304) ? 0 : 1); # Again, on Win32 no big surprise if this doesn't work if ($testZipDoesntWork) { warn('warning: ', ZIPTEST, " doesn't seem to work, may skip some tests"); } } } sub passthrough { my $fromFile = shift ; my $toFile = shift ; my $action = shift ; my $z = Archive::Zip->new; $z->read($fromFile); if ($action) { for my $member($z->members()) { &$action($member) ; } } $z->writeToFileNamed($toFile); } sub readFile { my $name = shift ; local $/; open F, "<$name" or die "Cannot open $name: $!\n"; my $data = ; close F ; return $data; } 1;