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                         ZIP_CM_LZMA );
13use Getopt::Long;
14
15my $VERSION = '1.0';
16
17my $compression_method = ZIP_CM_DEFLATE;
18my $stream = 0;
19my $zipfile = '-';
20my $memberName = '-' ;
21my $zip64 = 0 ;
22
23GetOptions("zip64"          => \$zip64,
24           "method=s"       => \&lookupMethod,
25           "stream"         => \$stream,
26           "zipfile=s"      => \$zipfile,
27           "member-name=s"  => \$memberName,
28           'version'        => sub { print "$VERSION\n"; exit 0 },
29           'help'           => \&Usage,
30          )
31    or Usage();
32
33Usage()
34    if @ARGV;
35
36
37zip '-' => $zipfile,
38           Name   => $memberName,
39           Zip64  => $zip64,
40           Method => $compression_method,
41           Stream => $stream
42    or die "Error creating zip file '$zipfile': $\n" ;
43
44exit 0;
45
46sub lookupMethod
47{
48    my $name  = shift;
49    my $value = shift ;
50
51    my %valid = ( store   => ZIP_CM_STORE,
52                  deflate => ZIP_CM_DEFLATE,
53                  bzip2   => ZIP_CM_BZIP2,
54                  lzma    => ZIP_CM_LZMA,
55                );
56
57    my $method = $valid{ lc $value };
58
59    Usage("Unknown method '$value'")
60        if ! defined $method;
61
62    # If LZMA was rquested, check that it is available
63    if ($method == ZIP_CM_LZMA)
64    {
65        eval ' use IO::Compress::Adapter::Lzma';
66        die "Method =. LZMA needs IO::Compress::Adapter::Lzma\n"
67            if ! defined $IO::Compress::Lzma::VERSION;
68    }
69
70    $compression_method =  $method;
71}
72
73sub Usage
74{
75    die <<EOM;
76streamzip [OPTIONS]
77
78Stream data from stdin, compress into a Zip container, and stream to stdout.
79
80OPTIONS
81
82  -zipfile=F      Write zip container to the filename F
83  -member-name=M  member name [Default '-']
84  -zip64          Create a Zip64-compliant zip file [Default: No]
85                  Use Zip64 if input is greater than 4Gig.
86  -stream         Write a streamed zip file
87                  Only applies when 'zipfile' option is used. [Default: No]
88                  Always enabled when writing to stdout.
89  -method=M       Compress using method "M".
90                  Valid methods are
91                    store    Store without compression
92                    deflate  Use Deflate compression [Deflault]
93                    bzip2    Use Bzip2 compression
94                    lzma     Use LZMA compression [needs IO::Compress::Lzma]
95                  Lzma needs IO::Compress::Lzma to be installed.
96  -version        Display version number [$VERSION]
97
98Copyright (c) 2019 Paul Marquess. All rights reserved.
99
100This program is free software; you can redistribute it and/or
101modify it under the same terms as Perl itself.
102
103EOM
104}
105
106
107__END__
108=head1 NAME
109
110streamzip - create a zip file from stdin
111
112=head1 SYNOPSIS
113
114    producer | streamzip [opts] | consumer
115    producer | streamzip [opts] -zipfile=output.zip
116
117=head1 DESCRIPTION
118
119This program will read data from stdin, compress it into a zip container and,
120by default, write a I<streamed> zip file to stdout. No temporary files are created.
121
122The zip container written to stdout is, by necessity, written in streaming
123format.  Most programs that read Zip files can cope with a streamed zip file,
124but if interoperability is important, and your workflow allows you to write the
125zip file directly to disk you can create a non-streamed zip file using the C<zipfile> option.
126
127=head2 OPTIONS
128
129=over 5
130
131=item -zip64
132
133Create a Zip64-compliant zip container.
134Use this option if the input is greater than 4Gig.
135
136Default is disabled.
137
138=item  -zipfile=F
139
140Write zip container to the filename F.
141
142Use the C<Stream> option to enable the creation of a  streamed zip file.
143
144=item  -member-name=M
145
146This option is used to name the "file" in the zip container.
147
148Default is '-'.
149
150=item  -stream
151
152Ignored when writing to stdout.
153
154If the C<zipfile> option is specified, including this option
155will trigger the creation of a streamed zip file.
156
157Default: Always enabled when writing to stdout, otherwise disabled.
158
159=item  -method=M
160
161Compress using method "M".
162
163Valid method names are
164
165    * store    Store without compression
166    * deflate  Use Deflate compression [Deflault]
167    * bzip2    Use Bzip2 compression
168    * lzma     Use LZMA compression
169
170Note that Lzma compress needs IO::Compress::Lzma to be installed.
171
172Default is deflate.
173
174=item  -version
175
176Display version number [$VERSION]
177
178=item -help
179
180Display help
181
182=back
183
184=head2 When to use a Streamed Zip File
185
186A Zip file created with streaming mode enabled allows you to create a zip file
187in situations where you cannot seek backwards/forwards in the file.
188
189A good examples is when you are
190serving dynamic content from a Web Server straight into a socket
191without needing to create a temporary zip file in the filesystsm.
192
193Similarly if your workfow uses a Linux pipelined commands.
194
195=head1 SUPPORT
196
197General feedback/questions/bug reports should be sent to
198L<https://github.com/pmqs/IO-Compress/issues> (preferred) or
199L<https://rt.cpan.org/Public/Dist/Display.html?Name=IO-Compress>.
200
201
202=head1 AUTHOR
203
204Paul Marquess F<pmqs@cpan.org>.
205
206=head1 COPYRIGHT
207
208Copyright (c) 2019 Paul Marquess. All rights reserved.
209
210This program is free software; you can redistribute it and/or modify it
211under the same terms as Perl itself.
212
213