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 |
BackupPC_archive BackupPC_archiveHost |
491 |
BackupPC_updatedb BackupPC_xls_report |
492 |
BackupPC_restore BackupPC_serverMesg BackupPC_zipCreate ) ) { |
493 |
InstallFile("bin/$prog", "$DestDir$Conf{InstallDir}/bin/$prog", 0555); |
494 |
} |
495 |
|
496 |
printf("Installing library in $DestDir$Conf{InstallDir}/lib\n"); |
497 |
foreach my $lib ( qw( |
498 |
BackupPC/Lib.pm |
499 |
BackupPC/FileZIO.pm |
500 |
BackupPC/Attrib.pm |
501 |
BackupPC/PoolWrite.pm |
502 |
BackupPC/View.pm |
503 |
BackupPC/Xfer/Archive.pm |
504 |
BackupPC/Xfer/Tar.pm |
505 |
BackupPC/Xfer/Smb.pm |
506 |
BackupPC/Xfer/Rsync.pm |
507 |
BackupPC/Xfer/RsyncDigest.pm |
508 |
BackupPC/Xfer/RsyncFileIO.pm |
509 |
BackupPC/Zip/FileMember.pm |
510 |
BackupPC/Lang/en.pm |
511 |
BackupPC/Lang/fr.pm |
512 |
BackupPC/Lang/es.pm |
513 |
BackupPC/Lang/de.pm |
514 |
BackupPC/Lang/it.pm |
515 |
BackupPC/Lang/nl.pm |
516 |
BackupPC/CGI/AdminOptions.pm |
517 |
BackupPC/CGI/Archive.pm |
518 |
BackupPC/CGI/ArchiveInfo.pm |
519 |
BackupPC/CGI/Browse.pm |
520 |
BackupPC/CGI/DirHistory.pm |
521 |
BackupPC/CGI/EmailSummary.pm |
522 |
BackupPC/CGI/GeneralInfo.pm |
523 |
BackupPC/CGI/HostInfo.pm |
524 |
BackupPC/CGI/Lib.pm |
525 |
BackupPC/CGI/LOGlist.pm |
526 |
BackupPC/CGI/Queue.pm |
527 |
BackupPC/CGI/ReloadServer.pm |
528 |
BackupPC/CGI/RestoreFile.pm |
529 |
BackupPC/CGI/RestoreInfo.pm |
530 |
BackupPC/CGI/Restore.pm |
531 |
BackupPC/CGI/StartServer.pm |
532 |
BackupPC/CGI/StartStopBackup.pm |
533 |
BackupPC/CGI/StopServer.pm |
534 |
BackupPC/CGI/Summary.pm |
535 |
BackupPC/CGI/View.pm |
536 |
BackupPC/CGI/BurnMedia.pm |
537 |
BackupPC/CGI/SearchArchives.pm |
538 |
BackupPC/SearchLib.pm |
539 |
) ) { |
540 |
InstallFile("lib/$lib", "$DestDir$Conf{InstallDir}/lib/$lib", 0444); |
541 |
} |
542 |
|
543 |
if ( $Conf{CgiImageDir} ne "" ) { |
544 |
printf("Installing images in $DestDir$Conf{CgiImageDir}\n"); |
545 |
foreach my $img ( <images/*> ) { |
546 |
(my $destImg = $img) =~ s{^images/}{}; |
547 |
InstallFile($img, "$DestDir$Conf{CgiImageDir}/$destImg", 0444, 1); |
548 |
} |
549 |
|
550 |
# |
551 |
# Install new CSS file, making a backup copy if necessary |
552 |
# |
553 |
my $cssBackup = "$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css.pre-2.1.0"; |
554 |
if ( -f "$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css" && !-f $cssBackup ) { |
555 |
rename("$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css", $cssBackup); |
556 |
} |
557 |
InstallFile("conf/BackupPC_stnd.css", |
558 |
"$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css", 0444, 0); |
559 |
} |
560 |
|
561 |
printf("Making init.d scripts\n"); |
562 |
foreach my $init ( qw(gentoo-backuppc gentoo-backuppc.conf linux-backuppc |
563 |
solaris-backuppc debian-backuppc suse-backuppc) ) { |
564 |
InstallFile("init.d/src/$init", "init.d/$init", 0444); |
565 |
} |
566 |
|
567 |
printf("Installing docs in $DestDir$Conf{InstallDir}/doc\n"); |
568 |
foreach my $doc ( qw(BackupPC.pod BackupPC.html) ) { |
569 |
InstallFile("doc/$doc", "$DestDir$Conf{InstallDir}/doc/$doc", 0444); |
570 |
} |
571 |
|
572 |
printf("Installing config.pl and hosts in $DestDir$Conf{TopDir}/conf\n"); |
573 |
InstallFile("conf/hosts", "$DestDir$Conf{TopDir}/conf/hosts", 0644) |
574 |
if ( !-f "$DestDir$Conf{TopDir}/conf/hosts" ); |
575 |
|
576 |
# |
577 |
# Now do the config file. If there is an existing config file we |
578 |
# merge in the new config file, adding any new configuration |
579 |
# parameters and deleting ones that are no longer needed. |
580 |
# |
581 |
my $dest = "$DestDir$Conf{TopDir}/conf/config.pl"; |
582 |
my ($newConf, $newVars) = ConfigParse("conf/config.pl"); |
583 |
my ($oldConf, $oldVars); |
584 |
if ( -f $dest ) { |
585 |
($oldConf, $oldVars) = ConfigParse($dest); |
586 |
$newConf = ConfigMerge($oldConf, $oldVars, $newConf, $newVars); |
587 |
} |
588 |
$Conf{EMailFromUserName} ||= $Conf{BackupPCUser}; |
589 |
$Conf{EMailAdminUserName} ||= $Conf{BackupPCUser}; |
590 |
|
591 |
# |
592 |
# Update various config parameters |
593 |
# |
594 |
|
595 |
# |
596 |
# Guess $Conf{CgiURL} |
597 |
# |
598 |
if ( !defined($Conf{CgiURL}) ) { |
599 |
if ( $Conf{CgiDir} =~ m{cgi-bin(/.*)} ) { |
600 |
$Conf{CgiURL} = "'http://$Conf{ServerHost}/cgi-bin$1/BackupPC_Admin'"; |
601 |
} else { |
602 |
$Conf{CgiURL} = "'http://$Conf{ServerHost}/cgi-bin/BackupPC_Admin'"; |
603 |
} |
604 |
} |
605 |
|
606 |
# |
607 |
# The smbclient commands have moved from hard-coded to the config file. |
608 |
# $Conf{SmbClientArgs} no longer exists, so merge it into the new |
609 |
# commands if it still exists. |
610 |
# |
611 |
if ( defined($Conf{SmbClientArgs}) ) { |
612 |
if ( $Conf{SmbClientArgs} ne "" ) { |
613 |
foreach my $param ( qw(SmbClientRestoreCmd SmbClientFullCmd |
614 |
SmbClientIncrCmd) ) { |
615 |
$newConf->[$newVars->{$param}]{text} |
616 |
=~ s/(-E\s+-N)/$1 $Conf{SmbClientArgs}/; |
617 |
} |
618 |
} |
619 |
delete($Conf{SmbClientArgs}); |
620 |
} |
621 |
|
622 |
# |
623 |
# CSS is now stored in a file rather than a big config variable. |
624 |
# |
625 |
delete($Conf{CSSstylesheet}); |
626 |
|
627 |
# |
628 |
# The blackout timing settings are now stored in a list of hashes, rather |
629 |
# than three scalar parameters. |
630 |
# |
631 |
if ( defined($Conf{BlackoutHourBegin}) ) { |
632 |
$Conf{BlackoutPeriods} = [ |
633 |
{ |
634 |
hourBegin => $Conf{BlackoutHourBegin}, |
635 |
hourEnd => $Conf{BlackoutHourEnd}, |
636 |
weekDays => $Conf{BlackoutWeekDays}, |
637 |
} |
638 |
]; |
639 |
delete($Conf{BlackoutHourBegin}); |
640 |
delete($Conf{BlackoutHourEnd}); |
641 |
delete($Conf{BlackoutWeekDays}); |
642 |
} |
643 |
|
644 |
# |
645 |
# $Conf{RsyncLogLevel} has been replaced by $Conf{XferLogLevel} |
646 |
# |
647 |
if ( defined($Conf{RsyncLogLevel}) ) { |
648 |
$Conf{XferLogLevel} = $Conf{RsyncLogLevel}; |
649 |
delete($Conf{RsyncLogLevel}); |
650 |
} |
651 |
|
652 |
# |
653 |
# In 2.1.0 the default for $Conf{CgiNavBarAdminAllHosts} is now 1 |
654 |
# |
655 |
$Conf{CgiNavBarAdminAllHosts} = 1; |
656 |
|
657 |
# |
658 |
# IncrFill should now be off |
659 |
# |
660 |
$Conf{IncrFill} = 0; |
661 |
|
662 |
# |
663 |
# Figure out sensible arguments for the ping command |
664 |
# |
665 |
if ( defined($Conf{PingArgs}) ) { |
666 |
$Conf{PingCmd} = '$pingPath ' . $Conf{PingArgs}; |
667 |
} elsif ( !defined($Conf{PingCmd}) ) { |
668 |
if ( $^O eq "solaris" || $^O eq "sunos" ) { |
669 |
$Conf{PingCmd} = '$pingPath -s $host 56 1'; |
670 |
} elsif ( ($^O eq "linux" || $^O eq "openbsd" || $^O eq "netbsd") |
671 |
&& !system("$Conf{PingPath} -c 1 -w 3 localhost") ) { |
672 |
$Conf{PingCmd} = '$pingPath -c 1 -w 3 $host'; |
673 |
} else { |
674 |
$Conf{PingCmd} = '$pingPath -c 1 $host'; |
675 |
} |
676 |
delete($Conf{PingArgs}); |
677 |
} |
678 |
|
679 |
# |
680 |
# Figure out sensible arguments for the df command |
681 |
# |
682 |
if ( !defined($Conf{DfCmd}) ) { |
683 |
if ( $^O eq "solaris" || $^O eq "sunos" ) { |
684 |
$Conf{DfCmd} = '$dfPath -k $topDir'; |
685 |
} |
686 |
} |
687 |
|
688 |
# |
689 |
# $Conf{SmbClientTimeout} is now $Conf{ClientTimeout} |
690 |
# |
691 |
if ( defined($Conf{SmbClientTimeout}) ) { |
692 |
$Conf{ClientTimeout} = $Conf{SmbClientTimeout}; |
693 |
delete($Conf{SmbClientTimeout}); |
694 |
} |
695 |
|
696 |
my $confCopy = "$dest.pre-2.1.0"; |
697 |
if ( -f $dest && !-f $confCopy ) { |
698 |
# |
699 |
# Make copy of config file, preserving ownership and modes |
700 |
# |
701 |
printf("Making backup copy of $dest -> $confCopy\n"); |
702 |
my @stat = stat($dest); |
703 |
my $mode = $stat[2]; |
704 |
my $uid = $stat[4]; |
705 |
my $gid = $stat[5]; |
706 |
die("can't copy($dest, $confCopy)\n") unless copy($dest, $confCopy); |
707 |
die("can't chown $uid, $gid $confCopy\n") |
708 |
unless chown($uid, $gid, $confCopy); |
709 |
die("can't chmod $mode $confCopy\n") unless chmod($mode, $confCopy); |
710 |
} |
711 |
open(OUT, ">", $dest) || die("can't open $dest for writing\n"); |
712 |
binmode(OUT); |
713 |
my $blockComment; |
714 |
foreach my $var ( @$newConf ) { |
715 |
if ( length($blockComment) |
716 |
&& substr($var->{text}, 0, length($blockComment)) eq $blockComment ) { |
717 |
$var->{text} = substr($var->{text}, length($blockComment)); |
718 |
$blockComment = undef; |
719 |
} |
720 |
$blockComment = $1 if ( $var->{text} =~ /^([\s\n]*#{70}.*#{70}[\s\n]+)/s ); |
721 |
$var->{text} =~ s/^\s*\$Conf\{(.*?)\}(\s*=\s*['"]?)(.*?)(['"]?\s*;)/ |
722 |
defined($Conf{$1}) && ref($Conf{$1}) eq "" |
723 |
&& $Conf{$1} ne $OrigConf{$1} |
724 |
? "\$Conf{$1}$2$Conf{$1}$4" |
725 |
: "\$Conf{$1}$2$3$4"/emg; |
726 |
print OUT $var->{text}; |
727 |
} |
728 |
close(OUT); |
729 |
if ( !defined($oldConf) ) { |
730 |
die("can't chmod 0640 mode $dest\n") unless chmod(0640, $dest); |
731 |
die("can't chown $Uid, $Gid $dest\n") unless chown($Uid, $Gid, $dest); |
732 |
} |
733 |
|
734 |
if ( $Conf{CgiDir} ne "" ) { |
735 |
printf("Installing cgi script BackupPC_Admin in $DestDir$Conf{CgiDir}\n"); |
736 |
mkpath("$DestDir$Conf{CgiDir}", 0, 0755); |
737 |
InstallFile("cgi-bin/BackupPC_Admin", "$DestDir$Conf{CgiDir}/BackupPC_Admin", |
738 |
04554); |
739 |
} |
740 |
|
741 |
print <<EOF; |
742 |
|
743 |
Ok, it looks like we are finished. There are several more things you |
744 |
will need to do: |
745 |
|
746 |
- Browse through the config file, $Conf{TopDir}/conf/config.pl, |
747 |
and make sure all the settings are correct. In particular, you |
748 |
will need to set the smb share password and user name, backup |
749 |
policies and check the email message headers and bodies. |
750 |
|
751 |
- Edit the list of hosts to backup in $Conf{TopDir}/conf/hosts. |
752 |
|
753 |
- Read the documentation in $Conf{InstallDir}/doc/BackupPC.html. |
754 |
Please pay special attention to the security section. |
755 |
|
756 |
- Verify that the CGI script BackupPC_Admin runs correctly. You might |
757 |
need to change the permissions or group ownership of BackupPC_Admin. |
758 |
|
759 |
- BackupPC should be ready to start. Don't forget to run it |
760 |
as user $Conf{BackupPCUser}! The installation also contains an |
761 |
init.d/backuppc script that can be copied to /etc/init.d |
762 |
so that BackupPC can auto-start on boot. This will also enable |
763 |
administrative users to start the server from the CGI interface. |
764 |
See init.d/README. |
765 |
|
766 |
Enjoy! |
767 |
EOF |
768 |
|
769 |
if ( `$Conf{PerlPath} -V` =~ /uselargefiles=undef/ ) { |
770 |
print <<EOF; |
771 |
|
772 |
Warning: your perl, $Conf{PerlPath}, does not support large files. |
773 |
This means BackupPC won't be able to backup files larger than 2GB. |
774 |
To solve this problem you should build/install a new version of perl |
775 |
with large file support enabled. Use |
776 |
|
777 |
$Conf{PerlPath} -V | egrep uselargefiles |
778 |
|
779 |
to check if perl has large file support (undef means no support). |
780 |
EOF |
781 |
} |
782 |
|
783 |
eval "use File::RsyncP;"; |
784 |
if ( !$@ && $File::RsyncP::VERSION < 0.51 ) { |
785 |
print("\nWarning: you need to upgrade File::RsyncP;" |
786 |
. " I found $File::RsyncP::VERSION and BackupPC needs 0.51\n"); |
787 |
} |
788 |
|
789 |
exit(0); |
790 |
|
791 |
########################################################################### |
792 |
# Subroutines |
793 |
########################################################################### |
794 |
|
795 |
sub InstallFile |
796 |
{ |
797 |
my($prog, $dest, $mode, $binary) = @_; |
798 |
my $first = 1; |
799 |
my($uid, $gid) = ($Uid, $Gid); |
800 |
|
801 |
if ( -f $dest ) { |
802 |
# |
803 |
# preserve ownership and modes of files that already exist |
804 |
# |
805 |
my @stat = stat($dest); |
806 |
$mode = $stat[2]; |
807 |
$uid = $stat[4]; |
808 |
$gid = $stat[5]; |
809 |
} |
810 |
unlink($dest) if ( -f $dest ); |
811 |
if ( $binary ) { |
812 |
die("can't copy($prog, $dest)\n") unless copy($prog, $dest); |
813 |
} else { |
814 |
open(PROG, $prog) || die("can't open $prog for reading\n"); |
815 |
open(OUT, ">", $dest) || die("can't open $dest for writing\n"); |
816 |
binmode(PROG); |
817 |
binmode(OUT); |
818 |
while ( <PROG> ) { |
819 |
s/__INSTALLDIR__/$Conf{InstallDir}/g; |
820 |
s/__TOPDIR__/$Conf{TopDir}/g; |
821 |
s/__BACKUPPCUSER__/$Conf{BackupPCUser}/g; |
822 |
s/__CGIDIR__/$Conf{CgiDir}/g; |
823 |
if ( $first && /^#.*bin\/perl/ ) { |
824 |
# |
825 |
# Fill in correct path to perl (no taint for >= 2.0.1). |
826 |
# |
827 |
print OUT "#!$Conf{PerlPath}\n"; |
828 |
} else { |
829 |
print OUT; |
830 |
} |
831 |
$first = 0; |
832 |
} |
833 |
close(PROG); |
834 |
close(OUT); |
835 |
} |
836 |
die("can't chown $uid, $gid $dest") unless chown($uid, $gid, $dest); |
837 |
die("can't chmod $mode $dest") unless chmod($mode, $dest); |
838 |
} |
839 |
|
840 |
sub FindProgram |
841 |
{ |
842 |
my($path, $prog) = @_; |
843 |
|
844 |
if ( defined($opts{"bin-path"}{$prog}) ) { |
845 |
return $opts{"bin-path"}{$prog}; |
846 |
} |
847 |
foreach my $dir ( split(/:/, $path) ) { |
848 |
my $file = File::Spec->catfile($dir, $prog); |
849 |
return $file if ( -x $file ); |
850 |
} |
851 |
return; |
852 |
} |
853 |
|
854 |
sub ConfigParse |
855 |
{ |
856 |
my($file) = @_; |
857 |
open(C, $file) || die("can't open $file"); |
858 |
binmode(C); |
859 |
my($out, @conf, $var); |
860 |
my $comment = 1; |
861 |
my $allVars = {}; |
862 |
my $endLine = undef; |
863 |
while ( <C> ) { |
864 |
if ( /^#/ && !defined($endLine) ) { |
865 |
if ( $comment ) { |
866 |
$out .= $_; |
867 |
} else { |
868 |
if ( $out ne "" ) { |
869 |
$allVars->{$var} = @conf if ( defined($var) ); |
870 |
push(@conf, { |
871 |
text => $out, |
872 |
var => $var, |
873 |
}); |
874 |
} |
875 |
$var = undef; |
876 |
$comment = 1; |
877 |
$out = $_; |
878 |
} |
879 |
} elsif ( /^\s*\$Conf\{([^}]*)/ ) { |
880 |
$comment = 0; |
881 |
if ( defined($var) ) { |
882 |
$allVars->{$var} = @conf if ( defined($var) ); |
883 |
push(@conf, { |
884 |
text => $out, |
885 |
var => $var, |
886 |
}); |
887 |
$out = $_; |
888 |
} else { |
889 |
$out .= $_; |
890 |
} |
891 |
$var = $1; |
892 |
$endLine = $1 if ( /^\s*\$Conf\{[^}]*} *= *<<(.*);/ ); |
893 |
$endLine = $1 if ( /^\s*\$Conf\{[^}]*} *= *<<'(.*)';/ ); |
894 |
} else { |
895 |
$endLine = undef if ( defined($endLine) && /^\Q$endLine[\n\r]*$/ ); |
896 |
$out .= $_; |
897 |
} |
898 |
} |
899 |
if ( $out ne "" ) { |
900 |
$allVars->{$var} = @conf if ( defined($var) ); |
901 |
push(@conf, { |
902 |
text => $out, |
903 |
var => $var, |
904 |
}); |
905 |
} |
906 |
close(C); |
907 |
return (\@conf, $allVars); |
908 |
} |
909 |
|
910 |
sub ConfigMerge |
911 |
{ |
912 |
my($old, $oldVars, $new, $newVars) = @_; |
913 |
my $posn = 0; |
914 |
my $res; |
915 |
|
916 |
# |
917 |
# Find which config parameters are not needed any longer |
918 |
# |
919 |
foreach my $var ( @$old ) { |
920 |
next if ( !defined($var->{var}) || defined($newVars->{$var->{var}}) ); |
921 |
#print(STDERR "Deleting old config parameter $var->{var}\n"); |
922 |
$var->{delete} = 1; |
923 |
} |
924 |
# |
925 |
# Find which config parameters are new |
926 |
# |
927 |
foreach my $var ( @$new ) { |
928 |
next if ( !defined($var->{var}) ); |
929 |
if ( defined($oldVars->{$var->{var}}) ) { |
930 |
$posn = $oldVars->{$var->{var}}; |
931 |
} else { |
932 |
#print(STDERR "New config parameter $var->{var}: $var->{text}\n"); |
933 |
push(@{$old->[$posn]{new}}, $var); |
934 |
} |
935 |
} |
936 |
# |
937 |
# Create merged config file |
938 |
# |
939 |
foreach my $var ( @$old ) { |
940 |
next if ( $var->{delete} ); |
941 |
push(@$res, $var); |
942 |
foreach my $new ( @{$var->{new}} ) { |
943 |
push(@$res, $new); |
944 |
} |
945 |
} |
946 |
return $res; |
947 |
} |
948 |
|
949 |
sub prompt |
950 |
{ |
951 |
my($question, $default, $option) = @_; |
952 |
|
953 |
$default = $opts{$option} if ( defined($opts{$option}) ); |
954 |
if ( $opts{batch} ) { |
955 |
print("$question [$default]\n"); |
956 |
return $default; |
957 |
} |
958 |
print("$question [$default]? "); |
959 |
my $reply = <STDIN>; |
960 |
$reply =~ s/[\n\r]*//g; |
961 |
return $reply if ( $reply !~ /^$/ ); |
962 |
return $default; |
963 |
} |
964 |
|
965 |
__END__ |
966 |
|
967 |
=head1 SYNOPSIS |
968 |
|
969 |
configure.pl [options] |
970 |
|
971 |
=head1 DESCRIPTION |
972 |
|
973 |
configure.pl is a script that is used to install or upgrade a BackupPC |
974 |
installation. It is usually run interactively without arguments. It |
975 |
also supports a batch mode where all the options can be specified |
976 |
via the command-line. |
977 |
|
978 |
For upgrading BackupPC you need to make sure that BackupPC is not |
979 |
running prior to running BackupPC. |
980 |
|
981 |
Typically configure.pl needs to run as the super user (root). |
982 |
|
983 |
=head1 OPTIONS |
984 |
|
985 |
=over 8 |
986 |
|
987 |
=item B<--batch> |
988 |
|
989 |
Run configure.pl in batch mode. configure.pl will run without |
990 |
prompting the user. The other command-line options are used |
991 |
to specify the settings that the user is usually prompted for. |
992 |
|
993 |
=item B<--bin-path PROG=PATH> |
994 |
|
995 |
Specify the path for various external programs that BackupPC |
996 |
uses. Several --bin-path options may be specified. configure.pl |
997 |
usually finds sensible defaults based on searching the PATH. |
998 |
The format is: |
999 |
|
1000 |
--bin-path PROG=PATH |
1001 |
|
1002 |
where PROG is one of perl, tar, smbclient, nmblookup, rsync, ping, |
1003 |
df, ssh, sendmail, hostname, split, par2, cat, gzip, bzip2 and |
1004 |
PATH is that full path to that program. |
1005 |
|
1006 |
Examples |
1007 |
|
1008 |
--bin-path cat=/bin/cat --bin-path bzip2=/home/user/bzip2 |
1009 |
|
1010 |
=item B<--config-path CONFIG_PATH> |
1011 |
|
1012 |
Path to the existing config.pl configuration file for BackupPC. |
1013 |
This option should be specified for batch upgrades to an |
1014 |
existing installation. The option should be omitted when |
1015 |
doing a batch new install. |
1016 |
|
1017 |
=item B<--cgi-dir CGI_DIR> |
1018 |
|
1019 |
Path to Apache's cgi-bin directory where the BackupPC_Admin |
1020 |
script will be installed. This option only needs to be |
1021 |
specified for a batch new install. |
1022 |
|
1023 |
=item B<--data-dir DATA_DIR> |
1024 |
|
1025 |
Path to the BackupPC data directory. This is where all the backup |
1026 |
data is stored, and it should be on a large file system. This option |
1027 |
only needs to be specified for a batch new install. |
1028 |
|
1029 |
Example: |
1030 |
|
1031 |
--data-dir /data/BackupPC |
1032 |
|
1033 |
=item B<--dest-dir DEST_DIR> |
1034 |
|
1035 |
An optional prefix to apply to all installation directories. |
1036 |
Usually this is not needed, but certain auto-installers like |
1037 |
to stage an install in a temporary directory, and then copy |
1038 |
the files to their real destination. This option can be used |
1039 |
to specify the temporary directory prefix. Note that if you |
1040 |
specify this option, BackupPC won't run correctly if you try |
1041 |
to run it from below the --dest-dir directory, since all the |
1042 |
paths are set assuming BackupPC is installed in the intended |
1043 |
final locations. |
1044 |
|
1045 |
=item B<--help|?> |
1046 |
|
1047 |
Print a brief help message and exits. |
1048 |
|
1049 |
=item B<--hostname HOSTNAME> |
1050 |
|
1051 |
Host name (this machine's name) on which BackupPC is being installed. |
1052 |
This option only needs to be specified for a batch new install. |
1053 |
|
1054 |
=item B<--html-dir HTML_DIR> |
1055 |
|
1056 |
Path to an Apache html directory where various BackupPC image files |
1057 |
and the CSS files will be installed. This is typically a directory |
1058 |
below Apache's DocumentRoot directory. This option only needs to be |
1059 |
specified for a batch new install. |
1060 |
|
1061 |
Example: |
1062 |
|
1063 |
--html-dir /usr/local/apache/htdocs/BackupPC |
1064 |
|
1065 |
=item B<--html-dir-url URL> |
1066 |
|
1067 |
The URL (without http://hostname) required to access the BackupPC html |
1068 |
directory specified with the --html-dir option. This option only needs |
1069 |
to be specified for a batch new install. |
1070 |
|
1071 |
Example: |
1072 |
|
1073 |
--html-dir-url /BackupPC |
1074 |
|
1075 |
=item B<--install-dir INSTALL_DIR> |
1076 |
|
1077 |
Installation directory for BackupPC scripts, libraries, and |
1078 |
documentation. This option only needs to be specified for a |
1079 |
batch new install. |
1080 |
|
1081 |
Example: |
1082 |
|
1083 |
--install-dir /usr/local/BackupPC |
1084 |
|
1085 |
=item B<--man> |
1086 |
|
1087 |
Prints the manual page and exits. |
1088 |
|
1089 |
=item B<--uid-ignore> |
1090 |
|
1091 |
configure.pl verifies that the script is being run as the super user |
1092 |
(root). Without the --uid-ignore option, in batch mode the script will |
1093 |
exit with an error if not run as the super user, and in interactive mode |
1094 |
the user will be prompted. Specifying this option will cause the script |
1095 |
to continue even if the user id is not root. |
1096 |
|
1097 |
=head1 EXAMPLES |
1098 |
|
1099 |
For a standard interactive install, run without arguments: |
1100 |
|
1101 |
configure.pl |
1102 |
|
1103 |
For a batch new install you need to specify answers to all the |
1104 |
questions that are normally prompted: |
1105 |
|
1106 |
configure.pl \ |
1107 |
--batch \ |
1108 |
--cgi-dir /var/www/cgi-bin/BackupPC \ |
1109 |
--data-dir /data/BackupPC \ |
1110 |
--hostname myHost \ |
1111 |
--html-dir /var/www/html/BackupPC \ |
1112 |
--html-dir-url /BackupPC \ |
1113 |
--install-dir /usr/local/BackupPC |
1114 |
|
1115 |
For a batch upgrade, you only need to specify the path to the |
1116 |
configuration file: |
1117 |
|
1118 |
configure.pl --batch --config-path /data/BackupPC/conf/config.pl |
1119 |
|
1120 |
=head1 AUTHOR |
1121 |
|
1122 |
Craig Barratt <cbarratt@users.sourceforge.net> |
1123 |
|
1124 |
=head1 COPYRIGHT |
1125 |
|
1126 |
Copyright (C) 2001-2004 Craig Barratt. |
1127 |
|
1128 |
This program is free software; you can redistribute it and/or modify |
1129 |
it under the terms of the GNU General Public License as published by |
1130 |
the Free Software Foundation; either version 2 of the License, or |
1131 |
(at your option) any later version. |
1132 |
|
1133 |
=cut |