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-2007 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;
116 pod2usage(1) if ( $opts{help} );
117 pod2usage(-exitstatus => 0, -verbose => 2) if $opts{man};
119 my $DestDir = $opts{"dest-dir"};
120 $DestDir = "" if ( $DestDir eq "/" );
122 if ( !$opts{"uid-ignore"} && $< != 0 ) {
125 This configure script should be run as root, rather than uid $<.
126 Provided uid $< has sufficient permissions to create the data and
127 install directories, then it should be ok to proceed. Otherwise,
128 please quit and restart as root.
131 exit(1) if ( prompt("--> Do you want to continue?",
133 exit(1) if ( $opts{batch} && !$opts{"uid-ignore"} );
137 # Whether we use the file system hierarchy conventions or not.
138 # Older versions did not. BackupPC used to be installed in
139 # two main directories (in addition to CGI and html pages)
141 # TopDir which includes subdirs conf, log, pc, pool, cpool
143 # InstallDir which includes subdirs bin, lib, doc
145 # With FHS enabled (which is the default for new installations)
146 # the config files move to /etc/BackupPC and log files to /var/log:
148 # /etc/BackupPC/config.pl main config file (was $TopDir/conf/config.pl)
149 # /etc/BackupPC/hosts hosts file (was $TopDir/conf/hosts)
150 # /etc/BackupPC/pc/HOST.pl per-pc config file (was $TopDir/pc/HOST/config.pl)
151 # /var/log/BackupPC log files (was $TopDir/log)
152 # /var/log/BackupPC Pid, status and email info (was $TopDir/log)
156 # Check if this is an upgrade, in which case read the existing
157 # config file to get all the defaults.
160 my $ConfigFileOK = 1;
162 if ( $ConfigFileOK && -f "/etc/BackupPC/config.pl" ) {
163 $ConfigPath = "/etc/BackupPC/config.pl";
164 $opts{fhs} = 1 if ( !defined($opts{fhs}) );
167 Found /etc/BackupPC/config.pl, so this is an upgrade of an
168 existing BackupPC installation. We will verify some existing
169 information, but you will probably not need to make any
170 changes - just hit ENTER to each question.
175 Is this a new installation or upgrade for BackupPC? If this is
176 an upgrade please tell me the full path of the existing BackupPC
177 configuration file (eg: /etc/BackupPC/config.pl). Otherwise, just
181 $ConfigPath = prompt("--> Full path to existing main config.pl",
185 last if ( $ConfigPath eq ""
186 || ($ConfigPath =~ /^\// && -f $ConfigPath && -w $ConfigPath) );
187 my $problem = "is not an absolute path";
188 $problem = "is not writable" if ( !-w $ConfigPath );
189 $problem = "is not readable" if ( !-r $ConfigPath );
190 $problem = "is not a regular file" if ( !-f $ConfigPath );
191 $problem = "doesn't exist" if ( !-e $ConfigPath );
192 print("The file '$ConfigPath' $problem.\n");
193 if ( $opts{batch} ) {
194 print("Need to specify a valid --config-path for upgrade\n");
199 $opts{fhs} = 1 if ( !defined($opts{fhs}) && $ConfigPath eq "" );
200 $opts{fhs} = 0 if ( !defined($opts{fhs}) );
203 if ( $ConfigPath ne "" && -r $ConfigPath ) {
204 (my $confDir = $ConfigPath) =~ s{/[^/]+$}{};
205 die("BackupPC::Lib->new failed\n")
206 if ( !($bpc = BackupPC::Lib->new(".", ".", $confDir, 1)) );
207 %Conf = $bpc->Conf();
210 ($Conf{TopDir} = $ConfigPath) =~ s{/[^/]+/[^/]+$}{}
211 if ( $Conf{TopDir} eq '' );
212 $bpc->{LogDir} = $Conf{LogDir} = "$Conf{TopDir}/log"
213 if ( $Conf{LogDir} eq '' );
215 $bpc->{ConfDir} = $Conf{ConfDir} = $confDir;
216 my $err = $bpc->ServerConnect($Conf{ServerHost}, $Conf{ServerPort}, 1);
220 BackupPC is running on $Conf{ServerHost}. You need to stop BackupPC
221 before you can upgrade the code. Depending upon your installation,
222 you could run "/etc/init.d/backuppc stop".
230 # Create defaults for FHS setup
233 $Conf{TopDir} ||= "/data/BackupPC";
234 $Conf{ConfDir} ||= $opts{"config-dir"} || "/etc/BackupPC";
235 $Conf{InstallDir} ||= "/usr/local/BackupPC";
236 $Conf{LogDir} ||= $opts{"log-dir"} || "/var/log/BackupPC";
240 # These are the programs whose paths we need to find
244 'gtar/tar' => "TarClientPath",
245 smbclient => "SmbClientPath",
246 nmblookup => "NmbLookupPath",
247 rsync => "RsyncClientPath",
250 'ssh/ssh2' => "SshPath",
251 sendmail => "SendmailPath",
252 hostname => "HostnamePath",
253 split => "SplitPath",
257 bzip2 => "Bzip2Path",
260 foreach my $prog ( sort(keys(%Programs)) ) {
262 foreach my $subProg ( split(/\//, $prog) ) {
263 $path = FindProgram("$ENV{PATH}:/bin:/usr/bin:/sbin:/usr/sbin",
264 $subProg) if ( !length($path) );
266 $Conf{$Programs{$prog}} = $path if ( !length($Conf{$Programs{$prog}}) );
272 I found the following locations for these programs:
275 foreach my $prog ( sort(keys(%Programs)) ) {
276 printf(" %-12s => %s\n", $prog, $Conf{$Programs{$prog}});
279 last if (prompt('--> Are these paths correct?', 'y') =~ /^y/i);
280 foreach my $prog ( sort(keys(%Programs)) ) {
281 $Conf{$Programs{$prog}} = prompt("--> $prog path",
282 $Conf{$Programs{$prog}});
286 my $Perl58 = system($Conf{PerlPath}
287 . q{ -e 'exit($^V && $^V ge v5.8.0 ? 1 : 0);'});
292 BackupPC needs perl version 5.8.0 or later. $Conf{PerlPath} appears
293 to be an older version. Please upgrade to a newer version of perl
294 and re-run this configure script.
302 Please tell me the hostname of the machine that BackupPC will run on.
305 chomp($Conf{ServerHost} = `$Conf{HostnamePath}`)
306 if ( defined($Conf{HostnamePath}) && !defined($Conf{ServerHost}) );
307 $Conf{ServerHost} = prompt("--> BackupPC will run on host",
313 BackupPC should run as a dedicated user with limited privileges. You
314 need to create a user. This user will need read/write permission on
315 the main data directory and read/execute permission on the install
316 directory (these directories will be setup shortly).
318 The primary group for this user should also be chosen carefully.
319 The data directories and files will have group read permission,
320 so group members can access backup files.
323 my($name, $passwd, $Uid, $Gid);
325 $Conf{BackupPCUser} = prompt("--> BackupPC should run as user",
326 $Conf{BackupPCUser} || "backuppc",
328 if ( $opts{"set-perms"} ) {
329 ($name, $passwd, $Uid, $Gid) = getpwnam($Conf{BackupPCUser});
330 last if ( $name ne "" );
333 getpwnam() says that user $Conf{BackupPCUser} doesn't exist. Please
334 check the name and verify that this user is in the passwd file.
337 exit(1) if ( $opts{batch} );
345 Please specify an install directory for BackupPC. This is where the
346 BackupPC scripts, library and documentation will be installed.
351 $Conf{InstallDir} = prompt("--> Install directory (full path)",
354 last if ( $Conf{InstallDir} =~ /^\// );
355 if ( $opts{batch} ) {
356 print("Need to specify --install-dir for new installation\n");
363 Please specify a data directory for BackupPC. This is where all the
364 PC backup data is stored. This file system needs to be big enough to
365 accommodate all the PCs you expect to backup (eg: at least several GB
371 $Conf{TopDir} = prompt("--> Data directory (full path)",
374 last if ( $Conf{TopDir} =~ /^\// );
375 if ( $opts{batch} ) {
376 print("Need to specify --data-dir for new installation\n");
381 $Conf{CompressLevel} = $opts{"compress-level"}
382 if ( defined($opts{"compress-level"}) );
384 if ( !defined($Conf{CompressLevel}) ) {
385 $Conf{CompressLevel} = BackupPC::FileZIO->compOk ? 3 : 0;
386 if ( $ConfigPath eq "" && $Conf{CompressLevel} ) {
389 BackupPC can compress pool files, providing around a 40% reduction in pool
390 size (your mileage may vary). Specify the compression level (0 turns
391 off compression, and 1 to 9 represent good/fastest to best/slowest).
392 The recommended values are 0 (off) or 3 (reasonable compression and speed).
393 Increasing the compression level to 5 will use around 20% more cpu time
394 and give perhaps 2-3% more compression.
397 } elsif ( $ConfigPath eq "" ) {
400 BackupPC can compress pool files, but it needs the Compress::Zlib
401 package installed (see www.cpan.org). Compression will provide around a
402 40% reduction in pool size, at the expense of cpu time. You can leave
403 compression off and run BackupPC without compression, in which case you
404 should leave the compression level at 0 (which means off). You could
405 install Compress::Zlib and turn compression on later, but read the
406 documentation first about how to do this. Or the better choice is
407 to quit, install Compress::Zlib, and re-run configure.pl.
410 } elsif ( $Conf{CompressLevel} ) {
411 $Conf{CompressLevel} = 0;
414 BackupPC now supports pool file compression. Since you are upgrading
415 BackupPC you probably have existing uncompressed backups. You have
416 several choices if you want to turn on compression. You can run
417 the script BackupPC_compressPool to convert everything to compressed
418 form. Or you can simply turn on compression, so that new backups
419 will be compressed. This will increase the pool storage requirement,
420 since both uncompressed and compressed copies of files will be stored.
421 But eventually the old uncompressed backups will expire, recovering
422 the pool storage. Please see the documentation for more details.
424 If you are not sure what to do, leave the Compression Level at 0,
425 which disables compression. You can always read the documentation
426 and turn it on later.
430 $Conf{CompressLevel} = 0;
433 BackupPC now supports pool file compression, but it needs the
434 Compress::Zlib module (see www.cpan.org). For now, leave
435 the compression level set at 0 to disable compression. If you
436 want you can install Compress::Zlib and turn compression on.
437 Please see the documentation for more details about converting
438 old backups to compressed form.
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 GIF images that
476 should be stored where Apache can serve them. They should be
477 placed somewhere under Apache's DocumentRoot. BackupPC also
478 needs to know the URL to access these images. Example:
480 Apache image directory: /usr/local/apache/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
532 next if ( -d "$DestDir$Conf{InstallDir}/$dir" );
533 mkpath("$DestDir$Conf{InstallDir}/$dir", 0, 0755);
534 if ( !-d "$DestDir$Conf{InstallDir}/$dir"
535 || !my_chown($Uid, $Gid, "$DestDir$Conf{InstallDir}/$dir") ) {
536 die("Failed to create or chown $DestDir$Conf{InstallDir}/$dir\n");
538 print("Created $DestDir$Conf{InstallDir}/$dir\n");
543 # Create CGI image directory
545 foreach my $dir ( ($Conf{CgiImageDir}) ) {
546 next if ( $dir eq "" || -d "$DestDir$dir" );
547 mkpath("$DestDir$dir", 0, 0755);
548 if ( !-d "$DestDir$dir" || !my_chown($Uid, $Gid, "$DestDir$dir") ) {
549 die("Failed to create or chown $DestDir$dir");
551 print("Created $DestDir$dir\n");
556 # Create other directories
560 "$Conf{TopDir}/pool",
561 "$Conf{TopDir}/cpool",
563 "$Conf{TopDir}/trash",
567 mkpath("$DestDir$dir", 0, 0750) if ( !-d "$DestDir$dir" );
568 if ( !-d "$DestDir$dir"
569 || !my_chown($Uid, $Gid, "$DestDir$dir") ) {
570 die("Failed to create or chown $DestDir$dir\n");
572 print("Created $DestDir$dir\n");
576 printf("Installing binaries in $DestDir$Conf{InstallDir}/bin\n");
577 foreach my $prog ( qw(
578 __CONFIGURE_BIN_LIST__
580 InstallFile($prog, "$DestDir$Conf{InstallDir}/$prog", 0555);
583 printf("Installing library in $DestDir$Conf{InstallDir}/lib\n");
584 foreach my $lib ( qw(
585 __CONFIGURE_LIB_LIST__
587 InstallFile($lib, "$DestDir$Conf{InstallDir}/$lib", 0444);
590 if ( $Conf{CgiImageDir} ne "" ) {
591 printf("Installing images in $DestDir$Conf{CgiImageDir}\n");
592 foreach my $img ( <images/*> ) {
593 (my $destImg = $img) =~ s{^images/}{};
594 InstallFile($img, "$DestDir$Conf{CgiImageDir}/$destImg", 0444, 1);
598 # Install new CSS file, making a backup copy if necessary
600 my $cssBackup = "$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css.pre-__VERSION__";
601 if ( -f "$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css" && !-f $cssBackup ) {
602 rename("$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css", $cssBackup);
604 InstallFile("conf/BackupPC_stnd.css",
605 "$DestDir$Conf{CgiImageDir}/BackupPC_stnd.css", 0444, 0);
606 InstallFile("conf/BackupPC_stnd_orig.css",
607 "$DestDir$Conf{CgiImageDir}/BackupPC_stnd_orig.css", 0444, 0);
608 InstallFile("conf/sorttable.js",
609 "$DestDir$Conf{CgiImageDir}/sorttable.js", 0444, 0);
612 printf("Making init.d scripts\n");
613 foreach my $init ( qw(gentoo-backuppc gentoo-backuppc.conf linux-backuppc
614 solaris-backuppc debian-backuppc freebsd-backuppc
615 suse-backuppc slackware-backuppc ) ) {
616 InstallFile("init.d/src/$init", "init.d/$init", 0444);
619 printf("Installing docs in $DestDir$Conf{InstallDir}/doc\n");
620 foreach my $doc ( qw(BackupPC.pod BackupPC.html) ) {
621 InstallFile("doc/$doc", "$DestDir$Conf{InstallDir}/doc/$doc", 0444);
624 printf("Installing config.pl and hosts in $DestDir$Conf{ConfDir}\n");
625 InstallFile("conf/hosts", "$DestDir$Conf{ConfDir}/hosts", 0644)
626 if ( !-f "$DestDir$Conf{ConfDir}/hosts" );
629 # Now do the config file. If there is an existing config file we
630 # merge in the new config file, adding any new configuration
631 # parameters and deleting ones that are no longer needed.
633 my $dest = "$DestDir$Conf{ConfDir}/config.pl";
634 my ($distConf, $distVars) = ConfigParse("conf/config.pl");
635 my ($oldConf, $oldVars);
636 my ($newConf, $newVars) = ($distConf, $distVars);
638 ($oldConf, $oldVars) = ConfigParse($dest);
639 ($newConf, $newVars) = ConfigMerge($oldConf, $oldVars, $distConf, $distVars);
643 # Update various config parameters. The old config is in Conf{}
644 # and the new config is an array in text form in $newConf->[].
646 $Conf{EMailFromUserName} ||= $Conf{BackupPCUser};
647 $Conf{EMailAdminUserName} ||= $Conf{BackupPCUser};
650 # Guess $Conf{CgiURL}
652 if ( !defined($Conf{CgiURL}) ) {
653 if ( $Conf{CgiDir} =~ m{cgi-bin(/.*)} ) {
654 $Conf{CgiURL} = "'http://$Conf{ServerHost}/cgi-bin$1/BackupPC_Admin'";
656 $Conf{CgiURL} = "'http://$Conf{ServerHost}/cgi-bin/BackupPC_Admin'";
661 # The smbclient commands have moved from hard-coded to the config file.
662 # $Conf{SmbClientArgs} no longer exists, so merge it into the new
663 # commands if it still exists.
665 if ( defined($Conf{SmbClientArgs}) ) {
666 if ( $Conf{SmbClientArgs} ne "" ) {
667 foreach my $param ( qw(SmbClientRestoreCmd SmbClientFullCmd
668 SmbClientIncrCmd) ) {
669 $newConf->[$newVars->{$param}]{text}
670 =~ s/(-E\s+-N)/$1 $Conf{SmbClientArgs}/;
673 delete($Conf{SmbClientArgs});
677 # CSS is now stored in a file rather than a big config variable.
679 delete($Conf{CSSstylesheet});
682 # The blackout timing settings are now stored in a list of hashes, rather
683 # than three scalar parameters.
685 if ( defined($Conf{BlackoutHourBegin}) ) {
686 $Conf{BlackoutPeriods} = [
688 hourBegin => $Conf{BlackoutHourBegin},
689 hourEnd => $Conf{BlackoutHourEnd},
690 weekDays => $Conf{BlackoutWeekDays},
693 delete($Conf{BlackoutHourBegin});
694 delete($Conf{BlackoutHourEnd});
695 delete($Conf{BlackoutWeekDays});
699 # $Conf{RsyncLogLevel} has been replaced by $Conf{XferLogLevel}
701 if ( defined($Conf{RsyncLogLevel}) ) {
702 $Conf{XferLogLevel} = $Conf{RsyncLogLevel};
703 delete($Conf{RsyncLogLevel});
707 # In 2.1.0 the default for $Conf{CgiNavBarAdminAllHosts} is now 1
709 $Conf{CgiNavBarAdminAllHosts} = 1;
712 # IncrFill should now be off
717 # Empty $Conf{ParPath} if it isn't a valid executable
718 # (pre-3.0.0 configure.pl incorrectly set it to a
721 $Conf{ParPath} = '' if ( $Conf{ParPath} ne '' && !-x $Conf{ParPath} );
724 # Figure out sensible arguments for the ping command
726 if ( defined($Conf{PingArgs}) ) {
727 $Conf{PingCmd} = '$pingPath ' . $Conf{PingArgs};
728 } elsif ( !defined($Conf{PingCmd}) ) {
729 if ( $^O eq "solaris" || $^O eq "sunos" ) {
730 $Conf{PingCmd} = '$pingPath -s $host 56 1';
731 } elsif ( ($^O eq "linux" || $^O eq "openbsd" || $^O eq "netbsd")
732 && !system("$Conf{PingPath} -c 1 -w 3 localhost") ) {
733 $Conf{PingCmd} = '$pingPath -c 1 -w 3 $host';
735 $Conf{PingCmd} = '$pingPath -c 1 $host';
737 delete($Conf{PingArgs});
741 # Figure out sensible arguments for the df command
743 if ( !defined($Conf{DfCmd}) ) {
744 if ( $^O eq "solaris" || $^O eq "sunos" ) {
745 $Conf{DfCmd} = '$dfPath -k $topDir';
750 # $Conf{SmbClientTimeout} is now $Conf{ClientTimeout}
752 if ( defined($Conf{SmbClientTimeout}) ) {
753 $Conf{ClientTimeout} = $Conf{SmbClientTimeout};
754 delete($Conf{SmbClientTimeout});
758 # Replace --devices with -D in RsyncArgs and RsyncRestoreArgs
760 foreach my $param ( qw(RsyncArgs RsyncRestoreArgs) ) {
761 next if ( !defined($newVars->{$param}) );
762 $newConf->[$newVars->{$param}]{text} =~ s/--devices/-D/g;
766 # Merge any new user-editable parameters into CgiUserConfigEdit
767 # by copying the old settings forward.
769 if ( defined($Conf{CgiUserConfigEdit}) ) {
771 # This is a real hack. The config file merging is done in text
772 # form without actually instantiating the new conf structure.
773 # So we need to extract the new hash of settings, update it,
774 # and merge the text. Ugh...
777 my $str = $distConf->[$distVars->{CgiUserConfigEdit}]{text};
779 $str =~ s/^\s*\$Conf\{.*?\}\s*=\s*/\$new = /m;
781 foreach my $p ( keys(%$new) ) {
782 $new->{$p} = $Conf{CgiUserConfigEdit}{$p}
783 if ( defined($Conf{CgiUserConfigEdit}{$p}) );
785 $Conf{CgiUserConfigEdit} = $new;
786 my $d = Data::Dumper->new([$new], [*value]);
789 my $value = $d->Dump;
790 $value =~ s/(.*)\n/$1;\n/s;
791 $newConf->[$newVars->{CgiUserConfigEdit}]{text}
792 =~ s/(\s*\$Conf\{.*?\}\s*=\s*).*/$1$value/s;
796 # Now backup and write the config file
798 my $confCopy = "$dest.pre-__VERSION__";
799 if ( -f $dest && !-f $confCopy ) {
801 # Make copy of config file, preserving ownership and modes
803 printf("Making backup copy of $dest -> $confCopy\n");
804 my @stat = stat($dest);
808 die("can't copy($dest, $confCopy)\n")
809 unless copy($dest, $confCopy);
810 die("can't chown $uid, $gid $confCopy\n")
811 unless my_chown($uid, $gid, $confCopy);
812 die("can't chmod $mode $confCopy\n")
813 unless my_chmod($mode, $confCopy);
815 open(OUT, ">", $dest) || die("can't open $dest for writing\n");
818 foreach my $var ( @$newConf ) {
819 if ( length($blockComment)
820 && substr($var->{text}, 0, length($blockComment)) eq $blockComment ) {
821 $var->{text} = substr($var->{text}, length($blockComment));
822 $blockComment = undef;
824 $blockComment = $1 if ( $var->{text} =~ /^([\s\n]*#{70}.*#{70}[\s\n]+)/s );
825 $var->{text} =~ s/^\s*\$Conf\{(.*?)\}(\s*=\s*['"]?)(.*?)(['"]?\s*;)/
826 defined($Conf{$1}) && ref($Conf{$1}) eq ""
827 && $Conf{$1} ne $OrigConf{$1}
828 ? "\$Conf{$1}$2$Conf{$1}$4"
829 : "\$Conf{$1}$2$3$4"/emg;
830 print OUT $var->{text};
833 if ( !defined($oldConf) ) {
834 die("can't chmod 0640 mode $dest\n") unless my_chmod(0640, $dest);
835 die("can't chown $Uid, $Gid $dest\n") unless my_chown($Uid, $Gid, $dest);
838 if ( $Conf{CgiDir} ne "" ) {
839 printf("Installing cgi script BackupPC_Admin in $DestDir$Conf{CgiDir}\n");
840 mkpath("$DestDir$Conf{CgiDir}", 0, 0755);
841 InstallFile("cgi-bin/BackupPC_Admin", "$DestDir$Conf{CgiDir}/BackupPC_Admin",
847 Ok, it looks like we are finished. There are several more things you
850 - Browse through the config file, $Conf{ConfDir}/config.pl,
851 and make sure all the settings are correct. In particular,
852 you will need to set \$Conf{CgiAdminUsers} so you have
853 administration privileges in the CGI interface.
855 - Edit the list of hosts to backup in $Conf{ConfDir}/hosts.
857 - Read the documentation in $Conf{InstallDir}/doc/BackupPC.html.
858 Please pay special attention to the security section.
860 - Verify that the CGI script BackupPC_Admin runs correctly. You might
861 need to change the permissions or group ownership of BackupPC_Admin.
862 If this is an upgrade and you are using mod_perl, you will need
863 to restart Apache. Otherwise it will have stale code.
865 - BackupPC should be ready to start. Don't forget to run it
866 as user $Conf{BackupPCUser}! The installation also contains an
867 init.d/backuppc script that can be copied to /etc/init.d
868 so that BackupPC can auto-start on boot. This will also enable
869 administrative users to start the server from the CGI interface.
875 if ( `$Conf{PerlPath} -V` =~ /uselargefiles=undef/ ) {
878 Warning: your perl, $Conf{PerlPath}, does not support large files.
879 This means BackupPC won't be able to backup files larger than 2GB.
880 To solve this problem you should build/install a new version of perl
881 with large file support enabled. Use
883 $Conf{PerlPath} -V | egrep uselargefiles
885 to check if perl has large file support (undef means no support).
889 eval "use File::RsyncP;";
890 if ( !$@ && $File::RsyncP::VERSION < 0.68 ) {
891 print("\nWarning: you need to upgrade File::RsyncP;"
892 . " I found $File::RsyncP::VERSION and BackupPC needs 0.68\n");
897 ###########################################################################
899 ###########################################################################
903 my($prog, $dest, $mode, $binary) = @_;
905 my($uid, $gid) = ($Uid, $Gid);
909 # preserve ownership and modes of files that already exist
911 my @stat = stat($dest);
916 unlink($dest) if ( -f $dest );
918 die("can't copy($prog, $dest)\n") unless copy($prog, $dest);
920 open(PROG, $prog) || die("can't open $prog for reading\n");
921 open(OUT, ">", $dest) || die("can't open $dest for writing\n");
925 s/__INSTALLDIR__/$Conf{InstallDir}/g;
926 s/__LOGDIR__/$Conf{LogDir}/g;
927 s/__CONFDIR__/$Conf{ConfDir}/g;
928 s/__TOPDIR__/$Conf{TopDir}/g;
929 s/^(\s*my \$useFHS\s*=\s*)\d;/${1}$opts{fhs};/
930 if ( $prog =~ /Lib.pm/ );
931 s/__BACKUPPCUSER__/$Conf{BackupPCUser}/g;
932 s/__CGIDIR__/$Conf{CgiDir}/g;
933 if ( $first && /^#.*bin\/perl/ ) {
935 # Fill in correct path to perl (no taint for >= 2.0.1).
937 print OUT "#!$Conf{PerlPath}\n";
946 die("can't chown $uid, $gid $dest") unless my_chown($uid, $gid, $dest);
947 die("can't chmod $mode $dest") unless my_chmod($mode, $dest);
952 my($path, $prog) = @_;
954 if ( defined($opts{"bin-path"}{$prog}) ) {
955 return $opts{"bin-path"}{$prog};
957 foreach my $dir ( split(/:/, $path) ) {
958 my $file = File::Spec->catfile($dir, $prog);
959 return $file if ( -x $file );
967 open(C, $file) || die("can't open $file");
969 my($out, @conf, $var);
974 if ( /^#/ && !defined($endLine) ) {
979 $allVars->{$var} = @conf if ( defined($var) );
989 } elsif ( /^\s*\$Conf\{([^}]*)/ ) {
991 if ( defined($var) ) {
992 $allVars->{$var} = @conf if ( defined($var) );
1002 $endLine = $1 if ( /^\s*\$Conf\{[^}]*} *= *<<(.*);/ );
1003 $endLine = $1 if ( /^\s*\$Conf\{[^}]*} *= *<<'(.*)';/ );
1005 $endLine = undef if ( defined($endLine) && /^\Q$endLine[\n\r]*$/ );
1010 $allVars->{$var} = @conf if ( defined($var) );
1017 return (\@conf, $allVars);
1022 my($old, $oldVars, $new, $newVars) = @_;
1027 # Find which config parameters are not needed any longer
1029 foreach my $var ( @$old ) {
1030 next if ( !defined($var->{var}) || defined($newVars->{$var->{var}}) );
1031 #print(STDERR "Deleting old config parameter $var->{var}\n");
1035 # Find which config parameters are new
1037 foreach my $var ( @$new ) {
1038 next if ( !defined($var->{var}) );
1039 if ( defined($oldVars->{$var->{var}}) ) {
1040 $posn = $oldVars->{$var->{var}};
1042 #print(STDERR "New config parameter $var->{var}: $var->{text}\n");
1043 push(@{$old->[$posn]{new}}, $var);
1047 # Create merged config file
1049 foreach my $var ( @$old ) {
1050 next if ( $var->{delete} );
1052 foreach my $new ( @{$var->{new}} ) {
1056 for ( my $i = 0 ; $i < @$res ; $i++ ) {
1057 $resVars->{$res->[$i]{var}} = $i;
1059 return ($res, $resVars);
1064 my($uid, $gid, $file) = @_;
1066 return 1 if ( !$opts{"set-perms"} );
1067 return chown($uid, $gid, $file);
1072 my ($mode, $file) = @_;
1074 return 1 if ( !$opts{"set-perms"} );
1075 return chmod($mode, $file);
1080 my($question, $default, $option) = @_;
1082 $default = $opts{$option} if ( defined($opts{$option}) );
1083 if ( $opts{batch} ) {
1084 print("$question [$default]\n");
1087 print("$question [$default]? ");
1088 my $reply = <STDIN>;
1089 $reply =~ s/[\n\r]*//g;
1090 return $reply if ( $reply !~ /^$/ );
1098 configure.pl [options]
1102 configure.pl is a script that is used to install or upgrade a BackupPC
1103 installation. It is usually run interactively without arguments. It
1104 also supports a batch mode where all the options can be specified
1105 via the command-line.
1107 For upgrading BackupPC you need to make sure that BackupPC is not
1108 running prior to running BackupPC.
1110 Typically configure.pl needs to run as the super user (root).
1118 Run configure.pl in batch mode. configure.pl will run without
1119 prompting the user. The other command-line options are used
1120 to specify the settings that the user is usually prompted for.
1122 =item B<--backuppc-user=USER>
1124 Specify the BackupPC user name that owns all the BackupPC
1125 files and runs the BackupPC programs. Default is backuppc.
1127 =item B<--bin-path PROG=PATH>
1129 Specify the path for various external programs that BackupPC
1130 uses. Several --bin-path options may be specified. configure.pl
1131 usually finds sensible defaults based on searching the PATH.
1134 --bin-path PROG=PATH
1136 where PROG is one of perl, tar, smbclient, nmblookup, rsync, ping,
1137 df, ssh, sendmail, hostname, split, par2, cat, gzip, bzip2 and
1138 PATH is that full path to that program.
1142 --bin-path cat=/bin/cat --bin-path bzip2=/home/user/bzip2
1144 =item B<--compress-level=N>
1146 Set the configuration compression level to N. Default is 3
1147 if Compress::Zlib is installed.
1149 =item B<--config-dir CONFIG_DIR>
1151 Configuration directory for new installations. Defaults
1152 to /etc/BackupPC with FHS. Automatically extracted
1153 from --config-path for existing installations.
1155 =item B<--config-path CONFIG_PATH>
1157 Path to the existing config.pl configuration file for BackupPC.
1158 This option should be specified for batch upgrades to an
1159 existing installation. The option should be omitted when
1160 doing a batch new install.
1162 =item B<--cgi-dir CGI_DIR>
1164 Path to Apache's cgi-bin directory where the BackupPC_Admin
1165 script will be installed. This option only needs to be
1166 specified for a batch new install.
1168 =item B<--data-dir DATA_DIR>
1170 Path to the BackupPC data directory. This is where all the backup
1171 data is stored, and it should be on a large file system. This option
1172 only needs to be specified for a batch new install.
1176 --data-dir /data/BackupPC
1178 =item B<--dest-dir DEST_DIR>
1180 An optional prefix to apply to all installation directories.
1181 Usually this is not needed, but certain auto-installers like
1182 to stage an install in a temporary directory, and then copy
1183 the files to their real destination. This option can be used
1184 to specify the temporary directory prefix. Note that if you
1185 specify this option, BackupPC won't run correctly if you try
1186 to run it from below the --dest-dir directory, since all the
1187 paths are set assuming BackupPC is installed in the intended
1192 Use locations specified by the Filesystem Hierarchy Standard
1193 for installing BackupPC. This is enabled by default for new
1194 installations. To use the pre-3.0 installation locations,
1199 Print a brief help message and exits.
1201 =item B<--hostname HOSTNAME>
1203 Host name (this machine's name) on which BackupPC is being installed.
1204 This option only needs to be specified for a batch new install.
1206 =item B<--html-dir HTML_DIR>
1208 Path to an Apache html directory where various BackupPC image files
1209 and the CSS files will be installed. This is typically a directory
1210 below Apache's DocumentRoot directory. This option only needs to be
1211 specified for a batch new install.
1215 --html-dir /usr/local/apache/htdocs/BackupPC
1217 =item B<--html-dir-url URL>
1219 The URL (without http://hostname) required to access the BackupPC html
1220 directory specified with the --html-dir option. This option only needs
1221 to be specified for a batch new install.
1225 --html-dir-url /BackupPC
1227 =item B<--install-dir INSTALL_DIR>
1229 Installation directory for BackupPC scripts, libraries, and
1230 documentation. This option only needs to be specified for a
1235 --install-dir /usr/local/BackupPC
1237 =item B<--log-dir LOG_DIR>
1239 Log directory. Defaults to /var/log/BackupPC with FHS.
1243 Prints the manual page and exits.
1245 =item B<--set-perms>
1247 When installing files and creating directories, chown them to
1248 the BackupPC user and chmod them too. This is enabled by default.
1249 To disable (for example, if staging a destination directory)
1250 then specify --no-set-perms.
1252 =item B<--uid-ignore>
1254 configure.pl verifies that the script is being run as the super user
1255 (root). Without the --uid-ignore option, in batch mode the script will
1256 exit with an error if not run as the super user, and in interactive mode
1257 the user will be prompted. Specifying this option will cause the script
1258 to continue even if the user id is not root.
1262 For a standard interactive install, run without arguments:
1266 For a batch new install you need to specify answers to all the
1267 questions that are normally prompted:
1271 --cgi-dir /var/www/cgi-bin/BackupPC \
1272 --data-dir /data/BackupPC \
1274 --html-dir /var/www/html/BackupPC \
1275 --html-dir-url /BackupPC \
1276 --install-dir /usr/local/BackupPC
1278 For a batch upgrade, you only need to specify the path to the
1281 configure.pl --batch --config-path /data/BackupPC/conf/config.pl
1285 Craig Barratt <cbarratt@users.sourceforge.net>
1289 Copyright (C) 2001-2007 Craig Barratt.
1291 This program is free software; you can redistribute it and/or modify
1292 it under the terms of the GNU General Public License as published by
1293 the Free Software Foundation; either version 2 of the License, or
1294 (at your option) any later version.