#!/usr/bin/perl =head1 NAME Brackup - Flexible backup tool. Slices, dices, encrypts, and sprays across the net. =head1 SYNOPSIS $ brackup --from= --to= --output=my_backup.brackup =head2 OPTIONS =over 4 =item --from=NAME Required. The source of your backup. Must match a [SOURCE:NAME] config section in your ~/.brackup.conf (which is auto-created for you on first run, so then you just have to go modify it) =item --to=NAME Required. The destination for your backup. Must match a [TARGET:NAME] config section in your ~/.brackup.conf =item --output=FILE Option. Defaults to "source-YYYYMMDD.brackup". This is the "metafile" index you'll need to restore. =item --verbose|-v Show status during backup. =back =head1 WARRANTY Brackup is distributed as-is and comes without warranty of any kind. It'll probably eat your files, kick your cat, and knock up your mother. You've been warned. If you feel like trusting it with your data, why don't you audit it first? =head1 SEE ALSO brackup-restore =head1 AUTHOR Brad Fitzpatrick Ebrad@danga.comE Copyright (c) 2006 Six Apart, Ltd. All rights reserved. This module is free software. You may use, modify, and/or redistribute this software under the terms of same terms as perl itself. =cut use strict; use warnings; use Getopt::Long; use Cwd; use FindBin qw($Bin); use lib "$Bin/lib"; use Brackup; my ($src_name, $target_name, $backup_file, $opt_help); my $opt_dryrun; my $opt_verbose; my $opt_du_stats; my $config_file = Brackup::Config->default_config_file_name; usage() unless GetOptions( 'from=s' => \$src_name, 'to=s' => \$target_name, 'verbose' => \$opt_verbose, 'output=s' => \$backup_file, 'help' => \$opt_help, 'dry-run' => \$opt_dryrun, 'du-stats' => \$opt_du_stats, 'config=s' => \$config_file, ); usage() if @ARGV; if ($opt_help) { eval "use Pod::Usage;"; Pod::Usage::pod2usage( -verbose => 1, -exitval => 0 ); exit 0; } my $config = eval { Brackup::Config->load($config_file) } or usage($@); if ($opt_du_stats && $src_name) { my $root = eval { $config->load_root($src_name); } or die "Bogus --from name"; $root->du_stats; exit 0; } usage() unless $src_name && $target_name; my $cwd = getcwd(); sub usage { my $why = shift || ""; if ($why) { $why =~ s/\s+$//; $why = "Error: $why\n\n"; } die "${why}brackup --from=[source_name] --to=[target_name] [--output=]\nbrackup --help\n"; } my $root = eval { $config->load_root($src_name); } or usage($@); my $target = eval { $config->load_target($target_name); } or usage($@); my @now = localtime(); $backup_file ||= $root->name . "-" . sprintf("%04d%02d%02d", $now[5]+1900, $now[4]+1, $now[3]) . ".brackup"; $backup_file =~ s!^~/!$ENV{HOME}/! if $ENV{HOME}; $backup_file = "$cwd/$backup_file" unless $backup_file =~ m!^/!; my $backup = Brackup::Backup->new( root => $root, target => $target, dryrun => $opt_dryrun, verbose => $opt_verbose, ); if (my $stats = eval { $backup->backup($backup_file) }) { warn "Backup complete." if $opt_verbose; if ($opt_dryrun || $opt_verbose) { $stats->print; } exit 0; } else { warn "Error running backup: $@\n"; exit 1; }