#!/usr/bin/perl
#
# charon by Stefan Tomanek <stefan.tomanek@wertarbyte.de>
#              http://wertarbyte.de/tartarus.shtml
#
# This script will remove tartarus backup files from an FTP server
# that have reached a certain age.
#
# WARNING: This script will delete your backup data when called
# improperly

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

# your backup FTP server
my $host = undef;
# username and password
my ($user, $pass) = (undef, "");
my $read_password = 0;
my $dir = "/";

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

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

sub usage {
    my ($error) = @_;
    print <<EOF;
charon.pl by Stefan Tomanek <stefan.tomanek\@wertarbyte.de>

    --host          FTP server to connect to
    --user          username to authenticate with
    --password      password to authenticate with
    --readpassword  read password from stdin
    --dir           server directory of the backup files
    --maxage        maximum age of backup files (in days)
    --profile       backup profile name to process
    --all           process all files found in the directory
    --dry-run       do a test run, don't actually delete files
    --verbose       be more verbose about the actions made
    --help          show this help text
EOF
    if (defined $error) {
        print "\n$error\n";
    }
    exit 1;
}

GetOptions(
    "host|h|server=s"   => \$host,
    "username|user|u=s" => \$user,
    "password|p=s"      => \$pass,
    "readpassword|r"    => \$read_password,
    "maxage|m=i"        => \$days_to_expire,
    "profile|p=s"       => \$uprofile,
    "all|a"             => \$all,
    "directory|dir|d=s" => \$dir,
    "test|dry-run|n"    => \$dry_run,
    "verbose|v"         => \$verbose,
    "help|h"            => \$help
) || usage();

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

if ($read_password) {
    print STDERR "Reading password:" if $verbose;
    while (<STDIN>) {
        $pass .= $_;
    }
    print STDERR " Thank you.\n" if $verbose;
}

my $ftp = Net::FTP->new($host, Debug => 0, Passive => 1) || die "Unable to connect to server";
$ftp->login($user, $pass) || die "Unable to authenticate, ", $ftp->message();
$ftp->cwd($dir) || die "Error changing to backup directory, ", $ftp->message();
my @listing = $ftp->ls();

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

# if $uprofile is undefined, the filter works on all profiles
for my $file ($c->expire($days_to_expire, $uprofile)) {
    print STDERR "Removing file $file...\n";
    unless ($dry_run) {
        $ftp->delete("$file") || print STDERR "Error removing $file!\n";
    }
}

$ftp->quit();
