#!/usr/bin/perl
# DocumentId:	$Id: emuga-groupgen.pl 1765 2004-02-10 11:22:10Z ola $
# Author:	$Author: ola $
# Date:		$Date: 2004-02-10 12:22:10 +0100 (tis, 10 feb 2004) $
# Version:	$Revision: 1.8 $
# Summary:
#

$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.
#	2004-02-02 Ola Lundqvist <opal@debian.org>
#		Removed need of opalmod.
###############################################################################

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 [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.
#	2004-02-02 Ola Lundqvist <opal@debian.org>
#		Removed need of opalmod.
###############################################################################

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 {
	    print "Unknown option $_.\n";
	    exit (1);
	}
    }
    elsif (/^-$/) {
	print "Unknown option '-'.\n";
	exit (1);
    }
    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 {
		print "Unknown option '-$_'.\n";
		exit (1);
	    }
	}
    }
}

require $definitionFile;

if (scalar(@GIDS) == 0) {
    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.
#	2004-02-10 Ola Lundqvist <opal@debian.org>
#		Rewrote some because changed style in emuga-usergen. Bugfix.
###############################################################################
my $grpcontent =
    stripGroup($groupFile,@GIDS).
    expandTemplate($templateFile,@GIDS);
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.
#	2004-02-02 Ola Lundqvist <opal@debian.org>
#		Rewrote some because changed style in emuga-usergen.
###############################################################################
sub stripGroup($@) {
    my ($groupFile, @gStrip) = @_;
    my $ret = "";
    open (G, $groupFile);
    @groups = <G>;
    close(G);
    # Strip for all groups defined.
    foreach my $s (@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.
#	2004-02-02 Ola Lundqvist <opal@debian.org>
#		Rewrote some because changed style in emuga-usergen.
#		Removed need of opalmod.
#	2004-02-09 Ola Lundqvist <opal@debian.org>
#		Added stripping of unwanted groups from template.
###############################################################################
sub expandTemplate($@) {
    my ($templateFile, @gStrip) = @_;
    my $ret = "";
    open (T, $templateFile);
    @template = grep(!/^\s*\#/,
		     grep (!/^\s*$/, <T>));
    close(T);
    my @su = ();
    foreach my $s (@gStrip) {
	if (length($s) > 0) {
	    push @su, grep(/^[^:]+:[^:]+:$s:/, @template);
	}
    }
    @template = @su;
    
    # 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 {
		print "Unknown user $u.\n";
		exit (1);
	    }
	}
	$line =~ s/,,+//g;
	$line =~ s/,$//;
	# Add to return string.
	$ret = "$ret$line\n";
    }
    return $ret;
}

=head1 NAME

emuga-groupgen - Generate group information.

=head1 USAGE

emuga-groupgen [options]

=head1 DESCRIPTION

Emuga groupgen takes a template, definition and group file and generates
new group information based on that.

=head1 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.

=head1 AUTHOR

Ola Lundqvist <opal@debian.org>

=head1 SEE ALSO

emuga-target(1)

=cut
