#!/usr/bin/perl -w
#
# $Id: groupCreator,v 1.1 2001/01/06 01:26:25 precision Exp $
#
# groupCreator - perl script to create /home/groups/* and /cvsroot/* from
#                ldap properly.  It's made independant of the other scripts
#                for a reason.
#
use strict;
use Net::LDAP;
use Getopt::Std;

# initialize our variables
umask(002);
my ($basedn, $binddn, $bindpw, $ldap, $filter, $uid, $gid, $type, $cvsdir);
my ($entry, $attr, $mesg, @groupArray, $counter, $ticker, $group, %opts);

@groupArray = ();
$counter = 0;
$ticker = 0;

# unbuffer our output
$| = 1;

# configuration
$basedn = 'dc=sourceforge,dc=net';
$binddn = 'cn=Manager, dc=sourceforge, dc=net';
$bindpw = '';
$filter = '(&(objectClass=posixGroup)(memberUid=*))';

# proccess the command line args
getopt('t', \%opts);
if (!$opts{'t'} || $opts{'t'} ne 'shell' && $opts{'t'} ne 'cvs') {
	print <<EOF;
usage: groupCreator [-t type]
creates project directories and repositories  based on information from LDAP

	-t	type (shell or cvs) will create either cvsroots
		or /home/groups directories

EOF
	exit;
}

$ldap = Net::LDAP->new('sf-ldap1') or die $@;

$ldap->bind(
	dn       => $binddn,
	password => $bindpw
);

print "Performing search query $filter: ";
$mesg = $ldap->search(
		base   => $basedn,
		filter => $filter,
		scope  => 'sub',
		attrs  => 'cn'
) or die $@;
print "done.\n";


# build an array of group names
foreach $entry ($mesg->entries) { 
	$counter++;
	push @groupArray, $entry->get('cn');
}

print "Preparing to process $counter groups: ";
@groupArray = sort @groupArray;
print "done.\n";

print "Processing: ";
foreach $group (@groupArray) {
	$ticker++;

	# print a . for every 1000 groups we process
	if ($ticker == 1000) {
		print ".";
		$ticker=0;
	}

	# get numeric uid for the user and group
	$uid = getpwnam('nobody');
	$gid = getgrnam($group);

	# uh oh! nobody or the group doesn't seem to exist on this machine??
	if (!$uid || !$gid) { die "\nhouston, we have a problem: $group\n"; }

	# process this batch like we're on a shell server (create /home/groups/*, /home/groups/*/htdocs, /home/groups/*/cgi-bin)
	if ($opts{'t'} eq 'shell') {
		if (! -e "/home/groups/$group" && $group eq 'alexandria') {
			mkdir "/home/precision/groups/$group", 0775 or die "Can't create top-level directory for $group: $!\n";
			mkdir "/home/precision/groups/$group/htdocs", 0775 or die "Can't create htdocs directory for $group: $!\n";
			mkdir "/home/precision/groups/$group/cgi-bin", 0775 or die "Can't create cgi-bin directory for $group: $!\n";
			chown $uid, $gid, ("/home/precision/groups/$group", "/home/precision/groups/$group/htdocs", "/home/precision/groups/$group/cgi-bin");
		}

	# proccess the batch like a cvs server (create /cvsroot/* and init the repository)
	} elsif ($opts{'t'} eq 'cvs') {
		$cvsdir = "/home/precision/groups/cvsroot/$group";
		if (! -e $cvsdir && $group eq 'alexandria') {
			mkdir $cvsdir, 0775 or die "Can't create $cvsdir: $!\n";
			system("/usr/bin/cvs -d$cvsdir init");
			system("echo \"\" > $cvsdir/CVSROOT/writers");
			system("echo \"anonymous\" > $cvsdir/CVSROOT/readers");
			system("echo \"anonymous:\\\$1\\\$0H\\\$2/LSjjwDfsSA0gaDYY5Df/:anoncvs_$group\" > $cvsdir/CVSROOT/passwd");

			# setup loginfo to make group ownership every commit
			system("echo \"ALL chgrp -R $group $cvsdir\" > $cvsdir/CVSROOT/loginfo");
			system("echo \"\" > $cvsdir/CVSROOT/val-tags");
			chmod 0664, "$cvsdir/CVSROOT/val-tags";

			# set group ownership, anonymous group user
			system("chown -R $uid:$gid $cvsdir");
			system("chmod g+rw $cvsdir/CVSROOT/*");
		}
	}
		
}
print " done.\n"
