Index: trunk/tiny-import.pl
===================================================================
--- trunk/tiny-import.pl	(revision 348)
+++ trunk/tiny-import.pl	(revision 353)
@@ -38,4 +38,5 @@
 my %cnt;
 my @deferred;
+my $errstr = '';
 
 foreach my $file (@ARGV) {
@@ -48,5 +49,5 @@
   if ($@) {
     print "bleh: $@\n";
-die "die harder\n";
+die "die harder: $errstr\n";
   }
 }
@@ -65,4 +66,6 @@
   our $recsth = $dbh->prepare("INSERT INTO records (domain_id,rdns_id,host,type,val,distance,weight,port,ttl) ".
 	" VALUES (?,?,?,?,?,?,?,?,?)");
+
+  my %deleg;
 
   while (<FLAT>) {
@@ -79,6 +82,8 @@
   }
 
+print scalar(@deferred)." deferred records in $flatfile\n";
+
   # Sub for various nonstandard types with lots of pure bytes expressed in octal
-  # Takes a tinydns rdata string and count, returns a lis of $count bytes as well
+  # Takes a tinydns rdata string and count, returns a list of $count bytes as well
   # as trimming those logical bytes off the front of the rdata string.
   sub _byteparse {
@@ -103,4 +108,13 @@
   }
 
+  # Convert octal-coded bytes back to something resembling normal characters, general case
+  sub _deoctal {
+    my $targ = shift;
+    while ($$targ =~ /\\(\d{3})/) {
+      my $sub = chr(oct($1));
+      $$targ =~ s/\\$1/$sub/g;
+    }
+  }
+
   sub recslurp {
     my $rec = shift;
@@ -114,15 +128,15 @@
 #=sud-rr-iGi0-1_sud-gw1-iGi4-2.vianet.ca::10.10.10.13:900::in
 }
-      my ($host,$ip,$ttl,$time,$loc) = split /:/, $rec;
+      my ($host,$ip,$ttl,$stamp,$loc) = split /:/, $rec, 5;
       $host =~ s/^=//;
       $host =~ s/\.$//;
-      $time = '' if !$time;
-      $loc = '' if !$loc;
-      print "bleh, bad A+PTR!  $rec\n" if $loc =~ /:/;
+      $ttl = 0 if !$ttl;
+      $stamp = '' if !$stamp;
+      $loc = '' if !$loc;
+      $loc = '' if $loc =~ /^:+$/;
       my $fparent = DNSDB::_hostparent($dbh, $host);
       my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($ip));
       if ($fparent && $rparent) {
-	$dbh->do("INSERT INTO records (domain_id,rdns_id,host,type,val,ttl) VALUES (?,?,?,?,?,?)", undef,
-      		($fparent, $rparent, $host, 65280, $ip, $ttl));
+	$recsth->execute($fparent, $rparent, $host, 65280, $ip, 0, 0, 0, $ttl);
       } else {
 	push @deferred, $rec unless $nodefer;
@@ -132,15 +146,30 @@
     } elsif ($rec =~ /^C/) {
       $cnt{CNAME}++;
-      my ($host,$targ,$ttl,$time,$loc) = split /:/, $rec;
+      my ($host,$targ,$ttl,$stamp,$loc) = split /:/, $rec, 5;
       $host =~ s/^C//;
       $host =~ s/\.$//;
-      $time = '' if !$time;
-      $loc = '' if !$loc;
-      my $fparent = DNSDB::_hostparent($dbh, $host);
-      if ($fparent) {
-
-      } else {
-	push @deferred, $rec unless $nodefer;
-	#  print "$tmporig deferred;  can't find parent zone\n";
+      $ttl = 0 if !$ttl;
+      $stamp = '' if !$stamp;
+      $loc = '' if !$loc;
+      $loc = '' if $loc =~ /^:+$/;
+      if ($host =~ /\.arpa$/) {
+	($code,$msg) = DNSDB::_zone2cidr($host);
+	my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($msg));
+	$recsth->execute(0, $rparent, $targ, 5, $msg->addr, 0, 0, 0, $ttl);
+
+##fixme:  automagically convert manually maintained sub-/24 delegations
+#	my ($subip, $zone) = split /\./, $targ, 2;
+#	($code, $msg) = DNSDB::_zone2cidr($zone);
+#	push @{$deleg{"$msg"}{iplist}}, $subip;
+#print "$msg $subip\n";
+
+      } else {
+	my $fparent = DNSDB::_hostparent($dbh, $host);
+	if ($fparent) {
+	  $recsth->execute($fparent, 0, $host, 5, $targ, 0, 0, 0, $ttl);
+	} else {
+	  push @deferred, $rec unless $nodefer;
+	  #  print "$tmporig deferred;  can't find parent zone\n";
+	}
       }
 
@@ -154,24 +183,24 @@
       $cnt{SOA}++;
 #Z128.91.209.in-addr.arpa:ns1.vianet.ca.:dnsadmin.vianet.ca.::1209600:1209600:900:900:900:
-      my ($zone,$master,$contact,$serial,$refresh,$retry,$expire,$minttl,$ttl,$time,$loc) = split /:/, $rec;
+      my ($zone,$master,$contact,$serial,$refresh,$retry,$expire,$minttl,$ttl,$stamp,$loc) = split /:/, $rec, 11;
       $zone =~ s/^Z//;
       $zone =~ s/\.$//;
       $master =~ s/\.$//;
       $contact =~ s/\.$//;
-      $time = '' if !$time;
-      $loc = '' if !$loc;
+      $ttl = 0 if !$ttl;
+      $stamp = '' if !$stamp;
+      $loc = '' if !$loc;
+      $loc = '' if $loc =~ /^:+$/;
       if ($zone =~ /\.arpa$/) {
 	($code,$msg) = DNSDB::_zone2cidr($zone);
 	$dbh->do("INSERT INTO revzones (revnet,group_id,status) VALUES (?,1,1)", undef, ($msg));
 	my ($rdns) = $dbh->selectrow_array("SELECT currval('revzones_rdns_id_seq')");
-	$dbh->do("INSERT INTO records (rdns_id,host,type,val,ttl) VALUES (?,?,6,?,?)", undef,
-		($rdns, "$contact:$master", "$refresh:$retry:$expire:$minttl", $ttl));
+        $recsth->execute(0, $rdns, "$contact:$master", 6, "$refresh:$retry:$expire:$minttl", 0, 0, 0, $ttl);
       } else {
 	$dbh->do("INSERT INTO domains (domain,group_id,status) VALUES (?,1,1)", undef, ($zone));
 	my ($domid) = $dbh->selectrow_array("SELECT currval('domains_domain_id_seq')");
-	$dbh->do("INSERT INTO records (rdns_id,host,type,val,ttl) VALUES (?,?,6,?,?)", undef,
-		($domid, "$contact:$master", "$refresh:$retry:$expire:$minttl", $ttl));
-      }
-
+        $recsth->execute($domid, 0, "$contact:$master", 6, "$refresh:$retry:$expire:$minttl", 0, 0, 0, $ttl);
+      }
+      return;  # since we don't use the "standard" record-add call at the bottom
     } elsif ($rec =~ /^\@/) {
       $cnt{MX}++;
@@ -179,17 +208,12 @@
       $cnt{TXT}++;
 
-sub _deoctal {
-  my $targ = shift;
-  while ($$targ =~ /\\(\d{3})/) {
-    my $sub = chr(oct($1));
-    $$targ =~ s/\\$1/$sub/g;
-  }
-}
-
-      my ($fqdn, $rdata, $ttl, $time, $loc) = split /:/, $rec;
+      my ($fqdn, $rdata, $ttl, $stamp, $loc) = split /:/, $rec, 5;
       $fqdn =~ s/^'//;
       _deoctal(\$rdata);
-
-print "$fqdn TXT '$rdata'\n" if $fqdn =~ /^\*/;
+      $ttl = 0 if !$ttl;
+      $stamp = '' if !$stamp;
+      $loc = '' if !$loc;
+      $loc = '' if $loc =~ /^:+$/;
+
       my $domid = DNSDB::_hostparent($dbh, $fqdn);
       if ($domid) {
@@ -201,4 +225,50 @@
     } elsif ($rec =~ /^\./) {
       $cnt{NSASOA}++;
+      my ($fqdn, $ip, $ns, $ttl, $stamp, $loc) = split /:/, $rec, 6;
+      $fqdn =~ s/^\.//;
+      $fqdn =~ s/\.$//;
+      $ns =~ s/\.$//;
+      $ns = "$ns.ns.$fqdn" if $ns !~ /\./;
+      $ttl = 0 if !$ttl;
+      $stamp = '' if !$stamp;
+      $loc = '' if !$loc;
+      $loc = '' if $loc =~ /^:+$/;
+
+      if ($fqdn =~ /\.arpa$/) {
+	($code,$msg) = DNSDB::_zone2cidr($fqdn);
+	my ($rdns) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet = ?", undef, ($msg));
+	if (!$rdns) {
+	  $errstr = "adding revzone $msg";
+	  $dbh->do("INSERT INTO revzones (revnet,group_id,status) VALUES (?,1,1)", undef, ($msg));
+	  ($rdns) = $dbh->selectrow_array("SELECT currval('revzones_rdns_id_seq')");
+# this would probably make a lot more sense to do hostmaster.$config{admindomain}
+          $recsth->execute(0, $rdns, "hostmaster.$fqdn:$ns", 6, "16384:2048:1048576:2560", 0, 0, 0, "2560");
+	}
+	$recsth->execute(0, $rdns, $ns, 2, "$msg", 0, 0, 0, $ttl);
+##fixme:  (?)  implement full conversion of tinydns . records?
+# -> problem:  A record for NS must be added to the appropriate *forward* zone, not the reverse
+#$recsth->execute(0, $rdns, $ns, 1, $ip, 0, 0, 0, $ttl)
+# ...  auto-A-record simply does not make sense in reverse zones.  Functionally
+# I think it would work, sort of, but it's a nasty mess and anyone hosting reverse
+# zones has names for their nameservers already.
+# Even the auto-nameserver-fqdn comes out...  ugly.
+
+##work
+      } else {
+	my ($domid) = $dbh->selectrow_array("SELECT domain_id FROM domains WHERE lower(domain) = lower(?)",
+		undef, ($fqdn));
+	if (!$domid) {
+	  $errstr = "adding domain $fqdn";
+	  $dbh->do("INSERT INTO domains (domain,group_id,status) VALUES (?,1,1)", undef, ($fqdn));
+	  ($domid) = $dbh->selectrow_array("SELECT currval('domains_domain_id_seq')");
+          $recsth->execute($domid, 0, "hostmaster.$fqdn:$ns", 6, "16384:2048:1048576:2560", 0, 0, 0, "2560");
+	}
+	$recsth->execute($domid, 0, $fqdn, 2, $ns, 0, 0, 0, $ttl);
+	$recsth->execute($domid, 0, $ns, 1, $ip, 0, 0, 0, $ttl) if $ip;
+      }
+
+
+    } elsif ($rec =~ /^\%/) {
+      $cnt{VIEWS}++;
     } elsif ($rec =~ /^:/) {
       $cnt{NCUST}++;
