auf dem Weg zu neuem
authorheiko
Mon, 28 Nov 2005 06:57:17 +0000
changeset 9 6f5ef6fb479d
parent 8 098af5defd01
child 10 8f7ba479860c
auf dem Weg zu neuem
Makefile
dns-autoslave
master_watcher
rc.ddns-autoslave
rc.dns-autoslave
rc.master_watcher
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile	Mon Nov 28 06:57:17 2005 +0000
@@ -0,0 +1,16 @@
+
+p = dns-autoslave
+SCRIPT = dns-autoslave
+RC = rc.dns-autoslave
+
+prefix = /usr/local
+sbindir = $(prefix)/stow/$p/sbin
+
+rcdir = /etc/init.d/
+
+install:
+	install -m 0755 -d $(sbindir)
+	install -m 0755 -d $(rcdir)
+	install -m 0755 $(SCRIPT) $(sbindir)/
+	install -m 0755 $(RC) $(rcdir)/
+	stow -d /usr/local/stow -vR $(p)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dns-autoslave	Mon Nov 28 06:57:17 2005 +0000
@@ -0,0 +1,350 @@
+#! /usr/bin/perl -w
+# $Id$
+my $USAGE = <<'#';
+Usage: $ME [options]
+       -l --logfile=s   Name of the logfile we've to read [$opt_logfile]
+       -z --zonesdir=s  Where the named.conf's are expected [$opt_zonesdir]
+       -u --[no]update  Update the \"masters\"-entries [$opt_update] 
+       -f --[no]follow  Follow the end of the logfile [$opt_follow]
+       -d --[no]debug   extra debug output [$opt_debug]
+       -h --help        This text [$opt_help]
+          --daemon      go into background [$opt_daemon]
+       -p --pidfile=s   file to store the pid [$opt_pidfile]
+       -v --version     print version [$opt_version]
+#
+# Es wird ein Verzeichnis geben, in diesem Verzeichnis liegt für 
+# *jede* Zone eine eigene Konfigurations-Datei.
+# Diese ganzen Konfigurationsdateien werden dann zusammengefaßt
+# und diese zusammengefaßte wird dem bind per "include" mitgeteilt.
+#
+# Wir durchsuchen den Syslog nach
+# NOTIFY von Master-Servern.
+#   o Wenn der Master nicht authorisiert ist -> ENDE GELÄNDE
+#   o Andernfalls merken wir uns diesen Master für diese Domain
+# Wenn dann mal zu lesen ist "not of our zones" und wir uns diesen
+# als einen unserer Master gemerkt haben, dann vermerken wir uns, daß
+# für diese Zone das Konfig-File fehlt.
+#
+# Sollte irgendwann mal ein "slave zone...loaded" auftauchen, ist das Konfig-File
+# inzwischen vorhanden und kein Grund zur Panik.  Wir entfernen es aus der Liste
+# der fehlenden Files.
+#
+# Sollte dieser Text ausbleiben, müssen wir ein File anlegen (wahrscheinlich).
+# -> Sollte trotzdem schon eins da sein, dann konnten wir aus irgendwelchen
+# Gründen nix laden (deshalb fehlt ja der "...loaded"-Text).  Das kann z.B. sein, weil ein 
+# Master mal keinen Bock hat oder nicht authoritativ ist.
+#
+# Etwas anders sieht's im update-Modus aus.  Hier wird *jeder* Master für jede Domain gemerkt und
+# geprüft, ob der in dem entsprechenden Konfig-File enthalten ist.
+#
+# Im täglichen Einsatz sollte es ohne Update-Modus ganz gut funktionieren.
+
+use strict;
+use File::Basename;
+use IO::Handle;
+use Fcntl qw/:flock/;
+use File::Path;
+use Getopt::Long;
+use Unix::Syslog qw/:macros :subs/;
+
+my $ME = basename $0;
+
+
+my %auth = (
+    "212.80.235.130" => "pu.schlittermann.de",
+    "212.80.235.132" => "mango.compot.com",
+    "145.253.160.50" => "bastion.actech.de",
+    "62.144.175.34" => "ns.add-on.de",	    
+    "195.145.19.34" => "ns.datom.de",
+    "62.157.194.1" => "ns.mueritzcomp.de",
+    "212.80.235.137" => "ns.flaemingnet.de omni.flaemingnet.de",
+    "212.80.235.152" => "www.nestwerk.de",
+    # "194.162.141.17" => "dalx1.nacamar.de",
+);
+
+$SIG{__DIE__} = sub { syslog(LOG_ERR, $_[0]); exit -1; };
+$SIG{__WARN__} = sub { syslog(LOG_WARNING, $_[0]); };
+$SIG{TERM} = $SIG{INT} = sub { exit 0; };
+
+my %seen;
+
+my $opt_help = 0;
+my $opt_pidfile = "/var/run/$ME.pid";
+my $opt_logfile = "/var/log/syslog";
+my $opt_zonesdir = "/etc/bind/zones.d";
+my $opt_follow = 0;
+my $opt_update = 0;
+my $opt_debug = 0;
+my $opt_daemon = 1;
+my $opt_version = 0;
+
+my $naptime = 60;
+
+
+sub updateFile($$$);
+sub debug($;@) { syslog(LOG_DEBUG, "DEBUG " . shift @_, @_) if $opt_debug; }
+
+END {
+    if (open(PID, $opt_pidfile)) {
+	my $pid = <PID>;
+	close(PID);
+	unlink $opt_pidfile if $$ == $pid;
+    }
+}
+
+MAIN: {
+
+
+    openlog($ME, LOG_PID | LOG_PERROR, LOG_DAEMON);
+    syslog(LOG_NOTICE, "starting");
+
+    GetOptions(
+	"help" => \$opt_help,
+	"logfile=s" => \$opt_logfile,
+	"follow!" => \$opt_follow,
+	"update!" => \$opt_update,
+	"debug!" => \$opt_debug,
+	"daemon!" => \$opt_daemon,
+	"pidfile=s" => \$opt_pidfile,
+	"version!" => \$opt_version,
+	"zonesdir=s" => \$opt_zonesdir)
+    or die "$ME: Bad Usage\n";
+
+    if ($opt_help) {
+	print eval "\"$USAGE\"";
+	exit 0;
+    }
+
+    if ($opt_version) {
+	print "$ME Version: ", '$Id$', "\n";
+	exit 0;
+    }
+
+
+    # Create the PID-File
+    {
+	open(PID, $_ = ">$opt_pidfile.$$") or die "Can't open $opt_pidfile: $!\n";
+	print PID "$$\n";
+	close(PID);
+
+	if (!link($_ = "$opt_pidfile.$$", $opt_pidfile)) {
+	    unlink "$opt_pidfile.$$";
+	    die "There's another $ME running.  Bad. Stop.";
+	}
+	unlink "$opt_pidfile.$$";
+    }
+
+    if ($opt_daemon) {
+	my $pid = fork();
+
+	if ($pid < 0) {
+	    die "Can't fork: $!\n";
+	} 
+
+	if ($pid) {
+	    open(PID, $_ = ">$opt_pidfile") or die "Can't open $_: $!\n";
+	    print PID "$pid\n";
+	    close(PID);
+	    exit 0;
+	}
+
+	close(STDIN); close(STDOUT); close(STDERR);
+    }
+
+
+    open (LOGFILE, $_ = "<$opt_logfile") or die "Can't open $_: $!\n";
+
+    for (;;) {
+	my (%masters, %missing, %nomasters);
+	while (<LOGFILE>) {
+	    
+	    my ($domain, $ip);
+	    
+	    # NOTIFY-Zeilen
+	    ($domain, $ip) = /NOTIFY.*?\((\S+?),.*?\[([\d.]+)\]/ and do {
+		if (not exists $auth{$ip}) {
+		    warn "notify for $domain from unauthorized ip $ip\n";
+		    next;
+		};
+		# also in die Liste (hier als Key eines Hashes wegen der möglichen
+		# Dopplungen) der Master für diese Domain aufnehmen.
+		debug("Master für $domain: $ip\n");
+		$masters{$domain}->{$ip} = 1;
+		next;
+	    };
+
+	    # Das müssen wir doch garnicht machen, da wir ja sowieso nach 
+	    # dem Master-Files gucken...
+	    # NOTIFY for vergessene 
+	    /NOTIFY for "(\S+?)".*not one of our zones/ and do {
+		my $domain = $1;
+		if (not exists $masters{$domain}) {
+		    debug "skipping $domain (not authorized)\n";
+		    next;
+		}
+		# Also in die Liste der vergessenen Domains (für die wir garkeine
+		# Konfigurations-Datei haben)
+		next if exists $missing{$domain};	# schon erledigt
+
+		debug("Missing file for $domain\n");
+		$missing{$domain} = 1;
+		next;
+	    };
+
+	    # Wenn wir ein "... loaded" finden, dann fehlt das File nicht gänzlich!
+	    /slave zone "(\S+?)" .*loaded/ and do {
+		my $domain = $1;
+		next if not exists $missing{$domain};	# ist noch nicht vermißt worden
+
+		debug("Missing file for $domain is not longer missing\n");
+		delete $missing{$domain};
+		next;
+	    };
+
+	    /\[([\d.]+)\] not authoritative for (\S+), SOA/ and do {
+		my ($master, $domain) = ($1, $2);
+		next if exists $nomasters{$domain}->{$master};
+
+		debug "$master isn't a auth. master for $domain\n";
+		$masters{$domain}->{$master} = 1;	# sieht blöd aus, wird aber gebraucht,
+							# weil wir nur die bearbeiten, die einen
+							# master haben
+		$nomasters{$domain}->{$master} = 1;
+		next;
+	    };
+	}
+
+	# Jetzt sind wir erstmal durch und verarbeiten alles
+	my $changed = 0;
+	foreach my $domain (sort ($opt_update ? keys %masters : keys %missing)) {
+	    $changed += updateFile($domain, [keys %{$masters{$domain}}], [keys %{$nomasters{$domain}}]);
+	    delete $masters{$domain};
+	    delete $missing{$domain} if exists $missing{$domain};
+	    delete $nomasters{$domain} if exists $nomasters{$domain};
+	}
+
+	debug "$changed changes."; 
+	if ($changed) {
+	    debug("bind reload required\n");
+	    open(ALL, $_ = ">/etc/bind/zones.all") or die "Can't open $_: $!\n";
+	    foreach (</etc/bind/zones.d/*>) {
+		open(IN, $_) or die "Can't open $_: $!\n";
+		print ALL <IN>;
+		close(IN);
+	    }
+	    system qw(ndc reload);
+	}
+
+	last if !$opt_follow;
+	syslog LOG_INFO, "Sleeping for $naptime seconds\n";
+	sleep $naptime;
+	if ((LOGFILE->stat())[1] != (stat($opt_logfile))[1]) {
+	    # new file to follow
+	    syslog(LOG_NOTICE, "Logfile changed, re-open it.\n");
+	    open(LOGFILE, $_ = "<$opt_logfile") 
+		or die "Can't open $_: $!\n";
+	} else {
+	    LOGFILE->clearerr();
+	}
+    }
+}
+
+sub updateFile($$$)
+{
+    local $_;
+    my $domain = $_[0];
+    my @new_masters = @{$_[1]};
+    my @no_masters = @{$_[2]};
+
+    my %masters = ();
+    my $masters;
+
+    my $file = "$opt_zonesdir/$domain";
+
+    debug "updateFile: $domain, @new_masters, @no_masters\n";
+
+    if (-f $file) {
+	# Das File ist also schon da, wir müssen nur mal gucken, ob die Master,
+	# von denen wir ein NOTIFY erhalten haben, auch in unserer Datei stehen.
+	#
+	open (F, $_ = "+<$file") or die "Can't open $_: $!\n";
+	flock(F, LOCK_EX); seek(F, 0, 0);
+
+	$_ = join "", <F>;
+
+	# Liste der Master raussuchen, darus noch die löschen, die uns
+	# die Mitarbeit verweigert haben..
+	/^(\s*masters\s*{\s*)(.*?);(\s*}\s*;)(\s*\/\/.*?\n)/ims;
+	%masters = map { $_, 1 } split/\s*;\s*/, $2;
+	$masters = %masters;	# für den späteren Vergleich
+
+	# noch unsere neuen hinzufügen...
+	@masters{@new_masters} = map { 1 } @new_masters;
+
+	# nun die weg, die sich nicht zuständig fühlen
+	delete @masters{@no_masters};
+
+	# Wenn sich nach alldem nichts verändert hat, haben wir fertig.
+	if ($masters eq %masters) {
+	    debug("File is up-to-date for $domain\n");
+	    syslog(LOG_NOTICE, "No changes made for $domain (no \"loaded\" seen, defective master?)\n")
+		unless $opt_update;
+	    close(F);
+	    return 0;
+	}
+
+	if (not %masters) {
+	    syslog LOG_NOTICE, "REMOVING $file (empty masters list)\n";
+	    close F;
+	    unlink $file;
+	    return 1;
+	}
+
+	$masters = join ";", keys %masters;
+	syslog(LOG_NOTICE, "Updated masters ($masters) list for $domain\n");
+	s/^(\s*masters\s*{\s*)(.*?);(\s*}\s*;)/$1$masters;$3/ims;
+
+	truncate(F, 0);
+	seek(F, 0, 0);
+	print F;
+	close F;
+
+	return 1;
+    } 
+
+
+    my $date = localtime();
+    my %new_masters = map { $_, 1 } @new_masters;
+    delete @new_masters{@no_masters};
+
+    if (not %new_masters) {
+	syslog LOG_INFO, "not creating $file (empty masters list)\n";
+	return 0;
+    }
+
+    $masters = join "; ", @new_masters;
+
+    -d $opt_zonesdir or mkpath($opt_zonesdir, 0, 0755);
+
+    syslog(LOG_NOTICE, "Creating $file for $domain");
+    open(OUT, $_ = ">$file") or die "Can't open $_: $!\n";
+
+	print OUT <<_EOF_;
+// Autogenerated by $ME: $date
+zone "$domain" {
+    type slave;
+    masters { $masters; };  // $date
+    file "/etc/bind/slave/$domain";
+    allow-query { any; };
+    allow-transfer { none; };
+    allow-update { none; };
+};
+
+_EOF_
+    close OUT;
+
+    return 1;
+}
+	
+
+# vim:sts=4 sw=4 aw ai sm:
--- a/master_watcher	Mon Jan 27 15:42:03 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,349 +0,0 @@
-#! /usr/bin/perl -w
-# $Id$
-my $USAGE = <<'#';
-Usage: $ME [options]
-       -l --logfile=s   Name of the logfile we've to read [$opt_logfile]
-       -z --zonesdir=s  Where the named.conf's are expected [$opt_zonesdir]
-       -u --[no]update  Update the \"masters\"-entries [$opt_update] 
-       -f --[no]follow  Follow the end of the logfile [$opt_follow]
-       -d --[no]debug   extra debug output [$opt_debug]
-       -h --help        This text [$opt_help]
-          --daemon      go into background [$opt_daemon]
-       -p --pidfile=s   file to store the pid [$opt_pidfile]
-       -v --version     print version [$opt_version]
-#
-# Es wird ein Verzeichnis geben, in diesem Verzeichnis liegt für 
-# *jede* Zone eine eigene Konfigurations-Datei.
-# Diese ganzen Konfigurationsdateien werden dann zusammengefaßt
-# und diese zusammengefaßte wird dem bind per "include" mitgeteilt.
-#
-# Wir durchsuchen den Syslog nach
-# NOTIFY von Master-Servern.
-#   o Wenn der Master nicht authorisiert ist -> ENDE GELÄNDE
-#   o Andernfalls merken wir uns diesen Master für diese Domain
-# Wenn dann mal zu lesen ist "not of our zones" und wir uns diesen
-# als einen unserer Master gemerkt haben, dann vermerken wir uns, daß
-# für diese Zone das Konfig-File fehlt.
-#
-# Sollte irgendwann mal ein "slave zone...loaded" auftauchen, ist das Konfig-File
-# inzwischen vorhanden und kein Grund zur Panik.  Wir entfernen es aus der Liste
-# der fehlenden Files.
-#
-# Sollte dieser Text ausbleiben, müssen wir ein File anlegen (wahrscheinlich).
-# -> Sollte trotzdem schon eins da sein, dann konnten wir aus irgendwelchen
-# Gründen nix laden (deshalb fehlt ja der "...loaded"-Text).  Das kann z.B. sein, weil ein 
-# Master mal keinen Bock hat oder nicht authoritativ ist.
-#
-# Etwas anders sieht's im update-Modus aus.  Hier wird *jeder* Master für jede Domain gemerkt und
-# geprüft, ob der in dem entsprechenden Konfig-File enthalten ist.
-#
-# Im täglichen Einsatz sollte es ohne Update-Modus ganz gut funktionieren.
-
-use strict;
-use File::Basename;
-use IO::Handle;
-use Fcntl qw/:flock/;
-use File::Path;
-use Getopt::Long;
-use Unix::Syslog qw/:macros :subs/;
-
-my $ME = basename $0;
-
-
-my %auth = (
-    "212.80.235.130" => "pu.schlittermann.de",
-    "212.80.235.132" => "mango.compot.com",
-    "145.253.160.50" => "bastion.actech.de",
-    "62.144.175.34" => "ns.add-on.de",	    
-    "195.145.19.34" => "ns.datom.de",
-    "62.157.194.1" => "ns.mueritzcomp.de",
-    "212.80.235.137" => "ns.flaemingnet.de omni.flaemingnet.de",
-    "212.80.235.152" => "www.proton24.de",
-    # "194.162.141.17" => "dalx1.nacamar.de",
-);
-
-$SIG{__DIE__} = sub { syslog(LOG_ERR, $_[0]); exit -1; };
-$SIG{__WARN__} = sub { syslog(LOG_WARNING, $_[0]); };
-$SIG{TERM} = $SIG{INT} = sub { exit 0; };
-
-my %seen;
-
-my $opt_help = 0;
-my $opt_pidfile = "/var/run/$ME.pid";
-my $opt_logfile = "/var/log/syslog";
-my $opt_zonesdir = "/etc/bind/zones.d";
-my $opt_follow = 0;
-my $opt_update = 0;
-my $opt_debug = 0;
-my $opt_daemon = 1;
-my $opt_version = 0;
-
-my $naptime = 60;
-
-
-sub updateFile($$$);
-sub debug($;@) { syslog(LOG_DEBUG, "DEBUG " . shift @_, @_) if $opt_debug; }
-
-END {
-    open(PID, $opt_pidfile);
-    my $pid = <PID>;
-    close(PID);
-    unlink $opt_pidfile if $$ == $pid;
-}
-
-MAIN: {
-
-
-    openlog($ME, LOG_PID | LOG_PERROR, LOG_DAEMON);
-    syslog(LOG_NOTICE, "starting");
-
-    GetOptions(
-	"help" => \$opt_help,
-	"logfile=s" => \$opt_logfile,
-	"follow!" => \$opt_follow,
-	"update!" => \$opt_update,
-	"debug!" => \$opt_debug,
-	"daemon!" => \$opt_daemon,
-	"pidfile=s" => \$opt_pidfile,
-	"version!" => \$opt_version,
-	"zonesdir=s" => \$opt_zonesdir)
-    or die "$ME: Bad Usage\n";
-
-    if ($opt_help) {
-	print eval "\"$USAGE\"";
-	exit 0;
-    }
-
-    if ($opt_version) {
-	print "$ME Version: ", '$Id$', "\n";
-	exit 0;
-    }
-
-
-    # Create the PID-File
-    {
-	open(PID, $_ = ">$opt_pidfile.$$") or die "Can't open $opt_pidfile: $!\n";
-	print PID "$$\n";
-	close(PID);
-
-	if (!link($_ = "$opt_pidfile.$$", $opt_pidfile)) {
-	    unlink "$opt_pidfile.$$";
-	    die "There's another $ME running.  Bad. Stop.";
-	}
-	unlink "$opt_pidfile.$$";
-    }
-
-    if ($opt_daemon) {
-	my $pid = fork();
-
-	if ($pid < 0) {
-	    die "Can't fork: $!\n";
-	} 
-
-	if ($pid) {
-	    open(PID, $_ = ">$opt_pidfile") or die "Can't open $_: $!\n";
-	    print PID "$pid\n";
-	    close(PID);
-	    exit 0;
-	}
-
-	close(STDIN); close(STDOUT); close(STDERR);
-    }
-
-
-    open (LOGFILE, $_ = "<$opt_logfile") or die "Can't open $_: $!\n";
-
-    for (;;) {
-	my (%masters, %missing, %nomasters);
-	while (<LOGFILE>) {
-	    
-	    my ($domain, $ip);
-	    
-	    # NOTIFY-Zeilen
-	    ($domain, $ip) = /NOTIFY.*?\((\S+?),.*?\[([\d.]+)\]/ and do {
-		if (not exists $auth{$ip}) {
-		    warn "notify for $domain from unauthorized ip $ip\n";
-		    next;
-		};
-		# also in die Liste (hier als Key eines Hashes wegen der möglichen
-		# Dopplungen) der Master für diese Domain aufnehmen.
-		debug("Master für $domain: $ip\n");
-		$masters{$domain}->{$ip} = 1;
-		next;
-	    };
-
-	    # Das müssen wir doch garnicht machen, da wir ja sowieso nach 
-	    # dem Master-Files gucken...
-	    # NOTIFY for vergessene 
-	    /NOTIFY for "(\S+?)".*not one of our zones/ and do {
-		my $domain = $1;
-		if (not exists $masters{$domain}) {
-		    debug "skipping $domain (not authorized)\n";
-		    next;
-		}
-		# Also in die Liste der vergessenen Domains (für die wir garkeine
-		# Konfigurations-Datei haben)
-		next if exists $missing{$domain};	# schon erledigt
-
-		debug("Missing file for $domain\n");
-		$missing{$domain} = 1;
-		next;
-	    };
-
-	    # Wenn wir ein "... loaded" finden, dann fehlt das File nicht gänzlich!
-	    /slave zone "(\S+?)" .*loaded/ and do {
-		my $domain = $1;
-		next if not exists $missing{$domain};	# ist noch nicht vermißt worden
-
-		debug("Missing file for $domain is not longer missing\n");
-		delete $missing{$domain};
-		next;
-	    };
-
-	    /\[([\d.]+)\] not authoritative for (\S+), SOA/ and do {
-		my ($master, $domain) = ($1, $2);
-		next if exists $nomasters{$domain}->{$master};
-
-		debug "$master isn't a auth. master for $domain\n";
-		$masters{$domain}->{$master} = 1;	# sieht blöd aus, wird aber gebraucht,
-							# weil wir nur die bearbeiten, die einen
-							# master haben
-		$nomasters{$domain}->{$master} = 1;
-		next;
-	    };
-	}
-
-	# Jetzt sind wir erstmal durch und verarbeiten alles
-	my $changed = 0;
-	foreach my $domain (sort ($opt_update ? keys %masters : keys %missing)) {
-	    $changed += updateFile($domain, [keys %{$masters{$domain}}], [keys %{$nomasters{$domain}}]);
-	    delete $masters{$domain};
-	    delete $missing{$domain} if exists $missing{$domain};
-	    delete $nomasters{$domain} if exists $nomasters{$domain};
-	}
-
-	debug "$changed changes."; 
-	if ($changed) {
-	    debug("bind reload required\n");
-	    open(ALL, $_ = ">/etc/bind/zones.all") or die "Can't open $_: $!\n";
-	    foreach (</etc/bind/zones.d/*>) {
-		open(IN, $_) or die "Can't open $_: $!\n";
-		print ALL <IN>;
-		close(IN);
-	    }
-	    system qw(ndc reload);
-	}
-
-	last if !$opt_follow;
-	syslog LOG_INFO, "Sleeping for $naptime seconds\n";
-	sleep $naptime;
-	if ((LOGFILE->stat())[1] != (stat($opt_logfile))[1]) {
-	    # new file to follow
-	    syslog(LOG_NOTICE, "Logfile changed, re-open it.\n");
-	    open(LOGFILE, $_ = "<$opt_logfile") 
-		or die "Can't open $_: $!\n";
-	} else {
-	    LOGFILE->clearerr();
-	}
-    }
-}
-
-sub updateFile($$$)
-{
-    local $_;
-    my $domain = $_[0];
-    my @new_masters = @{$_[1]};
-    my @no_masters = @{$_[2]};
-
-    my %masters = ();
-    my $masters;
-
-    my $file = "$opt_zonesdir/$domain";
-
-    debug "updateFile: $domain, @new_masters, @no_masters\n";
-
-    if (-f $file) {
-	# Das File ist also schon da, wir müssen nur mal gucken, ob die Master,
-	# von denen wir ein NOTIFY erhalten haben, auch in unserer Datei stehen.
-	#
-	open (F, $_ = "+<$file") or die "Can't open $_: $!\n";
-	flock(F, LOCK_EX); seek(F, 0, 0);
-
-	$_ = join "", <F>;
-
-	# Liste der Master raussuchen, darus noch die löschen, die uns
-	# die Mitarbeit verweigert haben..
-	/^(\s*masters\s*{\s*)(.*?);(\s*}\s*;)(\s*\/\/.*?\n)/ims;
-	%masters = map { $_, 1 } split/\s*;\s*/, $2;
-	$masters = %masters;	# für den späteren Vergleich
-
-	# noch unsere neuen hinzufügen...
-	@masters{@new_masters} = map { 1 } @new_masters;
-
-	# nun die weg, die sich nicht zuständig fühlen
-	delete @masters{@no_masters};
-
-	# Wenn sich nach alldem nichts verändert hat, haben wir fertig.
-	if ($masters eq %masters) {
-	    debug("File is up-to-date for $domain\n");
-	    syslog(LOG_NOTICE, "No changes made for $domain (no \"loaded\" seen, defective master?)\n")
-		unless $opt_update;
-	    close(F);
-	    return 0;
-	}
-
-	if (not %masters) {
-	    syslog LOG_NOTICE, "REMOVING $file (empty masters list)\n";
-	    close F;
-	    unlink $file;
-	    return 1;
-	}
-
-	$masters = join ";", keys %masters;
-	syslog(LOG_NOTICE, "Updated masters ($masters) list for $domain\n");
-	s/^(\s*masters\s*{\s*)(.*?);(\s*}\s*;)/$1$masters;$3/ims;
-
-	truncate(F, 0);
-	seek(F, 0, 0);
-	print F;
-	close F;
-
-	return 1;
-    } 
-
-
-    my $date = localtime();
-    my %new_masters = map { $_, 1 } @new_masters;
-    delete @new_masters{@no_masters};
-
-    if (not %new_masters) {
-	syslog LOG_INFO, "not creating $file (empty masters list)\n";
-	return 0;
-    }
-
-    $masters = join "; ", @new_masters;
-
-    -d $opt_zonesdir or mkpath($opt_zonesdir, 0, 0755);
-
-    syslog(LOG_NOTICE, "Creating $file for $domain");
-    open(OUT, $_ = ">$file") or die "Can't open $_: $!\n";
-
-	print OUT <<_EOF_;
-// Autogenerated by $ME: $date
-zone "$domain" {
-    type slave;
-    masters { $masters; };  // $date
-    file "/etc/bind/slave/$domain";
-    allow-query { any; };
-    allow-transfer { none; };
-    allow-update { none; };
-};
-
-_EOF_
-    close OUT;
-
-    return 1;
-}
-	
-
-# vim:sts=4 sw=4 aw ai sm:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rc.ddns-autoslave	Mon Nov 28 06:57:17 2005 +0000
@@ -0,0 +1,33 @@
+#! /bin/bash
+
+DAEMON=/usr/local/sbin/master_watcher
+PIDFILE=/var/run/master_watcher.pid
+
+test -x $MASTER_WATCHER || exit 0
+
+case $1 in
+	
+	start)	
+		echo -n "Starting $DAEMON..."
+		start-stop-daemon --start --pid $PIDFILE --exec $DAEMON -- -f
+		echo " OK";
+		;;
+		
+	stop)	
+		echo -n "Stopping $DAEMON..."
+		start-stop-daemon --stop --pid $PIDFILE
+		echo " OK";
+		;;
+		
+	restart) echo -n "Restarting $DAEMON..."
+		$0 stop
+		$0 start
+		;;
+
+	*)
+		echo "Usage: /etc/init.d/$DAEMON {start|stop|restart}" >&2
+		exit 1			
+		;;
+esac
+
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rc.dns-autoslave	Mon Nov 28 06:57:17 2005 +0000
@@ -0,0 +1,33 @@
+#! /bin/bash
+
+DAEMON=/usr/local/sbin/master_watcher
+PIDFILE=/var/run/master_watcher.pid
+
+test -x $MASTER_WATCHER || exit 0
+
+case $1 in
+	
+	start)	
+		echo -n "Starting $DAEMON..."
+		start-stop-daemon --start --pid $PIDFILE --exec $DAEMON -- -f
+		echo " OK";
+		;;
+		
+	stop)	
+		echo -n "Stopping $DAEMON..."
+		start-stop-daemon --stop --pid $PIDFILE
+		echo " OK";
+		;;
+		
+	restart) echo -n "Restarting $DAEMON..."
+		$0 stop
+		$0 start
+		;;
+
+	*)
+		echo "Usage: /etc/init.d/$DAEMON {start|stop|restart}" >&2
+		exit 1			
+		;;
+esac
+
+exit 0
--- a/rc.master_watcher	Mon Jan 27 15:42:03 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-#! /bin/bash
-
-DAEMON=/usr/local/sbin/master_watcher
-PIDFILE=/var/run/master_watcher.pid
-
-test -x $MASTER_WATCHER || exit 0
-
-case $1 in
-	
-	start)	
-		echo -n "Starting $DAEMON..."
-		start-stop-daemon --start --pid $PIDFILE --exec $DAEMON -- -f
-		echo " OK";
-		;;
-		
-	stop)	
-		echo -n "Stopping $DAEMON..."
-		start-stop-daemon --stop --pid $PIDFILE
-		echo " OK";
-		;;
-		
-	restart) echo -n "Restarting $DAEMON..."
-		$0 stop
-		$0 start
-		;;
-
-	*)
-		echo "Usage: /etc/init.d/$DAEMON {start|stop|restart}" >&2
-		exit 1			
-		;;
-esac
-
-exit 0