1 |
dpavlin |
1 |
#!/bin/perl |
2 |
|
|
#============================================================= -*-perl-*- |
3 |
|
|
# |
4 |
|
|
# configure.pl: Configuration and installation program for BackupPC |
5 |
|
|
# |
6 |
|
|
# DESCRIPTION |
7 |
|
|
# |
8 |
|
|
# This script should be run as root: |
9 |
|
|
# |
10 |
|
|
# perl configure.pl |
11 |
|
|
# |
12 |
|
|
# The installation steps are described as the script runs. |
13 |
|
|
# |
14 |
|
|
# AUTHOR |
15 |
|
|
# Craig Barratt <cbarratt@users.sourceforge.net> |
16 |
|
|
# |
17 |
|
|
# COPYRIGHT |
18 |
|
|
# Copyright (C) 2001-2004 Craig Barratt |
19 |
|
|
# |
20 |
|
|
# This program is free software; you can redistribute it and/or modify |
21 |
|
|
# it under the terms of the GNU General Public License as published by |
22 |
|
|
# the Free Software Foundation; either version 2 of the License, or |
23 |
|
|
# (at your option) any later version. |
24 |
|
|
# |
25 |
|
|
# This program is distributed in the hope that it will be useful, |
26 |
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
27 |
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
28 |
|
|
# GNU General Public License for more details. |
29 |
|
|
# |
30 |
|
|
# You should have received a copy of the GNU General Public License |
31 |
|
|
# along with this program; if not, write to the Free Software |
32 |
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
33 |
|
|
# |
34 |
|
|
#======================================================================== |
35 |
|
|
# |
36 |
|
|
# Version 2.1.0, released 20 Jun 2004. |
37 |
|
|
# |
38 |
|
|
# See http://backuppc.sourceforge.net. |
39 |
|
|
# |
40 |
|
|
#======================================================================== |
41 |
|
|
|
42 |
|
|
use strict; |
43 |
|
|
no utf8; |
44 |
|
|
use vars qw(%Conf %OrigConf); |
45 |
|
|
use lib "./lib"; |
46 |
|
|
|
47 |
|
|
my @Packages = qw(File::Path File::Spec File::Copy DirHandle Digest::MD5 |
48 |
|
|
Data::Dumper Getopt::Std Getopt::Long Pod::Usage |
49 |
|
|
BackupPC::Lib BackupPC::FileZIO); |
50 |
|
|
|
51 |
|
|
foreach my $pkg ( @Packages ) { |
52 |
|
|
eval "use $pkg"; |
53 |
|
|
next if ( !$@ ); |
54 |
|
|
if ( $pkg =~ /BackupPC/ ) { |
55 |
|
|
die <<EOF; |
56 |
|
|
|
57 |
|
|
BackupPC cannot find the package $pkg, which is included in the |
58 |
|
|
BackupPC distribution. This probably means you did not cd to the |
59 |
|
|
unpacked BackupPC distribution before running configure.pl, eg: |
60 |
|
|
|
61 |
|
|
cd BackupPC-2.1.0 |
62 |
|
|
./configure.pl |
63 |
|
|
|
64 |
|
|
Please try again. |
65 |
|
|
|
66 |
|
|
EOF |
67 |
|
|
} |
68 |
|
|
die <<EOF; |
69 |
|
|
|
70 |
|
|
BackupPC needs the package $pkg. Please install $pkg |
71 |
|
|
before installing BackupPC. |
72 |
|
|
|
73 |
|
|
EOF |
74 |
|
|
} |
75 |
|
|
|
76 |
|
|
my %opts; |
77 |
|
|
if ( !GetOptions( |
78 |
|
|
\%opts, |
79 |
|
|
"batch", |
80 |
|
|
"bin-path=s%", |
81 |
|
|
"config-path=s", |
82 |
|
|
"cgi-dir=s", |
83 |
|
|
"data-dir=s", |
84 |
|
|
"dest-dir=s", |
85 |
|
|
"help|?", |
86 |
|
|
"hostname=s", |
87 |
|
|
"html-dir=s", |
88 |
|
|
"html-dir-url=s", |
89 |
|
|
"install-dir=s", |
90 |
|
|
"man", |
91 |
|
|
"uid-ignore", |
92 |
|
|
) || @ARGV ) { |
93 |
|
|
pod2usage(2); |
94 |
|
|
} |
95 |
|
|
pod2usage(1) if ( $opts{help} ); |
96 |
|
|
pod2usage(-exitstatus => 0, -verbose => 2) if $opts{man}; |
97 |
|
|
|
98 |
|
|
my $DestDir = $opts{"dest-dir"}; |
99 |
|
|
|
100 |
|
|
if ( $< != 0 ) { |
101 |
|
|
print <<EOF; |
102 |
|
|
|
103 |
|
|
This configure script should be run as root, rather than uid $<. |
104 |
|
|
Provided uid $< has sufficient permissions to create the data and |
105 |
|
|
install directories, then it should be ok to proceed. Otherwise, |
106 |
|
|
please quit and restart as root. |
107 |
|
|
|
108 |
|
|
EOF |
109 |
|
|
exit(1) if ( prompt("--> Do you want to continue?", |
110 |
|
|
"y") !~ /y/i ); |
111 |
|
|
exit(1) if ( $opts{batch} && !$opts{"uid-ignore"} ); |
112 |
|
|
} |
113 |
|
|
|
114 |
|
|
print <<EOF; |
115 |
|
|
|
116 |
|
|
Is this a new installation or upgrade for BackupPC? If this is |
117 |
|
|
an upgrade please tell me the full path of the existing BackupPC |
118 |
|
|
configuration file (eg: /xxxx/conf/config.pl). Otherwise, just |
119 |
|
|
hit return. |
120 |
|
|
|
121 |
|
|
EOF |
122 |
|
|
|
123 |
|
|
# |
124 |
|
|
# Check if this is an upgrade, in which case read the existing |
125 |
|
|
# config file to get all the defaults. |
126 |
|
|
# |
127 |
|
|
my $ConfigPath = ""; |
128 |
|
|
while ( 1 ) { |
129 |
|
|
$ConfigPath = prompt("--> Full path to existing conf/config.pl", |
130 |
|
|
$ConfigPath, |
131 |
|
|
"config-path"); |
132 |
|
|
last if ( $ConfigPath eq "" |
133 |
|
|
|| ($ConfigPath =~ /^\// && -r $ConfigPath && -w $ConfigPath) ); |
134 |
|
|
my $problem = "is not an absolute path"; |
135 |
|
|
$problem = "is not writable" if ( !-w $ConfigPath ); |
136 |
|
|
$problem = "is not readable" if ( !-r $ConfigPath ); |
137 |
|
|
$problem = "doesn't exist" if ( !-f $ConfigPath ); |
138 |
|
|
print("The file '$ConfigPath' $problem.\n"); |
139 |
|
|
if ( $opts{batch} ) { |
140 |
|
|
print("Need to specify a valid --config-path for upgrade\n"); |
141 |
|
|
exit(1); |
142 |
|
|
} |
143 |
|
|
} |
144 |
|
|
my $bpc; |
145 |
|
|
if ( $ConfigPath ne "" && -r $ConfigPath ) { |
146 |
|
|
(my $topDir = $ConfigPath) =~ s{/[^/]+/[^/]+$}{}; |
147 |
|
|
die("BackupPC::Lib->new failed\n") |
148 |
|
|
if ( !($bpc = BackupPC::Lib->new($topDir, ".", 1)) ); |
149 |
|
|
%Conf = $bpc->Conf(); |
150 |
|
|
%OrigConf = %Conf; |
151 |
|
|
$Conf{TopDir} = $topDir; |
152 |
|
|
my $err = $bpc->ServerConnect($Conf{ServerHost}, $Conf{ServerPort}, 1); |
153 |
|
|
if ( $err eq "" ) { |
154 |
|
|
print <<EOF; |
155 |
|
|
|
156 |
|
|
BackupPC is running on $Conf{ServerHost}. You need to stop BackupPC |
157 |
|
|
before you can upgrade the code. Depending upon your installation, |
158 |
|
|
you could run "/etc/init.d/backuppc stop". |
159 |
|
|
|
160 |
|
|
EOF |
161 |
|
|
exit(1); |
162 |
|
|
} |
163 |
|
|
} |
164 |
|
|
|
165 |
|
|
# |
166 |
|
|
# These are the programs whose paths we need to find |
167 |
|
|
# |
168 |
|
|
my %Programs = ( |
169 |
|
|
perl => "PerlPath", |
170 |
|
|
'gtar/tar' => "TarClientPath", |
171 |
|
|
smbclient => "SmbClientPath", |
172 |
|
|
nmblookup => "NmbLookupPath", |
173 |
|
|
rsync => "RsyncClientPath", |
174 |
|
|
ping => "PingPath", |
175 |
|
|
df => "DfPath", |
176 |
|
|
'ssh/ssh2' => "SshPath", |
177 |
|
|
sendmail => "SendmailPath", |
178 |
|
|
hostname => "HostnamePath", |
179 |
|
|
split => "SplitPath", |
180 |
|
|
par2 => "ParPath", |
181 |
|
|
cat => "CatPath", |
182 |
|
|
gzip => "GzipPath", |
183 |
|
|
bzip2 => "Bzip2Path", |
184 |
|
|
); |
185 |
|
|
|
186 |
|
|
foreach my $prog ( sort(keys(%Programs)) ) { |
187 |
|
|
my $path; |
188 |
|
|
foreach my $subProg ( split(/\//, $prog) ) { |
189 |
|
|
$path = FindProgram("$ENV{PATH}:/bin:/usr/bin:/sbin:/usr/sbin", |
190 |
|
|
$subProg) if ( !length($path) ); |
191 |
|
|
} |
192 |
|
|
$Conf{$Programs{$prog}} = $path if ( !length($Conf{$Programs{$prog}}) ); |
193 |
|
|
} |
194 |
|
|
|
195 |
|
|
while ( 1 ) { |
196 |
|
|
print <<EOF; |
197 |
|
|
|
198 |
|
|
I found the following locations for these programs: |
199 |
|
|
|
200 |
|
|
EOF |
201 |
|
|
foreach my $prog ( sort(keys(%Programs)) ) { |
202 |
|
|
printf(" %-12s => %s\n", $prog, $Conf{$Programs{$prog}}); |
203 |
|
|
} |
204 |
|
|
print "\n"; |
205 |
|
|
last if (prompt('--> Are these paths correct?', 'y') =~ /^y/i); |
206 |
|
|
foreach my $prog ( sort(keys(%Programs)) ) { |
207 |
|
|
$Conf{$Programs{$prog}} = prompt("--> $prog path", |
208 |
|
|
$Conf{$Programs{$prog}}); |
209 |
|
|
} |
210 |
|
|
} |
211 |
|
|
|
212 |
|
|
my $Perl56 = system($Conf{PerlPath} |
213 |
|
|
. q{ -e 'exit($^V && $^V ge v5.6.0 ? 1 : 0);'}); |
214 |
|
|
|
215 |
|
|
if ( !$Perl56 ) { |
216 |
|
|
print <<EOF; |
217 |
|
|
|
218 |
|
|
BackupPC needs perl version 5.6.0 or later. $Conf{PerlPath} appears |
219 |
|
|
to be an older version. Please upgrade to a newer version of perl |
220 |
|
|
and re-run this configure script. |
221 |
|
|
|
222 |
|
|
EOF |
223 |
|
|
exit(1); |
224 |
|
|
} |
225 |
|
|
|
226 |
|
|
print <<EOF; |
227 |
|
|
|
228 |
|
|
Please tell me the hostname of the machine that BackupPC will run on. |
229 |
|
|
|
230 |
|
|
EOF |
231 |
|
|
chomp($Conf{ServerHost} = `$Conf{HostnamePath}`) |
232 |
|
|
if ( defined($Conf{HostnamePath}) && !defined($Conf{ServerHost}) ); |
233 |
|
|
$Conf{ServerHost} = prompt("--> BackupPC will run on host", |
234 |
|
|
$Conf{ServerHost}, |
235 |
|
|
"hostname"); |
236 |
|
|
|
237 |
|
|
print <<EOF; |
238 |
|
|
|
239 |
|
|
BackupPC should run as a dedicated user with limited privileges. You |
240 |
|
|
need to create a user. This user will need read/write permission on |
241 |
|
|
the main data directory and read/execute permission on the install |
242 |
|
|
directory (these directories will be setup shortly). |
243 |
|
|
|
244 |
|
|
The primary group for this user should also be chosen carefully. |
245 |
|
|
By default the install directories will have group write permission. |
246 |
|
|
The data directories and files will have group read permission but |
247 |
|
|
no other permission. |
248 |
|
|
|
249 |
|
|
EOF |
250 |
|
|
my($name, $passwd, $Uid, $Gid); |
251 |
|
|
while ( 1 ) { |
252 |
|
|
$Conf{BackupPCUser} = prompt("--> BackupPC should run as user", |
253 |
|
|
$Conf{BackupPCUser} || "backuppc", |
254 |
|
|
"username"); |
255 |
|
|
($name, $passwd, $Uid, $Gid) = getpwnam($Conf{BackupPCUser}); |
256 |
|
|
last if ( $name ne "" ); |
257 |
|
|
print <<EOF; |
258 |
|
|
|
259 |
|
|
getpwnam() says that user $Conf{BackupPCUser} doesn't exist. Please check the |
260 |
|
|
name and verify that this user is in the passwd file. |
261 |
|
|
|
262 |
|
|
EOF |
263 |
|
|
exit(1) if ( $opts{batch} ); |
264 |
|
|
} |
265 |
|
|
|
266 |
|
|
print <<EOF; |
267 |
|
|
|
268 |
|
|
Please specify an install directory for BackupPC. This is where the |
269 |
|
|
BackupPC scripts, library and documentation will be installed. |
270 |
|
|
|
271 |
|
|
EOF |
272 |
|
|
|
273 |
|
|
while ( 1 ) { |
274 |
|
|
$Conf{InstallDir} = prompt("--> Install directory (full path)", |
275 |
|
|
$Conf{InstallDir}, |
276 |
|
|
"install-dir"); |
277 |
|
|
last if ( $Conf{InstallDir} =~ /^\// ); |
278 |
|
|
if ( $opts{batch} ) { |
279 |
|
|
print("Need to specify --install-dir for new installation\n"); |
280 |
|
|
exit(1); |
281 |
|
|
} |
282 |
|
|
} |
283 |
|
|
|
284 |
|
|
print <<EOF; |
285 |
|
|
|
286 |
|
|
Please specify a data directory for BackupPC. This is where the |
287 |
|
|
configuration files, LOG files and all the PC backups are stored. |
288 |
|
|
This file system needs to be big enough to accommodate all the |
289 |
|
|
PCs you expect to backup (eg: at least 1-2GB per machine). |
290 |
|
|
|
291 |
|
|
EOF |
292 |
|
|
|
293 |
|
|
while ( 1 ) { |
294 |
|
|
$Conf{TopDir} = prompt("--> Data directory (full path)", |
295 |
|
|
$Conf{TopDir}, |
296 |
|
|
"data-dir"); |
297 |
|
|
last if ( $Conf{TopDir} =~ /^\// ); |
298 |
|
|
if ( $opts{batch} ) { |
299 |
|
|
print("Need to specify --data-dir for new installation\n"); |
300 |
|
|
exit(1); |
301 |
|
|
} |
302 |
|
|
} |
303 |
|
|
|
304 |
|
|
if ( !defined($Conf{CompressLevel}) ) { |
305 |
|
|
$Conf{CompressLevel} = BackupPC::FileZIO->compOk ? 3 : 0; |
306 |
|
|
if ( $ConfigPath eq "" && $Conf{CompressLevel} ) { |
307 |
|
|
print <<EOF; |
308 |
|
|
|
309 |
|
|
BackupPC can compress pool files, providing around a 40% reduction in pool |
310 |
|
|
size (your mileage may vary). Specify the compression level (0 turns |
311 |
|
|
off compression, and 1 to 9 represent good/fastest to best/slowest). |
312 |
|
|
The recommended values are 0 (off) or 3 (reasonable compression and speed). |
313 |
|
|
Increasing the compression level to 5 will use around 20% more cpu time |
314 |
|
|
and give perhaps 2-3% more compression. |
315 |
|
|
|
316 |
|
|
EOF |
317 |
|
|
} elsif ( $ConfigPath eq "" ) { |
318 |
|
|
print <<EOF; |
319 |
|
|
|
320 |
|
|
BackupPC can compress pool files, but it needs the Compress::Zlib |
321 |
|
|
package installed (see www.cpan.org). Compression will provide around a |
322 |
|
|
40% reduction in pool size, at the expense of cpu time. You can leave |
323 |
|
|
compression off and run BackupPC without compression, in which case you |
324 |
|
|
should leave the compression level at 0 (which means off). You could |
325 |
|
|
install Compress::Zlib and turn compression on later, but read the |
326 |
|
|
documentation first about how to do this. Or the better choice is |
327 |
|
|
to quit, install Compress::Zlib, and re-run configure.pl. |
328 |
|
|
|
329 |
|
|
EOF |
330 |
|
|
} elsif ( $Conf{CompressLevel} ) { |
331 |
|
|
$Conf{CompressLevel} = 0; |
332 |
|
|
print <<EOF; |
333 |
|
|
|
334 |
|
|
BackupPC now supports pool file compression. Since you are upgrading |
335 |
|
|
BackupPC you probably have existing uncompressed backups. You have |
336 |
|
|
several choices if you want to turn on compression. You can run |
337 |
|
|
the script BackupPC_compressPool to convert everything to compressed |
338 |
|
|
form. Or you can simply turn on compression, so that new backups |
339 |
|
|
will be compressed. This will increase the pool storage requirement, |
340 |
|
|
since both uncompressed and compressed copies of files will be stored. |
341 |
|
|
But eventually the old uncompressed backups will expire, recovering |
342 |
|
|
the pool storage. Please see the documentation for more details. |
343 |
|
|
|
344 |
|
|
If you are not sure what to do, leave the Compression Level at 0, |
345 |
|
|
which disables compression. You can always read the documentation |
346 |
|
|
and turn it on later. |
347 |
|
|
|
348 |
|
|
EOF |
349 |
|
|
} else { |
350 |
|
|
$Conf{CompressLevel} = 0; |
351 |
|
|
print <<EOF; |
352 |
|
|
|
353 |
|
|
BackupPC now supports pool file compression, but it needs the |
354 |
|
|
Compress::Zlib module (see www.cpan.org). For now, leave |
355 |
|
|
the compression level set at 0 to disable compression. If you |
356 |
|
|
want you can install Compress::Zlib and turn compression on. |
357 |
|
|
Please see the documentation for more details about converting |
358 |
|
|
old backups to compressed form. |
359 |
|
|
|
360 |
|
|
EOF |
361 |
|
|
} |
362 |
|
|
while ( 1 ) { |
363 |
|
|
$Conf{CompressLevel} |
364 |
|
|
= prompt("--> Compression level", $Conf{CompressLevel}); |
365 |
|
|
last if ( $Conf{CompressLevel} =~ /^\d+$/ ); |
366 |
|
|
} |
367 |
|
|
} |
368 |
|
|
|
369 |
|
|
print <<EOF; |
370 |
|
|
|
371 |
|
|
BackupPC has a powerful CGI perl interface that runs under Apache. |
372 |
|
|
A single executable needs to be installed in a cgi-bin directory. |
373 |
|
|
This executable needs to run as set-uid $Conf{BackupPCUser}, or |
374 |
|
|
it can be run under mod_perl with Apache running as user $Conf{BackupPCUser}. |
375 |
|
|
|
376 |
|
|
Leave this path empty if you don't want to install the CGI interface. |
377 |
|
|
|
378 |
|
|
EOF |
379 |
|
|
|
380 |
|
|
while ( 1 ) { |
381 |
|
|
$Conf{CgiDir} = prompt("--> CGI bin directory (full path)", |
382 |
|
|
$Conf{CgiDir}, |
383 |
|
|
"cgi-dir"); |
384 |
|
|
last if ( $Conf{CgiDir} =~ /^\// || $Conf{CgiDir} eq "" ); |
385 |
|
|
if ( $opts{batch} ) { |
386 |
|
|
print("Need to specify --cgi-dir for new installation\n"); |
387 |
|
|
exit(1); |
388 |
|
|
} |
389 |
|
|
} |
390 |
|
|
|
391 |
|
|
if ( $Conf{CgiDir} ne "" ) { |
392 |
|
|
|
393 |
|
|
print <<EOF; |
394 |
|
|
|
395 |
|
|
BackupPC's CGI script needs to display various GIF images that |
396 |
|
|
should be stored where Apache can serve them. They should be |
397 |
|
|
placed somewher under Apache's DocumentRoot. BackupPC also |
398 |
|
|
needs to know the URL to access these images. Example: |
399 |
|
|
|
400 |
|
|
Apache image directory: /usr/local/apache/htdocs/BackupPC |
401 |
|
|
URL for image directory: /BackupPC |
402 |
|
|
|
403 |
|
|
The URL for the image directory should start with a slash. |
404 |
|
|
|
405 |
|
|
EOF |
406 |
|
|
while ( 1 ) { |
407 |
|
|
$Conf{CgiImageDir} = prompt("--> Apache image directory (full path)", |
408 |
|
|
$Conf{CgiImageDir}, |
409 |
|
|
"html-dir"); |
410 |
|
|
last if ( $Conf{CgiImageDir} =~ /^\// ); |
411 |
|
|
if ( $opts{batch} ) { |
412 |
|
|
print("Need to specify --html-dir for new installation\n"); |
413 |
|
|
exit(1); |
414 |
|
|
} |
415 |
|
|
} |
416 |
|
|
while ( 1 ) { |
417 |
|
|
$Conf{CgiImageDirURL} = prompt("--> URL for image directory (omit http://host; starts with '/')", |
418 |
|
|
$Conf{CgiImageDirURL}, |
419 |
|
|
"html-dir-url"); |
420 |
|
|
last if ( $Conf{CgiImageDirURL} =~ /^\// ); |
421 |
|
|
if ( $opts{batch} ) { |
422 |
|
|
print("Need to specify --html-dir-url for new installation\n"); |
423 |
|
|
exit(1); |
424 |
|
|
} |
425 |
|
|
} |
426 |
|
|
} |
427 |
|
|
|
428 |
|
|
print <<EOF; |
429 |
|
|
|
430 |
|
|
Ok, we're about to: |
431 |
|
|
|
432 |
|
|
- install the binaries, lib and docs in $Conf{InstallDir}, |
433 |
|
|
- create the data directory $Conf{TopDir}, |
434 |
|
|
- create/update the config.pl file $Conf{TopDir}/conf, |
435 |
|
|
- optionally install the cgi-bin interface. |
436 |
|
|
|
437 |
|
|
EOF |
438 |
|
|
|
439 |
|
|
exit unless prompt("--> Do you want to continue?", "y") =~ /y/i; |
440 |
|
|
|
441 |
|
|
# |
442 |
|
|
# Create install directories |
443 |
|
|
# |
444 |
|
|
foreach my $dir ( qw(bin doc |
445 |
|
|
lib/BackupPC/CGI |
446 |
|
|
lib/BackupPC/Lang |
447 |
|
|
lib/BackupPC/Xfer |
448 |
|
|
lib/BackupPC/Zip |
449 |
|
|
) ) { |
450 |
|
|
next if ( -d "$DestDir$Conf{InstallDir}/$dir" ); |
451 |
|
|
mkpath("$DestDir$Conf{InstallDir}/$dir", 0, 0775); |
452 |
|
|
if ( !-d "$DestDir$Conf{InstallDir}/$dir" |
453 |
|
|
|| !chown($Uid, $Gid, "$DestDir$Conf{InstallDir}/$dir") ) { |
454 |
|
|
die("Failed to create or chown $DestDir$Conf{InstallDir}/$dir\n"); |
455 |
|
|
} else { |
456 |
|
|
print("Created $DestDir$Conf{InstallDir}/$dir\n"); |
457 |
|
|
} |
458 |
|
|
} |
459 |
|
|
|
460 |
|
|
# |
461 |
|
|
# Create CGI image directory |
462 |
|
|
# |
463 |
|
|
foreach my $dir ( ($Conf{CgiImageDir}) ) { |
464 |
|
|
next if ( $dir eq "" || -d $dir ); |
465 |
|
|
mkpath("$DestDir$dir", 0, 0775); |
466 |
|
|
if ( !-d "$DestDir$dir" || !chown($Uid, $Gid, "$DestDir$dir") ) { |
467 |
|
|
die("Failed to create or chown $DestDir$dir"); |
468 |
|
|
} else { |
469 |
|
|
print("Created $DestDir$dir\n"); |
470 |
|
|
} |
471 |
|
|
} |
472 |
|
|
|
473 |
|
|
# |
474 |
|
|
# Create $TopDir's top-level directories |
475 |
|
|
# |
476 |
|
|
foreach my $dir ( qw(. conf pool cpool pc trash log) ) { |
477 |
|
|
mkpath("$DestDir$Conf{TopDir}/$dir", 0, 0750) if ( !-d "$DestDir$Conf{TopDir}/$dir" ); |
478 |
|
|
if ( !-d "$DestDir$Conf{TopDir}/$dir" |
479 |
|
|
|| !chown($Uid, $Gid, "$DestDir$Conf{TopDir}/$dir") ) { |
480 |
|
|
die("Failed to create or chown $DestDir$Conf{TopDir}/$dir\n"); |
481 |
|
|
} else { |
482 |
|
|
print("Created $DestDir$Conf{TopDir}/$dir\n"); |
483 |
|
|
} |
484 |
|
|
} |
485 |
|
|
|
486 |
|
|
printf("Installing binaries in $DestDir$Conf{InstallDir}/bin\n"); |
487 |
|
|
foreach my $prog ( qw(BackupPC BackupPC_dump BackupPC_link BackupPC_nightly |
488 |
|
|
BackupPC_sendEmail BackupPC_tarCreate BackupPC_trashClean |
489 |
|
|
BackupPC_tarExtract BackupPC_compressPool BackupPC_zcat |
490 |
dpavlin |
6 |
BackupPC_archive BackupPC_archiveHost BackupPC_updatedb |
491 |
dpavlin |
1 |
BackupPC_restore BackupPC_serverMesg BackupPC_zipCreate ) ) { |
492 |
|
|
InstallFile("bin/$prog", "$DestDir$Conf{InstallDir}/bin/$prog", 0555); |
493 |
|
|
} |
494 |
|
|
|
495 |
|
|
printf("Installing library in $DestDir$Conf{InstallDir}/lib\n"); |
496 |
|
|
foreach my $lib ( qw( |
497 |
|
|
BackupPC/Lib.pm |
498 |
|
|
BackupPC/FileZIO.pm |
499 |
|
|
BackupPC/Attrib.pm |
500 |
|
|
BackupPC/PoolWrite.pm |
501 |
|
|
BackupPC/View.pm |
502 |
|
|
BackupPC/Xfer/Archive.pm |
503 |
|
|
BackupPC/Xfer/Tar.pm |
504 |
|
|
BackupPC/Xfer/Smb.pm |
505 |
|
|
BackupPC/Xfer/Rsync.pm |
506 |
|
|
BackupPC/Xfer/RsyncDigest.pm |
507 |
|
|
BackupPC/Xfer/RsyncFileIO.pm |
508 |
|
|
BackupPC/Zip/FileMember.pm |
509 |
|
|
BackupPC/Lang/en.pm |
510 |
|
|
BackupPC/Lang/fr.pm |
511 |
|
|
BackupPC/Lang/es.pm |
512 |
|
|
BackupPC/Lang/de.pm |
513 |
|
|
BackupPC/Lang/it.pm |
514 |
|
|
BackupPC/Lang/nl.pm |
515 |
|
|
BackupPC/CGI/AdminOptions.pm |
516 |
|
|
BackupPC/CGI/Archive.pm |
517 |
|
|
BackupPC/CGI/ArchiveInfo.pm |
518 |
|
|
BackupPC/CGI/Browse.pm |
519 |
|
|
BackupPC/CGI/DirHistory.pm |
520 |
|
|
BackupPC/CGI/EmailSummary.pm |
521 |
|
|
BackupPC/CGI/GeneralInfo.pm |
522 |
|
|
BackupPC/CGI/HostInfo.pm |
523 |
|
|
BackupPC/CGI/Lib.pm |
524 |
|
|
BackupPC/CGI/LOGlist.pm |
525 |
|
|
BackupPC/CGI/Queue.pm |
526 |
|
|
BackupPC/CGI/ReloadServer.pm |
527 |
|
|
BackupPC/CGI/RestoreFile.pm |
528 |
|
|
BackupPC/CGI/RestoreInfo.pm |
529 |
|
|
BackupPC/CGI/Restore.pm |
530 |
|
|
BackupPC/CGI/StartServer.pm |
531 |
|
|
BackupPC/CGI/StartStopBackup.pm |
532 |
|
|
BackupPC/CGI/StopServer.pm |
533 |
|
|
BackupPC/CGI/Summary.pm |
534 |
|
|
BackupPC/CGI/View.pm |
535 |
dpavlin |
6 |
BackupPC/CGI/BurnMedia.pm |
536 |
|
|
BackupPC/CGI/SearchArchives.pm |
537 |
|
|
BackupPC/SearchLib.pm |
538 |
dpavlin |
1 |
) ) { |
539 |
|
|
InstallFile("lib/$lib", "$DestDir$Conf{InstallDir}/lib/$lib", 0444); |
540 |
|
|
} |
541 |
|
|
|
542 |
|
|
if ( $Conf{CgiImageDir} ne "" ) { |
543 |
|
|
printf("Installing images in $DestDir$Conf{CgiImageDir}\n"); |
544 |
|
|
foreach my $img ( <images/*> ) { |
545 |
|
|
(my $destImg = $img) =~ s{^images/}{}; |
546 |
|
|
InstallFile($img, "$DestDir$Conf{CgiImageDir}/$destImg", 0444, 1); |
547 |
|
|
} |
548 |
|
|
|
549 |
|
|
# |
550 |
|
|
# Install new CSS file, making a backup copy if necessary |
551 |
|
|
# |
552 |
|
|
my $cssBackup = "$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css.pre-2.1.0"; |
553 |
|
|
if ( -f "$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css" && !-f $cssBackup ) { |
554 |
|
|
rename("$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css", $cssBackup); |
555 |
|
|
} |
556 |
|
|
InstallFile("conf/BackupPC_stnd.css", |
557 |
|
|
"$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css", 0444, 0); |
558 |
|
|
} |
559 |
|
|
|
560 |
|
|
printf("Making init.d scripts\n"); |
561 |
|
|
foreach my $init ( qw(gentoo-backuppc gentoo-backuppc.conf linux-backuppc |
562 |
|
|
solaris-backuppc debian-backuppc suse-backuppc) ) { |
563 |
|
|
InstallFile("init.d/src/$init", "init.d/$init", 0444); |
564 |
|
|
} |
565 |
|
|
|
566 |
|
|
printf("Installing docs in $DestDir$Conf{InstallDir}/doc\n"); |
567 |
|
|
foreach my $doc ( qw(BackupPC.pod BackupPC.html) ) { |
568 |
|
|
InstallFile("doc/$doc", "$DestDir$Conf{InstallDir}/doc/$doc", 0444); |
569 |
|
|
} |
570 |
|
|
|
571 |
|
|
printf("Installing config.pl and hosts in $DestDir$Conf{TopDir}/conf\n"); |
572 |
|
|
InstallFile("conf/hosts", "$DestDir$Conf{TopDir}/conf/hosts", 0644) |
573 |
|
|
if ( !-f "$DestDir$Conf{TopDir}/conf/hosts" ); |
574 |
|
|
|
575 |
|
|
# |
576 |
|
|
# Now do the config file. If there is an existing config file we |
577 |
|
|
# merge in the new config file, adding any new configuration |
578 |
|
|
# parameters and deleting ones that are no longer needed. |
579 |
|
|
# |
580 |
|
|
my $dest = "$DestDir$Conf{TopDir}/conf/config.pl"; |
581 |
|
|
my ($newConf, $newVars) = ConfigParse("conf/config.pl"); |
582 |
|
|
my ($oldConf, $oldVars); |
583 |
|
|
if ( -f $dest ) { |
584 |
|
|
($oldConf, $oldVars) = ConfigParse($dest); |
585 |
|
|
$newConf = ConfigMerge($oldConf, $oldVars, $newConf, $newVars); |
586 |
|
|
} |
587 |
|
|
$Conf{EMailFromUserName} ||= $Conf{BackupPCUser}; |
588 |
|
|
$Conf{EMailAdminUserName} ||= $Conf{BackupPCUser}; |
589 |
|
|
|
590 |
|
|
# |
591 |
|
|
# Update various config parameters |
592 |
|
|
# |
593 |
|
|
|
594 |
|
|
# |
595 |
|
|
# Guess $Conf{CgiURL} |
596 |
|
|
# |
597 |
|
|
if ( !defined($Conf{CgiURL}) ) { |
598 |
|
|
if ( $Conf{CgiDir} =~ m{cgi-bin(/.*)} ) { |
599 |
|
|
$Conf{CgiURL} = "'http://$Conf{ServerHost}/cgi-bin$1/BackupPC_Admin'"; |
600 |
|
|
} else { |
601 |
|
|
$Conf{CgiURL} = "'http://$Conf{ServerHost}/cgi-bin/BackupPC_Admin'"; |
602 |
|
|
} |
603 |
|
|
} |
604 |
|
|
|
605 |
|
|
# |
606 |
|
|
# The smbclient commands have moved from hard-coded to the config file. |
607 |
|
|
# $Conf{SmbClientArgs} no longer exists, so merge it into the new |
608 |
|
|
# commands if it still exists. |
609 |
|
|
# |
610 |
|
|
if ( defined($Conf{SmbClientArgs}) ) { |
611 |
|
|
if ( $Conf{SmbClientArgs} ne "" ) { |
612 |
|
|
foreach my $param ( qw(SmbClientRestoreCmd SmbClientFullCmd |
613 |
|
|
SmbClientIncrCmd) ) { |
614 |
|
|
$newConf->[$newVars->{$param}]{text} |
615 |
|
|
=~ s/(-E\s+-N)/$1 $Conf{SmbClientArgs}/; |
616 |
|
|
} |
617 |
|
|
} |
618 |
|
|
delete($Conf{SmbClientArgs}); |
619 |
|
|
} |
620 |
|
|
|
621 |
|
|
# |
622 |
|
|
# CSS is now stored in a file rather than a big config variable. |
623 |
|
|
# |
624 |
|
|
delete($Conf{CSSstylesheet}); |
625 |
|
|
|
626 |
|
|
# |
627 |
|
|
# The blackout timing settings are now stored in a list of hashes, rather |
628 |
|
|
# than three scalar parameters. |
629 |
|
|
# |
630 |
|
|
if ( defined($Conf{BlackoutHourBegin}) ) { |
631 |
|
|
$Conf{BlackoutPeriods} = [ |
632 |
|
|
{ |
633 |
|
|
hourBegin => $Conf{BlackoutHourBegin}, |
634 |
|
|
hourEnd => $Conf{BlackoutHourEnd}, |
635 |
|
|
weekDays => $Conf{BlackoutWeekDays}, |
636 |
|
|
} |
637 |
|
|
]; |
638 |
|
|
delete($Conf{BlackoutHourBegin}); |
639 |
|
|
delete($Conf{BlackoutHourEnd}); |
640 |
|
|
delete($Conf{BlackoutWeekDays}); |
641 |
|
|
} |
642 |
|
|
|
643 |
|
|
# |
644 |
|
|
# $Conf{RsyncLogLevel} has been replaced by $Conf{XferLogLevel} |
645 |
|
|
# |
646 |
|
|
if ( defined($Conf{RsyncLogLevel}) ) { |
647 |
|
|
$Conf{XferLogLevel} = $Conf{RsyncLogLevel}; |
648 |
|
|
delete($Conf{RsyncLogLevel}); |
649 |
|
|
} |
650 |
|
|
|
651 |
|
|
# |
652 |
|
|
# In 2.1.0 the default for $Conf{CgiNavBarAdminAllHosts} is now 1 |
653 |
|
|
# |
654 |
|
|
$Conf{CgiNavBarAdminAllHosts} = 1; |
655 |
|
|
|
656 |
|
|
# |
657 |
|
|
# IncrFill should now be off |
658 |
|
|
# |
659 |
|
|
$Conf{IncrFill} = 0; |
660 |
|
|
|
661 |
|
|
# |
662 |
|
|
# Figure out sensible arguments for the ping command |
663 |
|
|
# |
664 |
|
|
if ( defined($Conf{PingArgs}) ) { |
665 |
|
|
$Conf{PingCmd} = '$pingPath ' . $Conf{PingArgs}; |
666 |
|
|
} elsif ( !defined($Conf{PingCmd}) ) { |
667 |
|
|
if ( $^O eq "solaris" || $^O eq "sunos" ) { |
668 |
|
|
$Conf{PingCmd} = '$pingPath -s $host 56 1'; |
669 |
|
|
} elsif ( ($^O eq "linux" || $^O eq "openbsd" || $^O eq "netbsd") |
670 |
|
|
&& !system("$Conf{PingPath} -c 1 -w 3 localhost") ) { |
671 |
|
|
$Conf{PingCmd} = '$pingPath -c 1 -w 3 $host'; |
672 |
|
|
} else { |
673 |
|
|
$Conf{PingCmd} = '$pingPath -c 1 $host'; |
674 |
|
|
} |
675 |
|
|
delete($Conf{PingArgs}); |
676 |
|
|
} |
677 |
|
|
|
678 |
|
|
# |
679 |
|
|
# Figure out sensible arguments for the df command |
680 |
|
|
# |
681 |
|
|
if ( !defined($Conf{DfCmd}) ) { |
682 |
|
|
if ( $^O eq "solaris" || $^O eq "sunos" ) { |
683 |
|
|
$Conf{DfCmd} = '$dfPath -k $topDir'; |
684 |
|
|
} |
685 |
|
|
} |
686 |
|
|
|
687 |
|
|
# |
688 |
|
|
# $Conf{SmbClientTimeout} is now $Conf{ClientTimeout} |
689 |
|
|
# |
690 |
|
|
if ( defined($Conf{SmbClientTimeout}) ) { |
691 |
|
|
$Conf{ClientTimeout} = $Conf{SmbClientTimeout}; |
692 |
|
|
delete($Conf{SmbClientTimeout}); |
693 |
|
|
} |
694 |
|
|
|
695 |
|
|
my $confCopy = "$dest.pre-2.1.0"; |
696 |
|
|
if ( -f $dest && !-f $confCopy ) { |
697 |
|
|
# |
698 |
|
|
# Make copy of config file, preserving ownership and modes |
699 |
|
|
# |
700 |
|
|
printf("Making backup copy of $dest -> $confCopy\n"); |
701 |
|
|
my @stat = stat($dest); |
702 |
|
|
my $mode = $stat[2]; |
703 |
|
|
my $uid = $stat[4]; |
704 |
|
|
my $gid = $stat[5]; |
705 |
|
|
die("can't copy($dest, $confCopy)\n") unless copy($dest, $confCopy); |
706 |
|
|
die("can't chown $uid, $gid $confCopy\n") |
707 |
|
|
unless chown($uid, $gid, $confCopy); |
708 |
|
|
die("can't chmod $mode $confCopy\n") unless chmod($mode, $confCopy); |
709 |
|
|
} |
710 |
|
|
open(OUT, ">", $dest) || die("can't open $dest for writing\n"); |
711 |
|
|
binmode(OUT); |
712 |
|
|
my $blockComment; |
713 |
|
|
foreach my $var ( @$newConf ) { |
714 |
|
|
if ( length($blockComment) |
715 |
|
|
&& substr($var->{text}, 0, length($blockComment)) eq $blockComment ) { |
716 |
|
|
$var->{text} = substr($var->{text}, length($blockComment)); |
717 |
|
|
$blockComment = undef; |
718 |
|
|
} |
719 |
|
|
$blockComment = $1 if ( $var->{text} =~ /^([\s\n]*#{70}.*#{70}[\s\n]+)/s ); |
720 |
|
|
$var->{text} =~ s/^\s*\$Conf\{(.*?)\}(\s*=\s*['"]?)(.*?)(['"]?\s*;)/ |
721 |
|
|
defined($Conf{$1}) && ref($Conf{$1}) eq "" |
722 |
|
|
&& $Conf{$1} ne $OrigConf{$1} |
723 |
|
|
? "\$Conf{$1}$2$Conf{$1}$4" |
724 |
|
|
: "\$Conf{$1}$2$3$4"/emg; |
725 |
|
|
print OUT $var->{text}; |
726 |
|
|
} |
727 |
|
|
close(OUT); |
728 |
|
|
if ( !defined($oldConf) ) { |
729 |
|
|
die("can't chmod 0640 mode $dest\n") unless chmod(0640, $dest); |
730 |
|
|
die("can't chown $Uid, $Gid $dest\n") unless chown($Uid, $Gid, $dest); |
731 |
|
|
} |
732 |
|
|
|
733 |
|
|
if ( $Conf{CgiDir} ne "" ) { |
734 |
|
|
printf("Installing cgi script BackupPC_Admin in $DestDir$Conf{CgiDir}\n"); |
735 |
|
|
mkpath("$DestDir$Conf{CgiDir}", 0, 0755); |
736 |
|
|
InstallFile("cgi-bin/BackupPC_Admin", "$DestDir$Conf{CgiDir}/BackupPC_Admin", |
737 |
|
|
04554); |
738 |
|
|
} |
739 |
|
|
|
740 |
|
|
print <<EOF; |
741 |
|
|
|
742 |
|
|
Ok, it looks like we are finished. There are several more things you |
743 |
|
|
will need to do: |
744 |
|
|
|
745 |
|
|
- Browse through the config file, $Conf{TopDir}/conf/config.pl, |
746 |
|
|
and make sure all the settings are correct. In particular, you |
747 |
|
|
will need to set the smb share password and user name, backup |
748 |
|
|
policies and check the email message headers and bodies. |
749 |
|
|
|
750 |
|
|
- Edit the list of hosts to backup in $Conf{TopDir}/conf/hosts. |
751 |
|
|
|
752 |
|
|
- Read the documentation in $Conf{InstallDir}/doc/BackupPC.html. |
753 |
|
|
Please pay special attention to the security section. |
754 |
|
|
|
755 |
|
|
- Verify that the CGI script BackupPC_Admin runs correctly. You might |
756 |
|
|
need to change the permissions or group ownership of BackupPC_Admin. |
757 |
|
|
|
758 |
|
|
- BackupPC should be ready to start. Don't forget to run it |
759 |
|
|
as user $Conf{BackupPCUser}! The installation also contains an |
760 |
|
|
init.d/backuppc script that can be copied to /etc/init.d |
761 |
|
|
so that BackupPC can auto-start on boot. This will also enable |
762 |
|
|
administrative users to start the server from the CGI interface. |
763 |
|
|
See init.d/README. |
764 |
|
|
|
765 |
|
|
Enjoy! |
766 |
|
|
EOF |
767 |
|
|
|
768 |
|
|
if ( `$Conf{PerlPath} -V` =~ /uselargefiles=undef/ ) { |
769 |
|
|
print <<EOF; |
770 |
|
|
|
771 |
|
|
Warning: your perl, $Conf{PerlPath}, does not support large files. |
772 |
|
|
This means BackupPC won't be able to backup files larger than 2GB. |
773 |
|
|
To solve this problem you should build/install a new version of perl |
774 |
|
|
with large file support enabled. Use |
775 |
|
|
|
776 |
|
|
$Conf{PerlPath} -V | egrep uselargefiles |
777 |
|
|
|
778 |
|
|
to check if perl has large file support (undef means no support). |
779 |
|
|
EOF |
780 |
|
|
} |
781 |
|
|
|
782 |
|
|
eval "use File::RsyncP;"; |
783 |
|
|
if ( !$@ && $File::RsyncP::VERSION < 0.51 ) { |
784 |
|
|
print("\nWarning: you need to upgrade File::RsyncP;" |
785 |
|
|
. " I found $File::RsyncP::VERSION and BackupPC needs 0.51\n"); |
786 |
|
|
} |
787 |
|
|
|
788 |
|
|
exit(0); |
789 |
|
|
|
790 |
|
|
########################################################################### |
791 |
|
|
# Subroutines |
792 |
|
|
########################################################################### |
793 |
|
|
|
794 |
|
|
sub InstallFile |
795 |
|
|
{ |
796 |
|
|
my($prog, $dest, $mode, $binary) = @_; |
797 |
|
|
my $first = 1; |
798 |
|
|
my($uid, $gid) = ($Uid, $Gid); |
799 |
|
|
|
800 |
|
|
if ( -f $dest ) { |
801 |
|
|
# |
802 |
|
|
# preserve ownership and modes of files that already exist |
803 |
|
|
# |
804 |
|
|
my @stat = stat($dest); |
805 |
|
|
$mode = $stat[2]; |
806 |
|
|
$uid = $stat[4]; |
807 |
|
|
$gid = $stat[5]; |
808 |
|
|
} |
809 |
|
|
unlink($dest) if ( -f $dest ); |
810 |
|
|
if ( $binary ) { |
811 |
|
|
die("can't copy($prog, $dest)\n") unless copy($prog, $dest); |
812 |
|
|
} else { |
813 |
|
|
open(PROG, $prog) || die("can't open $prog for reading\n"); |
814 |
|
|
open(OUT, ">", $dest) || die("can't open $dest for writing\n"); |
815 |
|
|
binmode(PROG); |
816 |
|
|
binmode(OUT); |
817 |
|
|
while ( <PROG> ) { |
818 |
|
|
s/__INSTALLDIR__/$Conf{InstallDir}/g; |
819 |
|
|
s/__TOPDIR__/$Conf{TopDir}/g; |
820 |
|
|
s/__BACKUPPCUSER__/$Conf{BackupPCUser}/g; |
821 |
|
|
s/__CGIDIR__/$Conf{CgiDir}/g; |
822 |
|
|
if ( $first && /^#.*bin\/perl/ ) { |
823 |
|
|
# |
824 |
|
|
# Fill in correct path to perl (no taint for >= 2.0.1). |
825 |
|
|
# |
826 |
|
|
print OUT "#!$Conf{PerlPath}\n"; |
827 |
|
|
} else { |
828 |
|
|
print OUT; |
829 |
|
|
} |
830 |
|
|
$first = 0; |
831 |
|
|
} |
832 |
|
|
close(PROG); |
833 |
|
|
close(OUT); |
834 |
|
|
} |
835 |
|
|
die("can't chown $uid, $gid $dest") unless chown($uid, $gid, $dest); |
836 |
|
|
die("can't chmod $mode $dest") unless chmod($mode, $dest); |
837 |
|
|
} |
838 |
|
|
|
839 |
|
|
sub FindProgram |
840 |
|
|
{ |
841 |
|
|
my($path, $prog) = @_; |
842 |
|
|
|
843 |
|
|
if ( defined($opts{"bin-path"}{$prog}) ) { |
844 |
|
|
return $opts{"bin-path"}{$prog}; |
845 |
|
|
} |
846 |
|
|
foreach my $dir ( split(/:/, $path) ) { |
847 |
|
|
my $file = File::Spec->catfile($dir, $prog); |
848 |
|
|
return $file if ( -x $file ); |
849 |
|
|
} |
850 |
|
|
return; |
851 |
|
|
} |
852 |
|
|
|
853 |
|
|
sub ConfigParse |
854 |
|
|
{ |
855 |
|
|
my($file) = @_; |
856 |
|
|
open(C, $file) || die("can't open $file"); |
857 |
|
|
binmode(C); |
858 |
|
|
my($out, @conf, $var); |
859 |
|
|
my $comment = 1; |
860 |
|
|
my $allVars = {}; |
861 |
|
|
my $endLine = undef; |
862 |
|
|
while ( <C> ) { |
863 |
|
|
if ( /^#/ && !defined($endLine) ) { |
864 |
|
|
if ( $comment ) { |
865 |
|
|
$out .= $_; |
866 |
|
|
} else { |
867 |
|
|
if ( $out ne "" ) { |
868 |
|
|
$allVars->{$var} = @conf if ( defined($var) ); |
869 |
|
|
push(@conf, { |
870 |
|
|
text => $out, |
871 |
|
|
var => $var, |
872 |
|
|
}); |
873 |
|
|
} |
874 |
|
|
$var = undef; |
875 |
|
|
$comment = 1; |
876 |
|
|
$out = $_; |
877 |
|
|
} |
878 |
|
|
} elsif ( /^\s*\$Conf\{([^}]*)/ ) { |
879 |
|
|
$comment = 0; |
880 |
|
|
if ( defined($var) ) { |
881 |
|
|
$allVars->{$var} = @conf if ( defined($var) ); |
882 |
|
|
push(@conf, { |
883 |
|
|
text => $out, |
884 |
|
|
var => $var, |
885 |
|
|
}); |
886 |
|
|
$out = $_; |
887 |
|
|
} else { |
888 |
|
|
$out .= $_; |
889 |
|
|
} |
890 |
|
|
$var = $1; |
891 |
|
|
$endLine = $1 if ( /^\s*\$Conf\{[^}]*} *= *<<(.*);/ ); |
892 |
|
|
$endLine = $1 if ( /^\s*\$Conf\{[^}]*} *= *<<'(.*)';/ ); |
893 |
|
|
} else { |
894 |
|
|
$endLine = undef if ( defined($endLine) && /^\Q$endLine[\n\r]*$/ ); |
895 |
|
|
$out .= $_; |
896 |
|
|
} |
897 |
|
|
} |
898 |
|
|
if ( $out ne "" ) { |
899 |
|
|
$allVars->{$var} = @conf if ( defined($var) ); |
900 |
|
|
push(@conf, { |
901 |
|
|
text => $out, |
902 |
|
|
var => $var, |
903 |
|
|
}); |
904 |
|
|
} |
905 |
|
|
close(C); |
906 |
|
|
return (\@conf, $allVars); |
907 |
|
|
} |
908 |
|
|
|
909 |
|
|
sub ConfigMerge |
910 |
|
|
{ |
911 |
|
|
my($old, $oldVars, $new, $newVars) = @_; |
912 |
|
|
my $posn = 0; |
913 |
|
|
my $res; |
914 |
|
|
|
915 |
|
|
# |
916 |
|
|
# Find which config parameters are not needed any longer |
917 |
|
|
# |
918 |
|
|
foreach my $var ( @$old ) { |
919 |
|
|
next if ( !defined($var->{var}) || defined($newVars->{$var->{var}}) ); |
920 |
|
|
#print(STDERR "Deleting old config parameter $var->{var}\n"); |
921 |
|
|
$var->{delete} = 1; |
922 |
|
|
} |
923 |
|
|
# |
924 |
|
|
# Find which config parameters are new |
925 |
|
|
# |
926 |
|
|
foreach my $var ( @$new ) { |
927 |
|
|
next if ( !defined($var->{var}) ); |
928 |
|
|
if ( defined($oldVars->{$var->{var}}) ) { |
929 |
|
|
$posn = $oldVars->{$var->{var}}; |
930 |
|
|
} else { |
931 |
|
|
#print(STDERR "New config parameter $var->{var}: $var->{text}\n"); |
932 |
|
|
push(@{$old->[$posn]{new}}, $var); |
933 |
|
|
} |
934 |
|
|
} |
935 |
|
|
# |
936 |
|
|
# Create merged config file |
937 |
|
|
# |
938 |
|
|
foreach my $var ( @$old ) { |
939 |
|
|
next if ( $var->{delete} ); |
940 |
|
|
push(@$res, $var); |
941 |
|
|
foreach my $new ( @{$var->{new}} ) { |
942 |
|
|
push(@$res, $new); |
943 |
|
|
} |
944 |
|
|
} |
945 |
|
|
return $res; |
946 |
|
|
} |
947 |
|
|
|
948 |
|
|
sub prompt |
949 |
|
|
{ |
950 |
|
|
my($question, $default, $option) = @_; |
951 |
|
|
|
952 |
|
|
$default = $opts{$option} if ( defined($opts{$option}) ); |
953 |
|
|
if ( $opts{batch} ) { |
954 |
|
|
print("$question [$default]\n"); |
955 |
|
|
return $default; |
956 |
|
|
} |
957 |
|
|
print("$question [$default]? "); |
958 |
|
|
my $reply = <STDIN>; |
959 |
|
|
$reply =~ s/[\n\r]*//g; |
960 |
|
|
return $reply if ( $reply !~ /^$/ ); |
961 |
|
|
return $default; |
962 |
|
|
} |
963 |
|
|
|
964 |
|
|
__END__ |
965 |
|
|
|
966 |
|
|
=head1 SYNOPSIS |
967 |
|
|
|
968 |
|
|
configure.pl [options] |
969 |
|
|
|
970 |
|
|
=head1 DESCRIPTION |
971 |
|
|
|
972 |
|
|
configure.pl is a script that is used to install or upgrade a BackupPC |
973 |
|
|
installation. It is usually run interactively without arguments. It |
974 |
|
|
also supports a batch mode where all the options can be specified |
975 |
|
|
via the command-line. |
976 |
|
|
|
977 |
|
|
For upgrading BackupPC you need to make sure that BackupPC is not |
978 |
|
|
running prior to running BackupPC. |
979 |
|
|
|
980 |
|
|
Typically configure.pl needs to run as the super user (root). |
981 |
|
|
|
982 |
|
|
=head1 OPTIONS |
983 |
|
|
|
984 |
|
|
=over 8 |
985 |
|
|
|
986 |
|
|
=item B<--batch> |
987 |
|
|
|
988 |
|
|
Run configure.pl in batch mode. configure.pl will run without |
989 |
|
|
prompting the user. The other command-line options are used |
990 |
|
|
to specify the settings that the user is usually prompted for. |
991 |
|
|
|
992 |
|
|
=item B<--bin-path PROG=PATH> |
993 |
|
|
|
994 |
|
|
Specify the path for various external programs that BackupPC |
995 |
|
|
uses. Several --bin-path options may be specified. configure.pl |
996 |
|
|
usually finds sensible defaults based on searching the PATH. |
997 |
|
|
The format is: |
998 |
|
|
|
999 |
|
|
--bin-path PROG=PATH |
1000 |
|
|
|
1001 |
|
|
where PROG is one of perl, tar, smbclient, nmblookup, rsync, ping, |
1002 |
|
|
df, ssh, sendmail, hostname, split, par2, cat, gzip, bzip2 and |
1003 |
|
|
PATH is that full path to that program. |
1004 |
|
|
|
1005 |
|
|
Examples |
1006 |
|
|
|
1007 |
|
|
--bin-path cat=/bin/cat --bin-path bzip2=/home/user/bzip2 |
1008 |
|
|
|
1009 |
|
|
=item B<--config-path CONFIG_PATH> |
1010 |
|
|
|
1011 |
|
|
Path to the existing config.pl configuration file for BackupPC. |
1012 |
|
|
This option should be specified for batch upgrades to an |
1013 |
|
|
existing installation. The option should be omitted when |
1014 |
|
|
doing a batch new install. |
1015 |
|
|
|
1016 |
|
|
=item B<--cgi-dir CGI_DIR> |
1017 |
|
|
|
1018 |
|
|
Path to Apache's cgi-bin directory where the BackupPC_Admin |
1019 |
|
|
script will be installed. This option only needs to be |
1020 |
|
|
specified for a batch new install. |
1021 |
|
|
|
1022 |
|
|
=item B<--data-dir DATA_DIR> |
1023 |
|
|
|
1024 |
|
|
Path to the BackupPC data directory. This is where all the backup |
1025 |
|
|
data is stored, and it should be on a large file system. This option |
1026 |
|
|
only needs to be specified for a batch new install. |
1027 |
|
|
|
1028 |
|
|
Example: |
1029 |
|
|
|
1030 |
|
|
--data-dir /data/BackupPC |
1031 |
|
|
|
1032 |
|
|
=item B<--dest-dir DEST_DIR> |
1033 |
|
|
|
1034 |
|
|
An optional prefix to apply to all installation directories. |
1035 |
|
|
Usually this is not needed, but certain auto-installers like |
1036 |
|
|
to stage an install in a temporary directory, and then copy |
1037 |
|
|
the files to their real destination. This option can be used |
1038 |
|
|
to specify the temporary directory prefix. Note that if you |
1039 |
|
|
specify this option, BackupPC won't run correctly if you try |
1040 |
|
|
to run it from below the --dest-dir directory, since all the |
1041 |
|
|
paths are set assuming BackupPC is installed in the intended |
1042 |
|
|
final locations. |
1043 |
|
|
|
1044 |
|
|
=item B<--help|?> |
1045 |
|
|
|
1046 |
|
|
Print a brief help message and exits. |
1047 |
|
|
|
1048 |
|
|
=item B<--hostname HOSTNAME> |
1049 |
|
|
|
1050 |
|
|
Host name (this machine's name) on which BackupPC is being installed. |
1051 |
|
|
This option only needs to be specified for a batch new install. |
1052 |
|
|
|
1053 |
|
|
=item B<--html-dir HTML_DIR> |
1054 |
|
|
|
1055 |
|
|
Path to an Apache html directory where various BackupPC image files |
1056 |
|
|
and the CSS files will be installed. This is typically a directory |
1057 |
|
|
below Apache's DocumentRoot directory. This option only needs to be |
1058 |
|
|
specified for a batch new install. |
1059 |
|
|
|
1060 |
|
|
Example: |
1061 |
|
|
|
1062 |
|
|
--html-dir /usr/local/apache/htdocs/BackupPC |
1063 |
|
|
|
1064 |
|
|
=item B<--html-dir-url URL> |
1065 |
|
|
|
1066 |
|
|
The URL (without http://hostname) required to access the BackupPC html |
1067 |
|
|
directory specified with the --html-dir option. This option only needs |
1068 |
|
|
to be specified for a batch new install. |
1069 |
|
|
|
1070 |
|
|
Example: |
1071 |
|
|
|
1072 |
|
|
--html-dir-url /BackupPC |
1073 |
|
|
|
1074 |
|
|
=item B<--install-dir INSTALL_DIR> |
1075 |
|
|
|
1076 |
|
|
Installation directory for BackupPC scripts, libraries, and |
1077 |
|
|
documentation. This option only needs to be specified for a |
1078 |
|
|
batch new install. |
1079 |
|
|
|
1080 |
|
|
Example: |
1081 |
|
|
|
1082 |
|
|
--install-dir /usr/local/BackupPC |
1083 |
|
|
|
1084 |
|
|
=item B<--man> |
1085 |
|
|
|
1086 |
|
|
Prints the manual page and exits. |
1087 |
|
|
|
1088 |
|
|
=item B<--uid-ignore> |
1089 |
|
|
|
1090 |
|
|
configure.pl verifies that the script is being run as the super user |
1091 |
|
|
(root). Without the --uid-ignore option, in batch mode the script will |
1092 |
|
|
exit with an error if not run as the super user, and in interactive mode |
1093 |
|
|
the user will be prompted. Specifying this option will cause the script |
1094 |
|
|
to continue even if the user id is not root. |
1095 |
|
|
|
1096 |
|
|
=head1 EXAMPLES |
1097 |
|
|
|
1098 |
|
|
For a standard interactive install, run without arguments: |
1099 |
|
|
|
1100 |
|
|
configure.pl |
1101 |
|
|
|
1102 |
|
|
For a batch new install you need to specify answers to all the |
1103 |
|
|
questions that are normally prompted: |
1104 |
|
|
|
1105 |
|
|
configure.pl \ |
1106 |
|
|
--batch \ |
1107 |
|
|
--cgi-dir /var/www/cgi-bin/BackupPC \ |
1108 |
|
|
--data-dir /data/BackupPC \ |
1109 |
|
|
--hostname myHost \ |
1110 |
|
|
--html-dir /var/www/html/BackupPC \ |
1111 |
|
|
--html-dir-url /BackupPC \ |
1112 |
|
|
--install-dir /usr/local/BackupPC |
1113 |
|
|
|
1114 |
|
|
For a batch upgrade, you only need to specify the path to the |
1115 |
|
|
configuration file: |
1116 |
|
|
|
1117 |
|
|
configure.pl --batch --config-path /data/BackupPC/conf/config.pl |
1118 |
|
|
|
1119 |
|
|
=head1 AUTHOR |
1120 |
|
|
|
1121 |
|
|
Craig Barratt <cbarratt@users.sourceforge.net> |
1122 |
|
|
|
1123 |
|
|
=head1 COPYRIGHT |
1124 |
|
|
|
1125 |
|
|
Copyright (C) 2001-2004 Craig Barratt. |
1126 |
|
|
|
1127 |
|
|
This program is free software; you can redistribute it and/or modify |
1128 |
|
|
it under the terms of the GNU General Public License as published by |
1129 |
|
|
the Free Software Foundation; either version 2 of the License, or |
1130 |
|
|
(at your option) any later version. |
1131 |
|
|
|
1132 |
|
|
=cut |