diff options
Diffstat (limited to 'leo.pl')
-rwxr-xr-x | leo.pl | 184 |
1 files changed, 78 insertions, 106 deletions
diff --git a/leo.pl b/leo.pl index 6ff74c2..135b3d7 100755 --- a/leo.pl +++ b/leo.pl @@ -7,28 +7,28 @@ use IPC::Run3; use Path::Tiny; use Config::Tiny; use POSIX qw(strftime); -use Getopt::Long qw/ GetOptions /; -my $version = "leo v0.4.4"; +die "usage: leo [-hpvV] <profile>\n" unless scalar @ARGV; -# Options. -my %options = ( - L_SIGN => $ENV{L_SIGN}, - L_GZIP => $ENV{L_GZIP}, - L_ENCRYPT => $ENV{L_ENCRYPT}, - L_SIGNIFY => $ENV{L_SIGNIFY}, -); +my ($VERBOSE, $PRINT_PROFILES); +my $VERSION = "v0.5.0"; -GetOptions( - \%options, - qw{ verbose help version } -) or die "leo: error in command line arguments\n"; +# Dispatch table to be parsed before url. +my %dispatch = ( + '-V' => sub { print "Leo $VERSION\n"; exit; }, + '-v' => sub { $VERBOSE = 1; }, + '-h' => \&HelpMessage, + '-p' => sub { $PRINT_PROFILES = 1; }, +); +if (exists $dispatch{$ARGV[0]}) { + # shift @ARGV to get profile in next shift. + $dispatch{shift @ARGV}->(); +} -# Print version. -print $version, "\n" and exit 0 if $options{version}; +# Set umask. +umask 077; # Configuration. - my $config_file = $ENV{XDG_CONFIG_HOME} || "$ENV{HOME}/.config"; $config_file .= "/leo.conf"; @@ -37,25 +37,16 @@ $config = Config::Tiny->read( $config_file ) or die "Cannot read config file: `$config_file'\n"; # Reading config file. - +my %options; foreach my $key (sort keys $config->{_}->%*) { $options{$key} = $config->{_}->{$key}; } -# Die if user is using older config format. -die "leo: old config format detected\n" - if exists $options{encrypt} or exists $options{sign}; - my %profile; - +# Iterate through all sections in config file, we call this profile. foreach my $prof (sort keys $config->%*) { next if $prof eq "_"; - # Set global values to local profiles. - foreach (qw(L_ENCRYPT L_SIGN L_SIGNIFY L_GZIP)) { - $profile{$prof}{$_} = $options{$_}; - } - foreach my $key (sort keys $config->{$prof}->%*) { # $profile{$prof} contains config values ($), {exclude} # (@), {backup} (@). @@ -74,53 +65,41 @@ foreach my $prof (sort keys $config->%*) { } } -my $date = date(); my $backup_dir = $options{backup_dir} || "/tmp/backups"; - -my @gpg_recipients; -@gpg_recipients = split / /, $options{gpg_recipients} - if $options{gpg_recipients}; - -my $gpg_bin = $options{gpg_bin} || "gpg"; -warn "[WARN] \$gpg_bin is set to `$gpg_bin'" - unless $gpg_bin =~ /^(gpg2?)$/; - -# Print help. -HelpMessage() and exit 0 if scalar @ARGV == 0 or $options{help}; +PrintProfiles() if $PRINT_PROFILES; # Parsing the arguments. foreach my $prof ( @ARGV ) { if ( $profile{ $prof } ) { print "-------- $prof"; - print " [Encrypt]" if $profile{$prof}{L_ENCRYPT}; - print " [Sign]" if $profile{$prof}{L_SIGN}; - print " [Signify]" if $profile{$prof}{L_SIGNIFY}; - print " [gzip]" if $profile{$prof}{L_GZIP}; + print " [GnuPG]" if $profile{$prof}{L_GnuPG}; + print " [Signify]" if $profile{$prof}{L_signify}; print "\n"; - my $file = "$backup_dir/${prof}/${date}.tar"; - $file .= ".gz" if $profile{$prof}{L_GZIP}; - - path("$backup_dir/${prof}")->mkpath; # Create backup directory. - backup($prof, $file); + # Create backup directory. + path("$backup_dir/${prof}")->mkpath; - my $is_gpg_req = 1 if $profile{$prof}{L_SIGN} or $profile{$prof}{L_ENCRYPT}; - encrypt_sign($prof, $file) if $is_gpg_req; + my $date = date(); + my $file = "$backup_dir/${prof}/${date}.tgz"; - # gpg would've removed the `.tar' file. - $file = "${file}.gpg" if $is_gpg_req; - signify($prof, $file) if $profile{$prof}{L_SIGNIFY}; + run_tar($prof, $file); + run_gnupg($prof, $file) and $file = "${file}.gpg" + if $profile{$prof}{L_GnuPG}; + run_signify($prof, $file) if $profile{$prof}{L_signify}; } else { - warn "[WARN] leo: no such profile :: `$prof' \n"; + warn "leo: no such profile :: `$prof' \n"; } } -sub backup { +sub run_tar { my $prof = shift @_; - my $tar_file = shift @_; + my $file = shift @_; - my @options = ("-C", "/"); - push @options, "-z" if $profile{$prof}{L_GZIP}; + my @options = ( "-c", + "-f", $file, + "-C", '/', + "-z"); + push @options, "-v" if $options{verbose}; my @backup_paths; foreach my $path ($profile{$prof}{backup}->@*) { @@ -140,53 +119,47 @@ sub backup { @backup_paths = grep !/$exclude/, @backup_paths; } - # All paths should be relative to '/'. + # All paths should be relative to '/. @backup_paths = map { $_->relative('/') } @backup_paths; - tar_create($tar_file, @options, @backup_paths); + run3 ["/bin/tar", @options, @backup_paths]; $? # tar returns 1 on errors. ? die "Backup creation failed :: $?\n" - : print "Backup: $tar_file\n"; - - path($tar_file)->chmod(0600); - print "File was compressed with gzip(1).\n" - if $profile{$prof}{L_GZIP} and $options{verbose}; - - tar_list($tar_file) if $options{verbose}; + : print "Backup: $file\n"; } -# Encrypt, Sign backups. -sub encrypt_sign { +sub run_gnupg { my $prof = shift @_; my $file = shift @_; - my @options = (); - push @options, "--default-key", $options{gpg_fingerprint} + my @options = ( "--sign", "--encrypt", + "--yes", + "-o", "${file}.gpg" + ); + + push @options, + "--default-key", $options{gpg_fingerprint}, + "--recipient", $options{gpg_fingerprint} if $options{gpg_fingerprint}; - if ( $profile{$prof}{L_ENCRYPT} ) { - push @options, "--encrypt"; - push @options, "--recipient", $options{gpg_fingerprint} - if $options{gpg_fingerprint}; - push @options, "--recipient", $_ - foreach @gpg_recipients; - } + # Add recipients. + my @gpg_recipients; + @gpg_recipients = split / /, $options{gpg_recipients} + if $options{gpg_recipients}; + push @options, "--recipient", $_ foreach @gpg_recipients; - push @options, "--sign" if $profile{$prof}{L_SIGN}; push @options, "--verbose" if $options{verbose}; - run3 [$gpg_bin, "--yes", "-o", "${file}.gpg", @options, $file]; + run3 ["/usr/local/bin/gpg2", @options, $file]; $? # We assume non-zero is an error. - ? die "GPG failed :: $?\n" - : print "GPG: $file.gpg\n"; - - unlink $file or warn "[WARN] Could not delete `$file': $!\n"; + ? die "GnuPG failed :: $?\n" + : print "GnuPG: $file.gpg\n"; - path("$file.gpg")->chmod(0600); + unlink $file or warn "leo: Could not delete `$file': $!\n"; } -sub signify { +sub run_signify { my $prof = shift @_; my $file = shift @_; @@ -202,32 +175,31 @@ sub signify { : print "Signify: ${file}.sig\n"; } -sub HelpMessage { - print qq{Backup files to $backup_dir. - -Profile:\n}; +sub PrintProfiles { + print "Profile:\n"; foreach my $prof (sort keys %profile) { print " $prof"; - if ($options{verbose}) { - print " [Encrypt]" if $profile{$prof}{L_ENCRYPT}; - print " [Sign]" if $profile{$prof}{L_SIGN}; - print " [Signify]" if $profile{$prof}{L_SIGNIFY}; - print " [gzip]" if $profile{$prof}{L_GZIP}; - print "\n"; - - print " + $_\n" foreach $profile{$prof}{backup}->@*; - print " - $_\n" foreach $profile{$prof}{exclude}->@*; - } + print " [GnuPG]" if $profile{$prof}{L_GnuPG}; + print " [Signify]" if $profile{$prof}{L_signify}; + print "\n"; + + print " + $_\n" foreach $profile{$prof}{backup}->@*; + print " - $_\n" foreach $profile{$prof}{exclude}->@*; print "\n"; } +} +sub HelpMessage { print qq{Options: - --version [$version] - --verbose - --help + -V [$VERSION] + Print version. + -v + Increase verbosity. + -p + Print profiles. + -h + Print help. }; + exit; } -sub tar_create { run3 ["/bin/tar", "cf", @_]; } -sub tar_list { print "\n"; run3 ["/bin/tar", "tvf", @_]; print "\n";} - sub date { return strftime '%FT%T%z', localtime() } |