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-2010 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.1.0beta0, released 3 Sep 2007.
42 # See http://backuppc.sourceforge.net.
44 #========================================================================
48 use vars qw(%Conf %OrigConf);
52 my $EncodeVersion = eval($Encode::VERSION);
53 if ( $EncodeVersion < 1.99 ) {
54 print("Error: you need to upgrade perl's Encode package.\n"
55 . "I found $EncodeVersion and BackupPC needs >= 1.99\n"
56 . "Please go to www.cpan.org or use the cpan command.\n");
60 my @Packages = qw(File::Path File::Spec File::Copy DirHandle Digest::MD5
61 Data::Dumper Getopt::Std Getopt::Long Pod::Usage
62 BackupPC::Lib BackupPC::FileZIO);
64 foreach my $pkg ( @Packages ) {
67 if ( $pkg =~ /BackupPC/ ) {
70 Error loading $pkg: $@
71 BackupPC cannot load the package $pkg, which is included in the
72 BackupPC distribution. This probably means you did not cd to the
73 unpacked BackupPC distribution before running configure.pl, eg:
75 cd BackupPC-__VERSION__
84 BackupPC needs the package $pkg. Please install $pkg
85 before installing BackupPC.
91 $opts{"set-perms"} = 1;
100 "config-override=s%",
117 pod2usage(1) if ( $opts{help} );
118 pod2usage(-exitstatus => 0, -verbose => 2) if $opts{man};
120 my $DestDir = $opts{"dest-dir"};
121 $DestDir = "" if ( $DestDir eq "/" );
123 if ( !$opts{"uid-ignore"} && $< != 0 ) {
126 This configure script should be run as root, rather than uid $<.
127 Provided uid $< has sufficient permissions to create the data and
128 install directories, then it should be ok to proceed. Otherwise,
129 please quit and restart as root.
132 exit(1) if ( prompt("--> Do you want to continue?",
134 exit(1) if ( $opts{batch} && !$opts{"uid-ignore"} );
138 # Whether we use the file system hierarchy conventions or not.
139 # Older versions did not. BackupPC used to be installed in
140 # two main directories (in addition to CGI and html pages)
142 # TopDir which includes subdirs conf, log, pc, pool, cpool
144 # InstallDir which includes subdirs bin, lib, doc
146 # With FHS enabled (which is the default for new installations)
147 # the config files move to /etc/BackupPC and log files to /var/log:
149 # /etc/BackupPC/config.pl main config file (was $TopDir/conf/config.pl)
150 # /etc/BackupPC/hosts hosts file (was $TopDir/conf/hosts)
151 # /etc/BackupPC/pc/HOST.pl per-pc config file (was $TopDir/pc/HOST/config.pl)
152 # /var/log/BackupPC log files (was $TopDir/log)
153 # /var/log/BackupPC Pid, status and email info (was $TopDir/log)
157 # Check if this is an upgrade, in which case read the existing
158 # config file to get all the defaults.
161 my $ConfigFileOK = 1;
163 if ( $ConfigFileOK && -f "/etc/BackupPC/config.pl" ) {
164 $ConfigPath = "/etc/BackupPC/config.pl";
165 $opts{fhs} = 1 if ( !defined($opts{fhs}) );
168 Found /etc/BackupPC/config.pl, so this is an upgrade of an
169 existing BackupPC installation. We will verify some existing
170 information, but you will probably not need to make any
171 changes - just hit ENTER to each question.
176 Is this a new installation or upgrade for BackupPC? If this is
177 an upgrade please tell me the full path of the existing BackupPC
178 configuration file (eg: /etc/BackupPC/config.pl). Otherwise, just
182 $ConfigPath = prompt("--> Full path to existing main config.pl",
186 last if ( $ConfigPath eq ""
187 || ($ConfigPath =~ /^\// && -f $ConfigPath && -w $ConfigPath) );
188 my $problem = "is not an absolute path";
189 $problem = "is not writable" if ( !-w $ConfigPath );
190 $problem = "is not readable" if ( !-r $ConfigPath );
191 $problem = "is not a regular file" if ( !-f $ConfigPath );
192 $problem = "doesn't exist" if ( !-e $ConfigPath );
193 print("The file '$ConfigPath' $problem.\n");
194 if ( $opts{batch} ) {
195 print("Need to specify a valid --config-path for upgrade\n");
200 $opts{fhs} = 1 if ( !defined($opts{fhs}) && $ConfigPath eq "" );
201 $opts{fhs} = 0 if ( !defined($opts{fhs}) );
204 if ( $ConfigPath ne "" && -r $ConfigPath ) {
205 (my $confDir = $ConfigPath) =~ s{/[^/]+$}{};
206 die("BackupPC::Lib->new failed\n")
207 if ( !($bpc = BackupPC::Lib->new(".", ".", $confDir, 1)) );
208 %Conf = $bpc->Conf();
211 ($Conf{TopDir} = $ConfigPath) =~ s{/[^/]+/[^/]+$}{}
212 if ( $Conf{TopDir} eq '' );
213 $bpc->{LogDir} = $Conf{LogDir} = "$Conf{TopDir}/log"
214 if ( $Conf{LogDir} eq '' );
216 $bpc->{ConfDir} = $Conf{ConfDir} = $confDir;
217 my $err = $bpc->ServerConnect($Conf{ServerHost}, $Conf{ServerPort}, 1);
221 BackupPC is running on $Conf{ServerHost}. You need to stop BackupPC
222 before you can upgrade the code. Depending upon your installation,
223 you could run "/etc/init.d/backuppc stop".
231 # Create defaults for FHS setup
234 $Conf{TopDir} ||= $opts{"data-dir"} || "/data/BackupPC";
235 $Conf{ConfDir} ||= $opts{"config-dir"} || "/etc/BackupPC";
236 $Conf{InstallDir} ||= $opts{"install-dir"} || "/usr/local/BackupPC";
237 $Conf{LogDir} ||= $opts{"log-dir"} || "/var/log/BackupPC";
239 $Conf{TopDir} ||= $opts{"data-dir"} || "/data/BackupPC";
240 $Conf{ConfDir} ||= $opts{"config-dir"} || "$Conf{TopDir}/conf";
241 $Conf{InstallDir} ||= $opts{"install-dir"} || "/usr/local/BackupPC";
242 $Conf{LogDir} ||= $opts{"log-dir"} || "$Conf{TopDir}/log";
246 # These are the programs whose paths we need to find
250 'gtar/tar' => "TarClientPath",
251 smbclient => "SmbClientPath",
252 nmblookup => "NmbLookupPath",
253 rsync => "RsyncClientPath",
256 'ssh/ssh2' => "SshPath",
257 sendmail => "SendmailPath",
258 hostname => "HostnamePath",
259 split => "SplitPath",
263 bzip2 => "Bzip2Path",
266 foreach my $prog ( sort(keys(%Programs)) ) {
268 foreach my $subProg ( split(/\//, $prog) ) {
269 $path = FindProgram("$ENV{PATH}:/usr/bin:/bin:/sbin:/usr/sbin",
270 $subProg) if ( !length($path) );
272 $Conf{$Programs{$prog}} = $path if ( !length($Conf{$Programs{$prog}}) );
278 I found the following locations for these programs:
281 foreach my $prog ( sort(keys(%Programs)) ) {
282 printf(" %-12s => %s\n", $prog, $Conf{$Programs{$prog}});
285 last if (prompt('--> Are these paths correct?', 'y') =~ /^y/i);
286 foreach my $prog ( sort(keys(%Programs)) ) {
287 $Conf{$Programs{$prog}} = prompt("--> $prog path",
288 $Conf{$Programs{$prog}});
292 my $Perl58 = system($Conf{PerlPath}
293 . q{ -e 'exit($^V && $^V ge v5.8.0 ? 1 : 0);'});
298 BackupPC needs perl version 5.8.0 or later. $Conf{PerlPath} appears
299 to be an older version. Please upgrade to a newer version of perl
300 and re-run this configure script.
308 Please tell me the hostname of the machine that BackupPC will run on.
311 chomp($Conf{ServerHost} = `$Conf{HostnamePath}`)
312 if ( defined($Conf{HostnamePath}) && !defined($Conf{ServerHost}) );
313 $Conf{ServerHost} = prompt("--> BackupPC will run on host",
319 BackupPC should run as a dedicated user with limited privileges. You
320 need to create a user. This user will need read/write permission on
321 the main data directory and read/execute permission on the install
322 directory (these directories will be setup shortly).
324 The primary group for this user should also be chosen carefully.
325 The data directories and files will have group read permission,
326 so group members can access backup files.
329 my($name, $passwd, $Uid, $Gid);
331 $Conf{BackupPCUser} = prompt("--> BackupPC should run as user",
332 $Conf{BackupPCUser} || "backuppc",
334 if ( $opts{"set-perms"} ) {
335 ($name, $passwd, $Uid, $Gid) = getpwnam($Conf{BackupPCUser});
336 last if ( $name ne "" );
339 getpwnam() says that user $Conf{BackupPCUser} doesn't exist. Please
340 check the name and verify that this user is in the passwd file.
343 exit(1) if ( $opts{batch} );
351 Please specify an install directory for BackupPC. This is where the
352 BackupPC scripts, library and documentation will be installed.
357 $Conf{InstallDir} = prompt("--> Install directory (full path)",
360 last if ( $Conf{InstallDir} =~ /^\// );
361 if ( $opts{batch} ) {
362 print("Need to specify --install-dir for new installation\n");
369 Please specify a data directory for BackupPC. This is where all the
370 PC backup data is stored. This file system needs to be big enough to
371 accommodate all the PCs you expect to backup (eg: at least several GB
377 $Conf{TopDir} = prompt("--> Data directory (full path)",
380 last if ( $Conf{TopDir} =~ /^\// );
381 if ( $opts{batch} ) {
382 print("Need to specify --data-dir for new installation\n");
387 $Conf{CompressLevel} = $opts{"compress-level"}
388 if ( defined($opts{"compress-level"}) );
390 if ( !defined($Conf{CompressLevel}) ) {
391 $Conf{CompressLevel} = BackupPC::FileZIO->compOk ? 3 : 0;
392 if ( $ConfigPath eq "" && $Conf{CompressLevel} ) {
395 BackupPC can compress pool files, providing around a 40% reduction in pool
396 size (your mileage may vary). Specify the compression level (0 turns
397 off compression, and 1 to 9 represent good/fastest to best/slowest).
398 The recommended values are 0 (off) or 3 (reasonable compression and speed).
399 Increasing the compression level to 5 will use around 20% more cpu time
400 and give perhaps 2-3% more compression.
403 } elsif ( $ConfigPath eq "" ) {
406 BackupPC can compress pool files, but it needs the Compress::Zlib
407 package installed (see www.cpan.org). Compression will provide around a
408 40% reduction in pool size, at the expense of cpu time. You can leave
409 compression off and run BackupPC without compression, in which case you
410 should leave the compression level at 0 (which means off). Or the better
411 choice is to quit, install Compress::Zlib, and re-run configure.pl.
414 } elsif ( $Conf{CompressLevel} ) {
415 $Conf{CompressLevel} = 0;
418 BackupPC now supports pool file compression. Since you are upgrading
419 BackupPC you probably have existing uncompressed backups. You could
420 turn on compression, so that new backups will be compressed. This
421 will increase the pool storage requirement, since both uncompressed
422 and compressed copies of files will be stored. But eventually the old
423 uncompressed backups will expire, recovering the pool storage. Please
424 see the documentation for more details.
426 If you are not sure what to do, leave the Compression Level at 0,
427 which disables compression. You can always read the documentation
428 and turn it on later.
432 $Conf{CompressLevel} = 0;
435 BackupPC now supports pool file compression, but it needs the
436 Compress::Zlib module (see www.cpan.org). For now, leave
437 the compression level set at 0 to disable compression. If you
438 want you can install Compress::Zlib and turn compression on.
444 = prompt("--> Compression level", $Conf{CompressLevel});
445 last if ( $Conf{CompressLevel} =~ /^\d+$/ );
451 BackupPC has a powerful CGI perl interface that runs under Apache.
452 A single executable needs to be installed in a cgi-bin directory.
453 This executable needs to run as set-uid $Conf{BackupPCUser}, or
454 it can be run under mod_perl with Apache running as user $Conf{BackupPCUser}.
456 Leave this path empty if you don't want to install the CGI interface.
461 $Conf{CgiDir} = prompt("--> CGI bin directory (full path)",
464 last if ( $Conf{CgiDir} =~ /^\// || $Conf{CgiDir} eq "" );
465 if ( $opts{batch} ) {
466 print("Need to specify --cgi-dir for new installation\n");
471 if ( $Conf{CgiDir} ne "" ) {
475 BackupPC's CGI script needs to display various PNG/GIF images that
476 should be stored where Apache can serve them. They should be placed
477 somewhere under Apache's DocumentRoot. BackupPC also needs to know
478 the URL to access these images. Example:
480 Apache image directory: /var/www/htdocs/BackupPC
481 URL for image directory: /BackupPC
483 The URL for the image directory should start with a slash.
487 $Conf{CgiImageDir} = prompt("--> Apache image directory (full path)",
490 last if ( $Conf{CgiImageDir} =~ /^\// );
491 if ( $opts{batch} ) {
492 print("Need to specify --html-dir for new installation\n");
497 $Conf{CgiImageDirURL} = prompt("--> URL for image directory (omit http://host; starts with '/')",
498 $Conf{CgiImageDirURL},
500 last if ( $Conf{CgiImageDirURL} =~ /^\// );
501 if ( $opts{batch} ) {
502 print("Need to specify --html-dir-url for new installation\n");
512 - install the binaries, lib and docs in $Conf{InstallDir},
513 - create the data directory $Conf{TopDir},
514 - create/update the config.pl file $Conf{ConfDir}/config.pl,
515 - optionally install the cgi-bin interface.
519 exit unless prompt("--> Do you want to continue?", "y") =~ /y/i;
522 # Create install directories
524 foreach my $dir ( qw(bin doc
533 next if ( -d "$DestDir$Conf{InstallDir}/$dir" );
534 mkpath("$DestDir$Conf{InstallDir}/$dir", 0, 0755);
535 if ( !-d "$DestDir$Conf{InstallDir}/$dir"
536 || !my_chown($Uid, $Gid, "$DestDir$Conf{InstallDir}/$dir") ) {
537 die("Failed to create or chown $DestDir$Conf{InstallDir}/$dir\n");
539 print("Created $DestDir$Conf{InstallDir}/$dir\n");
544 # Create CGI image directory
546 foreach my $dir ( ($Conf{CgiImageDir}) ) {
547 next if ( $dir eq "" || -d "$DestDir$dir" );
548 mkpath("$DestDir$dir", 0, 0755);
549 if ( !-d "$DestDir$dir" || !my_chown($Uid, $Gid, "$DestDir$dir") ) {
550 die("Failed to create or chown $DestDir$dir");
552 print("Created $DestDir$dir\n");
557 # Create other directories
561 "$Conf{TopDir}/pool",
562 "$Conf{TopDir}/cpool",
564 "$Conf{TopDir}/trash",
568 mkpath("$DestDir$dir", 0, 0750) if ( !-d "$DestDir$dir" );
569 if ( !-d "$DestDir$dir"
570 || !my_chown($Uid, $Gid, "$DestDir$dir") ) {
571 die("Failed to create or chown $DestDir$dir\n");
573 print("Created $DestDir$dir\n");
577 printf("Installing binaries in $DestDir$Conf{InstallDir}/bin\n");
578 foreach my $prog ( qw(
579 __CONFIGURE_BIN_LIST__
581 InstallFile($prog, "$DestDir$Conf{InstallDir}/$prog", 0555);
584 printf("Installing library in $DestDir$Conf{InstallDir}/lib\n");
585 foreach my $lib ( qw(
586 __CONFIGURE_LIB_LIST__
588 InstallFile($lib, "$DestDir$Conf{InstallDir}/$lib", 0444);
591 if ( $Conf{CgiImageDir} ne "" ) {
592 printf("Installing images in $DestDir$Conf{CgiImageDir}\n");
593 foreach my $img ( <images/*> ) {
594 (my $destImg = $img) =~ s{^images/}{};
595 InstallFile($img, "$DestDir$Conf{CgiImageDir}/$destImg", 0444, 1);
599 # Install new CSS file, making a backup copy if necessary
601 my $cssBackup = "$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css.pre-__VERSION__";
602 if ( -f "$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css" && !-f $cssBackup ) {
603 rename("$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css", $cssBackup);
605 InstallFile("conf/BackupPC_stnd.css",
606 "$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css", 0444, 0);
607 InstallFile("conf/BackupPC_stnd_orig.css",
608 "$DestDir$Conf{CgiImageDir}/BackupPC_stnd_orig.css", 0444, 0);
609 InstallFile("conf/sorttable.js",
610 "$DestDir$Conf{CgiImageDir}/sorttable.js", 0444, 0);
613 printf("Making init.d scripts\n");
614 foreach my $init ( qw(gentoo-backuppc gentoo-backuppc.conf linux-backuppc
615 solaris-backuppc debian-backuppc freebsd-backuppc
616 freebsd-backuppc2 suse-backuppc slackware-backuppc ) ) {
617 InstallFile("init.d/src/$init", "init.d/$init", 0444);
620 printf("Making Apache configuration file for suid-perl\n");
621 InstallFile("httpd/src/BackupPC.conf", "httpd/BackupPC.conf", 0644);
623 printf("Installing docs in $DestDir$Conf{InstallDir}/doc\n");
624 foreach my $doc ( qw(BackupPC.pod BackupPC.html) ) {
625 InstallFile("doc/$doc", "$DestDir$Conf{InstallDir}/doc/$doc", 0444);
628 printf("Installing config.pl and hosts in $DestDir$Conf{ConfDir}\n");
629 InstallFile("conf/hosts", "$DestDir$Conf{ConfDir}/hosts", 0644)
630 if ( !-f "$DestDir$Conf{ConfDir}/hosts" );
633 # Now do the config file. If there is an existing config file we
634 # merge in the new config file, adding any new configuration
635 # parameters and deleting ones that are no longer needed.
637 my $dest = "$DestDir$Conf{ConfDir}/config.pl";
638 my ($distConf, $distVars) = ConfigParse("conf/config.pl");
639 my ($oldConf, $oldVars);
640 my ($newConf, $newVars) = ($distConf, $distVars);
642 ($oldConf, $oldVars) = ConfigParse($dest);
643 ($newConf, $newVars) = ConfigMerge($oldConf, $oldVars, $distConf, $distVars);
647 # Update various config parameters. The old config is in Conf{}
648 # and the new config is an array in text form in $newConf->[].
650 $Conf{EMailFromUserName} ||= $Conf{BackupPCUser};
651 $Conf{EMailAdminUserName} ||= $Conf{BackupPCUser};
654 # Guess $Conf{CgiURL}
656 if ( !defined($Conf{CgiURL}) ) {
657 if ( $Conf{CgiDir} =~ m{cgi-bin(/.*)} ) {
658 $Conf{CgiURL} = "'http://$Conf{ServerHost}/cgi-bin$1/BackupPC_Admin'";
660 $Conf{CgiURL} = "'http://$Conf{ServerHost}/cgi-bin/BackupPC_Admin'";
665 # The smbclient commands have moved from hard-coded to the config file.
666 # $Conf{SmbClientArgs} no longer exists, so merge it into the new
667 # commands if it still exists.
669 if ( defined($Conf{SmbClientArgs}) ) {
670 if ( $Conf{SmbClientArgs} ne "" ) {
671 foreach my $param ( qw(SmbClientRestoreCmd SmbClientFullCmd
672 SmbClientIncrCmd) ) {
673 $newConf->[$newVars->{$param}]{text}
674 =~ s/(-E\s+-N)/$1 $Conf{SmbClientArgs}/;
677 delete($Conf{SmbClientArgs});
681 # CSS is now stored in a file rather than a big config variable.
683 delete($Conf{CSSstylesheet});
686 # The blackout timing settings are now stored in a list of hashes, rather
687 # than three scalar parameters.
689 if ( defined($Conf{BlackoutHourBegin}) ) {
690 $Conf{BlackoutPeriods} = [
692 hourBegin => $Conf{BlackoutHourBegin},
693 hourEnd => $Conf{BlackoutHourEnd},
694 weekDays => $Conf{BlackoutWeekDays},
697 delete($Conf{BlackoutHourBegin});
698 delete($Conf{BlackoutHourEnd});
699 delete($Conf{BlackoutWeekDays});
703 # $Conf{RsyncLogLevel} has been replaced by $Conf{XferLogLevel}
705 if ( defined($Conf{RsyncLogLevel}) ) {
706 $Conf{XferLogLevel} = $Conf{RsyncLogLevel};
707 delete($Conf{RsyncLogLevel});
711 # In 2.1.0 the default for $Conf{CgiNavBarAdminAllHosts} is now 1
713 $Conf{CgiNavBarAdminAllHosts} = 1;
716 # IncrFill should now be off
721 # Empty $Conf{ParPath} if it isn't a valid executable
722 # (pre-3.0.0 configure.pl incorrectly set it to a
725 $Conf{ParPath} = '' if ( $Conf{ParPath} ne '' && !-x $Conf{ParPath} );
728 # Figure out sensible arguments for the ping command
730 if ( defined($Conf{PingArgs}) ) {
731 $Conf{PingCmd} = '$pingPath ' . $Conf{PingArgs};
732 } elsif ( !defined($Conf{PingCmd}) ) {
733 if ( $^O eq "solaris" || $^O eq "sunos" ) {
734 $Conf{PingCmd} = '$pingPath -s $host 56 1';
735 } elsif ( ($^O eq "linux" || $^O eq "openbsd" || $^O eq "netbsd")
736 && !system("$Conf{PingPath} -c 1 -w 3 localhost") ) {
737 $Conf{PingCmd} = '$pingPath -c 1 -w 3 $host';
739 $Conf{PingCmd} = '$pingPath -c 1 $host';
741 delete($Conf{PingArgs});
745 # Figure out sensible arguments for the df command
747 if ( !defined($Conf{DfCmd}) ) {
748 if ( $^O eq "solaris" || $^O eq "sunos" ) {
749 $Conf{DfCmd} = '$dfPath -k $topDir';
754 # $Conf{SmbClientTimeout} is now $Conf{ClientTimeout}
756 if ( defined($Conf{SmbClientTimeout}) ) {
757 $Conf{ClientTimeout} = $Conf{SmbClientTimeout};
758 delete($Conf{SmbClientTimeout});
762 # Replace --devices with -D in RsyncArgs and RsyncRestoreArgs
764 foreach my $param ( qw(RsyncArgs RsyncRestoreArgs) ) {
765 next if ( !defined($newVars->{$param}) );
766 $newConf->[$newVars->{$param}]{text} =~ s/--devices/-D/g;
770 # Merge any new user-editable parameters into CgiUserConfigEdit
771 # by copying the old settings forward.
773 if ( defined($Conf{CgiUserConfigEdit}) ) {
775 # This is a real hack. The config file merging is done in text
776 # form without actually instantiating the new conf structure.
777 # So we need to extract the new hash of settings, update it,
778 # and merge the text. Ugh...
781 my $str = $distConf->[$distVars->{CgiUserConfigEdit}]{text};
783 $str =~ s/^\s*\$Conf\{.*?\}\s*=\s*/\$new = /m;
785 foreach my $p ( keys(%$new) ) {
786 $new->{$p} = $Conf{CgiUserConfigEdit}{$p}
787 if ( defined($Conf{CgiUserConfigEdit}{$p}) );
789 $Conf{CgiUserConfigEdit} = $new;
790 my $d = Data::Dumper->new([$new], [*value]);
793 my $value = $d->Dump;
794 $value =~ s/(.*)\n/$1;\n/s;
795 $newConf->[$newVars->{CgiUserConfigEdit}]{text}
796 =~ s/(\s*\$Conf\{.*?\}\s*=\s*).*/$1$value/s;
800 # Apply any command-line configuration parameter settings
802 foreach my $param ( keys(%{$opts{"config-override"}}) ) {
803 my $val = eval { $opts{"config-override"}{$param} };
805 printf("Can't eval --config-override setting %s=%s\n",
806 $param, $opts{"config-override"}{$param});
809 if ( !defined($newVars->{$param}) ) {
810 printf("Unkown config parameter %s in --config-override\n", $param);
813 $newConf->[$newVars->{$param}]{text} = $opts{"config-override"}{$param};
817 # Now backup and write the config file
819 my $confCopy = "$dest.pre-__VERSION__";
820 if ( -f $dest && !-f $confCopy ) {
822 # Make copy of config file, preserving ownership and modes
824 printf("Making backup copy of $dest -> $confCopy\n");
825 my @stat = stat($dest);
829 die("can't copy($dest, $confCopy)\n")
830 unless copy($dest, $confCopy);
831 die("can't chown $uid, $gid $confCopy\n")
832 unless my_chown($uid, $gid, $confCopy);
833 die("can't chmod $mode $confCopy\n")
834 unless my_chmod($mode, $confCopy);
836 open(OUT, ">", $dest) || die("can't open $dest for writing\n");
839 foreach my $var ( @$newConf ) {
840 if ( length($blockComment)
841 && substr($var->{text}, 0, length($blockComment)) eq $blockComment ) {
842 $var->{text} = substr($var->{text}, length($blockComment));
843 $blockComment = undef;
845 $blockComment = $1 if ( $var->{text} =~ /^([\s\n]*#{70}.*#{70}[\s\n]+)/s );
846 $var->{text} =~ s/^\s*\$Conf\{(.*?)\}(\s*=\s*['"]?)(.*?)(['"]?\s*;)/
847 defined($Conf{$1}) && ref($Conf{$1}) eq ""
848 && $Conf{$1} ne $OrigConf{$1}
849 ? "\$Conf{$1}$2$Conf{$1}$4"
850 : "\$Conf{$1}$2$3$4"/emg;
851 print OUT $var->{text};
854 if ( !defined($oldConf) ) {
855 die("can't chmod 0640 mode $dest\n") unless my_chmod(0640, $dest);
856 die("can't chown $Uid, $Gid $dest\n") unless my_chown($Uid, $Gid, $dest);
859 if ( $Conf{CgiDir} ne "" ) {
860 printf("Installing cgi script BackupPC_Admin in $DestDir$Conf{CgiDir}\n");
861 mkpath("$DestDir$Conf{CgiDir}", 0, 0755);
862 InstallFile("cgi-bin/BackupPC_Admin", "$DestDir$Conf{CgiDir}/BackupPC_Admin",
868 Ok, it looks like we are finished. There are several more things you
871 - Browse through the config file, $Conf{ConfDir}/config.pl,
872 and make sure all the settings are correct. In particular,
873 you will need to set \$Conf{CgiAdminUsers} so you have
874 administration privileges in the CGI interface.
876 - Edit the list of hosts to backup in $Conf{ConfDir}/hosts.
878 - Read the documentation in $Conf{InstallDir}/doc/BackupPC.html.
879 Please pay special attention to the security section.
881 - Verify that the CGI script BackupPC_Admin runs correctly. You might
882 need to change the permissions or group ownership of BackupPC_Admin.
883 If this is an upgrade and you are using mod_perl, you will need
884 to restart Apache. Otherwise it will have stale code.
886 - BackupPC should be ready to start. Don't forget to run it
887 as user $Conf{BackupPCUser}! The installation also contains an
888 init.d/backuppc script that can be copied to /etc/init.d
889 so that BackupPC can auto-start on boot. This will also enable
890 administrative users to start the server from the CGI interface.
896 if ( `$Conf{PerlPath} -V` =~ /uselargefiles=undef/ ) {
899 Warning: your perl, $Conf{PerlPath}, does not support large files.
900 This means BackupPC won't be able to backup files larger than 2GB.
901 To solve this problem you should build/install a new version of perl
902 with large file support enabled. Use
904 $Conf{PerlPath} -V | egrep uselargefiles
906 to check if perl has large file support (undef means no support).
910 eval "use File::RsyncP;";
911 if ( !$@ && $File::RsyncP::VERSION < 0.68 ) {
912 print("\nWarning: you need to upgrade File::RsyncP;"
913 . " I found $File::RsyncP::VERSION and BackupPC needs 0.68\n");
918 ###########################################################################
920 ###########################################################################
924 my($prog, $dest, $mode, $binary) = @_;
926 my($uid, $gid) = ($Uid, $Gid);
930 # preserve ownership and modes of files that already exist
932 my @stat = stat($dest);
937 unlink($dest) if ( -f $dest );
939 die("can't copy($prog, $dest)\n") unless copy($prog, $dest);
941 open(PROG, $prog) || die("can't open $prog for reading\n");
942 open(OUT, ">", $dest) || die("can't open $dest for writing\n");
946 s/__INSTALLDIR__/$Conf{InstallDir}/g;
947 s/__LOGDIR__/$Conf{LogDir}/g;
948 s/__CONFDIR__/$Conf{ConfDir}/g;
949 s/__TOPDIR__/$Conf{TopDir}/g;
950 s/^(\s*my \$useFHS\s*=\s*)\d;/${1}$opts{fhs};/
951 if ( $prog =~ /Lib.pm/ );
952 s/__BACKUPPCUSER__/$Conf{BackupPCUser}/g;
953 s/__CGIDIR__/$Conf{CgiDir}/g;
954 s/__IMAGEDIR__/$Conf{CgiImageDir}/g;
955 s/__IMAGEDIRURL__/$Conf{CgiImageDirURL}/g;
956 if ( $first && /^#.*bin\/perl/ ) {
958 # Fill in correct path to perl (no taint for >= 2.0.1).
960 print OUT "#!$Conf{PerlPath}\n";
969 die("can't chown $uid, $gid $dest") unless my_chown($uid, $gid, $dest);
970 die("can't chmod $mode $dest") unless my_chmod($mode, $dest);
975 my($path, $prog) = @_;
977 if ( defined($opts{"bin-path"}{$prog}) ) {
978 return $opts{"bin-path"}{$prog};
980 foreach my $dir ( split(/:/, $path) ) {
981 my $file = File::Spec->catfile($dir, $prog);
982 return $file if ( -x $file );
990 open(C, $file) || die("can't open $file");
992 my($out, @conf, $var);
997 if ( /^#/ && !defined($endLine) ) {
1002 $allVars->{$var} = @conf if ( defined($var) );
1012 } elsif ( /^\s*\$Conf\{([^}]*)/ ) {
1014 if ( defined($var) ) {
1015 $allVars->{$var} = @conf if ( defined($var) );
1025 $endLine = $1 if ( /^\s*\$Conf\{[^}]*} *= *<<(.*);/ );
1026 $endLine = $1 if ( /^\s*\$Conf\{[^}]*} *= *<<'(.*)';/ );
1028 $endLine = undef if ( defined($endLine) && /^\Q$endLine[\n\r]*$/ );
1033 $allVars->{$var} = @conf if ( defined($var) );
1040 return (\@conf, $allVars);
1045 my($old, $oldVars, $new, $newVars) = @_;
1050 # Find which config parameters are not needed any longer
1052 foreach my $var ( @$old ) {
1053 next if ( !defined($var->{var}) || defined($newVars->{$var->{var}}) );
1054 #print(STDERR "Deleting old config parameter $var->{var}\n");
1058 # Find which config parameters are new
1060 foreach my $var ( @$new ) {
1061 next if ( !defined($var->{var}) );
1062 if ( defined($oldVars->{$var->{var}}) ) {
1063 $posn = $oldVars->{$var->{var}};
1065 #print(STDERR "New config parameter $var->{var}: $var->{text}\n");
1066 push(@{$old->[$posn]{new}}, $var);
1070 # Create merged config file
1072 foreach my $var ( @$old ) {
1073 next if ( $var->{delete} );
1075 foreach my $new ( @{$var->{new}} ) {
1079 for ( my $i = 0 ; $i < @$res ; $i++ ) {
1080 $resVars->{$res->[$i]{var}} = $i;
1082 return ($res, $resVars);
1087 my($uid, $gid, $file) = @_;
1089 return 1 if ( !$opts{"set-perms"} );
1090 return chown($uid, $gid, $file);
1095 my ($mode, $file) = @_;
1097 return 1 if ( !$opts{"set-perms"} );
1098 return chmod($mode, $file);
1103 my($question, $default, $option) = @_;
1105 $default = $opts{$option} if ( defined($opts{$option}) );
1106 if ( $opts{batch} ) {
1107 print("$question [$default]\n");
1110 print("$question [$default]? ");
1111 my $reply = <STDIN>;
1112 $reply =~ s/[\n\r]*//g;
1113 return $reply if ( $reply !~ /^$/ );
1121 configure.pl [options]
1125 configure.pl is a script that is used to install or upgrade a BackupPC
1126 installation. It is usually run interactively without arguments. It
1127 also supports a batch mode where all the options can be specified
1128 via the command-line.
1130 For upgrading BackupPC you need to make sure that BackupPC is not
1131 running prior to running BackupPC.
1133 Typically configure.pl needs to run as the super user (root).
1141 Run configure.pl in batch mode. configure.pl will run without
1142 prompting the user. The other command-line options are used
1143 to specify the settings that the user is usually prompted for.
1145 =item B<--backuppc-user=USER>
1147 Specify the BackupPC user name that owns all the BackupPC
1148 files and runs the BackupPC programs. Default is backuppc.
1150 =item B<--bin-path PROG=PATH>
1152 Specify the path for various external programs that BackupPC
1153 uses. Several --bin-path options may be specified. configure.pl
1154 usually finds sensible defaults based on searching the PATH.
1157 --bin-path PROG=PATH
1159 where PROG is one of perl, tar, smbclient, nmblookup, rsync, ping,
1160 df, ssh, sendmail, hostname, split, par2, cat, gzip, bzip2 and
1161 PATH is that full path to that program.
1165 --bin-path cat=/bin/cat --bin-path bzip2=/home/user/bzip2
1167 =item B<--compress-level=N>
1169 Set the configuration compression level to N. Default is 3
1170 if Compress::Zlib is installed.
1172 =item B<--config-dir CONFIG_DIR>
1174 Configuration directory for new installations. Defaults
1175 to /etc/BackupPC with FHS. Automatically extracted
1176 from --config-path for existing installations.
1178 =item B<--config-path CONFIG_PATH>
1180 Path to the existing config.pl configuration file for BackupPC.
1181 This option should be specified for batch upgrades to an
1182 existing installation. The option should be omitted when
1183 doing a batch new install.
1185 =item B<--cgi-dir CGI_DIR>
1187 Path to Apache's cgi-bin directory where the BackupPC_Admin
1188 script will be installed. This option only needs to be
1189 specified for a batch new install.
1191 =item B<--data-dir DATA_DIR>
1193 Path to the BackupPC data directory. This is where all the backup
1194 data is stored, and it should be on a large file system. This option
1195 only needs to be specified for a batch new install.
1199 --data-dir /data/BackupPC
1201 =item B<--dest-dir DEST_DIR>
1203 An optional prefix to apply to all installation directories.
1204 Usually this is not needed, but certain auto-installers like
1205 to stage an install in a temporary directory, and then copy
1206 the files to their real destination. This option can be used
1207 to specify the temporary directory prefix. Note that if you
1208 specify this option, BackupPC won't run correctly if you try
1209 to run it from below the --dest-dir directory, since all the
1210 paths are set assuming BackupPC is installed in the intended
1215 Use locations specified by the Filesystem Hierarchy Standard
1216 for installing BackupPC. This is enabled by default for new
1217 installations. To use the pre-3.0 installation locations,
1222 Print a brief help message and exits.
1224 =item B<--hostname HOSTNAME>
1226 Host name (this machine's name) on which BackupPC is being installed.
1227 This option only needs to be specified for a batch new install.
1229 =item B<--html-dir HTML_DIR>
1231 Path to an Apache html directory where various BackupPC image files
1232 and the CSS files will be installed. This is typically a directory
1233 below Apache's DocumentRoot directory. This option only needs to be
1234 specified for a batch new install.
1238 --html-dir /var/www/htdocs/BackupPC
1240 =item B<--html-dir-url URL>
1242 The URL (without http://hostname) required to access the BackupPC html
1243 directory specified with the --html-dir option. This option only needs
1244 to be specified for a batch new install.
1248 --html-dir-url /BackupPC
1250 =item B<--install-dir INSTALL_DIR>
1252 Installation directory for BackupPC scripts, libraries, and
1253 documentation. This option only needs to be specified for a
1258 --install-dir /usr/local/BackupPC
1260 =item B<--log-dir LOG_DIR>
1262 Log directory. Defaults to /var/log/BackupPC with FHS.
1266 Prints the manual page and exits.
1268 =item B<--set-perms>
1270 When installing files and creating directories, chown them to
1271 the BackupPC user and chmod them too. This is enabled by default.
1272 To disable (for example, if staging a destination directory)
1273 then specify --no-set-perms.
1275 =item B<--uid-ignore>
1277 configure.pl verifies that the script is being run as the super user
1278 (root). Without the --uid-ignore option, in batch mode the script will
1279 exit with an error if not run as the super user, and in interactive mode
1280 the user will be prompted. Specifying this option will cause the script
1281 to continue even if the user id is not root.
1285 For a standard interactive install, run without arguments:
1289 For a batch new install you need to specify answers to all the
1290 questions that are normally prompted:
1294 --cgi-dir /var/www/cgi-bin/BackupPC \
1295 --data-dir /data/BackupPC \
1297 --html-dir /var/www/html/BackupPC \
1298 --html-dir-url /BackupPC \
1299 --install-dir /usr/local/BackupPC
1301 For a batch upgrade, you only need to specify the path to the
1304 configure.pl --batch --config-path /data/BackupPC/conf/config.pl
1308 Craig Barratt <cbarratt@users.sourceforge.net>
1312 Copyright (C) 2001-2010 Craig Barratt.
1314 This program is free software; you can redistribute it and/or modify
1315 it under the terms of the GNU General Public License as published by
1316 the Free Software Foundation; either version 2 of the License, or
1317 (at your option) any later version.