X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-utils.git;a=blobdiff_plain;f=scripts%2Fnamed-conf;h=0cad8021db6dba31e66c89ca3bede0c8777177ca;hp=694ab940adff6fdf84f0fa975127a2dd8d2beec5;hb=bc4996ca564462b5c19d36e439ecb1afbe1d0951;hpb=574e0861ea27316499473f567e15e5ddf82d5b0f diff --git a/scripts/named-conf b/scripts/named-conf index 694ab94..0cad802 100755 --- a/scripts/named-conf +++ b/scripts/named-conf @@ -3,6 +3,7 @@ use strict; use IO::File; use Data::Dumper; +use POSIX; use vars qw($quis $mode $doall @@ -72,12 +73,11 @@ usage: named-conf-regen [-rvq] -f|-y|-n|...\n". " -v --verbose extra verbose\n"; } -cfg_fail("config filename $etcfile should have been absolute path of a file") - unless $etcfile =~ m,^/, && $etcfile !~ m,/$,; +cfg_fail("config filename $etcfile should not be directory") + if $etcfile =~ m,/$,; use vars qw($default_dir); -$default_dir= $etcfile; -$default_dir =~ s,/[^/]+$,,; +$default_dir= $etcfile =~ m,^.*/, ? $& : './'; use vars qw($slave_dir $slave_prefix $slave_suffix); $slave_dir= 'slave'; @@ -104,6 +104,7 @@ read_config($etcfile); debug_dump('@zone_cfg_list %zone_cfg'); process_zones($mode ? @zone_cfg_list : @ARGV); debug_dump('%output_contents'); +output_files() if $install; exit 0; @@ -113,7 +114,7 @@ sub cfg_fail ($) { die "$quis: $where:\n $_[0]\n"; } sub read_config ($) { my ($if) = @_; - my ($fh,$z,@self, $mod,$dir,$prefix,$suffix,$lprefix,$lsuffix); + my ($fh,$z,@self,$before, $mod,$dir,$prefix,$suffix,$lprefix,$lsuffix); local ($_); $fh= new IO::File $if,'r' or cfg_fail("open $if:\n $!"); @@ -123,10 +124,11 @@ sub read_config ($) { cfg_fail("read config file $if:\n $!") if $fh->error(); last; } - s/^\s+//; chomp; s/\s+$//; + chomp; s/\s+$//; if (m/\\$/) { $before.= $_; next; } $_= $before.$_; $before= ''; + s/^\s+//; $where= "$if:$."; next if m/^\#/; last if m/^end$/; @@ -176,7 +178,7 @@ sub read_config ($) { sub qualify ($) { my ($i) = @_; - $i= "$default_dir/$i" unless $i =~ m,^/,; + $i= "$default_dir$i" unless $i =~ m,^/,; return $i; } @@ -265,7 +267,7 @@ sub zone_warning ($) { } sub zone_warnmore ($) { - print STDERR " $_[0]\n" or die $!; + print STDERR "$zone: $_[0]\n" or die $!; } use vars qw(%delgs); # $delgs{$nameserver_list} = [ $whosaidandwhy ] @@ -513,6 +515,48 @@ END $$cfg{'file'}); } +sub output_files () { + my ($fn,$ofn,$mfn,$l,$dir, $maxmode,$h,@to_install); + + foreach $ofn (keys %output_contents) { + $fn= $ofn; $mfn= "output file $fn"; + for (;;) { + if (!lstat $fn) { + $! == &ENOENT or die "$quis: stat $mfn:\n $!\n"; + $maxmode= 0666; + last; + } elsif (-f _) { + $maxmode= (stat _)[2]; + last; + } elsif (-l _) { + defined($l= readlink $fn) + or die "$quis: readlink $mfn:\n $!\n"; + $dir= $fn =~ m,^.*/, ? $& : './'; + $fn= "$dir$l" unless $l =~ m,^/,; + $mfn= "output file $fn (symlink target of $ofn)"; + } else { + die "$quis: output file $mfn exists but is not a file". + " (or symlink to one)"; + } + } + unlink "$fn.new" or $! == &ENOENT or + die "$quis: cannot clear out old .new version of $mfn:\n $!"; + $h= new IO::File "$fn.new",'w',$maxmode + or die("$quis: create .new version of $mfn:\n $!"); + print $h + "# generated by $quis, do not edit\n", + $output_contents{$ofn} + or die "$quis: write data to .new version of $mfn:\n $!"; + $h->close + or die "$quis: close .new version of $mfn:\n $!"; + push @to_install, $fn,$mfn; + } + + while (($fn,$mfn, @to_install) = @to_install) { + rename "$fn.new",$fn + or die "$quis: install new version of $mfn:\n $!"; + } +} #-------------------- general utilities @@ -546,7 +590,7 @@ sub lookup ($$$) { $h->error and die "$quis: read from adnshost:\n $!\n"; chomp @result; $!=0; $h->close; - die "$quis: lookup -t$type $domain $okrcodes failed $? $!\n" + die "$quis: lookup -t$type $domain $okrcodes failed $? $! @result\n" if $! or $?>6 or index($okrcodes,$?)<0; debug_trace("lookup <== $? @result"); return ($?,@result);