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);
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 somewher 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);
610 printf("Making init.d scripts\n");
611 foreach my $init ( qw(gentoo-backuppc gentoo-backuppc.conf linux-backuppc
612 solaris-backuppc debian-backuppc suse-backuppc
613 slackware-backuppc ) ) {
614 InstallFile("init.d/src/$init", "init.d/$init", 0444);
617 printf("Installing docs in $DestDir$Conf{InstallDir}/doc\n");
618 foreach my $doc ( qw(BackupPC.pod BackupPC.html) ) {
619 InstallFile("doc/$doc", "$DestDir$Conf{InstallDir}/doc/$doc", 0444);
622 printf("Installing config.pl and hosts in $DestDir$Conf{ConfDir}\n");
623 InstallFile("conf/hosts", "$DestDir$Conf{ConfDir}/hosts", 0644)
624 if ( !-f "$DestDir$Conf{ConfDir}/hosts" );
627 # Now do the config file. If there is an existing config file we
628 # merge in the new config file, adding any new configuration
629 # parameters and deleting ones that are no longer needed.
631 my $dest = "$DestDir$Conf{ConfDir}/config.pl";
632 my ($distConf, $distVars) = ConfigParse("conf/config.pl");
633 my ($oldConf, $oldVars);
634 my ($newConf, $newVars) = ($distConf, $distVars);
636 ($oldConf, $oldVars) = ConfigParse($dest);
637 ($newConf, $newVars) = ConfigMerge($oldConf, $oldVars, $distConf, $distVars);
641 # Update various config parameters. The old config is in Conf{}
642 # and the new config is an array in text form in $newConf->[].
644 $Conf{EMailFromUserName} ||= $Conf{BackupPCUser};
645 $Conf{EMailAdminUserName} ||= $Conf{BackupPCUser};
648 # Guess $Conf{CgiURL}
650 if ( !defined($Conf{CgiURL}) ) {
651 if ( $Conf{CgiDir} =~ m{cgi-bin(/.*)} ) {
652 $Conf{CgiURL} = "'http://$Conf{ServerHost}/cgi-bin$1/BackupPC_Admin'";
654 $Conf{CgiURL} = "'http://$Conf{ServerHost}/cgi-bin/BackupPC_Admin'";
659 # The smbclient commands have moved from hard-coded to the config file.
660 # $Conf{SmbClientArgs} no longer exists, so merge it into the new
661 # commands if it still exists.
663 if ( defined($Conf{SmbClientArgs}) ) {
664 if ( $Conf{SmbClientArgs} ne "" ) {
665 foreach my $param ( qw(SmbClientRestoreCmd SmbClientFullCmd
666 SmbClientIncrCmd) ) {
667 $newConf->[$newVars->{$param}]{text}
668 =~ s/(-E\s+-N)/$1 $Conf{SmbClientArgs}/;
671 delete($Conf{SmbClientArgs});
675 # CSS is now stored in a file rather than a big config variable.
677 delete($Conf{CSSstylesheet});
680 # The blackout timing settings are now stored in a list of hashes, rather
681 # than three scalar parameters.
683 if ( defined($Conf{BlackoutHourBegin}) ) {
684 $Conf{BlackoutPeriods} = [
686 hourBegin => $Conf{BlackoutHourBegin},
687 hourEnd => $Conf{BlackoutHourEnd},
688 weekDays => $Conf{BlackoutWeekDays},
691 delete($Conf{BlackoutHourBegin});
692 delete($Conf{BlackoutHourEnd});
693 delete($Conf{BlackoutWeekDays});
697 # $Conf{RsyncLogLevel} has been replaced by $Conf{XferLogLevel}
699 if ( defined($Conf{RsyncLogLevel}) ) {
700 $Conf{XferLogLevel} = $Conf{RsyncLogLevel};
701 delete($Conf{RsyncLogLevel});
705 # In 2.1.0 the default for $Conf{CgiNavBarAdminAllHosts} is now 1
707 $Conf{CgiNavBarAdminAllHosts} = 1;
710 # IncrFill should now be off
715 # Figure out sensible arguments for the ping command
717 if ( defined($Conf{PingArgs}) ) {
718 $Conf{PingCmd} = '$pingPath ' . $Conf{PingArgs};
719 } elsif ( !defined($Conf{PingCmd}) ) {
720 if ( $^O eq "solaris" || $^O eq "sunos" ) {
721 $Conf{PingCmd} = '$pingPath -s $host 56 1';
722 } elsif ( ($^O eq "linux" || $^O eq "openbsd" || $^O eq "netbsd")
723 && !system("$Conf{PingPath} -c 1 -w 3 localhost") ) {
724 $Conf{PingCmd} = '$pingPath -c 1 -w 3 $host';
726 $Conf{PingCmd} = '$pingPath -c 1 $host';
728 delete($Conf{PingArgs});
732 # Figure out sensible arguments for the df command
734 if ( !defined($Conf{DfCmd}) ) {
735 if ( $^O eq "solaris" || $^O eq "sunos" ) {
736 $Conf{DfCmd} = '$dfPath -k $topDir';
741 # $Conf{SmbClientTimeout} is now $Conf{ClientTimeout}
743 if ( defined($Conf{SmbClientTimeout}) ) {
744 $Conf{ClientTimeout} = $Conf{SmbClientTimeout};
745 delete($Conf{SmbClientTimeout});
749 # Replace --devices with -D in RsyncArgs and RsyncRestoreArgs
751 foreach my $param ( qw(RsyncArgs RsyncRestoreArgs) ) {
752 next if ( !defined($newVars->{$param}) );
753 $newConf->[$newVars->{$param}]{text} =~ s/--devices/-D/g;
757 # Merge any new user-editable parameters into CgiUserConfigEdit
758 # by copying the old settings forward.
760 if ( defined($Conf{CgiUserConfigEdit}) ) {
762 # This is a real hack. The config file merging is done in text
763 # form without actually instantiating the new conf structure.
764 # So we need to extract the new hash of settings, update it,
765 # and merge the text. Ugh...
768 my $str = $distConf->[$distVars->{CgiUserConfigEdit}]{text};
770 $str =~ s/^\s*\$Conf\{.*?\}\s*=\s*/\$new = /m;
772 foreach my $p ( keys(%$new) ) {
773 $new->{$p} = $Conf{CgiUserConfigEdit}{$p}
774 if ( defined($Conf{CgiUserConfigEdit}{$p}) );
776 $Conf{CgiUserConfigEdit} = $new;
777 my $d = Data::Dumper->new([$new], [*value]);
780 my $value = $d->Dump;
781 $value =~ s/(.*)\n/$1;\n/s;
782 $newConf->[$newVars->{CgiUserConfigEdit}]{text}
783 =~ s/(\s*\$Conf\{.*?\}\s*=\s*).*/$1$value/s;
787 # Now backup and write the config file
789 my $confCopy = "$dest.pre-__VERSION__";
790 if ( -f $dest && !-f $confCopy ) {
792 # Make copy of config file, preserving ownership and modes
794 printf("Making backup copy of $dest -> $confCopy\n");
795 my @stat = stat($dest);
799 die("can't copy($dest, $confCopy)\n")
800 unless copy($dest, $confCopy);
801 die("can't chown $uid, $gid $confCopy\n")
802 unless my_chown($uid, $gid, $confCopy);
803 die("can't chmod $mode $confCopy\n")
804 unless my_chmod($mode, $confCopy);
806 open(OUT, ">", $dest) || die("can't open $dest for writing\n");
809 foreach my $var ( @$newConf ) {
810 if ( length($blockComment)
811 && substr($var->{text}, 0, length($blockComment)) eq $blockComment ) {
812 $var->{text} = substr($var->{text}, length($blockComment));
813 $blockComment = undef;
815 $blockComment = $1 if ( $var->{text} =~ /^([\s\n]*#{70}.*#{70}[\s\n]+)/s );
816 $var->{text} =~ s/^\s*\$Conf\{(.*?)\}(\s*=\s*['"]?)(.*?)(['"]?\s*;)/
817 defined($Conf{$1}) && ref($Conf{$1}) eq ""
818 && $Conf{$1} ne $OrigConf{$1}
819 ? "\$Conf{$1}$2$Conf{$1}$4"
820 : "\$Conf{$1}$2$3$4"/emg;
821 print OUT $var->{text};
824 if ( !defined($oldConf) ) {
825 die("can't chmod 0640 mode $dest\n") unless my_chmod(0640, $dest);
826 die("can't chown $Uid, $Gid $dest\n") unless my_chown($Uid, $Gid, $dest);
829 if ( $Conf{CgiDir} ne "" ) {
830 printf("Installing cgi script BackupPC_Admin in $DestDir$Conf{CgiDir}\n");
831 mkpath("$DestDir$Conf{CgiDir}", 0, 0755);
832 InstallFile("cgi-bin/BackupPC_Admin", "$DestDir$Conf{CgiDir}/BackupPC_Admin",
838 Ok, it looks like we are finished. There are several more things you
841 - Browse through the config file, $Conf{ConfDir}/config.pl,
842 and make sure all the settings are correct. In particular,
843 you will need to set \$Conf{CgiAdminUsers} so you have
844 administration privileges in the CGI interface.
846 - Edit the list of hosts to backup in $Conf{ConfDir}/hosts.
848 - Read the documentation in $Conf{InstallDir}/doc/BackupPC.html.
849 Please pay special attention to the security section.
851 - Verify that the CGI script BackupPC_Admin runs correctly. You might
852 need to change the permissions or group ownership of BackupPC_Admin.
853 If this is an upgrade and you are using mod_perl, you will need
854 to restart Apache. Otherwise it will have stale code.
856 - BackupPC should be ready to start. Don't forget to run it
857 as user $Conf{BackupPCUser}! The installation also contains an
858 init.d/backuppc script that can be copied to /etc/init.d
859 so that BackupPC can auto-start on boot. This will also enable
860 administrative users to start the server from the CGI interface.
866 if ( `$Conf{PerlPath} -V` =~ /uselargefiles=undef/ ) {
869 Warning: your perl, $Conf{PerlPath}, does not support large files.
870 This means BackupPC won't be able to backup files larger than 2GB.
871 To solve this problem you should build/install a new version of perl
872 with large file support enabled. Use
874 $Conf{PerlPath} -V | egrep uselargefiles
876 to check if perl has large file support (undef means no support).
880 eval "use File::RsyncP;";
881 if ( !$@ && $File::RsyncP::VERSION < 0.68 ) {
882 print("\nWarning: you need to upgrade File::RsyncP;"
883 . " I found $File::RsyncP::VERSION and BackupPC needs 0.68\n");
888 ###########################################################################
890 ###########################################################################
894 my($prog, $dest, $mode, $binary) = @_;
896 my($uid, $gid) = ($Uid, $Gid);
900 # preserve ownership and modes of files that already exist
902 my @stat = stat($dest);
907 unlink($dest) if ( -f $dest );
909 die("can't copy($prog, $dest)\n") unless copy($prog, $dest);
911 open(PROG, $prog) || die("can't open $prog for reading\n");
912 open(OUT, ">", $dest) || die("can't open $dest for writing\n");
916 s/__INSTALLDIR__/$Conf{InstallDir}/g;
917 s/__LOGDIR__/$Conf{LogDir}/g;
918 s/__CONFDIR__/$Conf{ConfDir}/g;
919 s/__TOPDIR__/$Conf{TopDir}/g;
920 s/^(\s*my \$useFHS\s*=\s*)\d;/${1}$opts{fhs};/
921 if ( $prog =~ /Lib.pm/ );
922 s/__BACKUPPCUSER__/$Conf{BackupPCUser}/g;
923 s/__CGIDIR__/$Conf{CgiDir}/g;
924 if ( $first && /^#.*bin\/perl/ ) {
926 # Fill in correct path to perl (no taint for >= 2.0.1).
928 print OUT "#!$Conf{PerlPath}\n";
937 die("can't chown $uid, $gid $dest") unless my_chown($uid, $gid, $dest);
938 die("can't chmod $mode $dest") unless my_chmod($mode, $dest);
943 my($path, $prog) = @_;
945 if ( defined($opts{"bin-path"}{$prog}) ) {
946 return $opts{"bin-path"}{$prog};
948 foreach my $dir ( split(/:/, $path) ) {
949 my $file = File::Spec->catfile($dir, $prog);
950 return $file if ( -x $file );
958 open(C, $file) || die("can't open $file");
960 my($out, @conf, $var);
965 if ( /^#/ && !defined($endLine) ) {
970 $allVars->{$var} = @conf if ( defined($var) );
980 } elsif ( /^\s*\$Conf\{([^}]*)/ ) {
982 if ( defined($var) ) {
983 $allVars->{$var} = @conf if ( defined($var) );
993 $endLine = $1 if ( /^\s*\$Conf\{[^}]*} *= *<<(.*);/ );
994 $endLine = $1 if ( /^\s*\$Conf\{[^}]*} *= *<<'(.*)';/ );
996 $endLine = undef if ( defined($endLine) && /^\Q$endLine[\n\r]*$/ );
1001 $allVars->{$var} = @conf if ( defined($var) );
1008 return (\@conf, $allVars);
1013 my($old, $oldVars, $new, $newVars) = @_;
1018 # Find which config parameters are not needed any longer
1020 foreach my $var ( @$old ) {
1021 next if ( !defined($var->{var}) || defined($newVars->{$var->{var}}) );
1022 #print(STDERR "Deleting old config parameter $var->{var}\n");
1026 # Find which config parameters are new
1028 foreach my $var ( @$new ) {
1029 next if ( !defined($var->{var}) );
1030 if ( defined($oldVars->{$var->{var}}) ) {
1031 $posn = $oldVars->{$var->{var}};
1033 #print(STDERR "New config parameter $var->{var}: $var->{text}\n");
1034 push(@{$old->[$posn]{new}}, $var);
1038 # Create merged config file
1040 foreach my $var ( @$old ) {
1041 next if ( $var->{delete} );
1043 foreach my $new ( @{$var->{new}} ) {
1047 for ( my $i = 0 ; $i < @$res ; $i++ ) {
1048 $resVars->{$res->[$i]{var}} = $i;
1050 return ($res, $resVars);
1055 my($uid, $gid, $file) = @_;
1057 return 1 if ( !$opts{"set-perms"} );
1058 return chown($uid, $gid, $file);
1063 my ($mode, $file) = @_;
1065 return 1 if ( !$opts{"set-perms"} );
1066 return chmod($mode, $file);
1071 my($question, $default, $option) = @_;
1073 $default = $opts{$option} if ( defined($opts{$option}) );
1074 if ( $opts{batch} ) {
1075 print("$question [$default]\n");
1078 print("$question [$default]? ");
1079 my $reply = <STDIN>;
1080 $reply =~ s/[\n\r]*//g;
1081 return $reply if ( $reply !~ /^$/ );
1089 configure.pl [options]
1093 configure.pl is a script that is used to install or upgrade a BackupPC
1094 installation. It is usually run interactively without arguments. It
1095 also supports a batch mode where all the options can be specified
1096 via the command-line.
1098 For upgrading BackupPC you need to make sure that BackupPC is not
1099 running prior to running BackupPC.
1101 Typically configure.pl needs to run as the super user (root).
1109 Run configure.pl in batch mode. configure.pl will run without
1110 prompting the user. The other command-line options are used
1111 to specify the settings that the user is usually prompted for.
1113 =item B<--backuppc-user=USER>
1115 Specify the BackupPC user name that owns all the BackupPC
1116 files and runs the BackupPC programs. Default is backuppc.
1118 =item B<--bin-path PROG=PATH>
1120 Specify the path for various external programs that BackupPC
1121 uses. Several --bin-path options may be specified. configure.pl
1122 usually finds sensible defaults based on searching the PATH.
1125 --bin-path PROG=PATH
1127 where PROG is one of perl, tar, smbclient, nmblookup, rsync, ping,
1128 df, ssh, sendmail, hostname, split, par2, cat, gzip, bzip2 and
1129 PATH is that full path to that program.
1133 --bin-path cat=/bin/cat --bin-path bzip2=/home/user/bzip2
1135 =item B<--compress-level=N>
1137 Set the configuration compression level to N. Default is 3
1138 if Compress::Zlib is installed.
1140 =item B<--config-dir CONFIG_DIR>
1142 Configuration directory for new installations. Defaults
1143 to /etc/BackupPC with FHS. Automatically extracted
1144 from --config-path for existing installations.
1146 =item B<--config-path CONFIG_PATH>
1148 Path to the existing config.pl configuration file for BackupPC.
1149 This option should be specified for batch upgrades to an
1150 existing installation. The option should be omitted when
1151 doing a batch new install.
1153 =item B<--cgi-dir CGI_DIR>
1155 Path to Apache's cgi-bin directory where the BackupPC_Admin
1156 script will be installed. This option only needs to be
1157 specified for a batch new install.
1159 =item B<--data-dir DATA_DIR>
1161 Path to the BackupPC data directory. This is where all the backup
1162 data is stored, and it should be on a large file system. This option
1163 only needs to be specified for a batch new install.
1167 --data-dir /data/BackupPC
1169 =item B<--dest-dir DEST_DIR>
1171 An optional prefix to apply to all installation directories.
1172 Usually this is not needed, but certain auto-installers like
1173 to stage an install in a temporary directory, and then copy
1174 the files to their real destination. This option can be used
1175 to specify the temporary directory prefix. Note that if you
1176 specify this option, BackupPC won't run correctly if you try
1177 to run it from below the --dest-dir directory, since all the
1178 paths are set assuming BackupPC is installed in the intended
1183 Use locations specified by the Filesystem Hierarchy Standard
1184 for installing BackupPC. This is enabled by default for new
1185 installations. To use the pre-3.0 installation locations,
1190 Print a brief help message and exits.
1192 =item B<--hostname HOSTNAME>
1194 Host name (this machine's name) on which BackupPC is being installed.
1195 This option only needs to be specified for a batch new install.
1197 =item B<--html-dir HTML_DIR>
1199 Path to an Apache html directory where various BackupPC image files
1200 and the CSS files will be installed. This is typically a directory
1201 below Apache's DocumentRoot directory. This option only needs to be
1202 specified for a batch new install.
1206 --html-dir /usr/local/apache/htdocs/BackupPC
1208 =item B<--html-dir-url URL>
1210 The URL (without http://hostname) required to access the BackupPC html
1211 directory specified with the --html-dir option. This option only needs
1212 to be specified for a batch new install.
1216 --html-dir-url /BackupPC
1218 =item B<--install-dir INSTALL_DIR>
1220 Installation directory for BackupPC scripts, libraries, and
1221 documentation. This option only needs to be specified for a
1226 --install-dir /usr/local/BackupPC
1228 =item B<--log-dir LOG_DIR>
1230 Log directory. Defaults to /var/log/BackupPC with FHS.
1234 Prints the manual page and exits.
1236 =item B<--set-perms>
1238 When installing files and creating directories, chown them to
1239 the BackupPC user and chmod them too. This is enabled by default.
1240 To disable (for example, if staging a destination directory)
1241 then specify --no-set-perms.
1243 =item B<--uid-ignore>
1245 configure.pl verifies that the script is being run as the super user
1246 (root). Without the --uid-ignore option, in batch mode the script will
1247 exit with an error if not run as the super user, and in interactive mode
1248 the user will be prompted. Specifying this option will cause the script
1249 to continue even if the user id is not root.
1253 For a standard interactive install, run without arguments:
1257 For a batch new install you need to specify answers to all the
1258 questions that are normally prompted:
1262 --cgi-dir /var/www/cgi-bin/BackupPC \
1263 --data-dir /data/BackupPC \
1265 --html-dir /var/www/html/BackupPC \
1266 --html-dir-url /BackupPC \
1267 --install-dir /usr/local/BackupPC
1269 For a batch upgrade, you only need to specify the path to the
1272 configure.pl --batch --config-path /data/BackupPC/conf/config.pl
1276 Craig Barratt <cbarratt@users.sourceforge.net>
1280 Copyright (C) 2001-2006 Craig Barratt.
1282 This program is free software; you can redistribute it and/or modify
1283 it under the terms of the GNU General Public License as published by
1284 the Free Software Foundation; either version 2 of the License, or
1285 (at your option) any later version.