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