#!/bin/bash
##
## Author: Lorenzo Canovi
## create/modify groups

CMD=`basename $0`


# (FUNCTIONS)

# compara i dati passati con quelli contenuti in /etc/group
# (tutti tranne la password), ritorna ok se non ci sono differenze,
# non ok ed elenco differenze su stdout se ce ne sono
#
compare_group()
{
	local name=$1
	local gid=$2

	pwent=`grep "^$name:" /etc/group`
	[ "$pwent" = "" ] && {
		echo "new"
		return 1
	}
	local pgid=`	echo "$pwent" | cut -d: -f 3`

	changes=""
	[ "$pgid" != "$gid" ]		&& changes="$changes gid=$pgid"

	[ "$changes" != "" ] && {
		echo $changes
		return 1
	}
	return 0
}


# search for local filesystems
#
local_fs()
{
	local done_dir=/tmp/done_dir.$$.tmp
	local done_dev=/tmp/done_dev.$$.tmp

	cp /dev/null $done_dir
	cp /dev/null $done_dev

	cat /proc/mounts | while read dev dir type parms
	do
		if [ $dir != "/" ]
		then
			case $type in
				ext*|reiserfs|xfs) ;; # OK
				*) continue ;;
			esac
		fi
		grep -q "^$dir$" $done_dir && continue
		grep -q "^$dev$" $done_dev && continue
		[ -d $dir ] && echo $dir	# may not exists, if in chroot jail
		echo $dir >>$done_dir
		echo $dev >>$done_dev
	done

	rm -f $done_dir $done_dev
}


usage()
{
	echo "
usage: $CMD gid:groupname ....
" >&2
	exit 1
}


# (MAIN)

groups=
RETRY=0
EXECUTE=true

while [ $# != 0 ]
do
	case $1 in
		-r)	shift
			[ $# = 0 ] && usage
			RETRY="$1"
			;;
		-n)	EXECUTE=false
			;;
		*:*)	# ignore silently other formats
			groups="$groups $1"
			;;
	esac
	shift
done

[ "$groups" = "" ] && usage

pass=0
status=0

while :
do
    pass=`expr $pass + 1`

    [ $pass -le $RETRY ] || exit 1

    [ $pass -gt 1 -a $status = 0 ] && break
    [ $pass -gt 1 -a $RETRY != 0 ] && echo -e "\n* RETRY $pass\n"

    status=0

    for group in $groups
    do
	[ $status != 0 -a $RETRY = 0 -a $EXECUTE = true ] && exit 1

	gid=`echo "$group" | cut -d: -f 1`
	group=`echo "$group" | cut -d: -f 2`

	# controlla se il gruppo esiste, e se si se deve modificare qualcosa
	#
	result=`compare_group $group $gid` && continue

	if [ "$result" = new ]
	then
		printf " grp %-12s %-30s " $group "NEW"
		command="groupadd"
	else
		printf " grp %-12s %-30s " $group "mod $result"
		command="groupmod"
	fi

	$EXECUTE || command="echo $command"

	$command -g $gid $group || {
		status=1
		continue
	}

	$EXECUTE && echo ok

	# fix: se cambiato gid deve riassegnare ownership ai files
	#
	echo $result | grep -q "gid=" && {
		pgid=`echo $result | sed -e 's/.*gid=//' -e 's/ .*//'`
		filesystems=`local_fs`
		files=xx
		echo -n "		  fixing gid from $pgid to $gid on " $filesystems " ... "
		$EXECUTE && {
			files=`find $filesystems -xdev -group $pgid -print -exec verbatim_chgrp $gid {} \; | wc -l`
		}
		echo "$files files/dirs"
	}
    done
done

exit 0
