set.
- added support for spaces in client names (ugh)
- non dhcp hosts are now looked up using nmblookup, if not known by NS
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
# Write out our initial status and save our PID
#
StatusWrite();
- if ( open(PID, ">$TopDir/log/BackupPC.pid") ) {
+ if ( open(PID, ">", "$TopDir/log/BackupPC.pid") ) {
print(PID $$);
close(PID);
}
host => $bpc->trashJob,
user => "BackupPC",
reqTime => time,
- cmd => "$BinDir/BackupPC_trashClean"
+ cmd => ["$BinDir/BackupPC_trashClean"],
});
$CmdQueueOn{$bpc->trashJob} = 1;
}
host => $bpc->adminJob,
user => "BackupPC",
reqTime => time,
- cmd => "$BinDir/BackupPC_nightly"
+ cmd => ["$BinDir/BackupPC_nightly"],
});
$CmdQueueOn{$bpc->adminJob} = 1;
$RunNightlyWhenIdle = 2;
}
if ( !$pid ) {
setpgrp 0,0;
- exec($cmd);
- print(LOG $bpc->timeStamp, "can't exec $cmd for $host\n");
+ exec(@$cmd);
+ print(LOG $bpc->timeStamp, "can't exec @$cmd for $host\n");
exit(0);
}
$Jobs{$host}{pid} = $pid;
vec($FDread, $Jobs{$host}{fn}, 1) = 1;
$Jobs{$host}{startTime} = time;
$Jobs{$host}{reqTime} = $req->{reqTime};
+ $cmd = join(" ", @$cmd);
$Jobs{$host}{cmd} = $cmd;
$Jobs{$host}{type} = $Status{$host}{type};
$Status{$host}{state} = "Status_link_running";
vec($FDread, $Jobs{$host}{fn}, 1) = 1;
$Jobs{$host}{startTime} = time;
$Jobs{$host}{reqTime} = $req->{reqTime};
- $Jobs{$host}{cmd} = "$progName " . join(" ", @args);
+ $Jobs{$host}{cmd} = join(" ", $progName, @args);
$Jobs{$host}{user} = $user;
$Jobs{$host}{type} = $type;
if ( !$req->{dhcp} ) {
$Jobs{$host}{mesg} = $2;
if ( $Jobs{$host}{dhcp} ) {
if ( $mesg =~ /^DHCP (\S+) (\S+)/ ) {
- my $newHost = $2;
+ my $newHost = $bpc->uriUnesc($2);
if ( defined($Jobs{$newHost}) ) {
print(LOG $bpc->timeStamp,
"Backup on $newHost is already running\n");
$host = $1;
my $user = $2;
my $backoff = $3;
+ $host = $bpc->uriUnesc($host);
if ( $CmdJob ne $host && defined($Status{$host})
&& defined($Jobs{$host}) ) {
print(LOG $bpc->timeStamp,
QueueAllPCs();
} elsif ( $cmd =~ /^backup (\S+)\s+(\S+)\s+(\S+)\s+(\S+)/ ) {
my $hostIP = $1;
- $host = $2;
- my $user = $3;
+ $host = $2;
+ my $user = $3;
my $doFull = $4;
+ $host = $bpc->uriUnesc($host);
+ $hostIP = $bpc->uriUnesc($hostIP);
if ( !defined($Status{$host}) ) {
print(LOG $bpc->timeStamp,
"User $user requested backup of unknown host"
$host = $2;
my $user = $3;
my $reqFileName = $4;
+ $host = $bpc->uriUnesc($host);
+ $hostIP = $bpc->uriUnesc($hostIP);
if ( !defined($Status{$host}) ) {
print(LOG $bpc->timeStamp,
"User $user requested restore to unknown host"
} elsif ( $type =~ /^hosts/ ) {
push(@values, \%Status);
push(@names, qw(*Status));
- } elsif ( $type =~ /^host\((.*)\)/
- && defined($Status{$1}) ) {
- push(@values, {
- %{$Status{$1}},
- BgQueueOn => $BgQueueOn{$1},
- UserQueueOn => $UserQueueOn{$1},
- CmdQueueOn => $CmdQueueOn{$1},
- });
- push(@names, qw(*StatusHost));
+ } elsif ( $type =~ /^host\((.*)\)/ ) {
+ my $h = $bpc->uriUnesc($1);
+ if ( defined($Status{$h}) ) {
+ push(@values, {
+ %{$Status{$h}},
+ BgQueueOn => $BgQueueOn{$h},
+ UserQueueOn => $UserQueueOn{$h},
+ CmdQueueOn => $CmdQueueOn{$h},
+ });
+ push(@names, qw(*StatusHost));
+ } else {
+ print(LOG $bpc->timeStamp,
+ "Unknown host $h for status request\n");
+ }
} else {
print(LOG $bpc->timeStamp,
"Unknown status request $type\n");
$reply = $dump->Dump;
} elsif ( $cmd =~ /^link\s+(.+)/ ) {
my($host) = $1;
+ $host = $bpc->uriUnesc($host);
QueueLink($host);
} elsif ( $cmd =~ /^log\s+(.*)/ ) {
print(LOG $bpc->timeStamp, "$1\n");
[ \%Info, \%Status],
[qw(*Info *Status)]);
$dump->Indent(1);
- if ( open(STATUS, ">$TopDir/log/status.pl") ) {
+ if ( open(STATUS, ">", "$TopDir/log/status.pl") ) {
print(STATUS $dump->Dump);
close(STATUS);
}
host => $host,
user => "BackupPC",
reqTime => time,
- cmd => "$BinDir/BackupPC_link $host"
+ cmd => ["$BinDir/BackupPC_link", $host],
});
$CmdQueueOn{$host} = 1;
}
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
-Bufsize => 65536,
-Level => $Compress,
);
- if ( !open(FH, $TestMode ? "<$file" : "+<$file") ) {
+ if ( !open(FH, $TestMode ? "<" : "+<", $file) ) {
print("Error: Can't open $file for read/write\n");
$Errors++;
return;
}
$dataOut .= $fragOut;
if ( !$copy && length($dataOut) > $CompMaxWrite ) {
- if ( !open(OUT, "+>$file.__z") ) {
+ if ( !open(OUT, "+>", "$file.__z") ) {
print("Error: Can't open $file.__z for write\n");
$Errors++;
close(FH);
my $newFile = cpoolFileName($file);
if ( $TestMode ) {
close(FH);
- if ( !open(FH, ">$newFile") ) {
+ if ( !open(FH, ">", $newFile) ) {
print("Error: Can't open $newFile for write\n");
$Errors++;
close(FH);
my($n, $nd, $r, $d, $d0);
local(*FH);
- if ( !open(FH, $file) ) {
+ if ( !open(FH, "<", $file) ) {
print("can't open $file for check\n");
$Errors++;
$f->close();
my($n, $nd, $r, $d, $d0);
local(*FH);
- if ( !open(FH, $file) ) {
+ if ( !open(FH, "<", $file) ) {
print("can't open $file for check\n");
$Errors++;
$f->close();
#!/bin/perl -T
#============================================================= -*-perl-*-
#
-# BackupPC_dump: Dump a single PC.
+# BackupPC_dump: Dump a single client.
#
# DESCRIPTION
#
-# Usage: BackupPC_dump [-i] [-f] [-d] [-e] <host>
+# Usage: BackupPC_dump [-i] [-f] [-d] [-e] <client>
#
# Flags:
#
#
# -f Do a full dump, overriding any scheduling.
#
-# -d Host is a DHCP pool address, so initially we have no
-# idea which machine this actually is. BackupPC_dump
-# determines the actual PC host name by using the NetBios
-# name.
+# -d Host is a DHCP pool address, and the client argument
+# just an IP address. We lookup the NetBios name from
+# the IP address.
#
-# -e Just do an dump expiry check for the host. Don't do anything else. # This is used periodically by BackupPC to make sure that dhcp hosts
-# have correctly expired old backups. Without this, dhcp hosts that
-# are no longer on the network will not expire old backups.
+# -e Just do an dump expiry check for the client. Don't do anything
+# else. This is used periodically by BackupPC to make sure that
+# dhcp hosts have correctly expired old backups. Without this,
+# dhcp hosts that are no longer on the network will not expire
+# old backups.
#
-# BackupPC_dump is run periodically by BackupPC to backup $host.
-# The file $TopDir/pc/$host/backups is read to decide whether a
+# BackupPC_dump is run periodically by BackupPC to backup $client.
+# The file $TopDir/pc/$client/backups is read to decide whether a
# full or incremental backup needs to be run. If no backup is
-# scheduled, or a ping to $host fails, then BackupPC_dump quits.
+# scheduled, or a ping to $client fails, then BackupPC_dump quits.
#
# The backup is done using the selected XferMethod (smb, tar, rsync etc),
-# extracting the dump into $TopDir/pc/$host/new. The xfer output is
-# put into $TopDir/pc/$host/XferLOG.
+# extracting the dump into $TopDir/pc/$client/new. The xfer output is
+# put into $TopDir/pc/$client/XferLOG.
#
# If the dump succeeds (based on parsing the output of the XferMethod):
-# - $TopDir/pc/$host/new is renamed to $TopDir/pc/$host/nnn, where
+# - $TopDir/pc/$client/new is renamed to $TopDir/pc/$client/nnn, where
# nnn is the next sequential dump number.
-# - $TopDir/pc/$host/XferLOG is renamed to $TopDir/pc/$host/XferLOG.nnn.
-# - $TopDir/pc/$host/backups is updated.
+# - $TopDir/pc/$client/XferLOG is renamed to $TopDir/pc/$client/XferLOG.nnn.
+# - $TopDir/pc/$client/backups is updated.
#
# If the dump fails:
-# - $TopDir/pc/$host/new is moved to $TopDir/trash for later removal.
-# - $TopDir/pc/$host/XferLOG is renamed to $TopDir/pc/$host/XferLOG.bad
+# - $TopDir/pc/$client/new is moved to $TopDir/trash for later removal.
+# - $TopDir/pc/$client/XferLOG is renamed to $TopDir/pc/$client/XferLOG.bad
# for later viewing.
#
# BackupPC_dump communicates to BackupPC via printing to STDOUT.
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
my %opts;
getopts("defi", \%opts);
if ( @ARGV != 1 ) {
- print("usage: $0 [-d] [-e] [-f] [-i] <host>\n");
+ print("usage: $0 [-d] [-e] [-f] [-i] <client>\n");
exit(1);
}
-if ( $ARGV[0] !~ /^([\w\.-]+)$/ ) {
- print("$0: bad host name '$ARGV[0]'\n");
+if ( $ARGV[0] !~ /^([\w\.-\s]+)$/ ) {
+ print("$0: bad client name '$ARGV[0]'\n");
exit(1);
}
-my $hostIP = $1;
-my($host, $user);
+my $client = $1; # BackupPC's client name (might not be real host name)
+my $hostIP; # this is the IP address
+my $host; # this is the real host name
+
+my($clientURI, $user);
if ( $opts{d} ) {
#
- # The host name $hostIP is simply a DHCP address. We need to check
+ # The client name $client is simply a DHCP address. We need to check
# if there is any machine at this address, and if so, get the actual
# host name via NetBios using nmblookup.
#
+ $hostIP = $client;
exit(1) if ( $bpc->CheckHostAlive($hostIP) < 0 );
- ($host, $user) = $bpc->NetBiosInfoGet($hostIP);
+ ($client, $user) = $bpc->NetBiosInfoGet($hostIP);
exit(1) if ( $host !~ /^([\w\.-]+)$/ );
- my $hosts = $bpc->HostInfoRead($host);
- exit(1) if ( !defined($hosts->{$host}) );
-} else {
- $host = $hostIP;
+ my $hosts = $bpc->HostInfoRead($client);
+ exit(1) if ( !defined($hosts->{$client}) );
+ $host = $client;
}
-my $Dir = "$TopDir/pc/$host";
+my $Dir = "$TopDir/pc/$client";
my $xferPid = -1;
my $tarPid = -1;
#
# Re-read config file, so we can include the PC-specific config
#
-if ( defined(my $error = $bpc->ConfigRead($host)) ) {
- print("Can't read PC's config file: $error\n");
+$clientURI = $bpc->uriEsc($client);
+if ( defined(my $error = $bpc->ConfigRead($client)) ) {
+ print("dump failed: Can't read PC's config file: $error\n");
exit(1);
}
%Conf = $bpc->Conf();
mkpath($Dir, 0, 0777) if ( !-d $Dir );
if ( !-f "$Dir/LOCK" ) {
- open(LOCK, ">$Dir/LOCK") && close(LOCK);
+ open(LOCK, ">", "$Dir/LOCK") && close(LOCK);
}
-open(LOG, ">>$Dir/LOG");
+open(LOG, ">>", "$Dir/LOG");
select(LOG); $| = 1; select(STDOUT);
+if ( !$opts{d} ) {
+ #
+ # In the non-DHCP case, make sure the host can be looked up
+ # via NS, or otherwise find the IP address via NetBios.
+ #
+ if ( $Conf{ClientNameAlias} ne "" ) {
+ $host = $Conf{ClientNameAlias};
+ } else {
+ $host = $client;
+ }
+ if ( !defined(gethostbyname($host)) ) {
+ #
+ # Ok, NS doesn't know about it. Maybe it is a NetBios name
+ # instead.
+ #
+ if ( !defined($hostIP = $bpc->NetBiosHostIPFind($host)) ) {
+ print(LOG $bpc->timeStamp,
+ "dump failed: Can't find host $host\n");
+ print("dump failed: Can't find host $host\n");
+ exit(1);
+ }
+ } else {
+ $hostIP = $host;
+ }
+}
+
###########################################################################
# Figure out what to do and do it
###########################################################################
# For the -e option we just expire backups and quit
#
if ( $opts{e} ) {
- BackupExpire($host);
+ BackupExpire($client);
exit(0);
}
print(LOG $bpc->timeStamp, "Can't connect to server ($err)\n");
exit(1);
}
-my $reply = $bpc->ServerMesg("status host($host)");
+my $reply = $bpc->ServerMesg("status host($clientURI)");
$reply = $1 if ( $reply =~ /(.*)/s );
my(%StatusHost);
eval($reply);
# oops, something is already running for this host
exit(0);
}
- print("DHCP $hostIP $host\n");
+ print("DHCP $hostIP $clientURI\n");
}
my($needLink, @Backups, $type, $lastBkupNum, $lastFullBkupNum);
#
# Now see if there are any old backups we should delete
#
-BackupExpire($host);
+BackupExpire($client);
#
# Read Backup information, and find times of the most recent full and
# incremental backups
#
-@Backups = $bpc->BackupInfoRead($host);
+@Backups = $bpc->BackupInfoRead($client);
for ( my $i = 0 ; $i < @Backups ; $i++ ) {
$needLink = 1 if ( $Backups[$i]{nFilesNew} eq ""
|| -f "$Dir/NewFileList.$Backups[$i]{num}" );
if ( $delay < 0 ) {
print(LOG $bpc->timeStamp, "no ping response\n");
print("no ping response\n");
- print("link $host\n") if ( $needLink );
+ print("link $clientURI\n") if ( $needLink );
exit(1);
} elsif ( $delay > $Conf{PingMaxMsec} ) {
printf(LOG "%sping too slow: %.4gmsec\n", $bpc->timeStamp, $delay);
printf("ping too slow: %.4gmsec (threshold is %gmsec)\n",
$delay, $Conf{PingMaxMsec});
- print("link $host\n") if ( $needLink );
+ print("link $clientURI\n") if ( $needLink );
exit(1);
}
open(STDERR, ">&STDOUT");
close(STDIN);
open(STDIN, "<&RH");
- exec("$BinDir/BackupPC_tarExtract '$host' '$shareName'"
- . " $Conf{CompressLevel}");
+ exec("$BinDir/BackupPC_tarExtract", $client, $shareName,
+ $Conf{CompressLevel});
print(LOG $bpc->timeStamp,
"can't exec $BinDir/BackupPC_tarExtract\n");
exit(0);
# We need to create the NewFileList output file
#
local(*NEW_FILES);
- open(NEW_FILES, ">$TopDir/pc/$host/NewFileList")
- || die("can't open $TopDir/pc/$host/NewFileList");
+ open(NEW_FILES, ">", "$TopDir/pc/$client/NewFileList")
+ || die("can't open $TopDir/pc/$client/NewFileList");
$newFilesFH = *NEW_FILES;
}
#
$xfer->args({
host => $host,
+ client => $client,
hostIP => $hostIP,
shareName => $shareName,
pipeRH => *RH,
if ( !defined($logMsg = $xfer->start()) ) {
print(LOG $bpc->timeStamp, "xfer start failed: ", $xfer->errStr, "\n");
print("dump failed: ", $xfer->errStr, "\n");
- print("link $host\n") if ( $needLink );
+ print("link $clientURI\n") if ( $needLink );
#
# kill off the tar process, first nicely then forcefully
#
$tarOut = $2;
$XferLOG->write(\"tarExtract: $_\n");
if ( /^Done: (\d+) errors, (\d+) filesExist, (\d+) sizeExist, (\d+) sizeExistComp, (\d+) filesTotal, (\d+) sizeTotal/ ) {
- $tarErrs = $1;
- $nFilesExist = $2;
- $sizeExist = $3;
- $sizeExistComp = $4;
- $nFilesTotal = $5;
- $sizeTotal = $6;
+ $tarErrs += $1;
+ $nFilesExist += $2;
+ $sizeExist += $3;
+ $sizeExistComp += $4;
+ $nFilesTotal += $5;
+ $sizeTotal += $6;
}
}
}
#
# otherwise the xfer module does everything for us
#
- ($tarErrs, $nFilesExist, $sizeExist, $sizeExistComp,
- $nFilesTotal, $sizeTotal) = $xfer->run();
+ my @results = $xfer->run();
+ $tarErrs += $results[0];
+ $nFilesExist += $results[1];
+ $sizeExist += $results[2];
+ $sizeExistComp += $results[3];
+ $nFilesTotal += $results[4];
+ $sizeTotal += $results[5];
}
#
close($newFilesFH) if ( defined($newFilesFH) );
if ( $stat{xferOK} ) {
- @Backups = $bpc->BackupInfoRead($host);
+ @Backups = $bpc->BackupInfoRead($client);
for ( my $i = 0 ; $i < @Backups ; $i++ ) {
$lastNum = $Backups[$i]{num} if ( $lastNum < $Backups[$i]{num} );
}
rename("$Dir/XferLOG$fileExt", "$Dir/XferLOG.bad$fileExt");
$bpc->RmTreeDefer("$TopDir/trash", "$Dir/new") if ( -d "$Dir/new" );
print("dump failed: $stat{hostError}\n");
- print("link $host\n") if ( $needLink );
+ print("link $clientURI\n") if ( $needLink );
exit(1);
}
#
# Add the new backup information to the backup file
#
-@Backups = $bpc->BackupInfoRead($host);
+@Backups = $bpc->BackupInfoRead($client);
my $i = @Backups;
$Backups[$i]{num} = $lastNum;
$Backups[$i]{type} = $type;
$Backups[$i]{compress} = $Conf{CompressLevel};
$Backups[$i]{noFill} = $type eq "full" ? 0 : 1;
$Backups[$i]{mangle} = 1; # name mangling always on for v1.04+
-$bpc->BackupInfoWrite($host, @Backups);
+$bpc->BackupInfoWrite($client, @Backups);
unlink("$Dir/timeStamp.level0");
. " $stat{xferErrCnt} xferErrs ($stat{xferBadFileCnt} bad files,"
. " $stat{xferBadShareCnt} bad shares, $otherCount other)\n");
-BackupExpire($host);
+BackupExpire($client);
print("$type backup complete\n");
my($needLink) = @_;
print("nothing to do\n");
- print("link $host\n") if ( $needLink );
+ print("link $clientURI\n") if ( $needLink );
exit(0);
}
} else {
print("dump failed: received signal=$signame\n");
}
- print("link $host\n") if ( $needLink );
+ print("link $clientURI\n") if ( $needLink );
exit(1);
}
#
sub BackupExpire
{
- my($host) = @_;
- my($Dir) = "$TopDir/pc/$host";
- my(@Backups) = $bpc->BackupInfoRead($host);
+ my($client) = @_;
+ my($Dir) = "$TopDir/pc/$client";
+ my(@Backups) = $bpc->BackupInfoRead($client);
my($cntFull, $cntIncr, $firstFull, $firstIncr, $oldestIncr, $oldestFull);
while ( 1 ) {
last;
}
}
- $bpc->BackupInfoWrite($host, @Backups);
+ $bpc->BackupInfoWrite($client, @Backups);
}
sub CorrectHostCheck
return if ( !defined($Conf{$type}) );
my $vars = {
xfer => $xfer,
+ client => $client,
host => $host,
hostIP => $hostIP,
share => $ShareNames->[0],
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
print("usage: $0 <host>\n");
exit(1);
}
-if ( $ARGV[0] !~ /^([\w\.-]+)$/ ) {
+if ( $ARGV[0] !~ /^([\w\.-\s]+)$/ ) {
print("$0: bad host name '$ARGV[0]'\n");
exit(1);
}
#
$CurrDumpDir = "$Dir/$Backups[$num]{num}";
$Compress = $Backups[$num]{compress};
- if ( open(NEW, "$Dir/NewFileList.$Backups[$num]{num}") ) {
+ if ( open(NEW, "<", "$Dir/NewFileList.$Backups[$num]{num}") ) {
while ( <NEW> ) {
chomp;
next if ( !/(\w+) (\d+) (.*)/ );
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
"$TopDir/pc/$host/LOG.0.z",
"$TopDir/pc/$host/LOG.0",
$Conf{CompressLevel}, 1);
- open(LOG, ">$TopDir/pc/$host/LOG") && close(LOG);
+ open(LOG, ">", "$TopDir/pc/$host/LOG") && close(LOG);
}
}
#
# DESCRIPTION
#
-# Usage: BackupPC_restore <hostIP> <host> <reqFileName>
+# Usage: BackupPC_restore <hostIP> <client> <reqFileName>
#
# AUTHOR
# Craig Barratt <cbarratt@users.sourceforge.net>
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
my %Conf = $bpc->Conf();
my $NeedPostCmd;
-my($hostIP, $host, $reqFileName);
+my($hostIP, $host, $client, $reqFileName, %stat);
$bpc->ChildInit();
if ( @ARGV != 3 ) {
- print("usage: $0 <hostIP> <host> <reqFileName>\n");
+ print("usage: $0 <hostIP> <client> <reqFileName>\n");
exit(1);
}
$hostIP = $1 if ( $ARGV[0] =~ /(.+)/ );
-$host = $1 if ( $ARGV[1] =~ /(.+)/ );
+$client = $1 if ( $ARGV[1] =~ /(.+)/ );
if ( $ARGV[2] !~ /^([\w.]+)$/ ) {
print("$0: bad reqFileName (arg #3): $ARGV[2]\n");
exit(1);
}
$reqFileName = $1;
-my $Hosts = $bpc->HostInfoRead();
+my $startTime = time();
-#
-# Re-read config file, so we can include the PC-specific config
-#
-if ( defined(my $error = $bpc->ConfigRead($host)) ) {
- print("Can't read PC's config file: $error\n");
- exit(1);
-}
-%Conf = $bpc->Conf();
+my $Hosts = $bpc->HostInfoRead();
-my $Dir = "$TopDir/pc/$host";
+my $Dir = "$TopDir/pc/$client";
my $xferPid = -1;
my $tarPid = -1;
$SIG{ALRM} = \&catch_signal;
$SIG{TERM} = \&catch_signal;
+mkpath($Dir, 0, 0777) if ( !-d $Dir );
+if ( !-f "$Dir/LOCK" ) {
+ open(LOCK, ">", "$Dir/LOCK") && close(LOCK);
+}
+open(LOG, ">>", "$Dir/LOG");
+select(LOG); $| = 1; select(STDOUT);
+
#
# Read the request file
#
if ( !(my $ret = do "$Dir/$reqFileName") ) {
- die "couldn't parse $Dir/$reqFileName: $@" if $@;
- die "couldn't do $Dir/$reqFileName: $!" unless defined $ret;
- die "couldn't run $Dir/$reqFileName";
+ my $err;
+ if ( $@ ) {
+ $err = "couldn't parse $Dir/$reqFileName: $@";
+ } elsif ( !defined($ret) ) {
+ $err = "couldn't do $Dir/$reqFileName: $!";
+ } else {
+ $err = "couldn't run $Dir/$reqFileName";
+ }
+ $stat{hostError} = $err;
+ exit(RestoreCleanup($client));
}
+#
+# Re-read config file, so we can include the PC-specific config
+#
+if ( defined(my $error = $bpc->ConfigRead($client)) ) {
+ $stat{hostError} = "Can't read PC's config file: $error";
+ exit(RestoreCleanup($client));
+}
+%Conf = $bpc->Conf();
+
#
# Make sure we eventually timeout if there is no activity from
# the data transport program.
#
alarm($Conf{ClientTimeout});
-mkpath($Dir, 0, 0777) if ( !-d $Dir );
-if ( !-f "$Dir/LOCK" ) {
- open(LOCK, ">$Dir/LOCK") && close(LOCK);
+#
+# See if the host name is aliased
+#
+if ( $Conf{ClientNameAlias} ne "" ) {
+ $host = $Conf{ClientNameAlias};
+} else {
+ $host = $client;
+}
+
+#
+# Find its IP address
+#
+if ( $hostIP !~ /\d+\.\d+\.\d+\.\d+/ ) {
+ if ( !defined(gethostbyname($host)) ) {
+ #
+ # Ok, NS doesn't know about it. Maybe it is a NetBios name
+ # instead.
+ #
+ if ( !defined($hostIP = $bpc->NetBiosHostIPFind($host)) ) {
+ $stat{hostError} = "Can't find host $host";
+ exit(RestoreCleanup($client));
+ }
+ } else {
+ $hostIP = $host;
+ }
}
-open(LOG, ">>$Dir/LOG");
-select(LOG); $| = 1; select(STDOUT);
#
# Check if $host is alive
#
my $delay = $bpc->CheckHostAlive($hostIP);
if ( $delay < 0 ) {
- print(LOG $bpc->timeStamp, "no ping response\n");
- print("no ping response\n");
- exit(1);
+ $stat{hostError} = "no ping response from $host ($hostIP)";
+ exit(RestoreCleanup($client));
} elsif ( $delay > $Conf{PingMaxMsec} ) {
- printf(LOG "%sping too slow: %.4gmsec\n", $bpc->timeStamp, $delay);
- printf("ping too slow: %.4gmsec (threshold is %gmsec)\n",
+ $stat{hostError} = sprintf("ping too slow: %.4gmsec (max is %gmsec)\n",
$delay, $Conf{PingMaxMsec});
- exit(1);
+ exit(RestoreCleanup($client));
}
#
# Make sure it is really the machine we expect
#
if ( (my $errMsg = CorrectHostCheck($hostIP, $host)) ) {
- print(LOG $bpc->timeStamp, "restore failed: $errMsg\n");
- print("restore failed: $errMsg\n");
- exit(1);
+ $stat{hostError} = $errMsg;
+ exit(RestoreCleanup($client));
}
#
my $fileExt = $Conf{CompressLevel} > 0 ? ".z" : "";
my $RestoreLOG = BackupPC::FileZIO->open("$Dir/RestoreLOG$fileExt", 1,
$Conf{CompressLevel});
-my $startTime = time();
-
my $tarCreateFileCnt = 0;
my $tarCreateByteCnt = 0;
my $tarCreateErrCnt = 1; # assume not ok until we learn otherwise
my $tarCreateErr;
-my($logMsg, %stat, $xfer);
+my($logMsg, $xfer);
$stat{xferOK} = $stat{hostAbort} = undef;
$stat{hostError} = $stat{lastOutputLine} = undef;
#
if ( !defined($xfer = BackupPC::Xfer::Rsync->new($bpc)) ) {
my $errStr = BackupPC::Xfer::Rsync->errStr;
- print(LOG $bpc->timeStamp, "restore failed: $errStr\n");
- print("restore failed: $errStr\n");
UserCommandRun("RestorePostUserCmd") if ( $NeedPostCmd );
- exit(1);
+ $stat{hostError} = $errStr;
+ exit(RestoreCleanup($client));
}
} else {
#
#
my @Backups = $bpc->BackupInfoRead($RestoreReq{hostSrc});
my $xferArgs = {
+ client => $client,
host => $host,
hostIP => $hostIP,
type => "restore",
$xfer->args($xferArgs);
if ( !defined($logMsg = $xfer->start()) ) {
- print(LOG $bpc->timeStamp, "xfer start failed: ", $xfer->errStr, "\n");
- print($xfer->errStr, "\n");
UserCommandRun("RestorePostUserCmd") if ( $NeedPostCmd );
- exit(1);
+ $stat{hostError} = "xfer start failed: ", $xfer->errStr;
+ exit(RestoreCleanup($client));
}
if ( $useTar ) {
@tarPathOpts,
@{$RestoreReq{fileList}},
);
- my $logMsg = "Running: $BinDir/BackupPC_tarCreate "
- . join(" ", @tarArgs) . "\n";
+ my $logMsg = "Running: "
+ . $bpc->execCmd2ShellCmd("$BinDir/BackupPC_tarCreate", @tarArgs)
+ . "\n";
$RestoreLOG->write(\$logMsg);
if ( !defined($tarPid = open(TAR, "-|")) ) {
- print(LOG $bpc->timeStamp, "can't fork to run tar\n");
- print("can't fork to run tar\n");
close(WH);
# FIX: need to cleanup xfer
UserCommandRun("RestorePostUserCmd") if ( $NeedPostCmd );
- exit(0);
+ $stat{hostError} = "Can't fork to run tar";
+ exit(RestoreCleanup($client));
}
if ( !$tarPid ) {
#
}
}
-$stat{xferOK} = 0 if ( $stat{hostError} || $stat{hostAbort} || $tarCreateErr );
-
-if ( !$stat{xferOK} ) {
- #
- # kill off the tranfer program, first nicely then forcefully
- #
- kill(2, $xferPid) if ( $xferPid > 0 );
- sleep(1);
- kill(9, $xferPid) if ( $xferPid > 0 );
- #
- # kill off the tar process, first nicely then forcefully
- #
- kill(2, $tarPid) if ( $tarPid > 0 );
- sleep(1);
- kill(9, $tarPid) if ( $tarPid > 0 );
-}
-
-my $lastNum = -1;
-my @Restores;
-
-#
-# Do one last check to make sure it is still the machine we expect.
-#
-if ( $stat{xferOK} && (my $errMsg = CorrectHostCheck($hostIP, $host)) ) {
- $stat{hostError} = $errMsg;
- $stat{xferOK} = 0;
-}
-@Restores = $bpc->RestoreInfoRead($host);
-for ( my $i = 0 ; $i < @Restores ; $i++ ) {
- $lastNum = $Restores[$i]{num} if ( $lastNum < $Restores[$i]{num} );
-}
-$lastNum++;
-
-#
-# Run an optional post-restore command
-#
-UserCommandRun("RestorePostUserCmd") if ( $NeedPostCmd );
-
-$RestoreLOG->close();
-rename("$Dir/RestoreLOG$fileExt", "$Dir/RestoreLOG.$lastNum$fileExt");
-rename("$Dir/$reqFileName", "$Dir/RestoreInfo.$lastNum");
-my $endTime = time();
-
-#
-# If the restore failed, clean up
-#
-if ( !$stat{xferOK} ) {
- #
- # wait a short while and see if the system is still alive
- #
- $stat{hostError} ||= $tarCreateErr if ( $tarCreateErr ne "" );
- $stat{hostError} = $stat{lastOutputLine} if ( $stat{hostError} eq "" );
- if ( $stat{hostError} ) {
- print(LOG $bpc->timeStamp,
- "Got fatal error during xfer ($stat{hostError})\n");
- }
- sleep(2);
- if ( $bpc->CheckHostAlive($hostIP) < 0 ) {
- $stat{hostAbort} = 1;
- }
- if ( $stat{hostAbort} ) {
- $stat{hostError} = "lost network connection during restore";
- }
-}
-
-#
-# Add the new restore information to the restore file
-#
-@Restores = $bpc->RestoreInfoRead($host);
-my $i = @Restores;
-$Restores[$i]{num} = $lastNum;
-$Restores[$i]{startTime} = $startTime;
-$Restores[$i]{endTime} = $endTime;
-$Restores[$i]{result} = $stat{xferOK} ? "ok" : "failed";
-$Restores[$i]{errorMsg} = $stat{hostError};
-$Restores[$i]{nFiles} = $tarCreateFileCnt;
-$Restores[$i]{size} = $tarCreateByteCnt;
-$Restores[$i]{tarCreateErrs} = $tarCreateErrCnt;
-$Restores[$i]{xferErrs} = $stat{xferErrCnt} || 0;
-
-while ( @Restores > $Conf{RestoreInfoKeepCnt} ) {
- my $num = $Restores[0]{num};
- unlink("$Dir/RestoreLOG.$num.z");
- unlink("$Dir/RestoreLOG.$num");
- unlink("$Dir/RestoreInfo.$num");
- shift(@Restores);
-}
-$bpc->RestoreInfoWrite($host, @Restores);
-
-if ( !$stat{xferOK} ) {
- print(LOG $bpc->timeStamp, "Restore aborted ($stat{hostError})\n");
- print("restore failed: $stat{hostError}\n");
-} else {
- print("restore complete\n");
-}
+exit(RestoreCleanup($client));
###########################################################################
# Subroutines
$stat{hostError} = "aborted by signal $signame";
}
+#
+# Cleanup and update the restore status
+#
+sub RestoreCleanup
+{
+ my($client) = @_;
+
+ $stat{xferOK} = 0 if ( $stat{hostError} || $stat{hostAbort}
+ || $tarCreateErr );
+
+ if ( !$stat{xferOK} ) {
+ #
+ # kill off the tranfer program, first nicely then forcefully
+ #
+ kill(2, $xferPid) if ( $xferPid > 0 );
+ sleep(1);
+ kill(9, $xferPid) if ( $xferPid > 0 );
+ #
+ # kill off the tar process, first nicely then forcefully
+ #
+ kill(2, $tarPid) if ( $tarPid > 0 );
+ sleep(1);
+ kill(9, $tarPid) if ( $tarPid > 0 );
+ }
+
+ my $lastNum = -1;
+ my @Restores;
+
+ #
+ # Do one last check to make sure it is still the machine we expect.
+ #
+ if ( $stat{xferOK} && (my $errMsg = CorrectHostCheck($hostIP, $host)) ) {
+ $stat{hostError} = $errMsg;
+ $stat{xferOK} = 0;
+ }
+ @Restores = $bpc->RestoreInfoRead($client);
+ for ( my $i = 0 ; $i < @Restores ; $i++ ) {
+ $lastNum = $Restores[$i]{num} if ( $lastNum < $Restores[$i]{num} );
+ }
+ $lastNum++;
+
+ #
+ # Run an optional post-restore command
+ #
+ UserCommandRun("RestorePostUserCmd") if ( $NeedPostCmd );
+
+ $RestoreLOG->close() if ( defined($RestoreLOG) );
+ rename("$Dir/RestoreLOG$fileExt", "$Dir/RestoreLOG.$lastNum$fileExt");
+ rename("$Dir/$reqFileName", "$Dir/RestoreInfo.$lastNum");
+ my $endTime = time();
+
+ #
+ # If the restore failed, clean up
+ #
+ if ( !$stat{xferOK} ) {
+ #
+ # wait a short while and see if the system is still alive
+ #
+ $stat{hostError} ||= $tarCreateErr if ( $tarCreateErr ne "" );
+ $stat{hostError} = $stat{lastOutputLine} if ( $stat{hostError} eq "" );
+ sleep(2);
+ if ( $bpc->CheckHostAlive($hostIP) < 0 ) {
+ $stat{hostAbort} = 1;
+ }
+ if ( $stat{hostAbort} && $stat{hostError} eq "" ) {
+ $stat{hostError} = "lost network connection during restore";
+ }
+ }
+
+ #
+ # Add the new restore information to the restore file
+ #
+ @Restores = $bpc->RestoreInfoRead($client);
+ my $i = @Restores;
+ $Restores[$i]{num} = $lastNum;
+ $Restores[$i]{startTime} = $startTime;
+ $Restores[$i]{endTime} = $endTime;
+ $Restores[$i]{result} = $stat{xferOK} ? "ok" : "failed";
+ $Restores[$i]{errorMsg} = $stat{hostError};
+ $Restores[$i]{nFiles} = $tarCreateFileCnt;
+ $Restores[$i]{size} = $tarCreateByteCnt;
+ $Restores[$i]{tarCreateErrs} = $tarCreateErrCnt;
+ $Restores[$i]{xferErrs} = $stat{xferErrCnt} || 0;
+
+ while ( @Restores > $Conf{RestoreInfoKeepCnt} ) {
+ my $num = $Restores[0]{num};
+ unlink("$Dir/RestoreLOG.$num.z");
+ unlink("$Dir/RestoreLOG.$num");
+ unlink("$Dir/RestoreInfo.$num");
+ shift(@Restores);
+ }
+ $bpc->RestoreInfoWrite($client, @Restores);
+
+ if ( !$stat{xferOK} ) {
+ print(LOG $bpc->timeStamp, "Restore aborted ($stat{hostError})\n");
+ print("restore failed: $stat{hostError}\n");
+ return 1;
+ } else {
+ print("restore complete\n");
+ return;
+ }
+}
+
#
# Run an optional pre- or post-dump command
#
#========================================================================
use strict;
-use lib "__INSTALLDIR__/lib";
+use lib "/usr/local/BackupPC/lib";
use BackupPC::Lib;
use BackupPC::FileZIO;
my $dumpStr = Data::Dumper->Dump(
[\%UserEmailInfo],
[qw(*UserEmailInfo)]);
- if ( open(HOST, ">$TopDir/log/UserEmailInfo.pl") ) {
+ if ( open(HOST, ">", "$TopDir/log/UserEmailInfo.pl") ) {
print(HOST $dumpStr);
close(HOST);
}
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
exit(1);
}
-if ( $opts{h} !~ /^([\w\.-]+)$/ ) {
+if ( $opts{h} !~ /^([\w\.-\s]+)$/ ) {
print(STDERR "$0: bad host name '$opts{h}'\n");
exit(1);
}
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
print("usage: $0 <host> <shareName> <compressLevel>\n");
exit(1);
}
-if ( $ARGV[0] !~ /^([\w\.-]+)$/ ) {
+if ( $ARGV[0] !~ /^([\w\.-\s]+)$/ ) {
print("$0: bad host name '$ARGV[0]'\n");
exit(1);
}
# Copyright 1998 Stephen Zander. All rights reserved.
#
my $tar_unpack_header
- = 'A100 A8 A8 A8 A12 A12 A8 A1 A100 A6 A2 A32 A32 A8 A8 A155 x12';
+ = 'Z100 A8 A8 A8 A12 A12 A8 A1 Z100 A6 A2 Z32 Z32 A8 A8 A155 x12';
my $tar_header_length = 512;
my $BufSize = 1048576; # 1MB or 2^20
}
mkpath("$OutDir/$ShareName", 0, 0777);
-open(NEW_FILES, ">>$TopDir/pc/$host/NewFileList")
+open(NEW_FILES, ">>", "$TopDir/pc/$host/NewFileList")
|| die("can't open $TopDir/pc/$host/NewFileList");
1 while ( TarReadFile(*STDIN) );
1 while ( sysread(STDIN, my $discard, 1024) );
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
if ( $In{doit} ) {
if ( $start ) {
if ( $Hosts->{$host}{dhcp} ) {
- $reply = $bpc->ServerMesg("backup $In{hostIP} $host"
- . " $User $doFull");
+ $reply = $bpc->ServerMesg("backup $In{hostIP} ${EscURI($host)}"
+ . " $User $doFull");
$str = eval("qq{$Lang->{Backup_requested_on_DHCP__host}}");
} else {
- $reply = $bpc->ServerMesg("backup $host $host $User $doFull");
+ $reply = $bpc->ServerMesg("backup ${EscURI($host)}"
+ . " ${EscURI($host)} $User $doFull");
$str = eval("qq{$Lang->{Backup_requested_on__host_by__User}}");
}
} else {
- $reply = $bpc->ServerMesg("stop $host $User $In{backoff}");
+ $reply = $bpc->ServerMesg("stop ${EscURI($host)} $User $In{backoff}");
$str = eval("qq{$Lang->{Backup_stopped_dequeued_on__host_by__User}}");
}
print (eval("qq{$Lang->{Are_you_sure_start}}"));
} else {
my $backoff = "";
- GetStatusInfo("host($host)");
+ GetStatusInfo("host(${EscURI($host)})");
if ( $StatusHost{backoffTime} > time ) {
$backoff = sprintf("%.1f",
($StatusHost{backoffTime} - time) / 3600);
print(eval("qq{$Lang->{skipped__skipped_lines}}"))
if ( $skipped );
$skipped = 0;
- print ${EscapeHTML($_)};
+ print ${EscHTML($_)};
}
} elsif ( $linkHosts ) {
while ( 1 ) {
$_ = $fh->readLine();
last if ( $_ eq "" );
- my $s = ${EscapeHTML($_)};
+ my $s = ${EscHTML($_)};
$s =~ s/\b([\w-]+)\b/defined($Hosts->{$1})
? ${HostLink($1)} : $1/eg;
print $s;
s/(SmbSharePasswd.*=.*['"]).*(['"])/$1$2/ig;
s/(SmbShareUserName.*=.*['"]).*(['"])/$1$2/ig;
s/(ServerMesgSecret.*=.*['"]).*(['"])/$1$2/ig;
- print ${EscapeHTML($_)};
+ print ${EscHTML($_)};
}
} else {
while ( 1 ) {
$_ = $fh->readLine();
last if ( $_ eq "" );
- print ${EscapeHTML($_)};
+ print ${EscHTML($_)};
}
}
$fh->close();
my($url0, $hdr, $root, $str);
if ( $host ne "" ) {
$root = "$TopDir/pc/$host/LOG";
- $url0 = "&host=$host";
+ $url0 = "&host=${EscURI($host)}";
$hdr = "for host $host";
} else {
$root = "$TopDir/log/LOG";
last if ( $Backups[$i]{num} == $num );
}
if ( $i >= @Backups ) {
- ErrorExit("Backup number $num for host ${EscapeHTML($host)} does"
+ ErrorExit("Backup number $num for host ${EscHTML($host)} does"
. " not exist.");
}
my $backupTime = timeStamp2($Backups[$i]{startTime});
$share = (sort(keys(%$attr)))[0];
$dir = '/';
} else {
- ErrorExit(eval("qq{$Lang->{Directory___EscapeHTML}}"));
+ ErrorExit(eval("qq{$Lang->{Directory___EscHTML}}"));
}
}
my $relDir = $dir;
$path = "/";
}
$path =~ s{^/+}{/};
- $path =~ s/([^\w.\/-])/uc sprintf("%%%02x", ord($1))/eg;
- $fURI =~ s/([^\w.\/-])/uc sprintf("%%%02x", ord($1))/eg;
- $shareURI =~ s/([^\w.\/-])/uc sprintf("%%%02x", ord($1))/eg;
+ $path =~ s/([^\w.\/-])/uc sprintf("%%%02X", ord($1))/eg;
+ $fURI =~ s/([^\w.\/-])/uc sprintf("%%%02X", ord($1))/eg;
+ $shareURI =~ s/([^\w.\/-])/uc sprintf("%%%02X", ord($1))/eg;
$dirOpen = 1 if ( defined($currDir) && $f eq $currDir );
if ( $attr->{$f}{type} == BPC_FTYPE_DIR ) {
#
push(@DirStr, {needTick => 1,
tdArgs => $BGcolor,
link => <<EOF});
-<a href="$MyURL?action=browse&host=$host&num=$num&share=$shareURI&dir=$path">$imgStr</a><a href="$MyURL?action=browse&host=$host&num=$num&share=$shareURI&dir=$path" style="font-size:13px;font-family:arial;text-decoration:none;line-height:15px"> $bold$dirName$unbold</a></td></tr>
+<a href="$MyURL?action=browse&host=${EscURI($host)}&num=$num&share=$shareURI&dir=$path">$imgStr</a><a href="$MyURL?action=browse&host=${EscURI($host)}&num=$num&share=$shareURI&dir=$path" style="font-size:13px;font-family:arial;text-decoration:none;line-height:15px"> $bold$dirName$unbold</a></td></tr>
EOF
$fileCnt++;
$gotDir = 1;
} else {
$attrStr .= "<td colspan=\"5\" align=\"center\"> </td>\n";
}
+ (my $fDisp = "${EscHTML($f)}") =~ s/ / /g;
if ( $gotDir ) {
$fileStr .= <<EOF;
-<tr bgcolor="#ffffcc"><td><input type="checkbox" name="fcb$checkBoxCnt" value="$path"> <a href="$MyURL?action=browse&host=$host&num=$num&share=$shareURI&dir=$path">${EscapeHTML($f)}</a></td>
+<tr bgcolor="#ffffcc"><td><input type="checkbox" name="fcb$checkBoxCnt" value="$path"> <a href="$MyURL?action=browse&host=${EscURI($host)}&num=$num&share=$shareURI&dir=$path">$fDisp</a></td>
$attrStr
</tr>
EOF
} else {
$fileStr .= <<EOF;
-<tr bgcolor="#ffffcc"><td><input type="checkbox" name="fcb$checkBoxCnt" value="$path"> <a href="$MyURL?action=RestoreFile&host=$host&num=$num&share=$shareURI&dir=$path">${EscapeHTML($f)}</a></td>
+<tr bgcolor="#ffffcc"><td><input type="checkbox" name="fcb$checkBoxCnt" value="$path"> <a href="$MyURL?action=RestoreFile&host=${EscURI($host)}&num=$num&share=$shareURI&dir=$path">$fDisp</a></td>
$attrStr
</tr>
EOF
my $shareURI = $share;
$path =~ s/([^\w.\/-])/uc sprintf("%%%02x", ord($1))/eg;
$shareURI =~ s/([^\w.\/-])/uc sprintf("%%%02x", ord($1))/eg;
- push(@otherDirs, "<a href=\"$MyURL?action=browse&host=$host&num=$i"
+ push(@otherDirs, "<a href=\"$MyURL?action=browse&host=${EscURI($host)}&num=$i"
. "&share=$shareURI&dir=$path\">$i</a>");
}
my $otherDirs = join(",\n", @otherDirs);
$filledBackup .= eval("qq{$Lang->{Visit_this_directory_in_backup}}");
}
-
print (eval("qq{$Lang->{Backup_browse_for__host}}"));
Trailer();
}
<input type="hidden" name="fcb$i" value="$In{'fcb' . $i}">
EOF
$fileListStr .= <<EOF;
-<li> ${EscapeHTML($name)}
+<li> ${EscHTML($name)}
EOF
}
$hiddenStr .= "<input type=\"hidden\" name=\"fcbMax\" value=\"$In{fcbMax}\">\n";
- $hiddenStr .= "<input type=\"hidden\" name=\"share\" value=\"${EscapeHTML($share)}\">\n";
+ $hiddenStr .= "<input type=\"hidden\" name=\"share\" value=\"${EscHTML($share)}\">\n";
$badFileCnt++ if ( $In{pathHdr} =~ m{(^|/)\.\.(/|$)} );
$badFileCnt++ if ( $In{num} =~ m{(^|/)\.\.(/|$)} );
if ( @fileList == 0 ) {
} else {
ErrorExit(eval("qq{$Lang->{Can_t_open_create}}"));
}
- $reply = $bpc->ServerMesg("restore $ipAddr"
- . " $hostDest $User $reqFileName");
+ $reply = $bpc->ServerMesg("restore ${EscURI($ipAddr)}"
+ . " ${EscURI($hostDest)} $User $reqFileName");
$str = eval("qq{$Lang->{Restore_requested_to_host__hostDest__backup___num}}");
Header(eval("qq{$Lang->{Restore_Requested_on__hostDest}}"));
print (eval("qq{$Lang->{Reply_from_server_was___reply}}"));
my $view = BackupPC::View->new($bpc, $host, \@Backups);
my $a = $view->fileAttrib($num, $share, $dir);
if ( $dir =~ m{(^|/)\.\.(/|$)} || !defined($a) ) {
- ErrorExit("Can't restore bad file ${EscapeHTML($dir)}");
+ ErrorExit("Can't restore bad file ${EscHTML($dir)}");
}
my $f = BackupPC::FileZIO->open($a->{fullPath}, 0, $a->{compress});
my $data;
}
$In{host} = $host;
}
- GetStatusInfo("host($host)");
+ GetStatusInfo("host(${EscURI($host)})");
$bpc->ConfigRead($host);
%Conf = $bpc->Conf();
my $Privileged = CheckPermission($host);
(1 - $Backups[$i]{sizeNewComp} / $Backups[$i]{sizeNew}));
}
my $age = sprintf("%.1f", (time - $Backups[$i]{startTime}) / (24*3600));
- my $browseURL = "$MyURL?action=browse&host=$host&num=$Backups[$i]{num}";
+ my $browseURL = "$MyURL?action=browse&host=${EscURI($host)}&num=$Backups[$i]{num}";
my $filled = $Backups[$i]{noFill} ? $Lang->{No} : $Lang->{Yes};
$filled .= " ($Backups[$i]{fillFromNum}) "
if ( $Backups[$i]{fillFromNum} ne "" );
$errStr .= <<EOF;
<tr><td align="center"> <a href="$browseURL">$Backups[$i]{num}</a> </td>
<td align="center"> $ltype </td>
- <td align="center"> <a href="$MyURL?action=view&type=XferLOG&num=$Backups[$i]{num}&host=$host">XferLOG</a>,
- <a href="$MyURL?action=view&type=XferErr&num=$Backups[$i]{num}&host=$host">Errors</a> </td>
+ <td align="center"> <a href="$MyURL?action=view&type=XferLOG&num=$Backups[$i]{num}&host=${EscURI($host)}">XferLOG</a>,
+ <a href="$MyURL?action=view&type=XferErr&num=$Backups[$i]{num}&host=${EscURI($host)}">Errors</a> </td>
<td align="right"> $Backups[$i]{xferErrs} </td>
<td align="right"> $Backups[$i]{xferBadFile} </td>
<td align="right"> $Backups[$i]{xferBadShare} </td>
my $Restores_Result = $Lang->{failed};
if ($Restores[$i]{result} ne "failed") { $Restores_Result = $Lang->{success}; }
$restoreStr .= <<EOF;
-<tr><td align="center"><a href="$MyURL?action=restoreInfo&num=$Restores[$i]{num}&host=$host">$Restores[$i]{num}</a> </td>
+<tr><td align="center"><a href="$MyURL?action=restoreInfo&num=$Restores[$i]{num}&host=${EscURI($host)}">$Restores[$i]{num}</a> </td>
<td align="center"> $Restores_Result </td>
<td align="right"> $startTime </td>
<td align="right"> $duration </td>
$statusStr .= eval("qq{$Lang->{Last_status_is_state_StatusHost_state_reason_as_of_startTime}}");
if ( $StatusHost{error} ne "" ) {
- $statusStr .= eval("qq{$Lang->{Last_error_is____EscapeHTML_StatusHost_error}}");
+ $statusStr .= eval("qq{$Lang->{Last_error_is____EscHTML_StatusHost_error}}");
}
my $priorStr = "Pings";
if ( $StatusHost{deadCnt} > 0 ) {
|| -f "$TopDir/pc/$host/XferLOG.bad.z"
) {
$XferViewStr = <<EOF;
-<a href="$MyURL?action=view&type=XferLOGbad&host=$host">XferLOG</a>,
-<a href="$MyURL?action=view&type=XferErrbad&host=$host">XferErr</a>
+<a href="$MyURL?action=view&type=XferLOGbad&host=${EscURI($host)}">XferLOG</a>,
+<a href="$MyURL?action=view&type=XferErrbad&host=${EscURI($host)}">XferErr</a>
EOF
} else {
$XferViewStr = "";
<td align="right"> $startTime </td>
<td> $XferViewStr </td>
<td align="right"> $errorTime </td>
- <td> ${EscapeHTML($shortErr)} </td></tr>
+ <td> ${EscHTML($shortErr)} </td></tr>
EOF
}
my $now = timeStamp2(time);
my($host) = @_;
my($s);
if ( defined($Hosts->{$host}) || defined($Status{$host}) ) {
- $s = "<a href=\"$MyURL?host=$host\">$host</a>";
+ $s = "<a href=\"$MyURL?host=${EscURI($host)}\">$host</a>";
} else {
$s = $host;
}
return \$s;
}
-sub EscapeHTML
+sub EscHTML
{
my($s) = @_;
$s =~ s/&/&/g;
$s =~ s/\"/"/g;
$s =~ s/>/>/g;
$s =~ s/</</g;
- $s =~ s{([^[:print:]])}{sprintf("&\#x%02X", ord($1));}eg;
+ $s =~ s{([^[:print:]])}{sprintf("&\#x%02X;", ord($1));}eg;
return \$s;
}
-##sub URIEncode
-##{
-## my($s) = @_;
-## $s =~ s{(['"&%[:^print:]])}{sprintf("%%%02X", ord($1));}eg;
-## return \$s;
-##}
+sub EscURI
+{
+ my($s) = @_;
+ $s =~ s{([^\w.\/-])}{sprintf("%%%02X", ord($1));}eg;
+ return \$s;
+}
sub ErrorExit
{
my($netBiosHost, $netBiosUser) = $bpc->NetBiosInfoGet($ipAddr);
if ( $netBiosHost ne $host ) {
my($tryIP);
- GetStatusInfo("host($host)");
+ GetStatusInfo("host(${EscURI($host)})");
if ( defined($StatusHost{dhcpHostIP})
&& $StatusHost{dhcpHostIP} ne $ipAddr ) {
$tryIP = eval("qq{$Lang->{tryIP}}");
my $host = $In{host};
NavSectionTitle( eval("qq{$Lang->{Host_Inhost}}") );
NavSectionStart();
- NavLink("?host=$host", $Lang->{Home});
- NavLink("?action=view&type=LOG&host=$host", $Lang->{LOG_file});
- NavLink("?action=LOGlist&host=$host", $Lang->{Old_LOGs});
+ NavLink("?host=${EscURI($host)}", $Lang->{Home});
+ NavLink("?action=view&type=LOG&host=${EscURI($host)}", $Lang->{LOG_file});
+ NavLink("?action=LOGlist&host=${EscURI($host)}", $Lang->{Old_LOGs});
if ( -f "$TopDir/pc/$host/SmbLOG.bad"
|| -f "$TopDir/pc/$host/SmbLOG.bad.z"
|| -f "$TopDir/pc/$host/XferLOG.bad"
|| -f "$TopDir/pc/$host/XferLOG.bad.z" ) {
- NavLink("?action=view&type=XferLOGbad&host=$host",
+ NavLink("?action=view&type=XferLOGbad&host=${EscURI($host)}",
$Lang->{Last_bad_XferLOG});
- NavLink("?action=view&type=XferErrbad&host=$host",
+ NavLink("?action=view&type=XferErrbad&host=${EscURI($host)}",
$Lang->{Last_bad_XferLOG_errors_only});
}
if ( -f "$TopDir/pc/$host/config.pl" ) {
- NavLink("?action=view&type=config&host=$host", $Lang->{Config_file});
+ NavLink("?action=view&type=config&host=${EscURI($host)}", $Lang->{Config_file});
}
NavSectionEnd();
}
if ( defined($Hosts) && %$Hosts > 0 ) {
NavSectionStart(0);
foreach my $host ( GetUserHosts() ) {
- NavLink("?host=$host", $host);
+ NavLink("?host=${EscURI($host)}", $host);
}
NavSectionEnd();
}
$Conf{SmbClientPath} = '/usr/bin/smbclient';
#
-# Additional optional arguments to smbclient.
-#
-# Some users have reported that the -b option can be used to improve
-# performance of smbclient. The default value is 4096, and if you
-# find smbclient has low throughput you might try a value of 2048, eg:
-#
-# $Conf{SmbClientArgs} = '-b 2048';
-#
+# Commands to run smbclient for a full dump, incremental dump or a restore.
# This setting only matters if $Conf{XferMethod} = 'smb'.
#
-$Conf{SmbClientArgs} = '';
+# Several variables are substituted at run-time:
+#
+# $smbClientPath same as $Conf{SmbClientPath}
+# $host host to backup/restore
+# $hostIP host IP address
+# $shareName share name
+# $userName user name
+# $fileList list of files to backup (based on exclude/include)
+# $I_option optional -I option to smbclient
+# $X_option exclude option (if $fileList is an exclude list)
+# $timeStampFile start time for incremental dump
+#
+$Conf{SmbClientFullCmd} = '$smbClientPath \\\\$host\\$shareName'
+ . '$I_option -U $userName -E -N -d 1'
+ . ' -c tarmode\\ full -Tc$X_option - $fileList';
+
+$Conf{SmbClientIncrCmd} = '$smbClientPath \\\\$host\\$shareName'
+ . '$I_option -U $userName -E -N -d 1'
+ . ' -c tarmode\\ full -TcN$X_option $timeStampFile - $fileList';
+
+$Conf{SmbClientRestoreCmd} = '$smbClientPath \\\\$host\\$shareName'
+ . '$I_option -U $userName -E -N -d 1'
+ . ' -c tarmode\\ full -Tx -';
#
# Full command to run tar on the client. GNU tar is required. You will
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
$fh = $fileName;
} else {
if ( $write ) {
- open(FH, ">$fileName") || return;
+ open(FH, ">", $fileName) || return;
} else {
- open(FH, "<$fileName") || return;
+ open(FH, "<", $fileName) || return;
}
$fh = *FH;
}
if ( $CompZlibOK && $compress > 0 ) {
my $fh = BackupPC::FileZIO->open($destFileZ, 1, $compress);
my $data;
- if ( defined($fh) && open(LOG, $srcFile) ) {
+ if ( defined($fh) && open(LOG, "<", $srcFile) ) {
while ( sysread(LOG, $data, 65536) > 0 ) {
$fh->write(\$data);
}
selected will be overwritten!
<form action="\$MyURL" method="post">
-<input type="hidden" name="host" value="\${EscapeHTML(\$host)}">
+<input type="hidden" name="host" value="\${EscHTML(\$host)}">
<input type="hidden" name="num" value="\$num">
<input type="hidden" name="type" value="3">
\$hiddenStr
<table border="0">
<tr>
<td>Restore the files to host</td>
- <td><input type="text" size="40" value="\${EscapeHTML(\$host)}"
+ <td><input type="text" size="40" value="\${EscHTML(\$host)}"
name="hostDest"></td>
</tr><tr>
<td>Restore the files to share</td>
- <td><input type="text" size="40" value="\${EscapeHTML(\$share)}"
+ <td><input type="text" size="40" value="\${EscHTML(\$share)}"
name="shareDest"></td>
</tr><tr>
<td>Restore the files below dir<br>(relative to share)</td>
<td valign="top"><input type="text" size="40" maxlength="256"
- value="\${EscapeHTML(\$pathHdr)}" name="pathHdr"></td>
+ value="\${EscHTML(\$pathHdr)}" name="pathHdr"></td>
</tr><tr>
<td><input type="submit" value="Start Restore" name=""></td>
</table>
space to store it.
<p>
<form action="\$MyURL" method="post">
-<input type="hidden" name="host" value="\${EscapeHTML(\$host)}">
+<input type="hidden" name="host" value="\${EscHTML(\$host)}">
<input type="hidden" name="num" value="\$num">
<input type="hidden" name="type" value="2">
\$hiddenStr
<input type="hidden" value="\$In{action}" name="action">
<input type="checkbox" value="1" name="relative" checked> Make archive relative
-to \${EscapeHTML(\$pathHdr eq "" ? "/" : \$pathHdr)}
+to \${EscHTML(\$pathHdr eq "" ? "/" : \$pathHdr)}
(otherwise archive will contain full paths).
<br>
Compression (0=off, 1=fast,...,9=best)
space to store it.
<p>
<form action="\$MyURL" method="post">
-<input type="hidden" name="host" value="\${EscapeHTML(\$host)}">
+<input type="hidden" name="host" value="\${EscHTML(\$host)}">
<input type="hidden" name="num" value="\$num">
<input type="hidden" name="type" value="1">
\$hiddenStr
<input type="hidden" value="\$In{action}" name="action">
<input type="checkbox" value="1" name="relative" checked> Make archive relative
-to \${EscapeHTML(\$pathHdr eq "" ? "/" : \$pathHdr)}
+to \${EscHTML(\$pathHdr eq "" ? "/" : \$pathHdr)}
(otherwise archive will contain full paths).
<br>
<input type="submit" value="Download Tar File" name="">
</table>
<form action="\$MyURL" method="post">
-<input type="hidden" name="host" value="\${EscapeHTML(\$host)}">
-<input type="hidden" name="hostDest" value="\${EscapeHTML(\$In{hostDest})}">
-<input type="hidden" name="shareDest" value="\${EscapeHTML(\$In{shareDest})}">
-<input type="hidden" name="pathHdr" value="\${EscapeHTML(\$In{pathHdr})}">
+<input type="hidden" name="host" value="\${EscHTML(\$host)}">
+<input type="hidden" name="hostDest" value="\${EscHTML(\$In{hostDest})}">
+<input type="hidden" name="shareDest" value="\${EscHTML(\$In{shareDest})}">
+<input type="hidden" name="pathHdr" value="\${EscHTML(\$In{pathHdr})}">
<input type="hidden" name="num" value="\$num">
<input type="hidden" name="type" value="4">
\$hiddenStr
<li> Click on a file below to restore that file.
</ul>
-\${h2("Contents of \${EscapeHTML(\$dirDisplay)}")}
+\${h2("Contents of \${EscHTML(\$dirDisplay)}")}
<form name="form1" method="post" action="\$MyURL">
<input type="hidden" name="num" value="\$num">
<input type="hidden" name="host" value="\$host">
-<input type="hidden" name="share" value="\${EscapeHTML(\$share)}">
+<input type="hidden" name="share" value="\${EscHTML(\$share)}">
<input type="hidden" name="fcbMax" value="\$checkBoxCnt">
<input type="hidden" name="action" value="$Lang{Restore}">
<br>
$Lang{Only_privileged_users_can_view_PC_summaries} = "Only privileged users can view PC summaries.";
$Lang{Only_privileged_users_can_stop_or_start_backups} =
"Only privileged users can stop or start backups on"
- . " \${EscapeHTML(\$host)}.";
+ . " \${EscHTML(\$host)}.";
$Lang{Invalid_number__num} = "Invalid number \$num";
$Lang{Unable_to_open__file__configuration_problem} = "Unable to open \$file: configuration problem?";
$Lang{Only_privileged_users_can_view_log_or_config_files} = "Only privileged users can view log or config files.";
$Lang{Only_privileged_users_can_view_log_files} = "Only privileged users can view log files.";
$Lang{Only_privileged_users_can_view_email_summaries} = "Only privileged users can view email summaries.";
$Lang{Only_privileged_users_can_browse_backup_files} = "Only privileged users can browse backup files"
- . " for host \${EscapeHTML(\$In{host})}.";
+ . " for host \${EscHTML(\$In{host})}.";
$Lang{Empty_host_name} = "Empty host name.";
-$Lang{Directory___EscapeHTML} = "Directory \${EscapeHTML(\"\$TopDir/pc/\$host/\$num\")}"
+$Lang{Directory___EscHTML} = "Directory \${EscHTML(\"\$TopDir/pc/\$host/\$num\")}"
. " is empty";
$Lang{Can_t_browse_bad_directory_name2} = "Can\'t browse bad directory name"
- . " \${EscapeHTML(\$relDir)}";
+ . " \${EscHTML(\$relDir)}";
$Lang{Only_privileged_users_can_restore_backup_files} = "Only privileged users can restore backup files"
- . " for host \${EscapeHTML(\$In{host})}.";
-$Lang{Bad_host_name} = "Bad host name \${EscapeHTML(\$host)}";
+ . " for host \${EscHTML(\$In{host})}.";
+$Lang{Bad_host_name} = "Bad host name \${EscHTML(\$host)}";
$Lang{You_haven_t_selected_any_files__please_go_Back_to} = "You haven\'t selected any files; please go Back to"
. " select some files.";
$Lang{Nice_try__but_you_can_t_put} = "Nice try, but you can\'t put \'..\' in any of the file names";
-$Lang{Host__doesn_t_exist} = "Host \${EscapeHTML(\$In{hostDest})} doesn\'t exist";
+$Lang{Host__doesn_t_exist} = "Host \${EscHTML(\$In{hostDest})} doesn\'t exist";
$Lang{You_don_t_have_permission_to_restore_onto_host} = "You don\'t have permission to restore onto host"
- . " \${EscapeHTML(\$In{hostDest})}";
+ . " \${EscHTML(\$In{hostDest})}";
$Lang{Can_t_open_create} = "Can\'t open/create "
- . "\${EscapeHTML(\"\$TopDir/pc/\$hostDest/\$reqFileName\")}";
+ . "\${EscHTML(\"\$TopDir/pc/\$hostDest/\$reqFileName\")}";
$Lang{Only_privileged_users_can_restore_backup_files2} = "Only privileged users can restore backup files"
- . " for host \${EscapeHTML(\$host)}.";
+ . " for host \${EscHTML(\$host)}.";
$Lang{Empty_host_name} = "Empty host name";
-$Lang{Unknown_host_or_user} = "Unknown host or user \${EscapeHTML(\$host)}";
+$Lang{Unknown_host_or_user} = "Unknown host or user \${EscHTML(\$host)}";
$Lang{Only_privileged_users_can_view_information_about} = "Only privileged users can view information about"
- . " host \${EscapeHTML(\$host)}." ;
+ . " host \${EscHTML(\$host)}." ;
$Lang{Only_privileged_users_can_view_restore_information} = "Only privileged users can view restore information.";
-$Lang{Restore_number__num_for_host__does_not_exist} = "Restore number \$num for host \${EscapeHTML(\$host)} does"
+$Lang{Restore_number__num_for_host__does_not_exist} = "Restore number \$num for host \${EscHTML(\$host)} does"
. " not exist.";
$Lang{Unable_to_connect_to_BackupPC_server} = "Unable to connect to BackupPC server",
"Perhaps the BackupPC server is not running or there is a "
. " configuration error. Please report this to your Sys Admin.";
-$Lang{Can_t_find_IP_address_for} = "Can\'t find IP address for \${EscapeHTML(\$host)}";
+$Lang{Can_t_find_IP_address_for} = "Can\'t find IP address for \${EscHTML(\$host)}";
$Lang{host_is_a_DHCP_host} = <<EOF;
\$host is a DHCP host, and I don\'t know its IP address. I checked the
netbios name of \$ENV{REMOTE_ADDR}\$tryIP, and found that that machine
EOF
# --------
-$Lang{Last_error_is____EscapeHTML_StatusHost_error} = <<EOF;
-<li>Last error is \"\${EscapeHTML(\$StatusHost{error})}\"
+$Lang{Last_error_is____EscHTML_StatusHost_error} = <<EOF;
+<li>Last error is \"\${EscHTML(\$StatusHost{error})}\"
EOF
# ------
$Lang{Yes} = "yes";
$Lang{The_directory_is_empty} = <<EOF;
-<tr><td bgcolor="#ffffff">The directory \${EscapeHTML(\$dirDisplay)} is empty
+<tr><td bgcolor="#ffffff">The directory \${EscHTML(\$dirDisplay)} is empty
</td></tr>
EOF
tous les fichiers correspondant à ceux que vous avez sélectionnés vont être effacés !
<form action="\$MyURL" method="post">
-<input type="hidden" name="host" value="\${EscapeHTML(\$host)}">
+<input type="hidden" name="host" value="\${EscHTML(\$host)}">
<input type="hidden" name="num" value="\$num">
<input type="hidden" name="type" value="3">
\$hiddenStr
<table border="0">
<tr>
<td>Restaurer les fichiers vers l\'hôte</td>
- <td><input type="text" size="40" value="\${EscapeHTML(\$host)}"
+ <td><input type="text" size="40" value="\${EscHTML(\$host)}"
name="hostDest"></td>
</tr><tr>
<td>Restaurer les fichiers vers le partage</td>
- <td><input type="text" size="40" value="\${EscapeHTML(\$share)}"
+ <td><input type="text" size="40" value="\${EscHTML(\$share)}"
name="shareDest"></td>
</tr><tr>
<td>Restaurer les fichiers du répertoire<br>(relatif au partage)</td>
<td valign="top"><input type="text" size="40" maxlength="256"
- value="\${EscapeHTML(\$pathHdr)}" name="pathHdr"></td>
+ value="\${EscHTML(\$pathHdr)}" name="pathHdr"></td>
</tr><tr>
<td><input type="submit" value="Démarrer la restauration" name=""></td>
</table>
et transférer cette archive, et vous aurez besoin d\'assez d\'espace disque pour le stocker.
<p>
<form action="\$MyURL" method="post">
-<input type="hidden" name="host" value="\${EscapeHTML(\$host)}">
+<input type="hidden" name="host" value="\${EscHTML(\$host)}">
<input type="hidden" name="num" value="\$num">
<input type="hidden" name="type" value="2">
\$hiddenStr
<input type="hidden" value="\$In{action}" name="action">
<input type="checkbox" value="1" name="relative" checked> Faire l\'archive relative Ã
-\${EscapeHTML(\$pathHdr eq "" ? "/" : \$pathHdr)}
+\${EscHTML(\$pathHdr eq "" ? "/" : \$pathHdr)}
(Autrement l\'archive contiendra les chemins complets).
<br>
Compression (0=désactivée, 1=rapide,...,9=meilleure)
d\'espace disque local pour la stocker.
<p>
<form action="\$MyURL" method="post">
-<input type="hidden" name="host" value="\${EscapeHTML(\$host)}">
+<input type="hidden" name="host" value="\${EscHTML(\$host)}">
<input type="hidden" name="num" value="\$num">
<input type="hidden" name="type" value="1">
\$hiddenStr
<input type="hidden" value="\$In{action}" name="action">
<input type="checkbox" value="1" name="relative" checked> Faire l\'archive relative Ã
-\${EscapeHTML(\$pathHdr eq "" ? "/" : \$pathHdr)}
+\${EscHTML(\$pathHdr eq "" ? "/" : \$pathHdr)}
(Autrement l\'archive contiendra des chemins absolus).
<br>
<input type="submit" value="Télécharger le fichier Tar" name="">
</table>
<form action="\$MyURL" method="post">
-<input type="hidden" name="host" value="\${EscapeHTML(\$host)}">
-<input type="hidden" name="hostDest" value="\${EscapeHTML(\$In{hostDest})}">
-<input type="hidden" name="shareDest" value="\${EscapeHTML(\$In{shareDest})}">
-<input type="hidden" name="pathHdr" value="\${EscapeHTML(\$In{pathHdr})}">
+<input type="hidden" name="host" value="\${EscHTML(\$host)}">
+<input type="hidden" name="hostDest" value="\${EscHTML(\$In{hostDest})}">
+<input type="hidden" name="shareDest" value="\${EscHTML(\$In{shareDest})}">
+<input type="hidden" name="pathHdr" value="\${EscHTML(\$In{pathHdr})}">
<input type="hidden" name="num" value="\$num">
<input type="hidden" name="type" value="4">
\$hiddenStr
<li> Cliquer dans un fichier ci-dessous pour le restaurer.
</ul>
-\${h2("Contenu de \${EscapeHTML(\$dirDisplay)}")}
+\${h2("Contenu de \${EscHTML(\$dirDisplay)}")}
<form name="form1" method="post" action="\$MyURL">
<input type="hidden" name="num" value="\$num">
<input type="hidden" name="host" value="\$host">
-<input type="hidden" name="share" value="\${EscapeHTML(\$share)}">
+<input type="hidden" name="share" value="\${EscHTML(\$share)}">
<input type="hidden" name="fcbMax" value="\$checkBoxCnt">
<input type="hidden" name="action" value="$Lang{Restore}">
<br>
"Mauvais utilisateur: mon userid est \$>, Ã la place de \$uid (\$Conf{BackupPCUser})\n";
$Lang{Only_privileged_users_can_view_PC_summaries} = "Seuls les utilisateurs privilégiés peuvent voir les résumés des PC.";
$Lang{Only_privileged_users_can_stop_or_start_backups} =
- "Seuls les utilisateurs privilégiés peuvent arrêter ou démarrer des sauvegardes sur \${EscapeHTML(\$host)}.";
+ "Seuls les utilisateurs privilégiés peuvent arrêter ou démarrer des sauvegardes sur \${EscHTML(\$host)}.";
$Lang{Invalid_number__num} = "Numéro invalide \$num";
$Lang{Unable_to_open__file__configuration_problem} = "Impossible d\'ouvrir \$file: problème de configuration ?";
$Lang{Only_privileged_users_can_view_log_or_config_files} = "Seuls les utilisateurs privilégiés peuvent voir les fichier de jounal ou les fichiers de configuration.";
$Lang{Only_privileged_users_can_view_log_files} = "Seuls les utilisateurs privilégiés peuvent voir les fichiers de journal.";
$Lang{Only_privileged_users_can_view_email_summaries} = "Seuls les utilisateurs privilégiés peuvent voir les compte-rendu des courriels.";
-$Lang{Only_privileged_users_can_browse_backup_files} = "Seuls les utilisateurs privilégiés peuvent parcourir les fichiers de sauvegarde pour l'hôte \${EscapeHTML(\$In{host})}.";
+$Lang{Only_privileged_users_can_browse_backup_files} = "Seuls les utilisateurs privilégiés peuvent parcourir les fichiers de sauvegarde pour l'hôte \${EscHTML(\$In{host})}.";
$Lang{Empty_host_name} = "Nom d\'hôte vide.";
-$Lang{Directory___EscapeHTML} = "Le répertoire \${EscapeHTML(\"\$TopDir/pc/\$host/\$num\")}"
+$Lang{Directory___EscHTML} = "Le répertoire \${EscHTML(\"\$TopDir/pc/\$host/\$num\")}"
. " est vide";
$Lang{Can_t_browse_bad_directory_name2} = "Ne peut pas parcourir "
- . " \${EscapeHTML(\$relDir)}:"
+ . " \${EscHTML(\$relDir)}:"
. " mauvais nom de répertoire";
$Lang{Only_privileged_users_can_restore_backup_files} = "Seuls les utilisateurs privilégiés peuvent restaurer "
. " des fichiers de sauvegarde"
- . " pour l\'hôte \${EscapeHTML(\$In{host})}.";
-$Lang{Bad_host_name} = "Mauvais nom d\'hôte \${EscapeHTML(\$host)}";
+ . " pour l\'hôte \${EscHTML(\$In{host})}.";
+$Lang{Bad_host_name} = "Mauvais nom d\'hôte \${EscHTML(\$host)}";
$Lang{You_haven_t_selected_any_files__please_go_Back_to} = "Vous n'avez sélectionné aucun fichier; "
. "vous pouvez revenir en arrière pour sélectionner des fichiers.";
$Lang{Nice_try__but_you_can_t_put} = "Bien tenté, mais vous ne pouvez pas mettre \'..\' dans"
. " n\'importe quel nom de fichier.";
-$Lang{Host__doesn_t_exist} = "L'hôte \${EscapeHTML(\$In{hostDest})} n\'existe pas.";
+$Lang{Host__doesn_t_exist} = "L'hôte \${EscHTML(\$In{hostDest})} n\'existe pas.";
$Lang{You_don_t_have_permission_to_restore_onto_host} = "Vous n\'avez pas la permission de restaurer sur l\'hôte"
- . " \${EscapeHTML(\$In{hostDest})}";
-$Lang{Can_t_open_create} = "Ne peut pas ouvrir/créer ". "\${EscapeHTML(\"\$TopDir/pc/\$hostDest/\$reqFileName\")}";
+ . " \${EscHTML(\$In{hostDest})}";
+$Lang{Can_t_open_create} = "Ne peut pas ouvrir/créer ". "\${EscHTML(\"\$TopDir/pc/\$hostDest/\$reqFileName\")}";
$Lang{Only_privileged_users_can_restore_backup_files2} = "Seuls les utilisateurs privilégiés peuvent restaurer"
. " des fichiers de sauvegarde"
- . " pour l\'hôte \${EscapeHTML(\$host)}.";
+ . " pour l\'hôte \${EscHTML(\$host)}.";
$Lang{Empty_host_name} = "Nom d\'hôte vide";
-$Lang{Unknown_host_or_user} = "\${EscapeHTML(\$host)}, hôte ou utilisateur inconnu.";
+$Lang{Unknown_host_or_user} = "\${EscHTML(\$host)}, hôte ou utilisateur inconnu.";
$Lang{Only_privileged_users_can_view_information_about} = "Seuls les utilisateurs privilégiés peuvent accéder aux "
- . " informations sur l\'hôte \${EscapeHTML(\$host)}." ;
+ . " informations sur l\'hôte \${EscHTML(\$host)}." ;
$Lang{Only_privileged_users_can_view_restore_information} = "Seuls les utilisateurs privilégiés peuvent restaurer "
."des informations.";
-$Lang{Restore_number__num_for_host__does_not_exist} = "Restauration numéro \$num de l\'hôte \${EscapeHTML(\$host)} n\'existe pas";
+$Lang{Restore_number__num_for_host__does_not_exist} = "Restauration numéro \$num de l\'hôte \${EscHTML(\$host)} n\'existe pas";
$Lang{Unable_to_connect_to_BackupPC_server} = "Impossible de se connecter au server BackupPC."
. "Ce script CGI (\$MyURL) ne peut pas se connecter au serveur BackupPC"
"Peut-être que BackupPC n\'a pas été lancé ou il y a une erreur "
. " de configuration. Veuillez faire suivre ce message à votre administrateur système.";
-$Lang{Can_t_find_IP_address_for} = "Ne peut pas trouver d\'adresse IP pour \${EscapeHTML(\$host)}";
+$Lang{Can_t_find_IP_address_for} = "Ne peut pas trouver d\'adresse IP pour \${EscHTML(\$host)}";
$Lang{host_is_a_DHCP_host} = <<EOF;
L\'hôte est un serveur DHCP, et je ne connais pas son adresse IP. J\'ai
vérifié le nom netbios de \$ENV{REMOTE_ADDR}\$tryIP, et j\'ai trouvé que
EOF
# --------
-$Lang{Last_error_is____EscapeHTML_StatusHost_error} = <<EOF;
-<li>La dernière erreur est \"\${EscapeHTML(\$StatusHost{error})}\"
+$Lang{Last_error_is____EscHTML_StatusHost_error} = <<EOF;
+<li>La dernière erreur est \"\${EscHTML(\$StatusHost{error})}\"
EOF
# ------
$Lang{Yes} = "oui";
$Lang{The_directory_is_empty} = <<EOF;
-<tr><td bgcolor="#ffffff">Le repertoire \${EscapeHTML(\$dirDisplay)} est vide
+<tr><td bgcolor="#ffffff">Le repertoire \${EscHTML(\$dirDisplay)} est vide
</td></tr>
EOF
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
TopDir => $topDir || '/data/BackupPC',
BinDir => $installDir || '/usr/local/BackupPC',
LibDir => $installDir || '/usr/local/BackupPC',
- Version => '1.6.0_CVS',
+ Version => '2.0.0_CVS',
BackupFields => [qw(
num type startTime endTime
nFiles size nFilesExist sizeExist nFilesNew sizeNew
s/[\n\r]+//;
s/#.*//;
s/\s+$//;
- next if ( /^\s*$/ || !/^([\w\.-]+\s+.*)/ );
- @fld = split(/\s+/, $1);
+ next if ( /^\s*$/ || !/^([\w\.-\\]+\s+.*)/ );
+ #
+ # Split on white space, except if preceded by \
+ # using zero-width negative look-behind assertion
+ # (always wanted to use one of those).
+ #
+ @fld = split(/(?<!\\)\s+/, $1);
+ #
+ # Remove any \
+ #
+ foreach ( @fld ) {
+ s{\\(\s)}{$1}g;
+ }
if ( @hdr ) {
if ( defined($host) ) {
next if ( lc($fld[0]) ne $host );
return $1;
}
+#
+# Given an IP address, return the host name and user name via
+# NetBios.
+#
sub NetBiosInfoGet
{
my($bpc, $host) = @_;
return (lc($netBiosHostName), lc($netBiosUserName));
}
+#
+# Given a NetBios name lookup the IP address via NetBios.
+#
+sub NetBiosHostIPFind
+{
+ my($bpc, $host) = @_;
+ my($netBiosHostName, $netBiosUserName);
+ my($s, $nmbCmd);
+
+ my $args = {
+ nmbLookupPath => $bpc->{Conf}{NmbLookupPath},
+ host => $host,
+ };
+ $nmbCmd = $bpc->cmdVarSubstitute($bpc->{Conf}{NmbLookupFindHostCmd}, $args);
+ my $resp = $bpc->cmdSystemOrEval($nmbCmd, undef, $args);
+ if ( $resp =~ /^\s*(\d+\.\d+\.\d+\.\d+)\s+\Q$host/m ) {
+ return $1;
+ } else {
+ return;
+ }
+}
+
sub fileNameEltMangle
{
my($bpc, $name) = @_;
return $cmd;
}
+#
+# For printing exec commands (which don't use a shell) so they look like
+# a valid shell command this function should be called with the exec
+# args. The shell command string is returned.
+#
+sub execCmd2ShellCmd
+{
+ my($bpc, @args) = @_;
+ my $str;
+
+ foreach my $a ( @args ) {
+ $str .= " " if ( $str ne "" );
+ $str .= $bpc->shellEscape($a);
+ }
+ return $str;
+}
+
+#
+# Do a URI-style escape to protect/encode special characters
+#
+sub uriEsc
+{
+ my($bpc, $s) = @_;
+ $s =~ s{([^\w.\/-])}{sprintf("%%%02X", ord($1));}eg;
+ return $s;
+}
+
+#
+# Do a URI-style unescape to restore special characters
+#
+sub uriUnesc
+{
+ my($bpc, $s) = @_;
+ $s =~ s{%(..)}{chr(hex($1))}eg;
+ return $s;
+}
+
#
# Do variable substitution prior to execution of a command.
#
if ( (ref($template) eq "ARRAY" ? $template->[0] : $template) =~ /^\&/ ) {
return $template;
}
- $template = [split(/\s+/, $template)] if ( ref($template) ne "ARRAY" );
+ if ( ref($template) ne "ARRAY" ) {
+ #
+ # Split at white space, except if escaped by \
+ #
+ $template = [split(/(?<!\\)\s+/, $template)];
+ #
+ # Remove the \ that escaped white space.
+ #
+ foreach ( @$template ) {
+ s{\\(\s)}{$1}g;
+ }
+ }
#
# Merge variables into @tarClientCmd
#
# Replace scalar variables first
#
$arg =~ s{\$(\w+)(\+?)}{
- defined($vars->{$1}) && ref($vars->{$1}) ne "ARRAY"
+ exists($vars->{$1}) && ref($vars->{$1}) ne "ARRAY"
? ($2 eq "+" ? $bpc->shellEscape($vars->{$1}) : $vars->{$1})
: "\$$1"
}eg;
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
# Simply create an empty file
#
local(*OUT);
- if ( !open(OUT, ">$a->{fileName}") ) {
+ if ( !open(OUT, ">", $a->{fileName}) ) {
push(@{$a->{errors}}, "Can't open $a->{fileName} for empty"
. " output\n");
} else {
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
$remoteDir =~ s{//+}{/}g;
$argList = ['--server', @$rsyncArgs, '.', $remoteDir];
$fioArgs = {
- host => $t->{bkupSrcHost},
+ client => $t->{bkupSrcHost},
share => $t->{bkupSrcShare},
viewNum => $t->{bkupSrcNum},
fileList => $t->{fileList},
$argList = ['--server', '--sender', @$rsyncArgs,
'.', $t->{shareNameSlash}];
$fioArgs = {
- host => $t->{host},
+ client => $t->{client},
share => $t->{shareName},
viewNum => $t->{lastFullBkupNum},
};
#
# Merge variables into $rsyncClientCmd
#
- $rsyncClientCmd = $bpc->cmdVarSubstitute($rsyncClientCmd,
- {
- host => $t->{host},
- hostIP => $t->{hostIP},
- shareName => $t->{shareName},
- shareNameSlash => $t->{shareNameSlash},
- rsyncPath => $conf->{RsyncClientPath},
- sshPath => $conf->{SshPath},
- argList => $argList,
- });
+ my $args = {
+ host => $t->{host},
+ hostIP => $t->{hostIP},
+ client => $t->{client},
+ shareName => $t->{shareName},
+ shareNameSlash => $t->{shareNameSlash},
+ rsyncPath => $conf->{RsyncClientPath},
+ sshPath => $conf->{SshPath},
+ argList => $argList,
+ };
+ $rsyncClientCmd = $bpc->cmdVarSubstitute($rsyncClientCmd, $args);
#
# Create the Rsync object, and tell it to use our own File::RsyncP::FileIO
$t->{rs} = File::RsyncP->new({
logLevel => $conf->{RsyncLogLevel},
rsyncCmd => sub {
- $bpc->cmdExecOrEval($rsyncClientCmd);
+ $bpc->cmdExecOrEval($rsyncClientCmd, $args);
},
rsyncCmdType => "full",
rsyncArgs => $rsyncArgs,
#
# Run rsync command
#
- $t->{XferLOG}->write(\"Running: @{$t->{rsyncClientCmd}}\n");
+ my $str = "Running: "
+ . $t->{bpc}->execCmd2ShellCmd(@{$t->{rsyncClientCmd}})
+ . "\n";
+ $t->{XferLOG}->write(\$str);
$rs->remoteStart($remoteSend, $remoteDir);
} else {
#
if ( defined(my $err = $rs->serverConnect($t->{hostIP},
$conf->{RsyncdClientPort})) ) {
$t->{hostError} = $err;
+ my $str = "Error connecting to rsync daemon at $t->{hostIP}"
+ . ":$conf->{RsyncdClientPort}: $err\n";
+ $t->{XferLOG}->write(\$str);
return;
}
#
$conf->{RsyncdUserName},
$conf->{RsyncdPasswd},
$conf->{RsyncdAuthRequired})) ) {
+ my $str = "Error connecting to module $module at $t->{hostIP}"
+ . ":$conf->{RsyncdClientPort}: $err\n";
+ $t->{XferLOG}->write(\$str);
$t->{hostError} = $err;
return;
}
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
$fio->{shareM} = $fio->{bpc}->fileNameEltMangle($fio->{share});
$fio->{outDir} = "$fio->{xfer}{outDir}/new/";
$fio->{outDirSh} = "$fio->{outDir}/$fio->{shareM}/";
- $fio->{view} = BackupPC::View->new($fio->{bpc}, $fio->{host},
+ $fio->{view} = BackupPC::View->new($fio->{bpc}, $fio->{client},
$fio->{backups});
$fio->{full} = $fio->{xfer}{type} eq "full" ? 1 : 0;
$fio->{newFilesFH} = $fio->{xfer}{newFilesFH};
#
unlink("$fio->{outDirSh}RStmp")
if ( -f "$fio->{outDirSh}RStmp" );
- if ( open(F, ">+$fio->{outDirSh}RStmp") ) {
+ if ( open(F, ">+", "$fio->{outDirSh}RStmp") ) {
my $data;
while ( $fh->read(\$data, 1024 * 1024) > 0 ) {
if ( syswrite(F, $data) != length($data) ) {
}
$fh->close;
} else {
- if ( open(F, $attr->{fullPath}) ) {
+ if ( open(F, "<", $attr->{fullPath}) ) {
$fio->{rxInFd} = *F;
$fio->{rxInName} = $attr->{fullPath};
} else {
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
my $bpc = $t->{bpc};
my $conf = $t->{conf};
my $I_option = $t->{hostIP} eq $t->{host} ? "" : " -I $t->{hostIP}";
- my($fileList, $optX, $smbClientCmd, $logMsg);
+ my(@fileList, $X_option, $smbClientCmd, $logMsg);
+ my($timeStampFile);
local(*SMB);
#
return;
}
if ( $t->{type} eq "restore" ) {
- $smbClientCmd =
- "$conf->{SmbClientPath} '\\\\$t->{host}\\$t->{shareName}'"
- . "$I_option -U '$conf->{SmbShareUserName}' -E -N -d 1"
- . " $conf->{SmbClientArgs}"
- . " -c 'tarmode full' -Tx -";
+ $smbClientCmd = $conf->{SmbClientRestoreCmd};
$logMsg = "restore started for share $t->{shareName}";
} else {
#
}
if ( defined($conf->{BackupFilesOnly}{$t->{shareName}}) ) {
foreach my $file ( @{$conf->{BackupFilesOnly}{$t->{shareName}}} ) {
- $file =~ s/'/\\'/g;
- $fileList .= "'$file' ";
+ push(@fileList, $file);
}
} elsif ( defined($conf->{BackupFilesExclude}{$t->{shareName}}) ) {
foreach my $file ( @{$conf->{BackupFilesExclude}{$t->{shareName}}} )
{
- $file =~ s/'/\\'/g;
- $fileList .= "'$file' ";
+ push(@fileList, $file);
}
#
# Allow simple wildcards in exclude list by specifying "r" option.
#
- $optX = "rX";
+ $X_option = "rX";
}
if ( $t->{type} eq "full" ) {
- $smbClientCmd =
- "$conf->{SmbClientPath} '\\\\$t->{host}\\$t->{shareName}'"
- . "$I_option -U '$conf->{SmbShareUserName}' -E -N -d 1"
- . " $conf->{SmbClientArgs}"
- . " -c 'tarmode full'"
- . " -Tc$optX - $fileList";
+ $smbClientCmd = $conf->{SmbClientFullCmd};
$logMsg = "full backup started for share $t->{shareName}";
} else {
- my $timeStampFile = "$t->{outDir}/timeStamp.level0";
- open(LEV0, ">$timeStampFile") && close(LEV0);
+ $timeStampFile = "$t->{outDir}/timeStamp.level0";
+ open(LEV0, ">", $timeStampFile) && close(LEV0);
utime($t->{lastFull} - 3600, $t->{lastFull} - 3600, $timeStampFile);
- $smbClientCmd =
- "$conf->{SmbClientPath} '\\\\$t->{host}\\$t->{shareName}'"
- . "$I_option -U '$conf->{SmbShareUserName}' -E -N -d 1"
- . " $conf->{SmbClientArgs}"
- . " -c 'tarmode full'"
- . " -TcN$optX $timeStampFile - $fileList";
+ $smbClientCmd = $conf->{SmbClientIncrCmd};
$logMsg = "incr backup started back to "
. $bpc->timeStamp($t->{lastFull} - 3600, 0)
. "for share $t->{shareName}";
}
}
+ my $args = {
+ smbClientPath => $conf->{SmbClientPath},
+ host => $t->{host},
+ hostIP => $t->{hostIP},
+ client => $t->{client},
+ shareName => $t->{shareName},
+ userName => $conf->{SmbShareUserName},
+ fileList => \@fileList,
+ I_option => $I_option,
+ X_option => $X_option,
+ timeStampFile => $timeStampFile,
+ };
+ $smbClientCmd = $bpc->cmdVarSubstitute($smbClientCmd, $args);
+
if ( !defined($t->{xferPid} = open(SMB, "-|")) ) {
$t->{_errStr} = "Can't fork to run smbclient";
return;
open(STDOUT, ">&$t->{pipeWH}");
}
#
- # exec smbclient.
+ # Run smbclient.
#
- exec($smbClientCmd);
+ $bpc->cmdExecOrEval($smbClientCmd, $args);
# should not be reached, but just in case...
$t->{_errStr} = "Can't exec $conf->{SmbClientPath}";
return;
}
- $t->{XferLOG}->write(\"Running: $smbClientCmd\n");
+ my $str = "Running: " . $bpc->execCmd2ShellCmd(@$smbClientCmd) . "\n";
+ $t->{XferLOG}->write(\$str);
alarm($conf->{ClientTimeout});
$t->{_errStr} = undef;
return $logMsg;
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#
local(*TAR);
if ( $t->{type} eq "restore" ) {
- if ( ref($conf->{TarClientRestoreCmd}) eq "ARRAY" ) {
- $tarClientCmd = $conf->{TarClientRestoreCmd};
- } else {
- $tarClientCmd = [split(/ +/, $conf->{TarClientRestoreCmd})];
- }
+ $tarClientCmd = $conf->{TarClientRestoreCmd};
$logMsg = "restore started below directory $t->{shareName}";
#
# restores are considered to work unless we see they fail
#
# Merge variables into @tarClientCmd
#
- $tarClientCmd = $bpc->cmdVarSubstitute($tarClientCmd, {
+ my $args = {
host => $t->{host},
hostIP => $t->{hostIP},
+ client => $t->{client},
incrDate => $incrDate,
shareName => $t->{shareName},
fileList => \@fileList,
tarPath => $conf->{TarClientPath},
sshPath => $conf->{SshPath},
- });
+ };
+ $tarClientCmd = $bpc->cmdVarSubstitute($tarClientCmd, $args);
if ( !defined($t->{xferPid} = open(TAR, "-|")) ) {
$t->{_errStr} = "Can't fork to run tar";
return;
#
# Run the tar command
#
- $bpc->cmdExecOrEval($tarClientCmd);
+ $bpc->cmdExecOrEval($tarClientCmd, $args);
# should not be reached, but just in case...
$t->{_errStr} = "Can't exec @$tarClientCmd";
return;
}
+ my $str = "Running: " . $bpc->execCmd2ShellCmd(@$tarClientCmd) . "\n";
$t->{XferLOG}->write(\"Running: @$tarClientCmd\n");
alarm($conf->{ClientTimeout});
$t->{_errStr} = undef;
#
#========================================================================
#
-# Version 1.6.0_CVS, released 10 Dec 2002.
+# Version 2.0.0_CVS, released 18 Jan 2003.
#
# See http://backuppc.sourceforge.net.
#