#!/usr/bin/perl
#
# charon.pipe by Stefan Tomanek <stefan.tomanek@wertarbyte.de>
#              http://wertarbyte.de/tartarus.shtml
#
# This script filters filters tartarus backup filenames passed
# through stdin and print expired ones on stdout.

use strict;
use warnings;
use Getopt::Long;
use Tartarus::Charon::Filter;

my $zero_termination = 0;
my $days_to_expire = undef;
my $uprofile = undef;
my $all = 0;

my $dry_run = 0;
my $verbose = 0;
my $help = 0;

=pod

=head1 NAME

charon.pipe - filter filenames generated by tartarus and print those exceeding a certain age

=head1 SYNOPSIS

B<charon.pipe> [--null|-0] --maxage I<days> (--profile I<identifier>| --all) [--dry-run] [--verbose] [--help]

=head1

This program is swiss-army-knife of the charon suite. It does not operate on files
itself, but exposes the filtering mechanism of the Tartarus::Charon::Filter module
to shell scripting. It does read filenames from its standard input and processes the
filenames supplied, writing the filenames of expired files to the standard output.

=head1 OPTIONS AND ARGUMENTS

=over

=item B<--null> | B<-0>

Setting this parameter makes charon.local use \0 as filename
separator instead of newline, allowing it to process even more
exotic filenames and collaboration with tools like find or xargs.

=item B<--maxage> I<n>

Set the maximum number of days after which a backup is expired.

=item B<--profile> I<name>

Set the profile name to process. This is mandatory unless B<--all> is supplied.

=item B<--all>

This options makes charon.pipe process the filenames of all profiles.

=item B<--dry-run>

This option prevents charon from actually deleting files.

=item B<--verbose>

This option makes charon more verbose about the actions made

=item B<--help>

This parameter shows a brief command reference.

=back

=head1 EXAMPLE

Charon.pipe can be used to emplay custom cleanup scripts, for example by gathering
filenames through an SSH connection. It can also be used for testing purposes:

    $ find -maxdepth 1 -type f -printf '%f\0' | charon.local -0 --maxage 7 --all | xargs -0 -- ls -l

=head1 AUTHOR

Stefan Tomanek E<lt>stefan.tomanek@wertarbyte.deE<gt>

=cut

sub usage {
    my ($error) = @_;
    print <<EOF;
charon.pipe by Stefan Tomanek <stefan.tomanek\@wertarbyte.de>
    
    --null|-0       filenames are terminated by the null character
    --maxage        maximum age of backup files (in days)
    --profile       backup profile name to process
    --all           process all files found in the directory
    --verbose       be more verbose about the actions made
    --help          show this help text
EOF
    if (defined $error) {
        print "\n$error\n";
    }
    exit 1;
}

GetOptions(
    "null|0!"           => \$zero_termination,
    "maxage|m=i"        => \$days_to_expire,
    "profile|p=s"       => \$uprofile,
    "all|a"             => \$all,
    "verbose|v"         => \$verbose,
    "help|h"            => \$help
) || usage();

usage "No expiration age given" unless defined $days_to_expire;
usage "Neither --all nor a single backup profile specified" unless ($all || defined $uprofile);

$/ = $zero_termination ? "\0" : "\n";

my @listing = ();
while (<STDIN>) {
    chop;
    push @listing, $_;
}

my $c = new Tartarus::Charon::Filter();
$c->verbose($verbose);
$c->files( @listing );

# if $uprofile is undefined, the filter works on all profiles
for ($c->expire($days_to_expire, $uprofile)) {
    print $_, $/;
}
