Index: branches/stable/tiny-import.pl
===================================================================
--- branches/stable/tiny-import.pl	(revision 547)
+++ branches/stable/tiny-import.pl	(revision 548)
@@ -3,5 +3,5 @@
 ##
 # $Id$
-# Copyright 2012 Kris Deugau <kdeugau@deepnet.cx>
+# Copyright 2012,2013 Kris Deugau <kdeugau@deepnet.cx>
 #
 #    This program is free software: you can redistribute it and/or modify
@@ -25,6 +25,8 @@
 use strict;
 use warnings;
-
-use lib '.';
+use POSIX;
+use Time::TAI64 qw(:tai);
+
+use lib '.';	##uselib##
 use DNSDB;
 
@@ -37,11 +39,13 @@
 	conv	=> 0,
 	trial	=> 0,
+	legacy  => 0,
 	);
 # Handle some command-line arguments
 while ($ARGV[0] =~ /^-/) {
   my $arg = shift @ARGV;
-  usage() if $arg !~ /^-[rct]+$/;
+  usage() if $arg !~ /^-[rclt]+$/;
   # -r  rewrite imported files to comment imported records
   # -c  coerce/downconvert A+PTR = records to PTR
+  # -l  swallow A+PTR as-is
   # -t  trial mode;  don't commit to DB or actually rewrite flatfile (disables -r)
   $arg =~ s/^-//;
@@ -50,4 +54,5 @@
     $importcfg{rw} = 1 if $_ eq 'r';
     $importcfg{conv} = 1 if $_ eq 'c';
+    $importcfg{legacy} = 1 if $_ eq 'l';
     $importcfg{trial} = 1 if $_ eq 't';
   }
@@ -65,4 +70,6 @@
 	    Multiple passes may be necessary if SOA and = records are heavily
 	    intermixed and not clustered together.
+	-l  (for "legacy")  Force import of A+PTR records as-is.  Mutually exclusive
+            with -c.  -l takes precedence as -c is lossy.
 	-t  Trial run mode;  spits out records that would be left unimported.
 	    Disables -r if set.
@@ -120,6 +127,6 @@
   }
 
-  our $recsth = $dbh->prepare("INSERT INTO records (domain_id,rdns_id,host,type,val,distance,weight,port,ttl,location) ".
-	" VALUES (?,?,?,?,?,?,?,?,?,?)");
+  our $recsth = $dbh->prepare("INSERT INTO records (domain_id,rdns_id,host,type,val,distance,weight,port,ttl,location,stamp,expires,stampactive) ".
+	" VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)");
 
   my %deleg;
@@ -243,4 +250,27 @@
   }
 
+  sub calcstamp {
+    my $stampin = shift;
+    my $ttl = shift;
+    my $pzone = shift;
+    my $revrec = shift;
+
+    return ($ttl, 'n', 'n', '1970-01-01 00:00:00 -0') if !$stampin;
+
+##fixme  Yes, this fails for records in 2038 sometime.  No, I'm not going to care for a while.
+    $stampin = "\@$stampin";	# Time::TAI64 needs the leading @.  Feh.
+    my $u = tai2unix($stampin);
+    $stampin = strftime("%Y-%m-%d %H:%M:%S %z", localtime($u));
+    my $expires = 'n';
+    if ($ttl) {
+      # TTL can stay put.
+    } else {
+      # TTL on import is 0, almost certainly wrong.  Get the parent zone's SOA and use the minttl.
+      my $soa = $dnsdb->getSOA('n', $revrec, $pzone);
+      $ttl = $soa->{minttl};
+      $expires = 'y';
+    } 
+    return ($ttl, 'y', $expires, $stampin);
+  }
 
   sub recslurp {
@@ -263,5 +293,5 @@
       $host =~ s/^=//;
       $host =~ s/\.$//;
-      $ttl = 0 if !$ttl;
+      $ttl = -1 if $ttl eq '';
       $stamp = '' if !$stamp;
       $loc = '' if !$loc;
@@ -269,10 +299,34 @@
       my $fparent = $dnsdb->_hostparent($host);
       my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($ip));
+
+      my $stampactive = 'n';
+      my $expires = 'n';
+
+      # can't set a timestamp on an orphaned record.  we'll actually fail import of this record a little later.
+      if ($fparent || $rparent) {
+        if ($fparent) {
+          ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $fparent, 'n');
+        } else {
+          ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y');
+        }
+      }
+
       if ($fparent && $rparent) {
-	$recsth->execute($fparent, $rparent, $host, 65280, $ip, 0, 0, 0, $ttl, $loc);
-      } else {
-	if ($importcfg{conv}) {
+	$recsth->execute($fparent, $rparent, $host, 65280, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
+      } else {
+	if ($importcfg{legacy}) {
+	  # Just import it already!  Record may still be subject to downconversion on editing.
+	  $fparent = 0 if !$fparent;
+	  $rparent = 0 if !$rparent;
+	  if ($fparent || $rparent) {
+	    $recsth->execute($fparent, $rparent, $host, 65280, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
+	  } else {
+	    # No parents found, cowardly refusing to add a dangling record
+	    push @deferred, $rec unless $nodefer;
+	    $impok = 0;
+	  }
+	} elsif ($importcfg{conv}) {
 	  # downconvert A+PTR if forward zone is not found
-	  $recsth->execute(0, $rparent, $host, 12, $ip, 0, 0, 0, $ttl, $loc);
+	  $recsth->execute(0, $rparent, $host, 12, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
 	  $converted++;
 	} else {
@@ -290,12 +344,23 @@
       $host =~ s/\.$//;
       $host =~ s/^\\052/*/;
-      $ttl = 0 if !$ttl;
-      $stamp = '' if !$stamp;
-      $loc = '' if !$loc;
-      $loc = '' if $loc =~ /^:+$/;
+      $ttl = -1 if $ttl eq '';
+      $stamp = '' if !$stamp;
+      $loc = '' if !$loc;
+      $loc = '' if $loc =~ /^:+$/;
+
+      my $stampactive = 'n';
+      my $expires = 'n';
+
       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, $loc);
+	if ($rparent) {
+	  ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y');
+	  $recsth->execute(0, $rparent, $targ, 5, $msg->addr, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
+	} else {
+	  push @deferred, $rec unless $nodefer;
+	  $impok = 0;
+	  #  print "$tmporig deferred;  can't find parent zone\n";
+	}
 
 ##fixme:  automagically convert manually maintained sub-/24 delegations
@@ -308,5 +373,6 @@
 	my $fparent = $dnsdb->_hostparent($host);
 	if ($fparent) {
-	  $recsth->execute($fparent, 0, $host, 5, $targ, 0, 0, 0, $ttl, $loc);
+	  ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $fparent, 'n');
+	  $recsth->execute($fparent, 0, $host, 5, $targ, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
 	} else {
 	  push @deferred, $rec unless $nodefer;
@@ -324,8 +390,12 @@
       $ns =~ s/\.$//;
       $ns = "$ns.ns.$zone" if $ns !~ /\./;
-      $ttl = 0 if !$ttl;
-      $stamp = '' if !$stamp;
-      $loc = '' if !$loc;
-      $loc = '' if $loc =~ /^:+$/;
+      $ttl = -1 if $ttl eq '';
+      $stamp = '' if !$stamp;
+      $loc = '' if !$loc;
+      $loc = '' if $loc =~ /^:+$/;
+
+      my $stampactive = 'n';
+      my $expires = 'n';
+
       if ($zone =~ /\.arpa$/) {
 	($code,$msg) = DNSDB::_zone2cidr($zone);
@@ -336,5 +406,6 @@
 #	if !$rparent;
 	if ($rparent) {
-	  $recsth->execute(0, $rparent, $ns, 2, $msg, 0, 0, 0, $ttl, $loc);
+	  ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y');
+	  $recsth->execute(0, $rparent, $ns, 2, $msg, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
 	} else {
 	  push @deferred, $rec unless $nodefer;
@@ -344,6 +415,7 @@
 	my $fparent = $dnsdb->_hostparent($zone);
 	if ($fparent) {
-	  $recsth->execute($fparent, 0, $zone, 2, $ns, 0, 0, 0, $ttl, $loc);
-	  $recsth->execute($fparent, 0, $ns, 2, $ip, 0, 0, 0, $ttl, $loc) if $ip;
+	  ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $fparent, 'n');
+	  $recsth->execute($fparent, 0, $zone, 2, $ns, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
+	  $recsth->execute($fparent, 0, $ns, 2, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive) if $ip;
 	} else {
 	  push @deferred, $rec unless $nodefer;
@@ -358,8 +430,12 @@
       $rip =~ s/^\^//;
       $rip =~ s/\.$//;
-      $ttl = 0 if !$ttl;
-      $stamp = '' if !$stamp;
-      $loc = '' if !$loc;
-      $loc = '' if $loc =~ /^:+$/;
+      $ttl = -1 if $ttl eq '';
+      $stamp = '' if !$stamp;
+      $loc = '' if !$loc;
+      $loc = '' if $loc =~ /^:+$/;
+
+      my $stampactive = 'n';
+      my $expires = 'n';
+
       my $rparent;
       if (my ($i, $z) = ($rip =~ /^(\d+)\.(\d+-(?:\d+\.){4}in-addr.arpa)$/) ) {
@@ -376,5 +452,6 @@
       }
       if ($rparent) {
-	$recsth->execute(0, $rparent, $host, 12, $msg->addr, 0, 0, 0, $ttl, $loc);
+	($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y');
+	$recsth->execute(0, $rparent, $host, 12, $msg->addr, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
       } else {
 	push @deferred, $rec unless $nodefer;
@@ -389,12 +466,16 @@
       $host =~ s/\.$//;
       $host =~ s/^\\052/*/;
-      $ttl = 0 if !$ttl;
-      $stamp = '' if !$stamp;
-      $loc = '' if !$loc;
-      $loc = '' if $loc =~ /^:+$/;
+      $ttl = -1 if $ttl eq '';
+      $stamp = '' if !$stamp;
+      $loc = '' if !$loc;
+      $loc = '' if $loc =~ /^:+$/;
+
+      my $stampactive = 'n';
+      my $expires = 'n';
 
       my $domid = $dnsdb->_hostparent($host);
       if ($domid) {
-	$recsth->execute($domid, 0, $host, 1, $ip, 0, 0, 0, $ttl, $loc);
+	($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n');
+	$recsth->execute($domid, 0, $host, 1, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
       } else {
 	push @deferred, $rec unless $nodefer;
@@ -410,8 +491,25 @@
       $master =~ s/\.$//;
       $contact =~ s/\.$//;
-      $ttl = 0 if !$ttl;
-      $stamp = '' if !$stamp;
-      $loc = '' if !$loc;
-      $loc = '' if $loc =~ /^:+$/;
+      $ttl = -1 if $ttl eq '';
+      $stamp = '' if !$stamp;
+      $loc = '' if !$loc;
+      $loc = '' if $loc =~ /^:+$/;
+
+      my $stampactive = 'n';
+      my $expires = 'n';
+
+##fixme er... what do we do with an SOA with a timestamp?  O_o
+# fail for now, since there's no clean way I can see to handle this (yet)
+# maybe (ab)use the -l flag to import as-is?
+      if ($stamp) {
+	push @deferred, $rec unless $nodefer;
+	return 0;
+      }
+
+##fixme: need more magic on TTL, so we can decide whether to use the minttl or newttl
+#      my $newttl;
+#      ($newttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $minttl, 0, 'n');
+#      $ttl = $newttl if !$ttl;
+
       if ($zone =~ /\.arpa$/) {
 	($code,$msg) = DNSDB::_zone2cidr($zone);
@@ -419,10 +517,18 @@
 		undef, ($msg, $loc));
 	my ($rdns) = $dbh->selectrow_array("SELECT currval('revzones_rdns_id_seq')");
-        $recsth->execute(0, $rdns, "$contact:$master", 6, "$refresh:$retry:$expire:$minttl", 0, 0, 0, $ttl, $loc);
+	my $newttl;
+        ($newttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $minttl, 0, 'y');
+	$ttl = $newttl if !$ttl;
+        $recsth->execute(0, $rdns, "$contact:$master", 6, "$refresh:$retry:$expire:$minttl", 0, 0, 0, $ttl,
+		$loc, $stamp, $expires, $stampactive);
       } else {
 	$dbh->do("INSERT INTO domains (domain,group_id,status,default_location) VALUES (?,1,1,?)",
 		undef, ($zone, $loc));
 	my ($domid) = $dbh->selectrow_array("SELECT currval('domains_domain_id_seq')");
-        $recsth->execute($domid, 0, "$contact:$master", 6, "$refresh:$retry:$expire:$minttl", 0, 0, 0, $ttl, $loc);
+	my $newttl;
+        ($newttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $minttl, 0, 'n');
+	$ttl = $newttl if !$ttl;
+        $recsth->execute($domid, 0, "$contact:$master", 6, "$refresh:$retry:$expire:$minttl", 0, 0, 0, $ttl,
+		$loc, $stamp, $expires, $stampactive);
       }
 
@@ -436,8 +542,11 @@
       $host =~ s/\.$//;
       $host = "$host.mx.$zone" if $host !~ /\./;
-      $ttl = 0 if !$ttl;
-      $stamp = '' if !$stamp;
-      $loc = '' if !$loc;
-      $loc = '' if $loc =~ /^:+$/;
+      $ttl = -1 if $ttl eq '';
+      $stamp = '' if !$stamp;
+      $loc = '' if !$loc;
+      $loc = '' if $loc =~ /^:+$/;
+
+      my $stampactive = 'n';
+      my $expires = 'n';
 
 # note we don't check for reverse domains here, because MX records don't make any sense in reverse zones.
@@ -447,6 +556,7 @@
       my $domid = $dnsdb->_hostparent($zone);
       if ($domid) {
-	$recsth->execute($domid, 0, $zone, 15, $host, $dist, 0, 0, $ttl, $loc);
-	$recsth->execute($domid, 0, $host, 1, $ip, 0, 0, 0, $ttl, $loc) if $ip;
+	($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n');
+	$recsth->execute($domid, 0, $zone, 15, $host, $dist, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
+	$recsth->execute($domid, 0, $host, 1, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive) if $ip;
       } else {
 	push @deferred, $rec unless $nodefer;
@@ -461,17 +571,22 @@
       $fqdn =~ s/^\\052/*/;
       _deoctal(\$rdata);
-      $ttl = 0 if !$ttl;
-      $stamp = '' if !$stamp;
-      $loc = '' if !$loc;
-      $loc = '' if $loc =~ /^:+$/;
+      $ttl = -1 if $ttl eq '';
+      $stamp = '' if !$stamp;
+      $loc = '' if !$loc;
+      $loc = '' if $loc =~ /^:+$/;
+
+      my $stampactive = 'n';
+      my $expires = 'n';
 
       if ($fqdn =~ /\.arpa$/) {
 	($code,$msg) = DNSDB::_zone2cidr($fqdn);
 	my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($msg));
-	$recsth->execute(0, $rparent, $rdata, 16, "$msg", 0, 0, 0, $ttl, $loc);
+	($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y');
+	$recsth->execute(0, $rparent, $rdata, 16, "$msg", 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
       } else {
 	my $domid = $dnsdb->_hostparent($fqdn);
 	if ($domid) {
-	  $recsth->execute($domid, 0, $fqdn, 16, $rdata, 0, 0, 0, $ttl, $loc);
+	  ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n');
+	  $recsth->execute($domid, 0, $fqdn, 16, $rdata, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
 	} else {
 	  push @deferred, $rec unless $nodefer;
@@ -488,8 +603,23 @@
       $ns =~ s/\.$//;
       $ns = "$ns.ns.$fqdn" if $ns !~ /\./;
-      $ttl = 0 if !$ttl;
-      $stamp = '' if !$stamp;
-      $loc = '' if !$loc;
-      $loc = '' if $loc =~ /^:+$/;
+      $ttl = -1 if $ttl eq '';
+      $stamp = '' if !$stamp;
+      $loc = '' if !$loc;
+      $loc = '' if $loc =~ /^:+$/;
+
+      my $stampactive = 'n';
+      my $expires = 'n';
+
+##fixme er... what do we do with an SOA with a timestamp?  O_o
+# fail for now, since there's no clean way I can see to handle this (yet)
+# maybe (ab)use the -l flag to import as-is?
+      if ($stamp) {
+	push @deferred, $rec unless $nodefer;
+	return 0;
+      }
+
+##fixme: need more magic on TTL, so we can decide whether to use the minttl or newttl
+#      my $newttl;
+#      ($newttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $minttl, 0, 'n');
 
       if ($fqdn =~ /\.arpa$/) {
@@ -501,11 +631,16 @@
 		undef, ($msg, $loc));
 	  ($rdns) = $dbh->selectrow_array("SELECT currval('revzones_rdns_id_seq')");
+          ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, 2560, 0, 'y');
 # 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", $loc);
-	}
-	$recsth->execute(0, $rdns, $ns, 2, "$msg", 0, 0, 0, $ttl, $loc);
+# otherwise, it's as per the tinydns defaults that work tolerably well on a small scale
+# serial -> modtime of data file, ref -> 16384, ret -> 2048, exp -> 1048576, min -> 2560
+          $recsth->execute(0, $rdns, "hostmaster.$fqdn:$ns", 6, "16384:2048:1048576:2560", 0, 0, 0, "2560",
+		$loc, $stamp, $expires, $stampactive);
+	}
+        ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, 2560, $rdns, 'y') if !$stamp;
+	$recsth->execute(0, $rdns, $ns, 2, "$msg", 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
 ##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)
+#$recsth->execute(0, $rdns, $ns, 1, $ip, 0, 0, 0, $ttl, $stamp, $expires, $stampactive)
 # ...  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
@@ -521,8 +656,11 @@
 		undef, ($fqdn, $loc));
 	  ($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", $loc);
-	}
-	$recsth->execute($domid, 0, $fqdn, 2, $ns, 0, 0, 0, $ttl, $loc);
-	$recsth->execute($domid, 0, $ns, 1, $ip, 0, 0, 0, $ttl, $loc) if $ip;
+          ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, 2560, 0, 'n');
+          $recsth->execute($domid, 0, "hostmaster.$fqdn:$ns", 6, "16384:2048:1048576:2560", 0, 0, 0, "2560",
+		$loc, $stamp, $expires, $stampactive);
+	}
+        ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n') if !$stamp;
+	$recsth->execute($domid, 0, $fqdn, 2, $ns, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
+	$recsth->execute($domid, 0, $ns, 1, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive) if $ip;
       }
 
@@ -556,8 +694,11 @@
       $fqdn =~ s/\.$//;
       $fqdn =~ s/^\\052/*/;
-      $ttl = 0 if !$ttl;
-      $stamp = '' if !$stamp;
-      $loc = '' if !$loc;
-      $loc = '' if $loc =~ /^:+$/;
+      $ttl = -1 if $ttl eq '';
+      $stamp = '' if !$stamp;
+      $loc = '' if !$loc;
+      $loc = '' if $loc =~ /^:+$/;
+
+      my $stampactive = 'n';
+      my $expires = 'n';
 
       if ($type == 33) {
@@ -588,5 +729,6 @@
 	my $domid = $dnsdb->_hostparent($fqdn);
 	if ($domid) {
-	  $recsth->execute($domid, 0, $fqdn, 33, $target, $prio, $weight, $port, $ttl, $loc) if $domid;
+	  ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n');
+	  $recsth->execute($domid, 0, $fqdn, 33, $target, $prio, $weight, $port, $ttl, $loc, $stamp, $expires, $stampactive) if $domid;
 	} else {
 	  push @deferred, $rec unless $nodefer;
@@ -605,6 +747,8 @@
 
 	my $fparent = $dnsdb->_hostparent($fqdn);
+
 	if ($fparent) {
-	  $recsth->execute($fparent, 0, $fqdn, 28, $val->addr, 0, 0, 0, $ttl, $loc);
+	  ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $fparent, 'n');
+	  $recsth->execute($fparent, 0, $fqdn, 28, $val->addr, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
 	} else {
 	  push @deferred, $rec unless $nodefer;
@@ -620,5 +764,6 @@
 	  my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($msg));
 	  if ($rparent) {
-	    $recsth->execute(0, $rparent, $txtstring, 16, "$msg", 0, 0, 0, $ttl, $loc);
+	    ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y');
+	    $recsth->execute(0, $rparent, $txtstring, 16, "$msg", 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
 	  } else {
 	    push @deferred, $rec unless $nodefer;
@@ -628,5 +773,6 @@
 	  my $domid = $dnsdb->_hostparent($fqdn);
 	  if ($domid) {
-	    $recsth->execute($domid, 0, $fqdn, 16, $txtstring, 0, 0, 0, $ttl, $loc);
+	    ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n');
+	    $recsth->execute($domid, 0, $fqdn, 16, $txtstring, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
 	  } else {
 	    push @deferred, $rec unless $nodefer;
@@ -648,5 +794,6 @@
 	  my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($msg));
 	  if ($rparent) {
-	    $recsth->execute(0, $rparent, "$email $txtrec", 17, "$msg", 0, 0, 0, $ttl, $loc);
+	    ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y');
+	    $recsth->execute(0, $rparent, "$email $txtrec", 17, "$msg", 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive );
 	  } else {
 	    push @deferred, $rec unless $nodefer;
@@ -656,5 +803,6 @@
 	  my $domid = $dnsdb->_hostparent($fqdn);
 	  if ($domid) {
-	    $recsth->execute($domid, 0, $fqdn, 17, "$email $txtrec", 0, 0, 0, $ttl, $loc);
+	    ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n');
+	    $recsth->execute($domid, 0, $fqdn, 17, "$email $txtrec", 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
 	  } else {
 	    push @deferred, $rec unless $nodefer;
@@ -672,5 +820,6 @@
 	my $domid = $dnsdb->_hostparent($fqdn);
 	if ($domid) {
-	  $recsth->execute($domid, 0, $fqdn, 44, $sshfp, 0, 0, 0, $ttl, $loc);
+	  ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n');
+	  $recsth->execute($domid, 0, $fqdn, 44, $sshfp, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive);
 	} else {
 	  push @deferred, $rec unless $nodefer;
