/[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

Contents of /upstream/2.1.0/bin/BackupPC_zipCreate

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show 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 #!/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