xref: /openbsd-src/gnu/usr.bin/perl/cpan/IO-Compress/bin/streamzip (revision 5486feefcc8cb79b19e014ab332cc5dfd05b3b33)
1#!/usr/bin/perl
2
3# Streaming zip
4
5use strict;
6use warnings;
7
8use IO::Compress::Zip qw(zip
9                         ZIP_CM_STORE
10                         ZIP_CM_DEFLATE
11                         ZIP_CM_BZIP2 ) ;
12
13use Getopt::Long;
14
15my $VERSION = '1.00';
16
17my $compression_method = ZIP_CM_DEFLATE;
18my $stream = 0;
19my $zipfile = '-';
20my $memberName = '-' ;
21my $zip64 = 0 ;
22my $level ;
23
24GetOptions("zip64"          => \$zip64,
25           "method=s"       => \&lookupMethod,
26           "0"              => sub { $level = 0 },
27           "1"              => sub { $level = 1 },
28           "2"              => sub { $level = 2 },
29           "3"              => sub { $level = 3 },
30           "4"              => sub { $level = 4 },
31           "5"              => sub { $level = 5 },
32           "6"              => sub { $level = 6 },
33           "7"              => sub { $level = 7 },
34           "8"              => sub { $level = 8 },
35           "9"              => sub { $level = 9 },
36           "stream"         => \$stream,
37           "zipfile=s"      => \$zipfile,
38           "member-name=s"  => \$memberName,
39           'version'        => sub { print "$VERSION\n"; exit 0 },
40           'help'           => \&Usage,
41          )
42    or Usage();
43
44Usage()
45    if @ARGV;
46
47my @extraOpts = ();
48
49if ($compression_method == ZIP_CM_DEFLATE && defined $level)
50{
51    push @extraOpts, (Level => $level)
52}
53
54# force streaming zip file when writing to stdout.
55$stream = 1
56    if $zipfile eq '-';
57
58zip '-' => $zipfile,
59           Name   => $memberName,
60           Zip64  => $zip64,
61           Method => $compression_method,
62           Stream => $stream,
63           @extraOpts
64    or die "Error creating zip file '$zipfile': $\n" ;
65
66exit 0;
67
68sub lookupMethod
69{
70    my $name  = shift;
71    my $value = shift ;
72
73    my %valid = ( store   => ZIP_CM_STORE,
74                  deflate => ZIP_CM_DEFLATE,
75                  bzip2   => ZIP_CM_BZIP2,
76                  lzma    => 14,
77                  xz      => 95,
78                  zstd    => 93,
79                );
80
81    my $method = $valid{ lc $value };
82
83    Usage("Unknown method '$value'")
84        if ! defined $method;
85
86    installModule("Lzma")
87        if $method == 14 ;
88
89    installModule("Xz")
90        if $method == 95 ;
91
92    installModule("Zstd")
93        if $method == 93;
94
95    $compression_method =  $method;
96}
97
98sub installModule
99{
100    my $name = shift ;
101
102    eval " use IO::Compress::$name; use IO::Compress::Adapter::$name ; " ;
103    die "Method '$name' needs IO::Compress::$name\n"
104        if $@;
105}
106
107sub Usage
108{
109    print <<EOM;
110Usage:
111  producer | streamzip [OPTIONS] | consumer
112  producer | streamzip [OPTIONS] -zipfile output.zip
113
114Stream data from stdin, compress into a Zip container, and either stream to stdout, or
115write to a named file.
116
117OPTIONS
118
119  -zipfile=F      Write zip container to the filename 'F'
120                  Outputs to stdout if zipfile not specified.
121  -member-name=M  Set member name to 'M' [Default '-']
122  -0 ... -9       Set compression level for Deflate
123                  [Default: 6]
124  -zip64          Create a Zip64-compliant zip file [Default: No]
125                  Enable Zip64 if input is greater than 4Gig.
126  -stream         Force a streamed zip file when 'zipfile' option is also enabled.
127                  Only applies when 'zipfile' option is used. [Default: No]
128                  Stream is always enabled when writing to stdout.
129  -method=M       Compress using method 'M'.
130                  Valid methods are
131                    store    Store without compression
132                    deflate  Use Deflate compression [Deflault]
133                    bzip2    Use Bzip2 compression
134                    lzma     Use LZMA compression [needs IO::Compress::Lzma]
135                    xz       Use LZMA compression [needs IO::Compress::Xz]
136                    zstd     Use LZMA compression [needs IO::Compress::Zstd]
137  -version        Display version number [$VERSION]
138
139Copyright (c) 2019-2024 Paul Marquess. All rights reserved.
140
141This program is free software; you can redistribute it and/or
142modify it under the same terms as Perl itself.
143
144EOM
145    exit;
146}
147
148
149__END__
150=head1 NAME
151
152streamzip - create a zip file from stdin
153
154=head1 SYNOPSIS
155
156    producer | streamzip [opts] | consumer
157    producer | streamzip [opts] -zipfile=output.zip
158
159=head1 DESCRIPTION
160
161This program will read data from C<stdin>, compress it into a zip container
162and, by default, write a I<streamed> zip file to C<stdout>. No temporary
163files are created.
164
165The zip container written to C<stdout> is, by necessity, written in
166streaming format. Most programs that read Zip files can cope with a
167streamed zip file, but if interoperability is important, and your workflow
168allows you to write the zip file directly to disk you can create a
169non-streamed zip file using the C<zipfile> option.
170
171=head2 OPTIONS
172
173=over 5
174
175=item -zip64
176
177Create a Zip64-compliant zip container. Use this option if the input is
178greater than 4Gig.
179
180Default is disabled.
181
182=item  -zipfile=F
183
184Write zip container to the filename C<F>.
185
186Use the C<Stream> option to force the creation of a streamed zip file.
187
188=item  -member-name=M
189
190This option is used to name the "file" in the zip container.
191
192Default is '-'.
193
194=item  -stream
195
196Ignored when writing to C<stdout>.
197
198If the C<zipfile> option is specified, including this option will trigger
199the creation of a streamed zip file.
200
201Default: Always enabled when writing to C<stdout>, otherwise disabled.
202
203=item  -method=M
204
205Compress using method C<M>.
206
207Valid method names are
208
209    * store    Store without compression
210    * deflate  Use Deflate compression [Deflault]
211    * bzip2    Use Bzip2 compression
212    * lzma     Use LZMA compression
213    * xz       Use xz compression
214    * zstd     Use Zstandard compression
215
216Note that Lzma compress needs C<IO::Compress::Lzma> to be installed.
217
218Note that Zstd compress needs C<IO::Compress::Zstd> to be installed.
219
220Default is C<deflate>.
221
222=item -0, -1, -2, -3, -4, -5, -6, -7, -8, -9
223
224Sets the compression level for C<deflate>. Ignored for all other compression methods.
225
226C<-0> means no compression and C<-9> for maximum compression.
227
228Default is 6
229
230=item  -version
231
232Display version number
233
234=item -help
235
236Display help
237
238=back
239
240=head2 Examples
241
242Create a zip file bt reading daa from stdin
243
244    $ echo Lorem ipsum dolor sit | perl ./bin/streamzip >abcd.zip
245
246Check the contents of C<abcd,zip> with the standard C<unzip> utility
247
248    Archive:  abcd.zip
249      Length      Date    Time    Name
250    ---------  ---------- -----   ----
251           22  2021-01-08 19:45   -
252    ---------                     -------
253           22                     1 file
254
255Notice how the C<Name> is set to C<->.
256That is the default for a few zip utilities whwre the member name is not given.
257
258If you want to explicitly name the file, use the C<-member-name> option as follows
259
260    $ echo Lorem ipsum dolor sit | perl ./bin/streamzip -member-name latin >abcd.zip
261
262    $ unzip -l abcd.zip
263    Archive:  abcd.zip
264      Length      Date    Time    Name
265    ---------  ---------- -----   ----
266           22  2021-01-08 19:47   latin
267    ---------                     -------
268           22                     1 file
269
270
271=head2 When to write a Streamed Zip File
272
273A Streamed Zip File is useful in situations where you cannot seek
274backwards/forwards in the file.
275
276A good examples is when you are serving dynamic content from a Web Server
277straight into a socket without needing to create a temporary zip file in
278the filesystsm.
279
280Similarly if your workfow uses a Linux pipelined commands.
281
282=head1 SUPPORT
283
284General feedback/questions/bug reports should be sent to
285L<https://github.com/pmqs/IO-Compress/issues> (preferred) or
286L<https://rt.cpan.org/Public/Dist/Display.html?Name=IO-Compress>.
287
288
289=head1 AUTHOR
290
291Paul Marquess F<pmqs@cpan.org>.
292
293=head1 COPYRIGHT
294
295Copyright (c) 2019-2024 Paul Marquess. All rights reserved.
296
297This program is free software; you can redistribute it and/or modify it
298under the same terms as Perl itself.
299