#!/usr/bin/perl -w

# twiggi custom configuration
# Edit twiggi.conf and run this script
# 
# Version 4.4 
#
# (C) neddix 2001, www.neddix.de 
#
use strict;

my $twiggiconf="/etc/twiggi.conf"; # please change, if your twiggi.conf is somewhere else.

my $dbs; # database server
my $u="";
my $p="";
if ( defined $ARGV[0] && defined $ARGV[1] )
	{
	$u="user " . $ARGV[0];
	$p="password " . $ARGV[1];
	}

sub customconfig () ;
sub exclude_users () ;
sub comment () ;
sub set_address ($) ;
sub IPquadToAddr ($) ;
sub set_local_net () ;

my $custom="<?php\n";
(my $myname=$0)=~s#^.*/##;
my ($year, $month, $day, $hour, $min, $sec) = (localtime)[5,4,3,2,1,0];
$custom .= "// DO NOT MODIFY THIS FILE!\n";
$custom .= "// It is updated automatically by the $myname script\n\n";
$custom .= sprintf ( "\$config[\"creationdate\"]=\"%04d%02d%02d%02d%02d%02d\";\n", $year+1900, $month+1, $day, $hour, $min, $sec);
my $rew="";
my $s;
my $users_exclude=":";
my $groups=":";
my $twiggi_path;
my ($min_uid, $max_uid, $user, $uid, $gid, $real, $config);

open (IN, "$twiggiconf") || die "Error: Could not open $twiggiconf";
while ( $rew ne "" || defined($s=<IN>)) {
	if ($rew ne "") {
		$s=$rew;
		$rew="";
	}
	chomp($s); $s =~ s/\r$//;
	if ($s=~/^\[local nets\]/) {set_local_net(); next}
	if ($s=~/^\[include users with user id greater or equal\]/) {chomp($min_uid=<IN>); $min_uid =~ s/\r$//; next}
	if ($s=~/^\[include users with user id less or equal\]/) {chomp($max_uid=<IN>); $max_uid =~ s/\r$//; next}
	if ($s=~/^\[twiggi installation path\]/) {chomp($twiggi_path=<IN>); $twiggi_path =~ s/\r$//;next}
	if ($s=~/^\[exclude users by name\]/) {exclude_users(); next}
	if ($s=~/^\[twiggi customized configuration PHP code\]/) {customconfig(); next}
	if ($s=~/^\[comment\]/) {comment(); next}
	if ($s=~/^\[EOF\]/) {last}
	print "Unknown key: $s\n" if $s=~/\[.*\]/;
}
close (IN);

$custom .= "\n// twiggi-users\n";
setpwent();
while ( ($user,undef,$uid, undef, undef, undef, $real)=getpwent() ) {
	if ( $real eq "" ) {
		$real="?";
	}	
	if ( $uid>=$min_uid && $uid<=$max_uid && !($users_exclude=~/:$user:/) && !($user=~/\$$/) ) {
		$custom .= "\$config[\"localuser\"][\"$user\"]=\"$real\";\n";
	}
}

$custom .= "?>\n";

(undef,undef,undef,undef, $uid, $gid)=stat("$twiggi_path/config/config.inc.php");
die "Error: twiggi not installed or bad twiggi installation path set." if !defined($uid);

$config="$twiggi_path/config/custom.inc.php";
open (OUT, ">$config") or die "Error: Could not open $config for writing.";
print OUT $custom;
close(OUT);
chown ($uid, $gid, $config);
chmod (0660, $config);

system ("cd ../setup &&  ./twiggi-db-setup twiggi twiggi edunix_admin 'edun!xadm1n' $dbs $u $p");

exit;

sub customconfig () {
	$_=<IN>; s/\r$//;
	while ( not /^\[.*\]/ ) {
		chomp(); s/\r$//;
		s/^ *//g;
		s/ *$//g;
		if( $_ =~ 'dbconfig\["sqlserver"\]' )
			{
			($dbs=$_) =~ s/.*=.*["'](.*)["'].*/$1/;
			}
		if ( $_ ne "" ) {
			$custom .= "$_\n";
		}
		$_=<IN>;
	}
	$rew=$_;
}

sub exclude_users () {
	$_=<IN>; s/\r$//;
	while ( not /^\[.*\]/ ) {
		chomp(); s/\r$//;
		s/^ *//g;
		s/ *$//g;
		if ( $_ ne "" ) {
			$users_exclude.="$_:";	
		}
		$_=<IN>;
	}
	$rew=$_;
}

sub comment () {
	$_=<IN>; s/\r$//;
	while ( not /^\[.*\]/ ) {
		$_=<IN>; s/\r$//;
	}
	$rew=$_;
}

sub set_local_net () {
	my $i=0;
	$_=<IN>; s/\r$//;
	while ( not /^\[.*\]/ ) {
		chomp(); s/\r$//;
		s/^ *//g;
		s/ *$//g;
		if ( $_ ne "" ) {
			my $adr=$_;
			$adr =~ s/\r$//;
    		$adr =~  /^(\d+\.\d+\.\d+\.\d+)\/(\d+\.\d+\.\d+\.\d+)$/;
			(my $first_adr, my $last_adr) = computeHostRange ($1, $2);
			$custom .= "\$config[\"first_local_addr\"][$i]=$first_adr; // $adr\n";
			$custom .= "\$config[\"last_local_addr\"][$i]=$last_adr;\n";
			$i++;
		}
		$_=<IN>;
	}
	$rew=$_;
}


sub computeHostRange ($$)
{
    my ($ipaddr, $netmask) = @_;

    my $ipaddrBits   = IPquadToAddr ($ipaddr);
    my $netmaskBits  = IPquadToAddr ($netmask);
    my $hostmaskBits = ((~ $netmaskBits) & 0xffffffff);

    my $firstAddrBits = $ipaddrBits & $netmaskBits;
    my $lastAddrBits  = $ipaddrBits | $hostmaskBits;

    return ($firstAddrBits, $lastAddrBits);
}

sub IPquadToAddr ($)
{
    my ($quad) = @_;
    if ($quad =~  /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/)
    {
        return ($1 << 24) + ($2 << 16) + ($3 << 8) + $4;
    }
    return 0;
}
