/[BackupPC]/upstream/2.1.0/bin/BackupPC_zipCreate
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /upstream/2.1.0/bin/BackupPC_zipCreate

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Wed Jun 22 19:12:04 2005 UTC (18 years, 9 months ago) by dpavlin
File size: 8808 byte(s)
import of version 2.1.0

1 dpavlin 1 #!/bin/perl
2     #============================================================= -*-perl-*-
3     #
4     # BackupPC_zipCreate: create a zip archive of an existing dump
5     # for restore on a client.
6     #
7     # DESCRIPTION
8     #
9     # Usage: BackupPC_zipCreate [-t] [-h host] [-n dumpNum] [-s shareName]
10     # [-r pathRemove] [-p pathAdd] [-c compressionLevel]
11     # files/directories...
12     #
13     # Flags:
14     # Required options:
15     #
16     # -h host host from which the zip archive is created
17     # -n dumpNum dump number from which the zip archive is created
18     # -s shareName share name from which the zip archive is created
19     #
20     # Other options:
21     # -t print summary totals
22     # -r pathRemove path prefix that will be replaced with pathAdd
23     # -p pathAdd new path prefix
24     # -c level compression level (default is 0, no compression)
25     #
26     # The -h, -n and -s options specify which dump is used to generate
27     # the zip archive. The -r and -p options can be used to relocate
28     # the paths in the zip archive so extracted files can be placed
29     # in a location different from their original location.
30     #
31     # AUTHOR
32     # Guillaume Filion <gfk@users.sourceforge.net>
33     # Based on Backup_tarCreate by Craig Barratt <cbarratt@users.sourceforge.net>
34     #
35     # COPYRIGHT
36     # Copyright (C) 2002-2003 Craig Barratt and Guillaume Filion
37     #
38     # This program is free software; you can redistribute it and/or modify
39     # it under the terms of the GNU General Public License as published by
40     # the Free Software Foundation; either version 2 of the License, or
41     # (at your option) any later version.
42     #
43     # This program is distributed in the hope that it will be useful,
44     # but WITHOUT ANY WARRANTY; without even the implied warranty of
45     # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46     # GNU General Public License for more details.
47     #
48     # You should have received a copy of the GNU General Public License
49     # along with this program; if not, write to the Free Software
50     # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
51     #
52     #========================================================================
53     #
54     # Version 2.1.0, released 20 Jun 2004.
55     #
56     # See http://backuppc.sourceforge.net.
57     #
58     #========================================================================
59    
60     use strict;
61     no utf8;
62     use lib "__INSTALLDIR__/lib";
63     use Archive::Zip qw(:ERROR_CODES);
64     use File::Path;
65     use Getopt::Std;
66     use IO::Handle;
67     use BackupPC::Lib;
68     use BackupPC::Attrib qw(:all);
69     use BackupPC::FileZIO;
70     use BackupPC::Zip::FileMember;
71     use BackupPC::View;
72    
73     die("BackupPC::Lib->new failed\n") if ( !(my $bpc = BackupPC::Lib->new) );
74     my $TopDir = $bpc->TopDir();
75     my $BinDir = $bpc->BinDir();
76     my %Conf = $bpc->Conf();
77    
78     my %opts;
79    
80     if ( !getopts("th:n:p:r:s:c:", \%opts) || @ARGV < 1 ) {
81     print(STDERR "usage: $0 [-t] [-h host] [-n dumpNum] [-s shareName]"
82     . " [-r pathRemove] [-p pathAdd] [-c compressionLevel]"
83     . " files/directories...\n");
84     exit(1);
85     }
86    
87     if ( $opts{h} !~ /^([\w\.\s-]+)$/ ) {
88     print(STDERR "$0: bad host name '$opts{h}'\n");
89     exit(1);
90     }
91     my $Host = $opts{h};
92    
93     if ( $opts{n} !~ /^(\d+)$/ ) {
94     print(STDERR "$0: bad dump number '$opts{n}'\n");
95     exit(1);
96     }
97     my $Num = $opts{n};
98     $opts{c} = 0 if ( $opts{c} eq "" );
99     if ( $opts{c} !~ /^(\d+)$/ ) {
100     print(STDERR "$0: invalid compression level '$opts{c}'. 0=none, 9=max\n");
101     exit(1);
102     }
103     my $compLevel = $opts{c};
104    
105     my @Backups = $bpc->BackupInfoRead($Host);
106     my($i);
107     my $FileCnt = 0;
108     my $ByteCnt = 0;
109     my $DirCnt = 0;
110     my $SpecialCnt = 0;
111     my $ErrorCnt = 0;
112    
113     for ( $i = 0 ; $i < @Backups ; $i++ ) {
114     last if ( $Backups[$i]{num} == $Num );
115     }
116     if ( $i >= @Backups ) {
117     print(STDERR "$0: bad backup number $Num for host $Host\n");
118     exit(1);
119     }
120    
121     my $PathRemove = $1 if ( $opts{r} =~ /(.+)/ );
122     my $PathAdd = $1 if ( $opts{p} =~ /(.+)/ );
123     if ( $opts{s} !~ /^([\w\s\.\/\$-]+)$/ ) {
124     print(STDERR "$0: bad share name '$opts{s}'\n");
125     exit(1);
126     }
127     my $ShareName = $opts{s};
128    
129     my $BufSize = 1048576; # 1MB or 2^20
130     my(%UidCache, %GidCache);
131     #my $fh = *STDOUT;
132     my $fh = new IO::Handle;
133     $fh->fdopen(fileno(STDOUT),"w");
134     my $zipfh = Archive::Zip->new();
135    
136     binmode(STDOUT);
137     foreach my $dir ( @ARGV ) {
138     archiveWrite($zipfh, $dir);
139     }
140    
141     sub archiveWrite
142     {
143     my($zipfh, $dir, $zipPathOverride) = @_;
144    
145     my $view = BackupPC::View->new($bpc, $Host, \@Backups);
146    
147     if ( $dir =~ m{(^|/)\.\.(/|$)} || $dir !~ /^(.*)$/ ) {
148     print(STDERR "$0: bad directory '$dir'\n");
149     $ErrorCnt++;
150     return;
151     }
152     $view->find($Num, $ShareName, $dir, 0, \&ZipWriteFile,
153     $zipfh, $zipPathOverride);
154     }
155    
156     # Create Zip file
157     print STDERR "Can't write Zip file\n"
158     unless $zipfh->writeToFileHandle($fh, 0) == Archive::Zip::AZ_OK;
159    
160     #
161     # print out totals if requested
162     #
163     if ( $opts{t} ) {
164     print STDERR "Done: $FileCnt files, $ByteCnt bytes, $DirCnt dirs,",
165     " $SpecialCnt specials ignored, $ErrorCnt errors\n";
166     }
167     exit(0);
168    
169     ###########################################################################
170     # Subroutines
171     ###########################################################################
172    
173     sub UidLookup
174     {
175     my($uid) = @_;
176    
177     $UidCache{$uid} = (getpwuid($uid))[0] if ( !exists($UidCache{$uid}) );
178     return $UidCache{$uid};
179     }
180    
181     sub GidLookup
182     {
183     my($gid) = @_;
184    
185     $GidCache{$gid} = (getgrgid($gid))[0] if ( !exists($GidCache{$gid}) );
186     return $GidCache{$gid};
187     }
188    
189     my $Attr;
190     my $AttrDir;
191    
192     sub ZipWriteFile
193     {
194     my($hdr, $zipfh, $zipPathOverride) = @_;
195    
196     my $tarPath = $hdr->{relPath};
197     $tarPath = $zipPathOverride if ( defined($zipPathOverride) );
198    
199     if ( defined($PathRemove)
200     && substr($tarPath, 0, length($PathRemove)) eq $PathRemove ) {
201     substr($tarPath, 0, length($PathRemove)) = $PathAdd;
202     }
203     $tarPath = "./" . $tarPath if ( $tarPath !~ /^\.\// );
204     $tarPath =~ s{//+}{/}g;
205     $hdr->{name} = $tarPath;
206    
207     my $zipmember; # Container to hold the file/directory to zip.
208    
209     if ( $hdr->{type} == BPC_FTYPE_DIR ) {
210     #
211     # Directory: just write the header
212     #
213     $hdr->{name} .= "/" if ( $hdr->{name} !~ m{/$} );
214     $zipmember = Archive::Zip::Member->newDirectoryNamed($hdr->{name});
215     $DirCnt++;
216     } elsif ( $hdr->{type} == BPC_FTYPE_FILE ) {
217     #
218     # Regular file: write the header and file
219     #
220     $zipmember = BackupPC::Zip::FileMember->newFromFileNamed(
221     $hdr->{fullPath},
222     $hdr->{name},
223     $hdr->{size},
224     $hdr->{compress}
225     );
226     $FileCnt++;
227     $ByteCnt += $hdr->{size};
228     } elsif ( $hdr->{type} == BPC_FTYPE_HARDLINK ) {
229     #
230     # Hardlink file: not supported by Zip, so just make a copy
231     # of the pointed-to file.
232     #
233     # Start by reading the contents of the link.
234     #
235     my $f = BackupPC::FileZIO->open($hdr->{fullPath}, 0, $hdr->{compress});
236     if ( !defined($f) ) {
237     print(STDERR "Unable to open file $hdr->{fullPath}\n");
238     $ErrorCnt++;
239     return;
240     }
241     my $data;
242     while ( $f->read(\$data, $BufSize) > 0 ) {
243     $hdr->{linkname} .= $data;
244     }
245     $f->close;
246     #
247     # Dump the original file. Just call the top-level
248     # routine, so that we save the hassle of dealing with
249     # mangling, merging and attributes.
250     #
251     archiveWrite($zipfh, $hdr->{linkname}, $hdr->{name});
252     } elsif ( $hdr->{type} == BPC_FTYPE_SYMLINK ) {
253     #
254     # Symlinks can't be Zipped. 8(
255     # We could zip the pointed-to dir/file (just like hardlink), but we
256     # have to avoid the infinite-loop case of a symlink pointed to a
257     # directory above us. Ignore for now. Could be a comand-line
258     # option later.
259     #
260     $SpecialCnt++;
261     } elsif ( $hdr->{type} == BPC_FTYPE_CHARDEV
262     || $hdr->{type} == BPC_FTYPE_BLOCKDEV
263     || $hdr->{type} == BPC_FTYPE_FIFO ) {
264     #
265     # Special files can't be Zipped. 8(
266     #
267     $SpecialCnt++;
268     } else {
269     print(STDERR "Got unknown type $hdr->{type} for $hdr->{name}\n");
270     $ErrorCnt++;
271     }
272     return if ( !$zipmember );
273    
274     #
275     # Set the attributes and permissions. The standard zip file
276     # header cannot handle dates prior to 1/1/1980, or 315561600
277     # unix seconds, so we round up the mtime.
278     #
279     my $mtime = $hdr->{mtime};
280     $mtime = 315561600 if ( $mtime < 315561600 );
281     $zipmember->setLastModFileDateTimeFromUnix($mtime);
282     $zipmember->unixFileAttributes($hdr->{mode});
283     # Zip files don't accept uid and gid, so we put them in the comment field.
284     $zipmember->fileComment("uid=".$hdr->{uid}." gid=".$hdr->{gid})
285     if ( $hdr->{uid} || $hdr->{gid} );
286    
287     # Specify the compression level for this member
288     $zipmember->desiredCompressionLevel($compLevel) if ($compLevel =~ /[0-9]/);
289    
290     # Finally Zip the member
291     $zipfh->addMember($zipmember);
292     }

Properties

Name Value
svn:executable

  ViewVC Help
Powered by ViewVC 1.1.26