Index: branches/stable/DNSDB.pm
===================================================================
--- branches/stable/DNSDB.pm	(revision 568)
+++ branches/stable/DNSDB.pm	(revision 582)
@@ -213,4 +213,5 @@
 		force_refresh	=> 1,
 		lowercase	=> 0,	# mangle as little as possible by default
+		showrec_arpa_ns	=> 0,	# show formal .arpa zone name instead of logical CIDR on reverse NS records
 	);
 
@@ -242,5 +243,5 @@
 
   # Several settings are booleans.  Handle multiple possible ways of setting them.
-  for my $boolopt ('log_failures', 'force_refresh', 'lowercase', 'usecache') {
+  for my $boolopt ('log_failures', 'force_refresh', 'lowercase', 'usecache', 'showrec_arpa_ns') {
     if ($self->{$boolopt} ne '1' && $self->{$boolopt} ne '0') {
       # true/false, on/off, yes/no all valid.
@@ -1136,5 +1137,5 @@
     my $tmpzone = $zone;
     $tmpzone =~ s/\.in-addr\.arpa\.?//;
-    return ('FAIL', "Non-numerics in apparent IPv4 reverse zone name") if $tmpzone !~ /^(?:\d+-)?[\d\.]+$/;
+    return ('FAIL', "Non-numerics in apparent IPv4 reverse zone name [$tmpzone]") if $tmpzone !~ m{^(?:\d+[/-])?[\d\.]+$};
 
     # Snag the octet pieces
@@ -1153,5 +1154,5 @@
     # Alternate form:  The second number is actually the real netmask, not the end of the range.
     my $masklen = 0;
-    if ($octs[0] =~ /^((\d+)-(\d+))$/) {	# take the range...
+    if ($octs[0] =~ m{^((\d+)[/-](\d+))$}) {	# take the range...
       if (24 < $3 && $3 < 31) {
 	# we have a real netmask
@@ -1342,4 +1343,5 @@
       $cfg->{force_refresh}	= $1 if /^force_refresh\s*=\s*([a-z01]+)/i;
       $cfg->{lowercase}		= $1 if /^lowercase\s*=\s*([a-z01]+)/i;
+      $cfg->{showrec_arpa_ns}	= $1 if /^showrec_arpa_ns\s*=\s*([a-z01]+)/i;
 # not supported in dns.cgi yet
 #      $cfg->{templatedir}	= $1 if m{^templatedir\s*=\s*([a-z0-9/_.-]+)}i;
@@ -2307,5 +2309,5 @@
   if ($args{revrec} eq 'n') {
     $args{sortby} = 'domain' if !$args{sortby} || !grep /^$args{sortby}$/, ('domain','group','status');
-    $sql = "SELECT domain_id,domain,status,groups.group_name AS group FROM domains".
+    $sql = "SELECT domain_id AS zoneid,domain AS zone,status,groups.group_name AS group FROM domains".
 	" INNER JOIN groups ON domains.group_id=groups.group_id".
 	" WHERE domains.group_id IN ($args{curgroup}".($args{childlist} ? ",$args{childlist}" : '').")".
@@ -2315,5 +2317,5 @@
 ##fixme:  arguably startwith here is irrelevant.  depends on the UI though.
     $args{sortby} = 'revnet' if !$args{sortby} || !grep /^$args{sortby}$/, ('revnet','group','status');
-    $sql = "SELECT rdns_id,revnet,status,groups.group_name AS group FROM revzones".
+    $sql = "SELECT rdns_id AS zoneid,revnet AS zone,status,groups.group_name AS group FROM revzones".
 	" INNER JOIN groups ON revzones.group_id=groups.group_id".
 	" WHERE revzones.group_id IN ($args{curgroup}".($args{childlist} ? ",$args{childlist}" : '').")".
@@ -2325,18 +2327,7 @@
 	($args{offset} eq 'all' ? '' : " LIMIT $self->{perpage}".
 	" OFFSET ".$args{offset}*$self->{perpage});
-  my $sth = $dbh->prepare($sql);
-  $sth->execute(@filterargs);
-  my $rownum = 0;
-
-  while (my @data = $sth->fetchrow_array) {
-    my %row;
-    $row{domain_id} = $data[0];
-    $row{domain} = $data[1];
-    $row{status} = $data[2];
-    $row{group} = $data[3];
-    push @zonelist, \%row;
-  }
-
-  return \@zonelist;
+
+  my $ret = $dbh->selectall_arrayref($sql, { Slice => {} }, @filterargs);
+  return $ret;
 } # end getZoneList()
 
@@ -4712,9 +4703,9 @@
       } elsif ($type eq 'NS') {
 # hmm.  should we warn here if subdomain NS'es are left alone?
-	next if ($args{rwns} && ($rr->name eq $zone));
 	if ($rev eq 'y') {
 	  # revzones have records more or less reversed from forward zones.
 	  my ($tmpcode,$tmpmsg) = _zone2cidr($host);
 	  die "Error converting NS record: $tmpmsg\n" if $tmpcode eq 'FAIL';	# hmm.  may not make sense...
+	  next if ($args{rwns} && ($tmpmsg eq "$cidr"));
 	  $val = "$tmpmsg";
 	  $host = $rr->nsdname;
@@ -4726,4 +4717,5 @@
 #}
 	} else {
+	  next if ($args{rwns} && ($rr->name eq $zone));
 	  $val = $rr->nsdname;
 	}
@@ -4879,23 +4871,34 @@
     if ($args{rwsoa}) {
       $soaflag = 1;
-      my $sthgetsoa = $dbh->prepare("SELECT host,val,ttl FROM default_records WHERE group_id=? AND type=?");
-      my $sthputsoa = $dbh->prepare("INSERT INTO records (domain_id,host,type,val,ttl) VALUES (?,?,?,?,?)");
+      my $sthgetsoa = $dbh->prepare("SELECT host,val,ttl FROM "._rectable('y', $rev)." WHERE group_id=? AND type=?");
+      my $sthputsoa = $dbh->prepare("INSERT INTO records (".
+	($rev eq 'n' ? 'domain_id' : 'rdns_id').",host,type,val,ttl) VALUES (?,?,?,?,?)");
       $sthgetsoa->execute($group,$reverse_typemap{SOA});
       while (my ($host,$val,$ttl) = $sthgetsoa->fetchrow_array()) {
-	$host =~ s/DOMAIN/$zone/g;
-	$val =~ s/DOMAIN/$zone/g;
+	if ($rev eq 'n') {
+	  $host =~ s/DOMAIN/$zone/g;
+	  $val =~ s/DOMAIN/$zone/g;	# arguably useless
+	} else {
+	  $host =~ s/ADMINDOMAIN/$self->{domain}/g;
+	}
 	$sthputsoa->execute($zone_id,$host,$reverse_typemap{SOA},$val,$ttl);
       }
     }
 
-    # Overwrite NS records
+    # Add standard NS records.  The old one(s) should have been skipped by this point.
     if ($args{rwns}) {
       $nsflag = 1;
-      my $sthgetns = $dbh->prepare("SELECT host,val,ttl FROM default_records WHERE group_id=? AND type=?");
-      my $sthputns = $dbh->prepare("INSERT INTO records (domain_id,host,type,val,ttl) VALUES (?,?,?,?,?)");
+      my $sthgetns = $dbh->prepare("SELECT host,val,ttl FROM "._rectable('y',$rev)." WHERE group_id=? AND type=?");
+      my $sthputns = $dbh->prepare("INSERT INTO records (".
+	($rev eq 'n' ? 'domain_id' : 'rdns_id').",host,type,val,ttl) VALUES (?,?,?,?,?)");
       $sthgetns->execute($group,$reverse_typemap{NS});
       while (my ($host,$val,$ttl) = $sthgetns->fetchrow_array()) {
-	$host =~ s/DOMAIN/$zone/g;
-	$val =~ s/DOMAIN/$zone/g;
+	if ($rev eq 'n') {
+	  $host =~ s/DOMAIN/$zone/g;
+	  $val =~ s/DOMAIN/$zone/g;	#hmm.
+	} else {
+	  $host =~ s/ADMINDOMAIN/$self->{domain}/g;	#hmm.
+	  $val =~ s/ZONE/$cidr/g;
+	}
 	$sthputns->execute($zone_id,$host,$reverse_typemap{NS},$val,$ttl);
       }
@@ -5053,5 +5056,5 @@
 	"FROM records WHERE rdns_id=? AND type=6");
   my $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location,extract(epoch from stamp),expires,stampactive ".
-	"FROM records WHERE rdns_id=? AND not type=6 ".
+	"FROM records WHERE rdns_id=? AND NOT type=6 ".
 	"ORDER BY masklen(CAST(val AS inet)) DESC, CAST(val AS inet)");
   my $revsth = $dbh->prepare("SELECT rdns_id,revnet,status,changed FROM revzones WHERE status=1 ".
@@ -5089,9 +5092,10 @@
         $soasth->execute($revid);
         my (@zsoa) = $soasth->fetchrow_array();
-        _printrec_tiny($zonefilehandle,'y',\%recflags,$revzone,
+        _printrec_tiny($zonefilehandle, $zsoa[7], 'y',\%recflags,$revzone,
           $zsoa[0],$zsoa[1],$zsoa[2],$zsoa[3],$zsoa[4],$zsoa[5],$zsoa[6],$zsoa[8],'');
 
         $recsth->execute($revid);
-        while (my ($host,$type,$val,$dist,$weight,$port,$ttl,$recid,$loc,$stamp,$expires,$stampactive) = $recsth->fetchrow_array) {
+        while (my ($host, $type, $val, $dist, $weight, $port, $ttl, $recid, $loc, $stamp, $expires, $stampactive)
+		= $recsth->fetchrow_array) {
           next if $recflags{$recid};
 
@@ -5106,5 +5110,5 @@
 #	  }
 
-          _printrec_tiny($zonefilehandle, 'y', \%recflags, $revzone,
+          _printrec_tiny($zonefilehandle, $recid, 'y', \%recflags, $revzone,
             $host, $type, $val, $dist, $weight, $port, $ttl, $loc, $stamp, $expires, $stampactive);
 
@@ -5148,8 +5152,10 @@
   } # while ($revsth)
 
+  $soasth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location ".
+	"FROM records WHERE domain_id=? AND type=6");
+  $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location,extract(epoch from stamp),expires,stampactive ".
+	"FROM records WHERE domain_id=? AND NOT type=6");	# Just exclude all types relating to rDNS
+#	"FROM records WHERE domain_id=? AND type < 65280");	# Just exclude all types relating to rDNS
   my $domsth = $dbh->prepare("SELECT domain_id,domain,status,changed FROM domains WHERE status=1 ORDER BY domain_id");
-  $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location,extract(epoch from stamp),expires,stampactive ".
-	"FROM records WHERE domain_id=?");	# Just exclude all types relating to rDNS
-#	"FROM records WHERE domain_id=? AND type < 65280");	# Just exclude all types relating to rDNS
   $zonesth = $dbh->prepare("UPDATE domains SET changed='n' WHERE domain_id=?");
   $domsth->execute();
@@ -5177,4 +5183,11 @@
         }
 
+        # need to fetch this separately so the SOA comes first in the flatfile....
+        # Just In Case we need/want to reimport from the flatfile later on.
+        $soasth->execute($domid);
+        my (@zsoa) = $soasth->fetchrow_array();
+        _printrec_tiny($zonefilehandle, $zsoa[7], 'n',\%recflags,$dom,
+          $zsoa[0],$zsoa[1],$zsoa[2],$zsoa[3],$zsoa[4],$zsoa[5],$zsoa[6],$zsoa[8],'');
+
         $recsth->execute($domid);
         while (my ($host,$type,$val,$dist,$weight,$port,$ttl,$recid,$loc,$stamp,$expires,$stampactive) = $recsth->fetchrow_array) {
@@ -5190,5 +5203,5 @@
 	  }
 
-	  _printrec_tiny($zonefilehandle, 'n', \%recflags,
+	  _printrec_tiny($zonefilehandle, $recid, 'n', \%recflags,
 		$dom, $host, $type, $val, $dist, $weight, $port, $ttl, $loc, $stamp, $expires, $stampactive);
 
@@ -5239,5 +5252,6 @@
 # Utility sub for __export_tiny above
 sub _printrec_tiny {
-  my ($datafile,$revrec,$recflags,$zone,$host,$type,$val,$dist,$weight,$port,$ttl,$loc,$stamp,$expires,$stampactive) = @_;
+  my ($datafile, $recid, $revrec, $recflags, $zone, $host, $type, $val, $dist, $weight, $port, $ttl,
+	$loc, $stamp, $expires, $stampactive) = @_;
 
   $loc = '' if !$loc;	# de-nullify - just in case
