#!/usr/bin/perl

# Drakwizard

# Copyright (C) 2002 Arnaud Desmons <adesmons@mandrakesoft.com>
#               2003 Florent Villard <warly@mandrakesoft.com>
#
# This program is free software; you can redistribute it and/or modify
# it 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.
#
# This program is 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.

package MDK::Wizard::Bind_client;
use lib qw(/usr/lib/libDrakX);
use strict;

use common;
use services;
use MDK::Wizard::Varspaceval;
use MDK::Wizard::Wizcommon;

my $wiz = new MDK::Wizard::Wizcommon;
my $wiz_ip_server = $wiz->{net}->itf_get("IPADDR");
my $wiz_domain_name = $wiz->{net}->network_get("DOMAINNAME");

my $o = { 
    name => N('DNS Client Wizard'),
    var => { 
	    client_ip => '',
	    client_name => ''
	},
    needed_rpm => [ ],
    defaultimage => "$ENV{__WIZ_HOME__}client_wizard/images/DNS.png",
    init => sub {
	if (! -f "/var/named/$wiz_domain_name.db") {
	    return (0, N('You must first run the DNS server wizard'))
	}
	1
    }
    };

$o->{pages} = { 
		  welcome => {
		      name => N('DNS Client Wizard') . "\n\n" . N('A client of your local network is a machine connected to the network having its own name and IP number.') . "\n\n" . N('This wizard will help you in adding a new client in your local DNS.') . "\n\n" . N('The server will use the informations you enter here to make the name of the client available to other machines into your network.') . "\n\n" . N('Press next to begin, or Cancel to leave this wizard.'),
		      post => sub { $wiz->check_dhcp },
		  no_back => 1,
	          next => 'client_id'
	      },
	      client_id => {
	          name => N('Client identification:') . "\n\n" . N('Your client on the network will be identified by name, as in clientname.company.net. Every machine on the network must have a (unique) IP address, in the usual dotted syntax.') . "\n\n" . N("(you don't need to type the domain after the name)") . "\n\n" . N('Note that the given IP number and client name should be unique in the network.'),
		  pre => sub {
		    $o->{var}{client_ip} = ip();
		    $o->{var}{client_name} = name();
		  },
                  data => [
		      { label => N('Name of the machine:'), val => \$o->{var}{client_name} },
		      { label => N('IP number of the machine:'), val => \$o->{var}{client_ip} },
		      ],
	          next => 'summary'
	      },
	      dhcp_warning => {
		name => N('Warning') . "\n\n" . N('You are in dhcp, server may not work with your configuration.'),
		ignore => 1,
	        next => 'client_id'
	      },
	      system_error => {
		name => N('Error') . "\n\n" . N('System error, no configuration done'),
		ignore => 1,
	        next => 'client_id'
	      },
	      error => {
		name => N('Error') . "\n\n" . N('This is not a valid address... press next to continue'),
		ignore => 1,
	        next => 'client_id'
	      },
	      summary => {
	        name => N('Adding a new client to your network') . "\n\n" . N('The wizard collected the following parameters needed to add a client to your network:') . "\n\n" . N('To accept these values, and add your client, click the Next button or use the Back button to correct them.'),
                data => [
		      { label => N('Client name'), fixed_val => \$o->{var}{client_name} },
		      { label => N('Client IP:'), fixed_val => \$o->{var}{client_ip} },
		  ],
		post => \&do_it,
	        next => 'end'
	      },
	      end => { 
	        name => N('Congratulations') . "\n\n" . N('The wizard successfully added the client.'),
		end => 1,
	        next => 0
	  },
};

sub check_dhcp {
    $wiz->{net}->is_dhcp() and return 'dhcp_warning';
}

sub name {
    $wiz->{net}->network_get("HOSTNAME");
}

sub ip {
    $wiz_ip_server;
}

sub get_root {
    my	$file = "/etc/sysconfig/named";
    if (-f $file) {
	my %mdk = MDK::Wizard::Varspaceval->get($file);
	return $mdk{ROOTDIR};
    }
    "";
}

sub up_serial {
    my	($file) = @_;

    my (undef, undef, undef, $mday, $mon, $year) = gmtime(time);
    $year += 1900;
    my	$serial_nbm = sprintf "%4dY%2dm%2d00", $year, $mon, $mday;
    output($file, map {
	my $line = $_;
	if (/^(\s*)(\d*)(\s*;\s*Serial.*)$/) {
	    my $serial_f = $2;
	    $serial_f++;
	    if ($serial_f <= $serial_nbm) {
		$serial_f = $serial_nbm;
		chomp($serial_f);
		$line = "$1$serial_f$3\n";
	    }
	}
	$line;
    } cat_($file));
}

sub test {
    !$o->{client_name} and return 'error';
    !$o->{client_ip} and return 'error';
    my $s_trunc = "$1.$2.$3" if $wiz_ip_server =~ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/;
    my $ds = "$4" if $wiz_ip_server =~ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/;
    my $dc = "$4" if $o->{var}{client_ip} =~ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/;
    my $sc_trunc = "$1.$2.$3" if $o->{var}{client_ip} =~ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/;
    (!$sc_trunc || !$dc || !$ds || !$s_trunc || ($s_trunc != $sc_trunc) || ($dc == $ds || $dc < 0 || $dc > 255)) and return 'error';
}

sub do_it {
    $::testing and return;
    my $date = `date`;
    chomp($date);
    my $wiz_ip_net = "$1.$2.$3.0" if $wiz_ip_server =~ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/;
    my $s_trunc = "$1.$2.$3" if $wiz_ip_server =~ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/;
    my $ds = "$4" if $wiz_ip_server =~ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/;
    my $dc = "$4" if $o->{var}{client_ip} =~ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/;

    my $file="/var/named/$wiz_domain_name.db";
    MDK::Common::cp_af($file, $file.".orig");
    open(NEW, ">> $file") or die "can not open $file";
    print NEW "\n$o->{var}{client_name}	IN A $o->{var}{client_ip} ; $date\n\n";
    close(NEW) or die "can not close $file";
    up_serial($file);

    my $file="/var/named/$s_trunc.rev";
    MDK::Common::cp_af($file, $file.".orig");
    open(NEW, ">> $file") or die "can not open $file";
    print NEW "\n$dc IN PTR $o->{var}{client_name}. ; $date\n\n";
    close(NEW)	or die "can not close $file";
    up_serial($file);
    if (services::is_service_running('named')) {
	services::restart('named') 
    } else {
        services::start('named')
    }
}

sub new {
    my ($class, $conf) = @_;
    bless {
	    o   => $o,
       }, $class;
}

1;