# Creation of a usermaint-hook (invoked after apply changes)
#
# 1) add the name of the new procedure to the HOOK_LIST.
#
#	set HOOK_LIST \
#	{
#		delete_directories
#		create_directories
#		my_hook
#	}
#
#    NOTE: hooks are executed in the order in which they
#	   apear in the hook list.
#
# 2) create the new hook procedure--a template follows.
#
#	proc my_hook {userlist_added userlist_edited userlist_deleted} \
#	{
#		foreach passwd_entry $userlist_added \
#		{
#			set passwd_entry [file_to_normal $passwd_entry]
#			if {[query "DO OPERATION ON USER...?"] == 1} \
#			{
#				...
#			}
#		}
#	}
#
# Creation of a uid_hook (added to the uid useredit menu)
#
# 1) addthe name of the new procedure to the UID_HOOKS list.
#
# 2) create the hook procedure.
#
#    uid_hook procedures are passed a passwd_entry, the editing window
#    name, and the userlist window name.  Refer to the code for info on
#    how to use these parameters.  The passwd_entry is the most simple
#    entity to work with, and you should refer to the passwd-manip.tcl
#    file for insight on how to work with it.
#
#    The procedure either returns -1 indicating that no change should be
#    made to the current uid, or another value which the uid is changed to.
#
# See the following code for further explanations.

set HOOK_LIST \
{
	delete_directories
	create_directories
}

set UID_HOOKS \
{
	Verify_Uniqueness
	Find_Unique_UID
}

proc delete_directories {userlist_added userlist_edited userlist_deleted} \
{
	foreach passwd_entry $userlist_deleted \
	{
		set passwd_entry [file_to_normal $passwd_entry]
		set dir [passwd_get_home_dir $passwd_entry]
		if {([string length $dir] > 0) && ([file exists $dir] == 1)} \
		{
			set user [passwd_get_username $passwd_entry]
			set realname [passwd_get_realname $passwd_entry]
			if {$realname != {}} {set user "$user ($realname)"}
			if {[query "Delete user $user's home directory ($dir)?"] == 1} \
			{
				catch "exec rm -rf $dir"
			}
		}
	}
}

proc create_directories {userlist_added userlist_edited userlist_deleted} \
{
	foreach passwd_entry [lunion $userlist_added $userlist_edited] \
	{
		set passwd_entry [file_to_normal $passwd_entry]
		set dir [passwd_get_home_dir $passwd_entry]
		if {([string length $dir] > 0) && ([file exists $dir] == 0)} \
		{
			set user [passwd_get_username $passwd_entry]
			set realname [passwd_get_realname $passwd_entry]
			if {$realname != {}} {set user "$user ($realname)"}
			apply_create_directory $user $dir
		}
	}
}

proc apply_create_directory {user dir} \
{
	if {[query "Create home directory ($dir) for user $user?"] == 1} \
	{
		catch {exec mkdir -p $dir}
		if {[file exists $dir] == 1} \
		{
			global SKEL_DIRECTORY
			if {[file exists $SKEL_DIRECTORY] == 1} \
			{
				if {[query "Initialize home directory ($dir) for user $user?"] == 1} \
				{
					catch "exec cp -r $SKEL_DIRECTORY/ $dir"
				}
			}
		}
	}
}

proc VERIFY_UNIQUENESS {passwd_entry w win} \
{
	upvar #0 tmp_passwd_text([expr "{$win} == {} ? {.} : {$win}"]) tmp_passwd_text
	set skip [userlist_tag_find $win $w]
	set uid [$w.useredit.entry.uid get]
	set i 0
	if {[string compare [string range $w 0 3] {.add}] == 0} {set skip -1}
	foreach passwd_entry $tmp_passwd_text \
	{
		if {$i != $skip} \
		{
			if {[string compare $uid [passwd_get_uid [file_to_normal $passwd_entry]]] == 0} \
			{
				return "UID IN USE."
			}
		}
		incr i
	}
	return -1
}

proc FIND_UNIQUE_UID {passwd_entry w win} \
{
	upvar #0 tmp_passwd_text([expr "{$win} == {} ? {.} : {$win}"]) tmp_passwd_text
	set skip [userlist_tag_find $win $w]
	set uid_list {}
	set i 0
	if {[string compare [string range $w 0 3] {.add}] == 0} {set skip -1}
	foreach passwd_entry $tmp_passwd_text \
	{
		if {$i != $skip} \
		{
			lappend uid_list [passwd_get_uid [file_to_normal $passwd_entry]]
		}
		incr i
	}
	set uid_list [lnumsort $uid_list]
	set uid 2000
	set size [llength $uid_list]
	for {set i 0} {$i < $size} {incr i} \
	{
		if {[lindex $uid_list $i] > $uid}  {break}
		if {[lindex $uid_list $i] == $uid} \
		{
			incr uid
		}
	}
	return $uid
}
