#!/usr/bin/perl -w

use strict;
use XML::LibXML;
use Digest::MD5 qw(md5_hex);
use POSIX qw(strftime);
use Fcntl qw(:DEFAULT :flock);

$| = 1;

if ($> == 0) {
	exec "su", "ganymede", "-c", $0;
	exit 1;
}

my $parser = XML::LibXML->new();

my $xml_source = '/var/cache/xsltdhcp/ganymede-data.xml';
my $xml_dhcp   = '/var/cache/xsltdhcp/dhcpd-conf.xml';
my $conf_dir   = '/var/cache/xsltdhcp/';
my $xsl_dhcp   = '/usr/share/xsltdhcp/create-dhcp.xsl';
my $lockfile   = '/var/lock/xsltdhcp';
my $exit = 0;

open(LOCKFILE, '>', $lockfile) or die "$0: can't open lockfile: $lockfile\n";
if (flock(LOCKFILE, LOCK_EX) == -1) {
	die "$0: can't get lock on $lockfile\n";
}

my $start;
printf "dumping ganymede data..."; $start = time;
system('/etc/xsltdhcp/dump-data');
printf " %ds\n", time - $start;
printf "generating dhcp data..."; $start = time;
system('xalan', -xsl => $xsl_dhcp, -in => $xml_source, -out => $xml_dhcp);
printf " %ds\n", time - $start;

my $tree = $parser->parse_file($xml_dhcp);
my $root = $tree->getDocumentElement();

my @dhcp = $root->findnodes('/dhcp/dhcp-conf');

foreach my $dhcpconf_el (@dhcp) {
	my $dhcpd = $dhcpconf_el->findvalue('@id');
	printf "writing config for $dhcpd\n";
	my $v4 = $dhcpconf_el->findvalue('ipv4');
	my $v6 = $dhcpconf_el->findvalue('ipv6');
	
	if (defined $v4 and $v4 ne '') {
		open(OUT, '>', $conf_dir."/dhcpd.conf.$dhcpd");
		print OUT $v4;
		close(OUT);
	}
	if (defined $v4 and $v4 ne '') {
		open(OUT, '>', $conf_dir."/dhcpd6.conf.$dhcpd");
		print OUT $v6;
		close(OUT);
	}
}

foreach my $dhcpconf_el (@dhcp) {
	my $dhcpd = $dhcpconf_el->findvalue('@id');
	my $hostname = $dhcpconf_el->findvalue('@fqdn');
	
	system("/etc/xsltdhcp/test-dhcp", $dhcpd);
	if ($? != 0) {
		print STDERR "config-test failed for $dhcpd, skipping\n";
		$exit = 1;
		next;
	}
	
	system("/etc/xsltdhcp/sync-dhcp", $dhcpd, $hostname);
}

flock(LOCKFILE, LOCK_UN);

exit $exit;
1;
