X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-utils.git;a=blobdiff_plain;f=scripts%2Fnamed-conf;h=8ce3e61c5e009af13289a3c9607670686f482c58;hp=1520fd8a7da7276339da345e3050e4f36ce2fc2f;hb=35eebe42ba3cd77674422cebf674e316d5a258b1;hpb=5812c849817258ecde6763c216e952d40d261c1d diff --git a/scripts/named-conf b/scripts/named-conf index 1520fd8..8ce3e61 100755 --- a/scripts/named-conf +++ b/scripts/named-conf @@ -1,4 +1,19 @@ #!/usr/bin/perl -w +# This is chiark-named-conf, which is Copyright 2002 Ian Jackson. +# +# chiark-named-conf and its manpage are free software; you can +# redistribute it and/or modify them under the terms of the GNU +# General Public License as published by the Free Software Foundation; +# either version 2, or (at your option) any later version. +# +# chiark-named-conf and its manpage are distributed in the hope that +# it will be useful, but WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. use strict; use IO::File; @@ -6,7 +21,7 @@ use Data::Dumper; use POSIX; use Fcntl qw(:DEFAULT :flock); -use vars qw($quis +use vars qw($quis $stdout_fh $stderr_fh $mode $doall $domail $etcfile $where $debug $needglue $localonly $repeat $verbosity @@ -27,10 +42,14 @@ $verbosity= 2; $admin=''; $mail_state_dir=''; $mail_max_warnfreq= 50; $repeat= 0; $domail= ''; -$progress_fh= 'STDOUT'; -$warn_fh= 'STDERR'; $modifiers= ''; +$group2modcmd{'foreign'}= '*$!@?'; +$group2used{'foreign'}= 1; +($progress_fh= $stdout_fh= new_from_fd IO::Handle(1,'w') and + $warn_fh= $stderr_fh = new_from_fd IO::Handle(2,'w')) + or die "$quis: setup standard filehandles: $!\n"; + use vars qw($dig_owner $dig_type $dig_rdata); while (@ARGV && $ARGV[0] =~ m/^\-/) { @@ -39,7 +58,10 @@ while (@ARGV && $ARGV[0] =~ m/^\-/) { last if m/^$/; if (m/^(yes|no|force)$/) { m/^./; $mode= $&; $domail=''; } elsif (m/^nothing$/) { $mode= 'x'; $domail=''; } - elsif (m/^mail\-(first|middle|final)/) { $mode='n'; $domail=$1; } + elsif (m/^mail\-(first|middle|final|final\-test)$/) { + $mode='n'; + $domail=$1; + } elsif (m/^all$/) { $doall=1; } elsif (m/^config$/) { $etcfile= loarg(); $where= '--config option'; } elsif (m/^glueless$/) { $needglue=0; } @@ -78,7 +100,7 @@ usageerr("-q may be specified at most twice") if $verbosity<0; usageerr("-v may be specified at most once") if $verbosity>3; usageerr("-D may be specified at most twice") if $debug>2; usageerr("must specify either -f|-y|-n or zones (and not both)") - if !!$mode == !!@ARGV; + if !!$mode == !!@ARGV && !$domail; sub usageerr ($) { die <close or die "$quis: write messages to stdout: $!\n"; +$stderr_fh->close or die "$quis: write messages to stderr: $!\n"; exit 0; #-------------------- configuration reading @@ -267,7 +291,7 @@ sub bad_modifiers ($) { local ($_) = @_; if (!eval { die "bad modifier $&" if m/[^!*\$\@~?]/; - die "repeated modifier $1" if m/(.).*$1/; + die "repeated modifier $1" if m/(.).*\1/; 1; }) { $@ =~ s/\n//; @@ -311,7 +335,7 @@ sub zone_conf ($$$$$@) { $zone_cfg{$zone}{$sfx}= $aref; } foreach $sfx (qw(self_soa self_ns)) { - $zone_cfg{$zone}{$sfx} =~ s/\*$/$zone/; + map { s/\*$/$zone/ } @{ $zone_cfg{$zone}{$sfx} }; } $zone_cfg{$zone}{'output'}= $output; push @zone_cfg_list, $zone; @@ -343,11 +367,12 @@ sub process_zones (@) { foreach $zone (@zones) { $cfg= $zone_cfg{$zone} || { 'style_p' => 'foreign', - 's' => 'f', + 's' => "f $group2modcmd{'foreign'}", 'servers' => [ ], }; - mail_zone_before() if $domail; + mail_zone_before() or next + if $domail; zone_reset(); progress(1, sprintf "%-20s %s", $zone, $$cfg{'style_p'}); if ($check && ($doall || !zone_style('?',0))) { @@ -697,14 +722,14 @@ sub mail_zone_before () { for (;;) { $m_lock= new IO::File "${m_base}_lock", O_RDWR|O_CREAT, 0600 - or die "$quis: create lockfile ${m_base}_lock"; + or die "$quis: create lockfile ${m_base}_lock: $!\n"; if (!flock($m_lock, LOCK_EX|LOCK_NB)) { <$m_lock> =~ m/^\d+ /; die "$quis: $zone: concurrrency? - flock $&$!\n"; $m_lock->close; - next; + return 0; } - (@s1= $m_lock->fstat) or die "$quis: fstat ${m_base}_lock: $!\n"; + (@s1= $m_lock->stat) or die "$quis: fstat ${m_base}_lock: $!\n"; (@s2= stat "${m_base}_lock") or die "$quis: stat ${m_base}_lock: $!\n"; last if ($s1[0] eq $s2[0] && $s1[1] eq $s2[1]); @@ -723,17 +748,17 @@ sub mail_zone_before () { if ($2 eq ':' && $3 eq ':') { warn "$quis: $zone: mid/last run, but last". "run already done, ignoring zone\n"; - next; + return 0; } @m_ok= split /\:/, $2; @m_fail= split /\:/, $3; } } elsif ($! != &ENOENT) { die "$quis: open ${m_base}_info: $!\n"; - } elsif ($domail eq 'first') { + } elsif ($domail ne 'first') { warn "$quis: $zone: first run, but not --mail-first,". " ignoring zone\n"; - next; + return 0; } if ($domail eq 'first') { remove "${m_base}_history" or $!==&ENOENT @@ -746,6 +771,7 @@ sub mail_zone_before () { $m_time= time; progress(-1, "\n".('-'x70)."\n".ptime($m_time)."\n"); + return 1; } sub mail_zone_after () { @@ -758,21 +784,28 @@ sub mail_zone_after () { progress(-1,"everything is fine"); } close $progress_fh or die "$quis: close ${m_base}_history: $!\n"; - $progress_fh= $warn_fh= 'STDERR'; + $progress_fh= $warn_fh= $stderr_fh; - if ($domail eq 'final') { + if ($domail =~ m/^final/) { if (100*@m_fail <= $$cfg{'mailmwarn'}*(@m_fail + @m_ok)) { - printf " %-40s ok\n" or die "$quis: mail ok report: $!\n"; + printf " %-40s ok\n", $zone or die "$quis: mail ok report: $!\n"; } elsif (zone_style('@',0)) { - printf " %-40s mail suppressed\n" + printf " %-40s mail suppressed\n", $zone or die "$quis: mail suppress report: $!\n"; } else { mail_zone_mail(); } - } + } else { + printf " %-40s %d warns. OK %s Fail %s\n", + $zone, + defined $zone_warnings{$zone} ? $zone_warnings{$zone} : 0, + join(',', map { $_ - $m_time } @m_ok), + join(',', map { $_ - $m_time } @m_fail) + or die "$quis: checking progress report: $!\n"; + } @m_fail= @m_ok= ('','') - if $domail eq 'final'; + if $domail =~ m/^final/; printf $m_info "%s %s %s %s \n", $m_time, $m_lastok, join(':',@m_ok), join(':',@m_fail) @@ -794,15 +827,15 @@ sub ptime ($) { } sub mail_zone_mail () { - my ($log, $zone_to, $zterr, $c, $r, $t); + my ($log, $zone_to, $zterr, $c, $r, $t, @soas); $m_m= new IO::File "${m_base}_mail", 'w', 0666 or die "$quis: create ${m_base}_mail: $!\n"; $zone_to=''; $zterr=''; - if (!zone_style("\$",$$cfg{'s'} =~ m/u/)) { + if (!zone_style("\$", $$cfg{'s'} !~ m/[ps]/)) { eval { - $_= lookup($zone,'soa','0','problem-addr'); - m/\n\n/ and die "multiple soas\n"; - m/^\S+ (\S.*\@\S+) [0-9 ]+$/ or + ($r,@soas)= lookup($zone,'soa','0','problem-addr'); + @soas==1 or die "multiple soas\n"; + $soas[0] =~ m/^\S+ (\S.*\@\S+) [0-9 ]+$/ or die "bad soa \`$_'\n"; $zone_to= $1; }; @@ -810,13 +843,13 @@ sub mail_zone_mail () { $zterr =~ s/\n$//; } pmail < +From: zone checker <$$cfg{'admin'}> Subject: $zone - configuration problems report END ; pmail("To: "); - pmail("SOA MNAME for $zone <$zone_to>\nCC: ") - if length($zone_to); + pmail("(testing!) ") if $domail ne 'final'; + pmail("SOA MNAME for $zone <$zone_to>\nCC: ") if length($zone_to); pmail($$cfg{'admin'}."\n\n"); pmail <getline); $/= "\n"; - $log->error && $log->close - or die "$quis: reread or close ${m_base}_log: $!"; + (!$log->error and $log->close) + or die "$quis: reread or close ${m_base}_log: $!\n"; + $log->eof or die; $m_m->close or die "$quis: close ${m_base}_mail: $!\n"; $m_m= new IO::File "${m_base}_mail" or die "$quis: reopen ${m_base}_mail: $!"; defined($c= fork) or die "$quis: fork for mail: $!\n"; if (!$c) { - open STDIN, "<& ${m_m}" or die "$quis - sendmail: dup for stdin: $!\n"; - exec '/usr/sbin/sendmail','-odq','-oee','-oi', - 'ijackson@chiark.greenend.org.uk'; # should be -t + defined dup2($m_m->fileno, 0) + or die "$quis - sendmail: dup for stdin: $!\n"; + exec (qw(/usr/sbin/sendmail -odb -oee -oi), + ($domail eq 'final' ? '-t' : $$cfg{'admin'})); die "$quis - sendmail: exec: $!\n"; } $m_m->close; @@ -877,8 +912,9 @@ END $r == $c or die "$quis: waitpid sendmail ($c): $r $!"; $? and warn "$quis: sendmail failed: $?\n"; - printf " %-40s %s\n", $zone, $zone_to or - die "$quis: write mailing report: $!\n"; + printf " %-40s %s\n", $zone, + length $zone_to ? $zone_to : 'reporting to admin' + or die "$quis: write mailing report: $!\n"; } #-------------------- outputting