#!/usr/bin/perl

use Net::DNS;
use Date::Parse;
use Net::DNS::SEC::Tools::timetrans;
use Net::DNS::SEC::Tools::QWPrimitives;

my %opts;
DTGetOptions(\%opts,
	     ['GUI:VERSION',           "DNSSEC-Tools Version: 2.1"],
	     ['GUI:otherargs_text',    "ZONENAME [ZONENAME...]"],
	     
	     ['m|minimum-reporting=s',
	                  "Minimum reporting time, or else be silent for the zone"],
    );

if ($#ARGV == -1) {
    print STDERR "You must specify at least one ZONENAME for this tool to do anything useful\n";
    exit 1;
}

my $res    = Net::DNS::Resolver->new;
my $count = 0;

foreach my $zone (@ARGV) {
    my $query  = $res->query($zone, "RRSIG");
    if ($query) {
	my $rrsig = ($query->answer)[0];
	my $enddate = $rrsig->sigexpiration();
	$enddate =~ s/^(....)(..)(..)(..)(..)(..)/$1-$2-$3 $4:$5:$6/;
	my $epochtime = str2time($enddate);
	my $delta = $epochtime - time();

	if (!defined($opts{'m'}) || $delta <= $opts{'m'}) {
	    $count++;
	    # 22 characters for zone should almost always print < 80 total
	    printf("%-22.22s will expire in %s\n", $zone, timetrans($delta));
	}
    } else {
	print "Failed to query for RRSIGs for '$zone'\n";
	print "This can happen because the authoritative server for the zone\n";
	print "or the local resolver doesn't support querying for RRSIGs\n";
    }
}

if (!defined($opts{'m'}) && $count > 0) {
    exit 1;
}


1;

=pod

=head1 NAME

check-zone-expiration - displays how long until a zone's records expire

=head1 SYNOPSIS

# check-zone-expiration dnssec-tools.org paypal.com
dnssec-tools.org    will expire in 26 days, 2 hours, 16 minutes, 36 seconds
paypal.com          will expire in 12 days, 17 hours, 7 minutes, 1 second

# check-zone-expiration -m 1123200 dnssec-tools.org paypal.com 
paypal.com          will expire in 12 days, 17 hours, 6 minutes, 22 seconds

=head1 DESCRIPTION

The check-zone-exiration script reports how long until a zone will
expire by querying for the zone's (top level) RRSIG and calculating
how much time is left before the signatures will no longer be valid.
It will then report how much time is left in human readable form.

If the -m switch is provided with a time argument (in seconds), it
will only print output for zones that have less than that time left.

=head1 OPTIONS

=over

=item  -m STRING

=item  --minimum-reporting=STRING

Minimum reporting time, or else be silent for the zone

=back

=head1 COPYRIGHT

Copyright 2012-2014 SPARTA, Inc.  All rights reserved.
See the COPYING file included with the DNSSEC-Tools package for details.

=head1 AUTHOR

Wes Hardaker, hardaker@tislabs.com

=head1 SEE ALSO

B<donuts(1)>

=cut

