#!/usr/bin/perl -Tw
#
#  $Id: canondig,v 1.3 2002/07/06 21:53:52 dgregor Exp $
#
# Copyright (c) 1998,2000 Daniel J. Gregor, Jr., All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
#    must display the following acknowledgement:
# 	This product includes software developed by Daniel J. Gregor, Jr.
# 4. The name of Daniel J. Gregor, Jr. may not be used to endorse or promote
#    products derived from this software without specific prior written
#    permission.
# 
# THIS SOFTWARE IS PROVIDED BY DANIEL J. GREGOR, JR. ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL DANIEL J. GREGOR, JR. BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
# 

use Getopt::Std;

$progname = "canondig";

$usage = << "EOF";
usage:
	dig <dig options> | $progname [-d]
	$progname -h
EOF

getopts('dh', \%opts) || die $usage;

if (defined($opts{'h'})) {
	die $usage;
}

$origin = "";

while (<>) {
	chomp();		# kill newline
	s/;.*//;		# kill comments
	m/^\s*$/ && next;	# skip empty lines

	m/^\$ORIGIN\s+([a-z0-9.-]+)/i && do {
		$origin = $1;
		next;
	};

	m/^(\s+|\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)(\s+(\S+))?(.+)?$/ || do {
		warn "could not parse line $.: \"$_\"\n";
		next;
	};

	$host = $1;
	$ttl = $2;
	$class = $3;
	$type = $4;
	$val = $5;
	$addl = "";
	$addl = $7 if defined($7);

	$other = "";
	if (defined($8) && $8 =~ m/^(.*\(.*)$/) {
		$other .= $1;
		while (!($other =~ m/\)/) && defined($_ = <>)) {
			chomp();		# kill newline
			s/;.*//;		# kill comments
			m/^\s*$/ && next;	# skip empty lines
			s/^\s*//;		# kill extra whitespace
			s/\s*$//;		# kill extra whitespace

			$other .= " " . $_;
		}
	}

	if ($opts{'d'}) {
		print STDERR "line number: $.\n";
		print STDERR "input line: \"$_\"\n";
		print STDERR "parsed host: $host\n";
		print STDERR "parsed ttl: $ttl\n";
		print STDERR "parsed class: $class\n";
		print STDERR "parsed type: $type\n";
		print STDERR "parsed val: $val\n";
		print STDERR "parsed addl: $addl\n";
		print STDERR "parsed other: $other\n";
		print STDERR "\n";
	}

	$host = $origin if ($host eq "@");
	$host = $lasthost if ($host =~ m/^\s*$/);
	$host .= "." . $origin unless ($host =~ m/\.$/);

	$class =~ m/^in$/i && do {
		$type =~ m/^(cname|ptr)$/i && do {
			$val .= "." . $origin unless ($val =~ m/\.$/);
		};
		$type =~ m/^mx$/i && do {
			$addl .= "." . $origin unless ($addl =~ m/\.$/);
		};
	};

	print "$host\t$ttl\t$class\t$type\t$val\t$addl\t$other\n";

	$lasthost = $host;
}
