enabled self extracting pipe
authorHeiko Schlittermann <hs@schlittermann.de>
Wed, 23 Dec 2009 00:03:02 +0100
changeset 26 31219f147347
parent 25 9e90da3204e2
child 27 e40e33b52d0b
enabled self extracting pipe
ftbackup
--- 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.