#!/bin/bash
#      ^^^^ Niech mi to qr** ktos ruszy to zabij ;) - Marek
#
#
#  adduser			Interactive user adding program.
#
#  Copyright (C) 1996		Petri Mattila, Prihateam Networks
#				petri@prihateam.fi
#	
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2, or (at your option)
#  any later version.
#
# Changes:
#	220496	v0.01	Initial version
#	230496	v0.02	More checks, embolden summary
#	240496		Even more checks
#	250496 		Help with ?
#	040596	v0.03	Cleanups
#	050596	v0.04	Bug fixes, expire date checks
#	070596	v0.05	Iso-latin-1 names
#	101098	v0.06p	Polish Linux Distribution release
#			 by Marek Obuchowicz <elephant@shadow.eu.org>
#			 some things (like setting password-aging or
#			 help with ?) removed, a lot of modifications and
#			 addons
#	131098	v1.1	Added internationalization by Arkadiusz Mikiewicz
#			<misiek@misiek.eu.org>. Few fixes. (Previous was
#			version 1.0)
#	191298  v1.02	Fixed error with login name checking,
#			a little modifications in translations
#			by Marek Obuchowicz <elephant@shadow.eu.org>
#			Previous was version 1.01 :)
#	??????  v1.03   Just a little cosmetic changes
#	030198	v1.04   Added command line arguments parsing,
#			added multi-lingual /etc/skel support and
#			default quota (by Arkadiusz Mikiewicz)
#

TEXTDOMAIN=adduser

login_regex='^[a-z][a-z0-9_-]*$'
home_regex='^/[a-zA-Z0-9/_-]*$'

## Functions

check_root() {
	if test "$EUID" -ne 0
	then
		echo $"Only root may add a user to system."
#		exit 1
	fi
}

check_user() {
	local usr pwd uid gid name home sh

	cat /etc/passwd | (
		while IFS=":" read usr pwd uid gid name home sh
		do
			if test "$1" = "${usr}"
			then
				return 1
			fi
		done
		return 0
	)
}

check_group() {
	local read grp pwd gid members

	cat /etc/group | (
		while IFS=":" read grp pwd gid members
		do
			if test "$1" = "${grp}"
			then
				return 1
			fi
		done
		return 0
	)
}

check_other_groups() {
	local grp check IFS

	check="$1"
	IFS=","

	set ${check}
	for grp
	do
		if check_group "${grp}"
		then
			echo $"Group ${grp} does not exist."
			return 1
		fi
	done
	return 0
}		

check_uid() {
	local usr pwd uid gid name home sh
	
	cat /etc/passwd | (
		while IFS=":" read usr pwd uid gid name home sh
		do
			if test "$1" = "${uid}"
			then
				return 1
			fi
		done
		return 0
	)
}

read_yn() {
	local ans ynd
	
	ynd="$1"
	
	while :
	do
		read ans	
		case "${ans}" in
		      "") return ${ynd} ;;
		    [nN]) return 1 ;;
		    [yYtT]) return 0 ;;
		       *) echo -n $"[Y]es or [N]o ? " ;;
		esac
	done
}

read_login() {
	while :
	do
		echo -n $"login [${def_login:+${def_login}}]: "
		read login
		
		if test -z "${login}" -a -n "${def_login}"
		then
			login="${def_login}"
		fi

		if [ "`echo ${login} | grep ${login_regex}`" = "" ]; then
			echo $"Login may include small letters, digits and -_ charactes"
			continue
		fi
		
		if test "${#login}" -gt 8
		then
			echo $"Login must have maximal 8 charactes"
			continue
		fi
		
		if test "${#login}" -lt 2
		then
			echo $"Login must have at least 2 characters"
			continue
		fi
		
		if ! check_user "${login}"
		then
			echo $"User ${login} already exist."
			continue
		fi
		
		def_login="${login}"
		return
	done
}

read_name () {
	while :
	do
		echo -n $"Real Name [${def_name:+${def_name}}]: "
		read name
		
		if test -z "${name}" -a -n "${def_name}"
		then
			name="${def_name}"
		fi

		if test "${#name}" -gt 32
		then
			echo $"Maximal number of characters in Real Name is 32"	
			continue
		fi

		def_name="${name}"
		return
	done
}

read_home() {
	local x
	
	while :
	do
		echo -n $"Home directory [${def_home_dir}/${login}]: "
		read home
		
		if test -z "${home}"
		then
			home="${def_home_dir}/${login}"
		fi

		if [ "`echo ${home} | grep ${home_regex}`" = "" ]; then
			echo $"Home directory must begin with / and may include letters,"
			echo $"digits and _-/ characters"
			continue
		fi
		
		x="$(basename ${home})"
		if test "${x}" != "${login}"
		then
			echo $"Warning: login is different than name of home directory."
		fi
		
		x="$(dirname ${home})"
		if ! test -d "${x}"
		then
			echo $"Directory ${x} does not exist."
			echo $"If you still want it then make it manually."
			continue
		fi
		
		def_home_dir="${x}"
		return
	done
}

read_shell () {
	local x

	while :
	do
		echo -n $"Shell [${def_shell}]: "
		read shell
		
		if test -z "${shell}"
		then
			shell="${def_shell}"
		fi
		
		for x in $(cat /etc/shells)
		do
			if test "${x}" = "${shell}"
			then
				def_shell="${shell}"
				return
			fi
		done

		echo $"Available shells:"
		cat /etc/shells
	done
}

read_group () {
	while :
	do
		echo -n $"Group [${def_group}]: "
		read group
		
		if test -z "${group}"
		then
			group="${def_group}"
		fi
		
		if check_group "${group}"
		then
			echo $"Group ${group} does not exist."
			continue
		fi
		
		def_group="${group}"
		return
	done
}

read_other_groups () {
	while :
	do
		echo -n $"Extra groups [${def_og}]: "
		read other_groups
		
		if test -z "${other_groups}"
		then
			if test -n "${def_og}"
			then
				other_groups="${def_og}"
			else	
				return
			fi
		fi
		
		
		if ! check_other_groups "${other_groups}"
		then
			continue
		fi
		
		def_og="${other_groups}"
		return
	done
}

read_uid () {
	while :
	do
		echo -n $"UID [first available]: "
		read uid
			
		if test -z "${uid}"
		then
			return
		fi
		
		if test "${uid}" -lt "${uid_low}"
		then
			echo $"UID must be bigger than ${uid_low}"
			continue
		fi
		if test "${uid}" -gt "${uid_high}"
		then
			echo $"UID must be lower than ${uid_high}"
			continue
		fi
		if ! check_uid "${uid}"
		then
			echo $"UID ${uid} is already used."
			continue
		fi
		
		return
	done
}

read_quota() {
        echo -e $"Do you want to use quota of user ${def_quota_user} [Y/n] ? "
	if read_yn 1; then
		def_quota_user=""
	fi
}

read_passwd_yn() {
	echo
	echo -en $"Do you want set a password [Y/n] ? "
	if read_yn 0
	then
		set_pwd="YES"
	else
		set_pwd=""
	fi
}


print_values() {

echo
echo $"Login:              "${login}
echo $"Group:              "${group}
echo $"Extra groups:       "${other_groups}
echo $"Real name:          "${name}
echo -n $"UID:                "
if [ -z "${uid}" ]; then
  echo $"first available"
else 
  echo ${uid}
fi
echo $"Home directory:     "${home}
echo $"Shell:              "${shell}
if [ -n "${def_quota_user}" ]; then
  echo $"Use quota of ${def_quota_user}."
fi
if [ -n "${set_pwd}" ]; then
  echo $"Set user's password."
fi
echo

}

set_user() {
	if ! useradd \
		-M \
		-c "${name}" \
		-d "${home}" \
		-g "${group}" \
		-s "${shell}" \
		${expire:+-e ${expire}} \
		${uid:+-u ${uid}} \
		${other_groups:+-G ${other_groups}} \
		${login}
	then
		echo $"Error ($?) in useradd..."
		exit 1
	fi
}

set_password() {
	if test -n "${set_pwd}"
	then
		echo
		passwd ${login}
		echo
	fi
}	

set_system() {
	## Add your own stuff here:
        if [ -x /usr/sbin/edquota ] && ! check_user "${login}"; then
                /usr/sbin/edquota -p ${def_quota_user} ${login}
        fi
	true
}


read_values() {
	echo $"Please enter data:"
	while :
	do
		read_login
		read_name
		read_group
		read_other_groups
		read_home
		read_shell
		read_uid
		read_quota
		read_passwd_yn

		print_values
		
		echo -n $"Are You sure [y/N] ? "
		read_yn 1 && return
	done
}

read_defaults() {
  if [ -f /etc/default/adduser ]; then
    . /etc/default/adduser
  else
    echo $"File /etc/default/adduser does not exist!"
    exit 1
  fi
}

copy_skel() {
  mkdir ${home}
  cp -af /etc/skel/C/. ${home}
  cp -af /etc/skel/${lang}/. ${home}
  chmod ${def_mode} ${home}
  chown -R ${login}.${group} ${home}
}

do_custom() {
  for run in /etc/adduser.d/*; do
    if [ -x ${run} ]; then
    . ${run} ${login} ${home}
    fi
  done
} 

parse_args () {
  for arg in $*; do
    case $arg in
      --lang=*)  
        lang=`echo $arg | cut -d= -f2 | cut -b1,2`
        continue;;
      -l*)
	lang=${arg:2:2}
        continue;;
      -h* | --help*)
        echo $"Syntax: adduser [-lXX | --lang=XX] [-h | --help] <login>"
        echo
        echo $"Available options:"
	echo $"-lXX or --lang=XX  - sets skeleton files language to XX"
	echo $"-h                 - prints this help"
	echo $"<login>            - name of the new user's account"
        exit;;
      -*)
        echo $"Unknown option: $arg"
	echo $"Try: adduser -h"
	exit;;
      *)
        def_login=$arg
        continue;;
    esac
  done
  [ "$lang" = "XX" ] && lang=default
}

main() {
	read_defaults
	lang=`echo ${def_lang:-XX} | cut -b1,2`
	parse_args $*
	check_root
	read_defaults
	read_values
	set_user
	set_system
	set_password
	copy_skel
	do_custom
}


# Uruchomienie - nareszcie ;)
# Wanie ;-)

main $*
