--- a/ftbackup Tue Dec 15 10:46:54 2009 +0100
+++ b/ftbackup Wed Dec 23 00:03:02 2009 +0100
@@ -31,6 +31,7 @@
my $opt_dry = 0;
my $opt_force = 0;
my $opt_label = "daily";
+my $opt_config = "";
sub get_configs(@);
sub get_candidates();
@@ -58,6 +59,7 @@
"f|force" => \$opt_force,
"h|help" => sub { pod2usage(-exit => 0, -verbose => 1) },
"m|man" => sub { pod2usage(-exit => 0, -verbose => 3) },
+ "C|config=s" => sub { @CONFIGS = ($_[1]) },
) or pod2usage;
@@ -73,14 +75,18 @@
push @errors, "Need KEY (see config)." if not defined $cf{KEY};
die join "\n", @errors, "" if @errors;
- my $ftp = new FTP($cf{FTP_HOST},
- Passive => $cf{FTP_PASSIVE},
- Debug => @opt_debug ~~ /^ftp$/) or die $@;
- $ftp->login or die $ftp->message;
- $ftp->home($ftp->try(pwd => ()));
- $ftp->try(binary => ());
- $ftp->try(mkpath => $cf{FTP_DIR});
- $ftp->try(cwd => $cf{FTP_DIR});
+ my $ftp;
+
+ if (not @opt_debug ~~ /^output$/) {
+ $ftp = new FTP($cf{FTP_HOST},
+ Passive => $cf{FTP_PASSIVE},
+ Debug => @opt_debug ~~ /^ftp$/) or die $@;
+ $ftp->login or die $ftp->message;
+ $ftp->home($ftp->try(pwd => ()));
+ $ftp->try(binary => ());
+ $ftp->try(mkpath => $cf{FTP_DIR});
+ $ftp->try(cwd => $cf{FTP_DIR});
+ }
### @dev
@@ -91,20 +97,22 @@
$dir =~ s/\//_/g;
$dir = "$cf{FTP_DIR}/$dir";
- $ftp->home();
- $ftp->try(mkpath => $dir);
- $ftp->try(cwd => $dir);
+ my @last;
+ if ($ftp) {
+ $ftp->home();
+ $ftp->try(mkpath => $dir);
+ $ftp->try(cwd => $dir);
- verbose "Now in @{[$ftp->pwd]}.\n";
+ verbose "Now in @{[$ftp->pwd]}.\n" if $ftp;
- # examine the situation and decide about the level
- # FIXME: currently we simply run a full dump every FULL_CYCLE
- # days, the intermediate dumps are level 1
- my @last;
- foreach (reverse sort $ftp->ls) {
- /^(?<date>.*)\.(?<level>\d+)$/;
- $last[$+{level}] = $+{date};
- last if $+{level} == 0;
+ # examine the situation and decide about the level
+ # FIXME: currently we simply run a full dump every FULL_CYCLE
+ # days, the intermediate dumps are level 1
+ foreach (reverse sort $ftp->ls) {
+ /^(?<date>.*)\.(?<level>\d+)$/;
+ $last[$+{level}] = $+{date};
+ last if $+{level} == 0;
+ }
}
if (not defined $opt_level) {
@@ -112,8 +120,7 @@
($NOW - iso2epoch $last[0])/86400 > $cf{FULL_CYCLE} ? 0 : 1;
}
- my $file = strftime("%F_%R", localtime $NOW)
- . ".$opt_level";
+ my $file = strftime("%F_%R", localtime $NOW) . ".$opt_level";
my $label = "$NODE:" . basename($dev->{rdev});
verbose "\tdumping $dev->{dev} as $dev->{rdev} on $dev->{mountpoint} to $file\n";
next if $opt_dry;
@@ -158,33 +165,47 @@
$ENV{key} = $cf{KEY};
my $dumper = open(my $dump, "-|") or do {
- my $head = <<__;
+ print <<__HEAD;
#! /bin/bash
-if test "\$1" = "--info"; then
+LC_ALL=C
+if test -t 1 || test "$1" ; then
cat <<___
NODE : $NODE
-DATE : $NOW @{[localtime $NOW]}
+DATE : $NOW @{[scalar localtime $NOW]}
LEVEL : $opt_level
DEVICE : $dev->{dev}
REAL_DEVICE: $dev->{rdev}
MOUNTPOINT : $dev->{mountpoint}
FSTYPE : $dev->{fstype}
+
+# For recovery pass everything following the first
+# ^### START to „recover -rf -“. Or do one of the following
+# lines:
+# sh <THIS SCRIPT> | recover -rf -
+# sh <(ftpipe <URL>) | recover -rf -
___
exit 0
fi
-tail -c XXXXX \$0 | openssl enc -d -blowfish "\$@"
-exit
+while read; do
+ test "\$REPLY" = "### START" \\
+ && exec openssl enc -d -blowfish "\$@"
+done <"\$0"
-__
- # adjust the placeholder
- $head =~ s/XXXXX/sprintf "% 5s", "+" . (length($head) +1)/e;
- print $head;
+### START
+__HEAD
exec "dump -$opt_level -L $label -f- -u -z6 $dev->{dump}"
. "| openssl enc -pass env:key -salt -blowfish";
die "Can't exec dumper\n";
};
- $ftp->try(put => $dump, $file);
+ if ($ftp) {
+ $ftp->try(put => $dump, $file);
+ }
+ else {
+ print while <$dump>;
+ warn "STOPPED after the first dump\n";
+ exit;
+ }
$dev->{cleanup}->() if $dev->{cleanup};
verbose "Done.\n";
}
@@ -193,7 +214,7 @@
sub verbose(@) {
return if not $opt_verbose;
- print @_;
+ print STDERR @_;
}
sub get_candidates() {
@@ -343,7 +364,19 @@
Enables debugging for the specified items (comma separated).
If no item is specified, just some debugging is done.
-Valid items are B<ftp> and currently nothing else.
+Valid items are B<ftp>, B<output> and currently nothing else.
+
+=over
+
+=item B<ftp>
+
+This switches on debugging of the used L<Net::FTP> module.
+
+=item B<output>
+
+The output is not sent via FTP but to stdoud. Beware!
+
+=back
Even more debugging is shown using the DEBUG=1 environment setting.