全部博文(1144)
分类: LINUX
2009-12-09 12:18:43
#!/usr/local/bin/perl use strict; use warnings; use Sys::Hostname; use DBI; my $DEBUG = 0; my $dbun = 'user'; # username to connect to sql database with my $dbpw = 'pass'; # password to connect to sql database with my $dsn = 'DBI:mysql:host=mysql.example.net;database=dns'; # dsn to access database my $dbh = DBI->connect($dsn, $dbun, $dbpw, {RaiseError => 1}); my $dir = '/home/config/tinydns/secondary'; my %ips; open(IFCONFIG, "/sbin/ifconfig -a |") || die "Cannot pipe ifconfig -a: $!\n"; while(){ if(/^\s*inet\s+(?:addr:)?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+/){ next if($1 =~ /^127\.0\.0\.1$/); $ips{$1} = 1; } } close IFCONFIG; my $sql = 'SELECT domain,axfr_host,source_addr FROM secondaries'; my $x = 0; foreach my $ip (keys %ips){ if($x){ $sql .= ' OR'; }else{ $sql .= ' WHERE'; $x=1; } $sql .= ' source_addr = ' . $dbh->quote($ip); } die "no ip addrs found\n" unless($x); $sql .= ' ORDER BY domain'; my $sth = $dbh->prepare($sql); $sth->execute; my $update; my %domains; while(my $row=$sth->fetchrow_arrayref){ $domains{$row->[0]} = 1; my $cmd = '/usr/local/bin/tcpclient -H -R -l 0 '; if($row->[2]){ $cmd .= "-i $row->[2] "; } $cmd .= "$row->[1] 53 /usr/local/bin/axfr-get $row->[0] $dir/$row->[0].new $dir/$row->[0].tmp"; warn "cmd: $cmd\n" if($DEBUG); system($cmd); if(-f "${dir}/$row->[0].new"){ if(-f "${dir}/$row->[0]"){ my $code = system("/usr/bin/cmp ${dir}/$row->[0].new ${dir}/$row->[0] >/dev/null 2>&1"); $code /= 256; if($code){ $update = 1; warn "$dir/$row->[0].new <-> $dir/$row->[0] differ.\n" if($DEBUG); rename("$dir/$row->[0].new","$dir/$row->[0]") || die "could not rename $row->[0].new to $row->[0]: $!\n"; }else{ unlink("$dir/$row->[0].new") || die "couldnt unlink $dir/$row->[0].new: $!\n"; } }else{ $update = 1; warn "no original $dir/$row->[0] - renaming to create.\n" if($DEBUG); rename("$dir/$row->[0].new","$dir/$row->[0]") || die "could not rename $row->[0].new to $row->[0]: $!\n"; } foreach my $table (qw/a mx txt cname domains srv ptr domains ns loc delegation/){ my $sql = "DELETE FROM $table WHERE domain = " . $dbh->quote($row->[0]); my $sth = $dbh->prepare($sql); $sth->execute; } my $sql = 'DELETE FROM delegation WHERE domain LIKE ' . $dbh->quote("%.$row->[0]"); my $sth = $dbh->prepare($sql); $sth->execute; }else{ warn "could not open $dir/$row->[0].new: $!\n"; } } # clean off [most] stale files. # if a secondary is listed for a source addr # that is no longer using this code, the zone # will sit there. $sql = 'SELECT domain FROM secondaries'; $sth = $dbh->prepare($sql); $sth->execute; my %current; while(my $row=$sth->fetchrow_arrayref){ $current{$row->[0]} = 1; } opendir(DIR, $dir) || die "cannot opendir $dir: $!\n"; foreach my $file (grep {!/^\./} readdir DIR){ unless($current{$file}){ if(unlink("$dir/$file")){ $update=1; }else{ warn "could not unlink $dir/$file ($file not in sql): $!\n"; } } } closedir DIR; $dbh->disconnect; if($update){ warn "See update\n" if($DEBUG); my $hostname = hostname(); open(SECONDARY, ">/home/config/tinydns/input/secondaries.out.$hostname.$$.tmp") || die "couldnt write to secondaries.out..$hostname.$$.tmp: $!\n"; open(SORT, "/usr/bin/sort -u $dir/* |") || die "Cannot pipe sort: $!\n"; while( ){ print SECONDARY; } close SORT; close SECONDARY; rename("/home/config/tinydns/input/secondaries.out.$hostname.$$.tmp",'/home/config/tinydns/input/secondaries.out') || die "could not rename secondaries.out.$hostname.$$.tmp: $!\n"; }