2 #============================================================= -*-perl-*-
4 # configure.pl: Configuration and installation program for BackupPC
8 # This script should be run as root:
12 # To read about the command-line options for this configure script:
14 # perldoc configure.pl
16 # The installation steps are described as the script runs.
19 # Craig Barratt <cbarratt@users.sourceforge.net>
22 # Copyright (C) 2001-2006 Craig Barratt
24 # This program is free software; you can redistribute it and/or modify
25 # it under the terms of the GNU General Public License as published by
26 # the Free Software Foundation; either version 2 of the License, or
27 # (at your option) any later version.
29 # This program is distributed in the hope that it will be useful,
30 # but WITHOUT ANY WARRANTY; without even the implied warranty of
31 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 # GNU General Public License for more details.
34 # You should have received a copy of the GNU General Public License
35 # along with this program; if not, write to the Free Software
36 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
38 #========================================================================
40 # Version 3.0.0alpha, released 8 Jul 2006.
42 # See http://backuppc.sourceforge.net.
44 #========================================================================
48 use vars qw(%Conf %OrigConf);
51 my @Packages = qw(File::Path File::Spec File::Copy DirHandle Digest::MD5
52 Data::Dumper Getopt::Std Getopt::Long Pod::Usage
53 BackupPC::Lib BackupPC::FileZIO);
55 foreach my $pkg ( @Packages ) {
58 if ( $pkg =~ /BackupPC/ ) {
61 BackupPC cannot find the package $pkg, which is included in the
62 BackupPC distribution. This probably means you did not cd to the
63 unpacked BackupPC distribution before running configure.pl, eg:
65 cd BackupPC-__VERSION__
74 BackupPC needs the package $pkg. Please install $pkg
75 before installing BackupPC.
81 $opts{"set-perms"} = 1;
106 pod2usage(1) if ( $opts{help} );
107 pod2usage(-exitstatus => 0, -verbose => 2) if $opts{man};
109 my $DestDir = $opts{"dest-dir"};
110 $DestDir = "" if ( $DestDir eq "/" );
112 if ( !$opts{"uid-ignore"} && $< != 0 ) {
115 This configure script should be run as root, rather than uid $<.
116 Provided uid $< has sufficient permissions to create the data and
117 install directories, then it should be ok to proceed. Otherwise,
118 please quit and restart as root.
121 exit(1) if ( prompt("--> Do you want to continue?",
123 exit(1) if ( $opts{batch} && !$opts{"uid-ignore"} );
127 # Whether we use the file system hierarchy conventions or not.
128 # Older versions did not. BackupPC used to be installed in
129 # two main directories (in addition to CGI and html pages)
131 # TopDir which includes subdirs conf, log, pc, pool, cpool
133 # InstallDir which includes subdirs bin, lib, doc
135 # With FHS enabled (which is the default for new installations)
136 # the config files move to /etc/BackupPC and log files to /var/log:
138 # /etc/BackupPC/config.pl main config file (was $TopDir/conf/config.pl)
139 # /etc/BackupPC/hosts hosts file (was $TopDir/conf/hosts)
140 # /etc/BackupPC/pc/HOST.pl per-pc config file (was $TopDir/pc/HOST/config.pl)
141 # /var/log/BackupPC log files (was $TopDir/log)
142 # /var/log/BackupPC Pid, status and email info (was $TopDir/log)
146 # Check if this is an upgrade, in which case read the existing
147 # config file to get all the defaults.
150 my $ConfigFileOK = 1;
152 if ( $ConfigFileOK && -f "/etc/BackupPC/config.pl" ) {
153 $ConfigPath = "/etc/BackupPC/config.pl";
154 $opts{fhs} = 1 if ( !defined($opts{fhs}) );
157 Found /etc/BackupPC/config.pl, so this is an upgrade of an
158 existing BackupPC installation. We will verify some existing
159 information, but you will probably not need to make any
160 changes - just hit ENTER to each question.
165 Is this a new installation or upgrade for BackupPC? If this is
166 an upgrade please tell me the full path of the existing BackupPC
167 configuration file (eg: /etc/BackupPC/config.pl). Otherwise, just
171 $ConfigPath = prompt("--> Full path to existing main config.pl",
175 last if ( $ConfigPath eq ""
176 || ($ConfigPath =~ /^\// && -f $ConfigPath && -w $ConfigPath) );
177 my $problem = "is not an absolute path";
178 $problem = "is not writable" if ( !-w $ConfigPath );
179 $problem = "is not readable" if ( !-r $ConfigPath );
180 $problem = "is not a regular file" if ( !-f $ConfigPath );
181 $problem = "doesn't exist" if ( !-e $ConfigPath );
182 print("The file '$ConfigPath' $problem.\n");
183 if ( $opts{batch} ) {
184 print("Need to specify a valid --config-path for upgrade\n");
189 $opts{fhs} = 1 if ( !defined($opts{fhs}) && $ConfigPath eq "" );
190 $opts{fhs} = 0 if ( !defined($opts{fhs}) );
193 if ( $ConfigPath ne "" && -r $ConfigPath ) {
194 (my $confDir = $ConfigPath) =~ s{/[^/]+$}{};
195 die("BackupPC::Lib->new failed\n")
196 if ( !($bpc = BackupPC::Lib->new(".", ".", $confDir, 1)) );
197 %Conf = $bpc->Conf();
200 ($Conf{TopDir} = $ConfigPath) =~ s{/[^/]+/[^/]+$}{}
201 if ( $Conf{TopDir} eq '' );
202 $bpc->{LogDir} = $Conf{LogDir} = "$Conf{TopDir}/log"
203 if ( $Conf{LogDir} eq '' );
205 $bpc->{ConfDir} = $Conf{ConfDir} = $confDir;
206 my $err = $bpc->ServerConnect($Conf{ServerHost}, $Conf{ServerPort}, 1);
210 BackupPC is running on $Conf{ServerHost}. You need to stop BackupPC
211 before you can upgrade the code. Depending upon your installation,
212 you could run "/etc/init.d/backuppc stop".
220 # Create defaults for FHS setup
223 $Conf{TopDir} ||= "/data/BackupPC";
224 $Conf{ConfDir} ||= $opts{"config-dir"} || "/etc/BackupPC";
225 $Conf{InstallDir} ||= "/usr/local/BackupPC";
226 $Conf{LogDir} ||= $opts{"log-dir"} || "/var/log/BackupPC";
230 # These are the programs whose paths we need to find
234 'gtar/tar' => "TarClientPath",
235 smbclient => "SmbClientPath",
236 nmblookup => "NmbLookupPath",
237 rsync => "RsyncClientPath",
240 'ssh/ssh2' => "SshPath",
241 sendmail => "SendmailPath",
242 hostname => "HostnamePath",
243 split => "SplitPath",
247 bzip2 => "Bzip2Path",
250 foreach my $prog ( sort(keys(%Programs)) ) {
252 foreach my $subProg ( split(/\//, $prog) ) {
253 $path = FindProgram("$ENV{PATH}:/bin:/usr/bin:/sbin:/usr/sbin",
254 $subProg) if ( !length($path) );
256 $Conf{$Programs{$prog}} = $path if ( !length($Conf{$Programs{$prog}}) );
262 I found the following locations for these programs:
265 foreach my $prog ( sort(keys(%Programs)) ) {
266 printf(" %-12s => %s\n", $prog, $Conf{$Programs{$prog}});
269 last if (prompt('--> Are these paths correct?', 'y') =~ /^y/i);
270 foreach my $prog ( sort(keys(%Programs)) ) {
271 $Conf{$Programs{$prog}} = prompt("--> $prog path",
272 $Conf{$Programs{$prog}});
276 my $Perl56 = system($Conf{PerlPath}
277 . q{ -e 'exit($^V && $^V ge v5.6.0 ? 1 : 0);'});
282 BackupPC needs perl version 5.6.0 or later. $Conf{PerlPath} appears
283 to be an older version. Please upgrade to a newer version of perl
284 and re-run this configure script.
292 Please tell me the hostname of the machine that BackupPC will run on.
295 chomp($Conf{ServerHost} = `$Conf{HostnamePath}`)
296 if ( defined($Conf{HostnamePath}) && !defined($Conf{ServerHost}) );
297 $Conf{ServerHost} = prompt("--> BackupPC will run on host",
303 BackupPC should run as a dedicated user with limited privileges. You
304 need to create a user. This user will need read/write permission on
305 the main data directory and read/execute permission on the install
306 directory (these directories will be setup shortly).
308 The primary group for this user should also be chosen carefully.
309 The data directories and files will have group read permission,
310 so group members can access backup files.
313 my($name, $passwd, $Uid, $Gid);
315 $Conf{BackupPCUser} = prompt("--> BackupPC should run as user",
316 $Conf{BackupPCUser} || "backuppc",
318 if ( $opts{"set-perms"} ) {
319 ($name, $passwd, $Uid, $Gid) = getpwnam($Conf{BackupPCUser});
320 last if ( $name ne "" );
323 getpwnam() says that user $Conf{BackupPCUser} doesn't exist. Please
324 check the name and verify that this user is in the passwd file.
327 exit(1) if ( $opts{batch} );
333 Please specify an install directory for BackupPC. This is where the
334 BackupPC scripts, library and documentation will be installed.
339 $Conf{InstallDir} = prompt("--> Install directory (full path)",
342 last if ( $Conf{InstallDir} =~ /^\// );
343 if ( $opts{batch} ) {
344 print("Need to specify --install-dir for new installation\n");
351 Please specify a data directory for BackupPC. This is where the
352 all the PC backup data is stored. This file system needs to be
353 big enough to accommodate all the PCs you expect to backup (eg:
354 at least several GB per machine).
359 $Conf{TopDir} = prompt("--> Data directory (full path)",
362 last if ( $Conf{TopDir} =~ /^\// );
363 if ( $opts{batch} ) {
364 print("Need to specify --data-dir for new installation\n");
369 $Conf{CompressLevel} = $opts{"compress-level"}
370 if ( defined($opts{"compress-level"}) );
372 if ( !defined($Conf{CompressLevel}) ) {
373 $Conf{CompressLevel} = BackupPC::FileZIO->compOk ? 3 : 0;
374 if ( $ConfigPath eq "" && $Conf{CompressLevel} ) {
377 BackupPC can compress pool files, providing around a 40% reduction in pool
378 size (your mileage may vary). Specify the compression level (0 turns
379 off compression, and 1 to 9 represent good/fastest to best/slowest).
380 The recommended values are 0 (off) or 3 (reasonable compression and speed).
381 Increasing the compression level to 5 will use around 20% more cpu time
382 and give perhaps 2-3% more compression.
385 } elsif ( $ConfigPath eq "" ) {
388 BackupPC can compress pool files, but it needs the Compress::Zlib
389 package installed (see www.cpan.org). Compression will provide around a
390 40% reduction in pool size, at the expense of cpu time. You can leave
391 compression off and run BackupPC without compression, in which case you
392 should leave the compression level at 0 (which means off). You could
393 install Compress::Zlib and turn compression on later, but read the
394 documentation first about how to do this. Or the better choice is
395 to quit, install Compress::Zlib, and re-run configure.pl.
398 } elsif ( $Conf{CompressLevel} ) {
399 $Conf{CompressLevel} = 0;
402 BackupPC now supports pool file compression. Since you are upgrading
403 BackupPC you probably have existing uncompressed backups. You have
404 several choices if you want to turn on compression. You can run
405 the script BackupPC_compressPool to convert everything to compressed
406 form. Or you can simply turn on compression, so that new backups
407 will be compressed. This will increase the pool storage requirement,
408 since both uncompressed and compressed copies of files will be stored.
409 But eventually the old uncompressed backups will expire, recovering
410 the pool storage. Please see the documentation for more details.
412 If you are not sure what to do, leave the Compression Level at 0,
413 which disables compression. You can always read the documentation
414 and turn it on later.
418 $Conf{CompressLevel} = 0;
421 BackupPC now supports pool file compression, but it needs the
422 Compress::Zlib module (see www.cpan.org). For now, leave
423 the compression level set at 0 to disable compression. If you
424 want you can install Compress::Zlib and turn compression on.
425 Please see the documentation for more details about converting
426 old backups to compressed form.
432 = prompt("--> Compression level", $Conf{CompressLevel});
433 last if ( $Conf{CompressLevel} =~ /^\d+$/ );
439 BackupPC has a powerful CGI perl interface that runs under Apache.
440 A single executable needs to be installed in a cgi-bin directory.
441 This executable needs to run as set-uid $Conf{BackupPCUser}, or
442 it can be run under mod_perl with Apache running as user $Conf{BackupPCUser}.
444 Leave this path empty if you don't want to install the CGI interface.
449 $Conf{CgiDir} = prompt("--> CGI bin directory (full path)",
452 last if ( $Conf{CgiDir} =~ /^\// || $Conf{CgiDir} eq "" );
453 if ( $opts{batch} ) {
454 print("Need to specify --cgi-dir for new installation\n");
459 if ( $Conf{CgiDir} ne "" ) {
463 BackupPC's CGI script needs to display various GIF images that
464 should be stored where Apache can serve them. They should be
465 placed somewher under Apache's DocumentRoot. BackupPC also
466 needs to know the URL to access these images. Example:
468 Apache image directory: /usr/local/apache/htdocs/BackupPC
469 URL for image directory: /BackupPC
471 The URL for the image directory should start with a slash.
475 $Conf{CgiImageDir} = prompt("--> Apache image directory (full path)",
478 last if ( $Conf{CgiImageDir} =~ /^\// );
479 if ( $opts{batch} ) {
480 print("Need to specify --html-dir for new installation\n");
485 $Conf{CgiImageDirURL} = prompt("--> URL for image directory (omit http://host; starts with '/')",
486 $Conf{CgiImageDirURL},
488 last if ( $Conf{CgiImageDirURL} =~ /^\// );
489 if ( $opts{batch} ) {
490 print("Need to specify --html-dir-url for new installation\n");
500 - install the binaries, lib and docs in $Conf{InstallDir},
501 - create the data directory $Conf{TopDir},
502 - create/update the config.pl file $Conf{ConfDir}/config.pl,
503 - optionally install the cgi-bin interface.
507 exit unless prompt("--> Do you want to continue?", "y") =~ /y/i;
510 # Create install directories
512 foreach my $dir ( qw(bin doc
520 next if ( -d "$DestDir$Conf{InstallDir}/$dir" );
521 mkpath("$DestDir$Conf{InstallDir}/$dir", 0, 0755);
522 if ( !-d "$DestDir$Conf{InstallDir}/$dir"
523 || !my_chown($Uid, $Gid, "$DestDir$Conf{InstallDir}/$dir") ) {
524 die("Failed to create or chown $DestDir$Conf{InstallDir}/$dir\n");
526 print("Created $DestDir$Conf{InstallDir}/$dir\n");
531 # Create CGI image directory
533 foreach my $dir ( ($Conf{CgiImageDir}) ) {
534 next if ( $dir eq "" || -d $dir );
535 mkpath("$DestDir$dir", 0, 0755);
536 if ( !-d "$DestDir$dir" || !my_chown($Uid, $Gid, "$DestDir$dir") ) {
537 die("Failed to create or chown $DestDir$dir");
539 print("Created $DestDir$dir\n");
544 # Create other directories
548 "$Conf{TopDir}/pool",
549 "$Conf{TopDir}/cpool",
551 "$Conf{TopDir}/trash",
555 mkpath("$DestDir$dir", 0, 0750) if ( !-d "$DestDir$dir" );
556 if ( !-d "$DestDir$dir"
557 || !my_chown($Uid, $Gid, "$DestDir$dir") ) {
558 die("Failed to create or chown $DestDir$dir\n");
560 print("Created $DestDir$dir\n");
564 printf("Installing binaries in $DestDir$Conf{InstallDir}/bin\n");
565 foreach my $prog ( qw(
566 __CONFIGURE_BIN_LIST__
568 InstallFile($prog, "$DestDir$Conf{InstallDir}/$prog", 0555);
571 printf("Installing library in $DestDir$Conf{InstallDir}/lib\n");
572 foreach my $lib ( qw(
573 __CONFIGURE_LIB_LIST__
575 InstallFile($lib, "$DestDir$Conf{InstallDir}/$lib", 0444);
578 if ( $Conf{CgiImageDir} ne "" ) {
579 printf("Installing images in $DestDir$Conf{CgiImageDir}\n");
580 foreach my $img ( <images/*> ) {
581 (my $destImg = $img) =~ s{^images/}{};
582 InstallFile($img, "$DestDir$Conf{CgiImageDir}/$destImg", 0444, 1);
586 # Install new CSS file, making a backup copy if necessary
588 my $cssBackup = "$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css.pre-__VERSION__";
589 if ( -f "$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css" && !-f $cssBackup ) {
590 rename("$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css", $cssBackup);
592 InstallFile("conf/BackupPC_stnd.css",
593 "$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css", 0444, 0);
596 printf("Making init.d scripts\n");
597 foreach my $init ( qw(gentoo-backuppc gentoo-backuppc.conf linux-backuppc
598 solaris-backuppc debian-backuppc suse-backuppc
599 slackware-backuppc ) ) {
600 InstallFile("init.d/src/$init", "init.d/$init", 0444);
603 printf("Installing docs in $DestDir$Conf{InstallDir}/doc\n");
604 foreach my $doc ( qw(BackupPC.pod BackupPC.html) ) {
605 InstallFile("doc/$doc", "$DestDir$Conf{InstallDir}/doc/$doc", 0444);
608 printf("Installing config.pl and hosts in $DestDir$Conf{ConfDir}\n");
609 InstallFile("conf/hosts", "$DestDir$Conf{ConfDir}/hosts", 0644)
610 if ( !-f "$DestDir$Conf{ConfDir}/hosts" );
613 # Now do the config file. If there is an existing config file we
614 # merge in the new config file, adding any new configuration
615 # parameters and deleting ones that are no longer needed.
617 my $dest = "$DestDir$Conf{ConfDir}/config.pl";
618 my ($distConf, $distVars) = ConfigParse("conf/config.pl");
619 my ($oldConf, $oldVars);
620 my ($newConf, $newVars) = ($distConf, $distVars);
622 ($oldConf, $oldVars) = ConfigParse($dest);
623 ($newConf, $newVars) = ConfigMerge($oldConf, $oldVars, $distConf, $distVars);
627 # Update various config parameters. The old config is in Conf{}
628 # and the new config is an array in text form in $newConf->[].
630 $Conf{EMailFromUserName} ||= $Conf{BackupPCUser};
631 $Conf{EMailAdminUserName} ||= $Conf{BackupPCUser};
634 # Guess $Conf{CgiURL}
636 if ( !defined($Conf{CgiURL}) ) {
637 if ( $Conf{CgiDir} =~ m{cgi-bin(/.*)} ) {
638 $Conf{CgiURL} = "'http://$Conf{ServerHost}/cgi-bin$1/BackupPC_Admin'";
640 $Conf{CgiURL} = "'http://$Conf{ServerHost}/cgi-bin/BackupPC_Admin'";
645 # The smbclient commands have moved from hard-coded to the config file.
646 # $Conf{SmbClientArgs} no longer exists, so merge it into the new
647 # commands if it still exists.
649 if ( defined($Conf{SmbClientArgs}) ) {
650 if ( $Conf{SmbClientArgs} ne "" ) {
651 foreach my $param ( qw(SmbClientRestoreCmd SmbClientFullCmd
652 SmbClientIncrCmd) ) {
653 $newConf->[$newVars->{$param}]{text}
654 =~ s/(-E\s+-N)/$1 $Conf{SmbClientArgs}/;
657 delete($Conf{SmbClientArgs});
661 # CSS is now stored in a file rather than a big config variable.
663 delete($Conf{CSSstylesheet});
666 # The blackout timing settings are now stored in a list of hashes, rather
667 # than three scalar parameters.
669 if ( defined($Conf{BlackoutHourBegin}) ) {
670 $Conf{BlackoutPeriods} = [
672 hourBegin => $Conf{BlackoutHourBegin},
673 hourEnd => $Conf{BlackoutHourEnd},
674 weekDays => $Conf{BlackoutWeekDays},
677 delete($Conf{BlackoutHourBegin});
678 delete($Conf{BlackoutHourEnd});
679 delete($Conf{BlackoutWeekDays});
683 # $Conf{RsyncLogLevel} has been replaced by $Conf{XferLogLevel}
685 if ( defined($Conf{RsyncLogLevel}) ) {
686 $Conf{XferLogLevel} = $Conf{RsyncLogLevel};
687 delete($Conf{RsyncLogLevel});
691 # In 2.1.0 the default for $Conf{CgiNavBarAdminAllHosts} is now 1
693 $Conf{CgiNavBarAdminAllHosts} = 1;
696 # IncrFill should now be off
701 # Figure out sensible arguments for the ping command
703 if ( defined($Conf{PingArgs}) ) {
704 $Conf{PingCmd} = '$pingPath ' . $Conf{PingArgs};
705 } elsif ( !defined($Conf{PingCmd}) ) {
706 if ( $^O eq "solaris" || $^O eq "sunos" ) {
707 $Conf{PingCmd} = '$pingPath -s $host 56 1';
708 } elsif ( ($^O eq "linux" || $^O eq "openbsd" || $^O eq "netbsd")
709 && !system("$Conf{PingPath} -c 1 -w 3 localhost") ) {
710 $Conf{PingCmd} = '$pingPath -c 1 -w 3 $host';
712 $Conf{PingCmd} = '$pingPath -c 1 $host';
714 delete($Conf{PingArgs});
718 # Figure out sensible arguments for the df command
720 if ( !defined($Conf{DfCmd}) ) {
721 if ( $^O eq "solaris" || $^O eq "sunos" ) {
722 $Conf{DfCmd} = '$dfPath -k $topDir';
727 # $Conf{SmbClientTimeout} is now $Conf{ClientTimeout}
729 if ( defined($Conf{SmbClientTimeout}) ) {
730 $Conf{ClientTimeout} = $Conf{SmbClientTimeout};
731 delete($Conf{SmbClientTimeout});
735 # Replace --devices with -D in RsyncArgs and RsyncRestoreArgs
737 foreach my $param ( qw(RsyncArgs RsyncRestoreArgs) ) {
738 next if ( !defined($newVars->{$param}) );
739 $newConf->[$newVars->{$param}]{text} =~ s/--devices/-D/g;
743 # Merge any new user-editable parameters into CgiUserConfigEdit
744 # by copying the old settings forward.
746 if ( defined($Conf{CgiUserConfigEdit}) ) {
748 # This is a real hack. The config file merging is done in text
749 # form without actually instantiating the new conf structure.
750 # So we need to extract the new hash of settings, update it,
751 # and merge the text. Ugh...
754 my $str = $distConf->[$distVars->{CgiUserConfigEdit}]{text};
756 $str =~ s/^\s*\$Conf\{.*?\}\s*=\s*/\$new = /m;
758 foreach my $p ( keys(%$new) ) {
759 $new->{$p} = $Conf{CgiUserConfigEdit}{$p}
760 if ( defined($Conf{CgiUserConfigEdit}{$p}) );
762 $Conf{CgiUserConfigEdit} = $new;
763 my $d = Data::Dumper->new([$new], [*value]);
766 my $value = $d->Dump;
767 $value =~ s/(.*)\n/$1;\n/s;
768 $newConf->[$newVars->{CgiUserConfigEdit}]{text}
769 =~ s/(\s*\$Conf\{.*?\}\s*=\s*).*/$1$value/s;
773 # Now backup and write the config file
775 my $confCopy = "$dest.pre-__VERSION__";
776 if ( -f $dest && !-f $confCopy ) {
778 # Make copy of config file, preserving ownership and modes
780 printf("Making backup copy of $dest -> $confCopy\n");
781 my @stat = stat($dest);
785 die("can't copy($dest, $confCopy)\n")
786 unless copy($dest, $confCopy);
787 die("can't chown $uid, $gid $confCopy\n")
788 unless my_chown($uid, $gid, $confCopy);
789 die("can't chmod $mode $confCopy\n")
790 unless my_chmod($mode, $confCopy);
792 open(OUT, ">", $dest) || die("can't open $dest for writing\n");
795 foreach my $var ( @$newConf ) {
796 if ( length($blockComment)
797 && substr($var->{text}, 0, length($blockComment)) eq $blockComment ) {
798 $var->{text} = substr($var->{text}, length($blockComment));
799 $blockComment = undef;
801 $blockComment = $1 if ( $var->{text} =~ /^([\s\n]*#{70}.*#{70}[\s\n]+)/s );
802 $var->{text} =~ s/^\s*\$Conf\{(.*?)\}(\s*=\s*['"]?)(.*?)(['"]?\s*;)/
803 defined($Conf{$1}) && ref($Conf{$1}) eq ""
804 && $Conf{$1} ne $OrigConf{$1}
805 ? "\$Conf{$1}$2$Conf{$1}$4"
806 : "\$Conf{$1}$2$3$4"/emg;
807 print OUT $var->{text};
810 if ( !defined($oldConf) ) {
811 die("can't chmod 0640 mode $dest\n") unless my_chmod(0640, $dest);
812 die("can't chown $Uid, $Gid $dest\n") unless my_chown($Uid, $Gid, $dest);
815 if ( $Conf{CgiDir} ne "" ) {
816 printf("Installing cgi script BackupPC_Admin in $DestDir$Conf{CgiDir}\n");
817 mkpath("$DestDir$Conf{CgiDir}", 0, 0755);
818 InstallFile("cgi-bin/BackupPC_Admin", "$DestDir$Conf{CgiDir}/BackupPC_Admin",
824 Ok, it looks like we are finished. There are several more things you
827 - Browse through the config file, $Conf{ConfDir}/config.pl,
828 and make sure all the settings are correct. In particular,
829 you will need to set \$Conf{CgiAdminUsers} so you have
830 administration privileges in the CGI interface.
832 - Edit the list of hosts to backup in $Conf{ConfDir}/hosts.
834 - Read the documentation in $Conf{InstallDir}/doc/BackupPC.html.
835 Please pay special attention to the security section.
837 - Verify that the CGI script BackupPC_Admin runs correctly. You might
838 need to change the permissions or group ownership of BackupPC_Admin.
840 - BackupPC should be ready to start. Don't forget to run it
841 as user $Conf{BackupPCUser}! The installation also contains an
842 init.d/backuppc script that can be copied to /etc/init.d
843 so that BackupPC can auto-start on boot. This will also enable
844 administrative users to start the server from the CGI interface.
850 if ( `$Conf{PerlPath} -V` =~ /uselargefiles=undef/ ) {
853 Warning: your perl, $Conf{PerlPath}, does not support large files.
854 This means BackupPC won't be able to backup files larger than 2GB.
855 To solve this problem you should build/install a new version of perl
856 with large file support enabled. Use
858 $Conf{PerlPath} -V | egrep uselargefiles
860 to check if perl has large file support (undef means no support).
864 eval "use File::RsyncP;";
865 if ( !$@ && $File::RsyncP::VERSION < 0.64 ) {
866 print("\nWarning: you need to upgrade File::RsyncP;"
867 . " I found $File::RsyncP::VERSION and BackupPC needs 0.64\n");
872 ###########################################################################
874 ###########################################################################
878 my($prog, $dest, $mode, $binary) = @_;
880 my($uid, $gid) = ($Uid, $Gid);
884 # preserve ownership and modes of files that already exist
886 my @stat = stat($dest);
891 unlink($dest) if ( -f $dest );
893 die("can't copy($prog, $dest)\n") unless copy($prog, $dest);
895 open(PROG, $prog) || die("can't open $prog for reading\n");
896 open(OUT, ">", $dest) || die("can't open $dest for writing\n");
900 s/__INSTALLDIR__/$Conf{InstallDir}/g;
901 s/__LOGDIR__/$Conf{LogDir}/g;
902 s/__CONFDIR__/$Conf{ConfDir}/g;
903 s/__TOPDIR__/$Conf{TopDir}/g;
904 s/^(\s*my \$useFHS\s*=\s*)\d;/${1}$opts{fhs};/
905 if ( $prog =~ /Lib.pm/ );
906 s/__BACKUPPCUSER__/$Conf{BackupPCUser}/g;
907 s/__CGIDIR__/$Conf{CgiDir}/g;
908 if ( $first && /^#.*bin\/perl/ ) {
910 # Fill in correct path to perl (no taint for >= 2.0.1).
912 print OUT "#!$Conf{PerlPath}\n";
921 die("can't chown $uid, $gid $dest") unless my_chown($uid, $gid, $dest);
922 die("can't chmod $mode $dest") unless my_chmod($mode, $dest);
927 my($path, $prog) = @_;
929 if ( defined($opts{"bin-path"}{$prog}) ) {
930 return $opts{"bin-path"}{$prog};
932 foreach my $dir ( split(/:/, $path) ) {
933 my $file = File::Spec->catfile($dir, $prog);
934 return $file if ( -x $file );
942 open(C, $file) || die("can't open $file");
944 my($out, @conf, $var);
949 if ( /^#/ && !defined($endLine) ) {
954 $allVars->{$var} = @conf if ( defined($var) );
964 } elsif ( /^\s*\$Conf\{([^}]*)/ ) {
966 if ( defined($var) ) {
967 $allVars->{$var} = @conf if ( defined($var) );
977 $endLine = $1 if ( /^\s*\$Conf\{[^}]*} *= *<<(.*);/ );
978 $endLine = $1 if ( /^\s*\$Conf\{[^}]*} *= *<<'(.*)';/ );
980 $endLine = undef if ( defined($endLine) && /^\Q$endLine[\n\r]*$/ );
985 $allVars->{$var} = @conf if ( defined($var) );
992 return (\@conf, $allVars);
997 my($old, $oldVars, $new, $newVars) = @_;
1002 # Find which config parameters are not needed any longer
1004 foreach my $var ( @$old ) {
1005 next if ( !defined($var->{var}) || defined($newVars->{$var->{var}}) );
1006 #print(STDERR "Deleting old config parameter $var->{var}\n");
1010 # Find which config parameters are new
1012 foreach my $var ( @$new ) {
1013 next if ( !defined($var->{var}) );
1014 if ( defined($oldVars->{$var->{var}}) ) {
1015 $posn = $oldVars->{$var->{var}};
1017 #print(STDERR "New config parameter $var->{var}: $var->{text}\n");
1018 push(@{$old->[$posn]{new}}, $var);
1022 # Create merged config file
1024 foreach my $var ( @$old ) {
1025 next if ( $var->{delete} );
1027 foreach my $new ( @{$var->{new}} ) {
1031 for ( my $i = 0 ; $i < @$res ; $i++ ) {
1032 $resVars->{$res->[$i]{var}} = $i;
1034 return ($res, $resVars);
1039 my($uid, $gid, $file) = @_;
1041 return 1 if ( !$opts{"set-perms"} );
1042 return chown($uid, $gid, $file);
1047 my ($mode, $file) = @_;
1049 return 1 if ( !$opts{"set-perms"} );
1050 return chmod($mode, $file);
1055 my($question, $default, $option) = @_;
1057 $default = $opts{$option} if ( defined($opts{$option}) );
1058 if ( $opts{batch} ) {
1059 print("$question [$default]\n");
1062 print("$question [$default]? ");
1063 my $reply = <STDIN>;
1064 $reply =~ s/[\n\r]*//g;
1065 return $reply if ( $reply !~ /^$/ );
1073 configure.pl [options]
1077 configure.pl is a script that is used to install or upgrade a BackupPC
1078 installation. It is usually run interactively without arguments. It
1079 also supports a batch mode where all the options can be specified
1080 via the command-line.
1082 For upgrading BackupPC you need to make sure that BackupPC is not
1083 running prior to running BackupPC.
1085 Typically configure.pl needs to run as the super user (root).
1093 Run configure.pl in batch mode. configure.pl will run without
1094 prompting the user. The other command-line options are used
1095 to specify the settings that the user is usually prompted for.
1097 =item B<--backuppc-user=USER>
1099 Specify the BackupPC user name that owns all the BackupPC
1100 files and runs the BackupPC programs. Default is backuppc.
1102 =item B<--bin-path PROG=PATH>
1104 Specify the path for various external programs that BackupPC
1105 uses. Several --bin-path options may be specified. configure.pl
1106 usually finds sensible defaults based on searching the PATH.
1109 --bin-path PROG=PATH
1111 where PROG is one of perl, tar, smbclient, nmblookup, rsync, ping,
1112 df, ssh, sendmail, hostname, split, par2, cat, gzip, bzip2 and
1113 PATH is that full path to that program.
1117 --bin-path cat=/bin/cat --bin-path bzip2=/home/user/bzip2
1119 =item B<--compress-level=N>
1121 Set the configuration compression level to N. Default is 3
1122 if Compress::Zlib is installed.
1124 =item B<--config-dir CONFIG_DIR>
1126 Configuration directory for new installations. Defaults
1127 to /etc/BackupPC with FHS. Automatically extracted
1128 from --config-path for existing installations.
1130 =item B<--config-path CONFIG_PATH>
1132 Path to the existing config.pl configuration file for BackupPC.
1133 This option should be specified for batch upgrades to an
1134 existing installation. The option should be omitted when
1135 doing a batch new install.
1137 =item B<--cgi-dir CGI_DIR>
1139 Path to Apache's cgi-bin directory where the BackupPC_Admin
1140 script will be installed. This option only needs to be
1141 specified for a batch new install.
1143 =item B<--data-dir DATA_DIR>
1145 Path to the BackupPC data directory. This is where all the backup
1146 data is stored, and it should be on a large file system. This option
1147 only needs to be specified for a batch new install.
1151 --data-dir /data/BackupPC
1153 =item B<--dest-dir DEST_DIR>
1155 An optional prefix to apply to all installation directories.
1156 Usually this is not needed, but certain auto-installers like
1157 to stage an install in a temporary directory, and then copy
1158 the files to their real destination. This option can be used
1159 to specify the temporary directory prefix. Note that if you
1160 specify this option, BackupPC won't run correctly if you try
1161 to run it from below the --dest-dir directory, since all the
1162 paths are set assuming BackupPC is installed in the intended
1167 Use locations specified by the Filesystem Hierarchy Standard
1168 for installing BackupPC. This is enabled by default for new
1169 installatios. To use the pre-3.0 installation locations,
1174 Print a brief help message and exits.
1176 =item B<--hostname HOSTNAME>
1178 Host name (this machine's name) on which BackupPC is being installed.
1179 This option only needs to be specified for a batch new install.
1181 =item B<--html-dir HTML_DIR>
1183 Path to an Apache html directory where various BackupPC image files
1184 and the CSS files will be installed. This is typically a directory
1185 below Apache's DocumentRoot directory. This option only needs to be
1186 specified for a batch new install.
1190 --html-dir /usr/local/apache/htdocs/BackupPC
1192 =item B<--html-dir-url URL>
1194 The URL (without http://hostname) required to access the BackupPC html
1195 directory specified with the --html-dir option. This option only needs
1196 to be specified for a batch new install.
1200 --html-dir-url /BackupPC
1202 =item B<--install-dir INSTALL_DIR>
1204 Installation directory for BackupPC scripts, libraries, and
1205 documentation. This option only needs to be specified for a
1210 --install-dir /usr/local/BackupPC
1212 =item B<--log-dir LOG_DIR>
1214 Log directory. Defaults to /var/log/BackupPC with FHS.
1218 Prints the manual page and exits.
1220 =item B<--set-perms>
1222 When installing files and creating directories, chown them to
1223 the BackupPC user and chmod them too. This is enabled by default.
1224 To disable (for example, if staging a destination directory)
1225 then specify --no-set-perms.
1227 =item B<--uid-ignore>
1229 configure.pl verifies that the script is being run as the super user
1230 (root). Without the --uid-ignore option, in batch mode the script will
1231 exit with an error if not run as the super user, and in interactive mode
1232 the user will be prompted. Specifying this option will cause the script
1233 to continue even if the user id is not root.
1237 For a standard interactive install, run without arguments:
1241 For a batch new install you need to specify answers to all the
1242 questions that are normally prompted:
1246 --cgi-dir /var/www/cgi-bin/BackupPC \
1247 --data-dir /data/BackupPC \
1249 --html-dir /var/www/html/BackupPC \
1250 --html-dir-url /BackupPC \
1251 --install-dir /usr/local/BackupPC
1253 For a batch upgrade, you only need to specify the path to the
1256 configure.pl --batch --config-path /data/BackupPC/conf/config.pl
1260 Craig Barratt <cbarratt@users.sourceforge.net>
1264 Copyright (C) 2001-2006 Craig Barratt.
1266 This program is free software; you can redistribute it and/or modify
1267 it under the terms of the GNU General Public License as published by
1268 the Free Software Foundation; either version 2 of the License, or
1269 (at your option) any later version.