#!/usr/bin/perl
# Import a BIND zone file
##
# Copyright 2020 Kris Deugau <kdeugau@deepnet.cx>
# 
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version. 
# 
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
# 
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
##

use strict;
use warnings;
use Data::Dumper;

use lib '.';
use DNSDB;

my $dnsdb = new DNSDB;

#print Dumper(\%reverse_typemap);

my $zname = shift @ARGV;
my $rev = 'n';
my $zid;

if ($zname =~ /\.arpa$/ || $zname =~ m,^[\d./]+$,) {
  $rev = 'y';
  $zname = _zone2cidr($zname) if $zname =~ /\.arpa$/;
  $zid = $dnsdb->revID($zname,':ANY:');
} else {
  $zid = $dnsdb->domainID($zname,':ANY:');
}

die "zone $zname not on file\n" if !$zid;

##fixme:  retrieve defttl from SOA record
my $zonettl = 900;

while (<>) {
  next if /^\s*$/;
  next if /^\s*;/;
  my ($name) = /([\w_.-]+)\s/;
  s/([\w_.-]+)\s+//;
  my ($class) = /(IN|CS|CH|HS)\s/;
  if ($class) {
    if ($class ne 'IN') {
      print "Non-Internet class records not supported, you weirdo\n";
      next;
    }
    s/(IN|CS|CH|HS)\s+//;
  } else {
    $class = 'IN' if !$class;
  }
  my ($ttl) = /(\d+)?\s/;
  if (defined $ttl) {
    # TTL may be zero
    s/(\d+)?\s+//;
  } else {
    # Fall back to zone default TTL
    $ttl = $zonettl;
  }
  my ($type) = /([A-Z-]+)\s/;
  if (!$reverse_typemap{$type}) {
    print "Unknown type $type, skipping\n";
    next;
  }
  my $itype = $reverse_typemap{$type};
  s/([A-Z-]+)\s+//;
  chomp;
  my $rdata = $_;

  # Quotes may arguably be syntactically required, but they're not actually part of the record data
  if ($itype == 16) {
    $rdata =~ s/^"//;
    $rdata =~ s/"$//;
  }

no warnings qw(uninitialized);
print "parsed: '$name' '$class' '$ttl' '$type'->'$itype' '$rdata'\t";
#print;
#;imap   IN      900     CNAME   deepnet.cx.
##fixme:  not sure how to handle the case where someone leaves off the class.
  my ($code,$msg) = $dnsdb->addRec('n', $rev, $zid, \$name, \$itype, \$rdata, $ttl);
  print "$code: $msg\n";
}
