summaryrefslogtreecommitdiff
path: root/t/common.pm
blob: cff8f7812ff0510e49232f26e1dd7fad51a06608 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
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) };
        $testZipDoesntWork = $status;

        # 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 = <F>;
    close F ;
    return $data;
}

1;