全部博文(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";
}