#!/usr/bin/perl
# DocumentId:	$Id: emuga-groupgen.pl,v 1.4 2002/03/19 07:34:08 ola Exp $
# Author:	$Author: ola $
# Date:		$Date: 2002/03/19 07:34:08 $
# Version:	$Revision: 1.4 $
# Summary:
#

$range = "norange";
$definitionFile = "/etc/emuga/group.def";
$templateFile = "/etc/emuga/group.template";
$groupFile = "/etc/group";
$outFile = $groupFile;

###############################################################################
############################# USES ############################################
# Changes:
#	2002-03-18 Ola Lundqvist <opal@debian.org>
#		Wrote the uses.
###############################################################################

use OpaL::action qw(pdebug action
		    setDebugLevel setQuitLevel
		    setErrorHandler);
use OpaL::read qw(readfile readcommand);
use File::Copy;
use File::Basename;
use File::Find;

###############################################################################
############################# HELP ############################################
# Changes:
#	2002-03-18 Ola Lundqvist <opal@debian.org>
#		Wrote it.
###############################################################################

$help = "
USAGE: emuaga-groupgen.pl [options]

options:
  --outfile file | -o file
		The file to put the output
  -s
		Output to stdout.
  --groupfile file | -g file
		The original group file to generate data from.
  --templatefile file | -t file
		The template file to use for GIDS and some other things.
  --definitionfile file | -d file
		The definition file to use (for group definitions).
  --dl n
		Set the debug level.
  --ql n
		Set the quit level.
  --help
		Print this help message.

";

###############################################################################
############################# ARGS ############################################
# Desctiption:
#	Argument handling.
# Changes:
#	2002-03-18 Ola Lundqvist <opal@debian.org>
#		Wrote it.
###############################################################################

while ($_ = shift @ARGV) {
    if (/^--/) {
	if (/^--dl$/ || /^--debug-level$/) {
	    setDebugLevel(shift @ARGV);
	}
	elsif (/^--ql$/ || /^--quit-level$/) {
	    setQuitLevel(shift @ARGV);
	}
	elsif (/^--help$/) {
            print($help);
	    exit 0;
	}
	elsif (/^--groupfile$/) {
	    $groupFile = shift @ARGV;
	}
	elsif (/^--definitionfile$/) {
	    $definitionFile = shift @ARGV;
	}
	elsif (/^--templatefile$/) {
	    $templateFile = shift @ARGV;
	}
	elsif (/^--outfile$/) {
	    $outFile = shift @ARGV;
	}
	else {
	    pdebug(3, "Unknown option $_.");
	}
    }
    elsif (/^-$/) {
	pdebug(3, "Unknown option '-'.");
    }
    elsif (/^-/) {
	s/^\-//;
	my $t = $_;
	foreach (split //, $t) {
	    if (/g/) {
		$groupFile = shift @ARGV;
	    }
	    elsif (/d/) {
		$definitionFile = shift @ARGV;
	    }
	    elsif (/t/) {
		$templateFile = shift @ARGV;
	    }
	    elsif (/o/) {
		$outFile = shift @ARGV;
	    }
	    elsif (/s/) {
		$outFile = "-";
	    }
	    else {
		pdebug(3, "Unknown option '-$_'.");
	    }
	}
    }
}

require $definitionFile;

if ($GIDS eq "norange") {
    print("You have to specify a GID range in where you are placing your\n".
	  "group definitions.\n");
    exit(0);
}

###############################################################################
############################ The actual program ###############################
# Changes:
#	2002-03-18 Ola Lundqvist <opal@debian.org>
#		Wrote it.
###############################################################################
my $grpcontent =
    stripGroup($groupFile,$GIDS).
    expandTemplate($templateFile);
open(G, ">$outFile");
print G $grpcontent;
close(G);

###############################################################################
# Name:		stripGroup
# Argument:	group file name
#		GIDS definition to strip for.
# Return:	a string with the group file content.
# Changes:
#	2002-03-18 Ola Lundqvist <opal@debian.org>
#		Wrote it.
###############################################################################
sub stripGroup($$) {
    my ($groupFile, $gStrip) = @_;
    my $ret = "";
    open (G, $groupFile);
    @groups = <G>;
    close(G);
    # Strip for all groups defined.
    foreach my $s (split /\|/, $gStrip) {
	@groups = grep(!/^[^:]+:[^:]+:$s:/, @groups);
    }
    foreach my $g (@groups) {
	$ret = "$ret$g";
    }
    return $ret;
}

###############################################################################
# Name:		expandTeplate
# Argument:	template file name
# Return:	a string with the template file content.
# Changes:
#	2002-03-18 Ola Lundqvist <opal@debian.org>
#		Wrote it.
###############################################################################
sub expandTemplate($) {
    my ($templateFile) = @_;
    my $ret = "";
    open (T, $templateFile);
    @template = grep(!/^\s*\#/,
		     grep (!/^\s*$/, <T>));
    close(T);
    
    # Apply DEFINITION rules on each line.
    foreach my $line (@template) {
	my $oldline = "";
	while ($oldline ne $line && $line =~ /\%\S+\%/) {
	    $oldline = $line;
	    # DEFINITION rules is applied here.
	    foreach my $k (keys %DEFINITIONS) {
		$line =~ s/\%$k\%/$DEFINITIONS{$k}/g;
	    }
	}
	# Strip white-spaces.
	$line =~ s/\s//g;
	# Strip double user definitions.
	my %users = ();
	my $tmpline = $line;
	$tmpline =~ s/^.*:([^:]*)$/$1/;
	foreach my $u (split /,/, $tmpline) {
	    $users{$u} = 1;
	}
	$line =~ s/^(.*:)[^:]*$/$1/;
	$line =~ s/,,+//g;
	foreach my $u (keys %users) {
	    if ($u eq "") {
	    }
	    elsif (getpwnam $u) {
		$line = "$line$u,";
	    }
	    else {
		pdebug(3, "Unknown user $u.");
	    }
	}
	$line =~ s/,,+//g;
	$line =~ s/,$//;
	# Add to return string.
	$ret = "$ret$line\n";
    }
    return $ret;
}
