Index: /trunk/DNSDB.pm
===================================================================
--- /trunk/DNSDB.pm	(revision 34)
+++ /trunk/DNSDB.pm	(revision 35)
@@ -816,5 +816,5 @@
 sub importAXFR {
   my $dbh = shift;
-  my $ifrom = shift;
+  my $ifrom_in = shift;
   my $domain = shift;
   my $group = shift;
@@ -824,8 +824,15 @@
 ##fixme:  add mode to delete&replace, merge+overwrite, merge new?
 
-
 my $nrecs = 0;
-my $flags = 0;
-my $warnmsg;
+my $soaflag = 0;
+my $nsflag = 0;
+my $warnmsg = '';
+my $ifrom;
+
+  # choke on possible bad setting in ifrom
+  # IPv4 and v6!
+  ($ifrom) = ($ifrom_in =~ /^([0-9a-f\:.]+|[0-9a-z_.-]+)$/i);
+  return ('FAIL', "Bad AXFR source host $ifrom")
+	unless ($ifrom) = ($ifrom_in =~ /^([0-9a-f\:.]+|[0-9a-z_.-]+)$/i);
 
   # Allow transactions, and raise an exception on errors so we can catch it later.
@@ -834,34 +841,41 @@
   local $dbh->{RaiseError} = 1;
 
+  my $sth_domin = $dbh->prepare("INSERT INTO domains (domain,group_id,status) VALUES (?,?,?)");
+  my $sth_getid = $dbh->prepare("SELECT domain_id FROM domains WHERE domain=?");
   my $dom_id;
+
+# quick check to start to see if we've already got one
+  $sth_getid->execute($domain);
+  ($dom_id) = $sth_getid->fetchrow_array;
+
+  return ('FAIL', "Domain already exists") if $dom_id;
 
   eval {
     # can't do this, can't nest transactions.  sigh.
-    #my ($dcode, $dmsg) = addDomain($dbh, $domain, $group, $status);
+    #my ($dcode, $dmsg) = addDomain(dbh, domain, group, status);
 
 ##fixme:  serial
-    my $sth = $dbh->prepare("INSERT INTO domains (domain,group_id,status) VALUES (?,?,?)");
-$warnmsg = "trying lokido... (".$dbh->{AutoCommit}."), (".$dbh->{RaiseError}.")" if $domain eq 'waslokido.com';
-    $sth->execute($domain,$group,$status);
+    $sth_domin->execute($domain,$group,$status);
+
+## bizarre DBI<->Net::DNS interaction bug:
+## sometimes a zone will cause an immediate commit-and-exit (sort of) of the while()
 
     # get domain id so we can do the records
-    $sth = $dbh->prepare("select domain_id from domains where domain='$domain'");
-    $sth->execute;
-    ($dom_id) = $sth->fetchrow_array();
-$warnmsg .= " [domid $dom_id]";
+    $sth_getid->execute($domain);
+    ($dom_id) = $sth_getid->fetchrow_array();
 
     my $res = Net::DNS::Resolver->new;
-    unless ($res->axfr_start($domain)) {
-      $dbh->rollback;
-      die "Couldn't begin AXFR\n";
-    }
-
-#die "just started AXFR\n";
-
-    while (my $rr = $res->axfr_next) {
-$warnmsg = $rr->string;
+    $res->nameservers($ifrom);
+    $res->axfr_start($domain)
+	or die "Couldn't begin AXFR\n";
+
+#my $foobar = $res->axfr_next() if $domain =~ /loki/;
+#die "outside the loop with ".$foobar->type."\n" if $domain =~ /loki/;
+
+    while (my $rr = $res->axfr_next()) {
       my $type = $rr->type;
-# nasty big ugly case-like thing here, since we have to do *some* different
-# processing depending on the record.  le sigh.
+
+#die "first record! $type\n" if $domain =~ /lok/;
+
       my $sql = "INSERT INTO records (domain_id,host,type,ttl,val";
       my $vallen = "?,?,?,?,?";
@@ -870,11 +884,16 @@
 #      my $val;
 
+$soaflag = 1 if $type eq 'SOA';
+$nsflag = 1 if $type eq 'NS';
+
 ##work
-# gnnnnnh.  going to need to (rr->string)  ->  split  ->  <localvars>  ?
-my @vallist = ($dom_id, $rr->name, $reverse_typemap{$type}, $rr->ttl);
+      my @vallist = ($dom_id, $rr->name, $reverse_typemap{$type}, $rr->ttl);
 
 # "Primary" types:
 # A, NS, CNAME, SOA, PTR(warn in forward), MX, TXT, AAAA, SRV, A6(ob), SPF
 # maybe KEY
+
+# nasty big ugly case-like thing here, since we have to do *some* different
+# processing depending on the record.  le sigh.
 
       if ($type eq 'A') {
@@ -882,4 +901,5 @@
       } elsif ($type eq 'NS') {
 	push @vallist, $rr->nsdname;
+	$nsflag = 1;
       } elsif ($type eq 'CNAME') {
 	push @vallist, $rr->cname;
@@ -887,4 +907,5 @@
 	$vallist[1] = $rr->mname.":".$rr->rname;
 	push @vallist, ($rr->refresh.":".$rr->retry.":".$rr->expire.":".$rr->minimum);
+	$soaflag = 1;
       } elsif ($type eq 'PTR') {
 	# hmm.  PTR records should not be in forward zones.
@@ -910,10 +931,10 @@
 	push @vallist, $rr->port;
       } elsif ($type eq 'KEY') {
+	# we don't actually know what to do with these...
 	push @vallist, ($rr->flags.":".$rr->protocol.":".$rr->algorithm.":".$rr->key.":".$rr->keytag.":".$rr->privatekeyname);
+      } else {
+	# Finding a different record type is not fatal.... just problematic.
+	$warnmsg .= "Unusual record ".$rr->name." ($type) found\n";
       }
-
-$warnmsg = $rr->string;
-$dbh->rollback if $domain eq 'waslokido.com';
-die "first record: ".$rr->string."\n" if $domain eq 'waslokido.com';
 
 # BIND supports:
@@ -934,15 +955,25 @@
       }
 
-      $sth = $dbh->prepare($sql.") VALUES (".$vallen.")");
-      $sth->execute(@vallist) or die "failed to insert ".$rr->string.": ".$sth->errstr."\n" if $sth->err;
+      my $sth_rr = $dbh->prepare($sql.") VALUES (".$vallen.")");
+      $sth_rr->execute(@vallist) or die "failed to insert ".$rr->string.": ".$sth_rr->errstr."\n" if $sth_rr->err;
 
       if ($type eq 'SOA') {
       }
 
+#die "die.die.die!\n";
+
+      $nrecs++;
+
+    } # while axfr_next
+
+    die "No records found;  either $ifrom is not authoritative or doesn't allow transfers\n" if !$nrecs;
+    die "Bad zone:  No SOA record!\n" if !$soaflag;
+    die "Bad zone:  No NS records!\n" if !$nsflag;
+
 $dbh->rollback;
-#die "die.die.die!\n";
-
-      #print $rr->rdata."\n";
-    }
+#    $dbh->commit;
+
+#    die "Bad zone.  BAD zone!  No cookie!\n";
+#die "don't insert me!  I'm nasty, I am!\n";
   };
 
@@ -950,8 +981,9 @@
     my $msg = $@;
     eval { $dbh->rollback; };
+#    $dbh->do("delete from domains where domain='$domain'");
     return ('FAIL',$msg." $warnmsg");
   } else {
-    return ('WARN', "OOOK!  Ooooook.  Ook. ($warnmsg)") if $domain eq 'deepnet.cx';
-    return ('WARN', "Funky Things Happened: $warnmsg") if $domain eq 'waslokido.com';
+#    $dbh->do("delete from domains where domain='$domain'");
+    return ('WARN', $warnmsg) if $warnmsg;
     return ('OK',"ook");
   }
Index: /trunk/dns.cgi
===================================================================
--- /trunk/dns.cgi	(revision 34)
+++ /trunk/dns.cgi	(revision 35)
@@ -601,5 +601,5 @@
   $page->param(rwsoa => $webvar{rwsoa}) if $webvar{rwsoa};
   $page->param(rwns => $webvar{rwns}) if $webvar{rwns};
-  $page->param(dominactive => 1) unless $webvar{domactive};
+  $page->param(dominactive => 1) if !$webvar{domactive};
   $page->param(importdoms => $webvar{importdoms}) if $webvar{importdoms};
 ##work
@@ -618,8 +618,10 @@
       my ($code,$msg) = importAXFR($dbh, $webvar{ifrom}, $domain, $webvar{group},
 	$webvar{domstatus}, $webvar{rwsoa}, $webvar{rwns});
-  $row{domok} = 1 if $code eq 'OK';
-  $row{domwarn} = $msg if $code eq 'WARN';
-  $row{domerr} = $msg if $code eq 'FAIL';
-push @debugbits, "$domain: $code<br>\n";
+      $row{domok} = $msg if $code eq 'OK';
+      if ($code eq 'WARN') {
+	$msg =~ s|\n|<br />|g;
+	$row{domwarn} = $msg;
+      }
+      $row{domerr} = $msg if $code eq 'FAIL';
       # do stuff!  DNSDB::importAXFR($webvar{ifrom}, $webvar{rwsoa}, $webvar{rwns}, $domain, <flags>)
       $row{domain} = $domain;
@@ -630,5 +632,4 @@
   }
 
-  push @debugbits, "<pre>$webvar{importdoms}</pre>";
 }
 
Index: /trunk/templates/axfr.tmpl
===================================================================
--- /trunk/templates/axfr.tmpl	(revision 34)
+++ /trunk/templates/axfr.tmpl	(revision 35)
@@ -3,5 +3,5 @@
 <TMPL_INCLUDE NAME="menu.tmpl">
 
-<td align="center">
+<td align="center" valign="top">
 
 <form action="dns.cgi" method="POST">
@@ -56,5 +56,6 @@
 	<td><TMPL_VAR NAME=domain></td>
 <TMPL_IF domok>	<td>Imported OK</td>
-<TMPL_ELSE><TMPL_IF domwarn>	<td class="warn">Warning: <TMPL_VAR NAME=domwarn></td>
+<TMPL_ELSE><TMPL_IF domwarn>	<td class="warn">Import OK but:<br />
+<TMPL_VAR NAME=domwarn></td>
 <TMPL_ELSE>	<td class="err">Failed: <TMPL_VAR NAME=domerr></td>
 </TMPL_IF></TMPL_IF>
