#!/bin/ksh
:
: adduser
:
# Uses ksh to get around bug in sh!
#
# pragma ident "@(#)adduser:adduser.sh 1.32 92/02/05 "
# 
# Copyright 1989 Apple Computer, Inc.
# All Rights Reserved.
# 
# THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF APPLE COMPUTER, INC.
# The copyright notice above does not evidence any actual or
# intended publication of such source code.
#
# Add a user to the system
# get unused UID number; add to existing group or make new one
# edit /etc/passwd, /etc/group
# make home directory
# copy in .login, .cshrc, .profile, .kshrc, .logout (everything in $SKEL)
# change ownerships appropriately
#
# If local machine runs Yellow Pages, all users must be in YP database
#
# usage:
#    adduser		    # completely interactive
#    adduser -h /home/guys  # interactive, but override home default
#
#    adduser fred	    # non-interactive; add account for user fred
#			    # use all default settings
#    adduser -d /u fred	    # non-interactive; put home in /u/fred
#
# optional flags:
#	-r real-name	# quoted string, e.g. 'Joe Programmer'
#	-a address	# office address (e.g. mail stop)
#	-x extension	# office phone no
#	-p home-phone	# home phone number
#	-g group	# group to use for all accounts created
#	-d dir		# parent of home directory (home is dir/$user)
#	-h home		# the precise home directory (home == home)
#	-s shell	# login shell to use for all accounts
#	-u uid		# specify lowest desirable uid
#	-U UID		# force UID number
#	-i		# force interactive mode
#	-c		# use the global System Folder
# if names are given, they must come after all flags
#
# the range of user/group ids available, plus password file locking is done
# by a subroutine: /usr/lib/addusersub

##############################################################
#			Variables			     #
##############################################################

USAGE='usage: adduser [-r real-name] [-a address] [-x extension] [-p home-phone]
              [-g group] [-d dir | -h home] [-s shell] [-u uid | -U UID] [-i] [-c] name'

SKEL=/usr/lib/skel	# directory of skeletal .login, .profile, etc...
XSKEL=/usr/lib/X11	# contains X11 startup files
UID=1000	# lowest uid with which to start looking for openings
GID=1000	# lowest gid with which to start looking for openings
MAXID=32767	# maximum (positive) user/group ID number
ABSMAXID=65535	# absolute maximum ID number (including negatives!)
SHELL=/bin/csh	# default shell
HOMEDIR=/users	# default directory containing homes
MACDIR=/mac/bin # directory of Mac applications
UC='System Folder' # local System Folder

d_folder=TRUE; folder='yes'	# create a personal System Folder

PATH="/bin:/usr/bin:/usr/ucb:/etc:/usr/lib:"

export UID GID
##############################################################
#		Function definitions			     #
##############################################################

check_shell() {
  p=`ps -p$$`
  if [ `expr "$p" : "^.* \(.*\)$"` != 'ksh' ]; then
      echo "$0 is a ksh script; it must not be run with sh"
      exit 1
  fi
}

usage()
{
    echo $USAGE >&2; exit 1
}

salida()
{
    # clean up tmp files and exit
    rm -f /etc/ptmp /etc/gtmp /tmp/yppw$$ /tmp/ypgp$$
    exit $1
}

#	f_badname - check full pathnames (returns 0 on bad name)
f_badname()
{
    trap "salida" 2 15
    if [ "$1" = "/" ]; then
	return 1
    fi
    return `expr "$1" : "^/.*"`
}

#	f_badnum - check whether value is a number (returns 0 if bad)
f_badnum()
{
    trap "salida" 2 15
    return `expr "$1" : "^[0-9]*[0-9]"`
}

#	f_badphone - check whether value is a phone number (returns 0 if bad)
#  acepts any of: 1234, (408) 555-1212, ext. 1234, X5555, +1 408 555-1212
f_badphone()
{
    trap "salida" 2 15
    num=$1
    num=`expr "$num" : '^[EeXxTt\. +]*\(.*\)' `
    return `expr "$num" : "^[- ()0-9]*[- ()0-9]$"`
}


#	f_reply - ask for a yes/no response
f_reply() {
  trap "salida" 2 15
  unset reply
  while :; do
    echo "$1 \c"
    read answer
    case $answer in
     [yY]*) reply=y; break ;;
     [nN]*) reply=n; break ;;
	"") if [ "$2" != "" ]; then
	      reply=$2; break
	    else
		echo '\nNo default response; you must answer "y" or "n".'
	    fi
	    ;;
	 *) echo '\nYou must answer "y" or "n".' ;;
    esac
  done
}

#	f_chkname - Check that login name is OK
f_chkname()
{
    trap "salida" 2 15
    user=$1
    err=0
    if [ `expr "$user" : '^.*[a-z].*'` -eq 0 ]; then
	echo "adduser: <$user> names must contain at least one lower case letter." >&2
	err=2
    elif [ `expr "$user" : '^.*[ 	].*'` -ne 0 ]; then
	echo "adduser: <$user> names must not contain blanks." >&2; err=2
    elif [ `expr "$user" : '^.*:.*'` -ne 0 ]; then
	echo "adduser: <$user> names must not contain ':'." >&2; err=2
    elif [ "`expr $user : '^\(.\).*:.*'`" = '~' ]; then
	echo "adduser: <$user> names must not begin with '~'." >&2; err=2
    elif [ "`expr $user : '^\(.\).*:.*'`" = '+' ]; then
	echo "adduser: <$user> names must not begin with '+'." >&2; err=2
    elif [ `expr $user : '^.*$'` -ge 15 ]; then
	echo "adduser: <$user> names must not exceed 14 characters"; err=2
    elif [ `expr $user : '^.*$'` -gt 8 ]; then
	echo "adduser: <$user> names should not exceed 8 characters
	 Remote access (rlogin) prohibits login names > 8 characters."
	err=1
    fi
    return $err
}

#	f_chkpw - Check if user is already in password file
f_chkpw() {
    trap "salida" 2 15
    if grep "^$user:" /etc/passwd >/dev/null; then
	# already in local password file
	if [ "$interactive" = 'TRUE' ]; then
	    echo "adduser: login name '"$user"' already in local passwd file."
	    finger -m $user
	    echo 'Select a different login name [enter empty line to quit] \c'
	    read new
	    case "$new" in
	    "") return 2;;
	    esac
	else
	    echo "adduser: login name '"$user"' already in local passwd file." >&2
	    finger -m $user >&2
	    set $userlist
	    case $# in
	    1) return 2;;		# no more names in list; clean up & exit
	    *) shift; userlist="$@";	# skip name already in use
	    esac
	fi
	return 1
    elif [ "$YP" = 'TRUE' ]; then
	# running yellow pages; see if user is listed already
	passwd_entry=`grep "^$user:" /tmp/yppw$$ 2>/dev/null`
	if [ "$passwd_entry" != "" ]; then
	    # got a match
	    echo "adduser: $user is listed in NIS data base."
	    finger -m $user
	    eval `
	      echo "$passwd_entry" |
	      awk -F: '
	      { 
		  split($5, gcos, ",")
		  printf("passwd=%s; uid=%s; gid=%s; home=%s; shell=%s; ", \
		    $2, $3, $4, $6, $7)
		  printf("gcos1=\"%s\"; gcos2=\"%s\"; gcos3=\"%s\"; gcos4=\"%s\"", \
		    gcos[1], gcos[2], gcos[3], gcos[4])
	      }'
	    `
	    return 0
	else
	    # YP data base should have all IDs - we do NOT want a conflict
	    # If administrator wants a local user he can do it himself
	    echo "adduser: $user is not in NIS data base." >&2
	    echo 'Add user on NIS server.' >&2
	    salida 2
	fi
    else
	# brand new user
	unset new
	return 0
    fi
}

#	f_groupmenu - show a menu of possible groups
f_groupmenu()
{
    trap "salida" 2 15
    echo 'Currently available groups are:'
    awk -F: '
    BEGIN { printf("Special (system) groups:\n") }
    $3 <= 10 { 
	if(++cnt == 8) printf("\n")
        printf("  %-8s", $1)
	next
    }
    flag == 0 {
	flag=1; cnt=0
	printf("\n\nRegular (user) groups:\n")
    }
    $3 > 10 && $1 !~/^gp[1-9]+/ {
	 if( (++cnt % 8) == 0 ) printf("\n")
         printf("  %-8s", $1)
    }
    END { printf("\n") }
    ' /etc/group 
}

#	f_group - handle the group name and group ID
f_group()
{
    # called only if password file is NOT served via Yellow Pages
    # If interactive, group ID's calculated here may not actually
    # be used - user may override

    trap "salida" 2 15
    if [ -z "$group" ]; then
	# no group information available; create a default name
	# get highest unused group id; will add to group file
	gid=$lo_gid
	group=gp$gid
	newgroup=TRUE

    else	# group info given
	# determine if group info is name or numeric gid
	if [ `expr "$group" : "^[0-9]*[0-9]"` -ne 0 ]; then
	  # numeric
	  gid=$group; unset group
	fi

	if [ "$gYP" != 'TRUE' ]; then
	    # Will add to local group file

	    # See if group/gid is already in /etc/group file
	    if [ -n "$gid" ]; then
		# key off of gid to get group name
		group=`awk -F: ' /:'"$gid:"'/ { print $1 }' /etc/group`
	    else
		# key off of group name to get gid number
		gid=`awk -F: ' /^'"$group:"'/ { print $3 }' /etc/group`
	    fi	

	    if [ -n "$gid" ] && [ -n "$group" ]; then
		# existing entry in /etc/group
		unset newgroup
	    else
		# no match in /etc/group
		# we have one but not both of gid and group name
		# invent the missing member
		if [ -z "$group" ]; then
		    group=gp$gid
		elif [ -z "$gid" ]; then
		    gid=$lo_gid
		fi
		newgroup=TRUE
	    fi	
	elif [ "$gYP" = 'TRUE' ] && [ -z "$gid" ]; then
	    # It is unlikely administrator is running YP for group and not
	    # for password, but it is possible.
	    # Use group name to get gid from YP data base (for passwd file)
	    # nothing added to local /etc/group
	    g=`grep "^$group:" /tmp/ypgp$$ 2>/dev/null`
	    if [ "$g" = "" ]; then
		# no match from YP
		echo "adduser: group $group not in NIS data base." >&2
		salida 2
	    else
		gid=`echo $g | awk -F: '{print $3}'`
	    fi
	# else gYP == TRUE and gid provided
	    # get all info from Yellow pages; nothing added to local file
	fi
    fi
}

#	f_getinfo - Interactively get information from administrator
f_getinfo()
{
    trap "salida" 2 15
    if [ -z "$d_gcos1" ]; then
	echo "User's full name (e.g. Fred Smith) [$gcos1] \c"
	read answer
	case "$answer" in
	"") gcos1=${gcos1:-""};;
	 *) gcos1="$answer";;
	esac
    fi
	 
    if [ -z "$d_gcos2" ]; then
	echo 'Office address (e.g. mail stop) ['"$gcos2"'] \c'
	read answer
	case "$answer" in
	"") gcos2=${gcos2:-""};;
	 *) gcos2="$answer";;
	esac
    fi

    if [ -z "$d_gcos3" ]; then
        while :; do
	    echo 'Office telephone (extension) ['"$gcos3"'] \c'
	    read answer
	    case "$answer" in
	    "") gcos3=${gcos3:-""}; break;;
	     *) if f_badphone "$answer"; then
	            echo "$answer is not a valid telephone number."
	        else
 		    gcos3="$answer"
	            break
	        fi
	        ;;
	    esac
	done
    fi

    if [ -z "$d_gcos4" ]; then
        while :; do
	    echo 'Home telephone ['"$gcos4"'] \c'
	    read answer
	    case "$answer" in
	    "") gcos4=${gcos4:-""}; break;;
	     *) if f_badphone "$answer"; then
	            echo "$answer is not a valid telephone number."
	        else
 		    gcos4="$answer"
	            break
	        fi
	        ;;
	    esac
        done
    fi

    if [ -z "$d_group" ] && [ "$YP" != 'TRUE' ]; then
	echo '\nInitial group  (create a new group by entering a new name).'
	f_groupmenu
	while :; do
	    echo "\nInitial group [${l_group:-gp$gid}] \c"
	    read answer
	    case "$answer" in
	    \?|[Hh]|[Hh]elp) f_groupmenu; continue;;
		  "") group=${l_group:-gp$gid}; break;;
		   *) group=$answer; l_group=$group; break;;
	    esac
	done
	if [ "$group" != "gp$gid" ]; then
    	    unset gid
    	    f_group
	fi
    fi

    if [ -z "$d_shell" ]; then
	while :; do
	    echo "Shell [${l_shell:-$SHELL}] \c"
	    read answer
	    case $answer in
	    "") shell=${l_shell:-$SHELL}; break;;
	     *) if f_badname $answer; then
		    echo "Shell must be specified by full pathname."
		else
		    shell=$answer;
		    break
		fi
		;;
	    esac
	done
	l_shell=$shell
    fi

    if [ -z "$d_home" ] && [ -z "$d_homes" ]; then
	while :; do
	    echo "Home directory [${l_home:-$HOMEDIR/$user}] \c"
	    read answer
	    case $answer in
	    "") home=${l_home:-$HOMEDIR/$user}; break;;
	     *) if f_badname $answer; then
		    echo "Home must be specified by full pathname."
		else
		    home=$answer;
		    break
		fi
		;;
	    esac
	done
	if [ "$home" != '/' ] && [ `basename $home` = "$user" ]; then
	    if [ `dirname $home` != "$HOMEDIR" ]; then
		HOMEDIR=`dirname $home`
	    fi
	    unset l_home
	else
	    l_home=$answer
	fi
    fi

    if [ "$d_folder" != 'FALSE' ]; then
        while :; do
	    echo "Create a personal System Folder? [${folder:-yes}] \c"
	    read answer
	    case "$answer" in
	             "") folder=${folder:-yes}; break;;
		    [nN]*) folder=no; break;;
		    [yY]*) folder=yes; break;;
	 	    *) echo '\nYou must answer "yes" or "no".' ;;
	    esac
        done
    fi
	
}

#	f_doypentry - handle adding entry to passwd file before +::0:0:
#		or any other style of +... line
f_doypentry()
{
    trap "salida" 2 15
	awk '
	  /^\+/ { exit }
		{ print }
	' /etc/passwd > /etc/ptmp
	echo $passwd_entry >> /etc/ptmp
	awk '
	       /^\+/ { ready = 1 }
	  ready == 1 { print }
	' /etc/passwd >> /etc/ptmp
}

#
#	f_doreadme - put README file into new account
#
f_doreadme()
{
    trap "echo 'adduser: Interrupts temporarily disabled'" 2 15
    cat > $home/README << END_OF_README
Welcome to A/UX.

Your account has been set up with the following attributes:
	home directory: $home
	default shell: $shell
	initial group: $group
If you wish to change your shell, you may use the chsh command to switch to
/bin/sh, /bin/ksh, or /bin/csh.	 To use any other shell, or to change your
home directory or group, see your System Administrator.

In addition, the following personal information has been logged for you:
	full real name: $gcos1
	office address: $gcos2
	office phone: $gcos3
	home phone: $gcos4
To change any of this information, use the chfn command or see your System
Administrator.

Information on using A/UX and customizing your account may be found in the
manuals which came with your A/UX distribution.

This information is stored in the file called README and can be examined
or printed later.  From the finder, double-click the README file to view.
Or, use the TextEditor application, found in the directory /mac/bin.
END_OF_README

    if [ "$shell"  = '/bin/csh' ]; then
	echo '
# If new account, show README file
if ( -f $HOME/.newacct ) then
    cat $HOME/README; rm $HOME/.newacct
endif
	' >> $home/.login
    else
	echo '
# If new account, show README file
if [ -f $HOME/.newacct ]; then
    cat $HOME/README; rm $HOME/.newacct
fi
	' >> $home/.profile
    fi
}

##############################################################
#		Check usage and all that		     #
##############################################################
###
#	Ensure ksh!
###
check_shell

###
#	 Adduser must be run as root
###
id="`id`"
id=`expr "$id" : '^uid=\(.*\)(.*) gid=.*'`
if [ "$id" != '0' ]; then
    echo "You must be the superuser to run $0" >&2; exit 1
fi
unset id

###
#	Check calling parameters
###
case $# in
0) interactive=TRUE ;;
*) # noninteractive
    x=`getopt U:u:h:d:g:s:r:a:x:p:ic "$@"`''
    if [ $? -ne 0 ]; then
       usage
    fi
    eval set -- $x
    while [ "$1" != '--' ]; do
	case $2 in
	-*) if [ "$1" != "-i" ] && [ "$1" != "-c" ]; then
	        usage
	    fi
            ;;
        esac
	case $1 in
	-U) d_UID=$2;	  shift 2 	# explicitly forced uid
	    if f_badnum $d_UID; then
   	        echo "adduser: UID <$d_UID> must be a number" >&2
	        errs=TRUE
            fi
    	    if [ -n "$d_uid" ] ; then
		echo 'adduser: Only one of flags -U and -u may be specified.' >&2
		errs=TRUE
	    fi
	    ;;
	-u) d_uid=$2;	  shift 2 	# uid with which to start search
	    if f_badnum $d_uid; then
   	        echo "adduser: uid <$d_uid> must be a number" >&2
	        errs=TRUE
            fi
    	    if [ -n "$d_UID" ] ; then
		echo 'adduser: Only one of flags -U and -u may be specified.' >&2
		errs=TRUE
	    fi
	    ;;
	-h) d_home=$2;	  shift 2 	# home dir
	    if f_badname $d_home; then
   	        echo "adduser: directory <$d_home> must be a full pathname" >&2
	        errs=TRUE
            fi
    	    if [ -n "$d_homes" ] ; then
		echo 'adduser: Only one of flags -h and -d may be specified.' >&2
		errs=TRUE
	    fi
	    ;;
	-d) d_homes=$2;	  shift 2 	# parent of home dir
	    if f_badname $d_homes; then
   	        echo "adduser: directory <$d_homes> must be a full pathname" >&2
	        errs=TRUE
            fi
    	    if [ -n "$d_home" ] ; then
		echo 'adduser: Only one of flags -h and -d may be specified.' >&2
		errs=TRUE
	    fi
	    ;;
	-s) d_shell=$2;	  shift 2 	# shell
	    if f_badname $d_shell; then
   	        echo "adduser: shell <$d_shell> must be a full pathname" >&2
		errs=TRUE
	    fi
	    ;;
	-g) d_group=$2;	  shift 2 ;;	# group
	-r) d_gcos1="$2"; shift 2 ;;	# real name
	-a) d_gcos2="$2"; shift 2 ;;	# office address
	-x) d_gcos3="$2"; shift 2 	# office phone
	    if f_badphone "$d_gcos3"; then
   	        echo "adduser:<$d_gcos3> is not a valid telephone number" >&2
	        errs=TRUE
            fi
	    ;;
	-p) d_gcos4="$2"; shift 2 	# home phone
	    if f_badphone "$d_gcos4"; then
   	        echo "adduser:<$d_gcos4> is not a valid telephone number" >&2
	        errs=TRUE
            fi
	    ;;
	-i) shift; interactive=TRUE;;		# interactive mode
	-c) shift; d_folder=FALSE; folder='no';		# System Folder
	esac
    done; shift
    if [ "$errs" = 'TRUE' ]; then
	usage
    fi
    
    case $# in
    0) interactive=TRUE ;;
    *) for user in "$@"; do
	   case "$user" in
	   -*) usage;;
	   esac
           f_chkname "$user"; status=$?
           case $status in
	   0) userlist="$userlist $user"
	      ;;
	   1) if [ "$interactive" = 'TRUE' ]; then
		 f_reply 'Do you still want to use this name? [y/n]'
	         case $reply in
	         y) userlist="$userlist $user" ;;
		 n) echo "adduser: skipping <$user>" >&2 ;;
	         esac
	      else
		 echo "adduser: skipping <$user>" >&2
	      fi
	      ;;
	   2) echo "adduser: skipping <$user>" >&2
           esac
       done
       ;;
    esac
    ;;
esac

###
#	Lock password (and group) files
# 	get range of UIDs, GIDs available, look for ^+... lines
# 	in passwd, group files
###
if [ -n "$d_UID" ]; then
    u=`awk -F: ' $3 == '$d_UID' {print $1; exit}' /etc/passwd`
    if [ "$u" != '' ]; then
	echo "User ID $d_UID already in use for login name \"$u\"" >&2
	if [ "$interactive" = 'TRUE' ]; then
	    f_reply "Re-use ID $d_UID? [no]" n
	    case $reply in
	    y) ;;
	    n) f_reply "Use first available UID above $d_UID? [yes]" y
	       case $reply in
	       y) UID=$d_UID
	          unset d_UID
		  ;;
	       n) exit 3;;
	       esac
	       ;;
	    esac
	else
	    exit 3
	fi
    fi
else
    UID=${d_uid:-"$UID"}		# lowest desirable uid
fi
x=`addusersub init`		# get uid/gid values; initialize tmp files
if [ $? != 0 ]; then
    exit 1
fi
trap "salida" 2 15

if [ "$x" = "" ]; then
    echo 'adduser: Error reading passwd/group file(s)' >&2; salida 3
else
    eval "$x"
fi

if grep '^+:' /etc/passwd > /dev/null ; then
    yp=TRUE
fi
if grep '^+:' /etc/passwd > /dev/null ; then
    gyp=TRUE
fi

###
#	Check if system using Yellow Pages
###
if [ "$yp" = 'TRUE' ] || [ "$gyp" = 'TRUE' ]; then
  ypcat passwd > /tmp/yppw$$ 2>/dev/null; status=$?	# Is ypbind running ?
  if [ "$status" -eq 0 ]; then
    if [ "$yp" = 'TRUE' ]; then
      YP=TRUE	# using YP for password file
    fi
    if [ "$gyp" = 'TRUE' ]; then
      ypcat group > /tmp/ypgp$$ 2> /dev/null; status=$?
      if [ "$status" -eq 0 ]; then
        gYP=TRUE	# using YP for group file
      fi
    fi
  fi
fi

##############################################################
#			main				     #
##############################################################
comment="Enter user's login name (e.g. fred)"
cp /etc/passwd /etc/opasswd; cp /etc/group /etc/ogroup
while :; do
    set $userlist''
    user=${new:-$1}

    if [ "$user" = "" ] ; then
	if [ "$interactive" != 'TRUE' ]; then
	  salida
	fi
	echo "$comment \c"
	read new
	case "$new" in
	"") break;;
	*) user="$new"
	   f_chkname "$user"; status=$?		# check validity of user name
           case $status in
	   0) ;;
	   1) f_reply 'Do you still want to use this name? [y/n]'
	      case $reply in
	      n) unset new; continue;;
	      esac
	      ;;
	   2) unset new ; continue;;
           esac
	   ;;
	esac
    fi

    # Check password file
    f_chkpw; status=$?
    case $status in
    1) continue;;
    2) break;;
    esac

    if [ "$interactive" = 'TRUE' ]; then
        echo '\nSuggested values are shown in brackets.'
        echo 'To accept, press RETURN; otherwise, type the new value.\n'
    fi
    
    ###
    #	Set up values - check all possible overrides
    #	  Command line options override YP values and defaults
    #	  YP values override defaults
    ###

    if [ "$YP" = 'TRUE' ]; then
	gcos1=${d_gcos1:-"$gcos1"}	# defaults to YP value
	gcos2=${d_gcos2:-"$gcos2"}
	gcos3=${d_gcos3:-"$gcos3"}
	gcos4=${d_gcos4:-"$gcos4"}
	group=${d_group:-"$gid"}
	l_home=${d_home:-"$home"}
	l_shell=${d_shell:-"$shell"}
    else
	gcos1=${d_gcos1:-""}		#  ignore if not set
	gcos2=${d_gcos2:-""}		#     "         "
	gcos3=${d_gcos3:-""}		#     "		"
	gcos4=${d_gcos4:-""}		#     "		"
	group=${d_group:-""}		# calculate later if not set
	shell=${d_shell:-"$SHELL"}	# defaults to C shell
    fi

    if [ -n "$d_home" ]; then
	home=$d_home
    elif [ -n "$d_homes" ]; then
	home=${d_homes}/$user
    elif [ "$YP" != 'TRUE' ]; then
	home="$HOMEDIR"/$user	# defaults to /users/$user
    fi

    if [ -z "$YP" ]; then	# local, not YP, account
	if [ -n "$d_UID" ]; then
	    uid="$d_UID"
	    if [ "$uid" -ge "$ABSMAXID" ]; then
	         echo "adduser: UID must be less than $ABSMAXID." >&2
	         salida 3
	    fi
        else
	    uid=$lo_uid
	    lo_uid=`expr $lo_uid + 1`
	    if [ "$lo_uid" -gt "$hi_uid" ]; then
	        if [ "$hi_uid" = "$MAXID" ]; then
	            echo "adduser: next uid would exceed maximum $MAXID." >&2
	            echo "    specify a lower uid from which to start." >&2
	            salida 3
	        fi
	        UID=$lo_uid
                eval `addusersub`
	    fi
        fi
	f_group
	passwd=",.."
    fi

    while :; do
        ###
        #	Get information if interactive
        # present nice defaults to accept with CR
        ###
        if [ "$interactive" = 'TRUE' ] ; then
	    f_getinfo
        fi

        # Print report; if interactive, confirm data

        echo "
The account for $user will be created with the following attributes:

Login name: $user (uid $uid)	Real name: $gcos1
Office address: $gcos2	ext.: $gcos3 	Home phone: $gcos4
Home directory: $home	Shell: $shell		"

        if [ -n "$newgroup" ]; then
            echo "Group $group (gid $gid)  *This is a new group*"
        else
            echo "Group $group (gid $gid)"
        fi

	if [ "$folder" = 'no' ] ; then
	    echo "The common System Folder will be used."
        else
	    echo "A personal System Folder will be created."
	fi
        if [ "$interactive" = 'TRUE' ]; then
	    f_reply '\nOK to create account? [yes]' y
	    case $reply in
	    y) break;;
	    n) echo '';
	       f_reply "Change values for $user? [yes]" y
	       case $reply in
	       y) continue;;
	       n) salida;;
	       esac
	    esac
        else
            break
        fi
    done

    gcos="$gcos1,$gcos2,$gcos3,$gcos4"
    passwd_entry="$user:$passwd:$uid:$gid:$gcos:$home:$shell"

    trap "echo 'adduser: Interrupts temporarily disabled'" 2 15
    if [ "$YP" = 'TRUE' ] || [ "$yp" = 'TRUE' ]; then
	# add line above '+::0:0:' stuff in passwd file
	f_doypentry 
    else
        cp /etc/passwd /etc/ptmp
	echo $passwd_entry >> /etc/ptmp
    fi
    cp /etc/ptmp /etc/passwd
    /etc/SHADOW/pwconv

    if [ -n "$newgroup" ]; then
	unset newgroup
	cp /etc/group /etc/gtmp
	echo "$group:*:$gid:" >> /etc/gtmp
        cp /etc/gtmp /etc/group
    fi
    if [ $gid -eq $lo_gid ]; then
	# Used the calculated group ID; bump the low end of the range
        lo_gid=`expr $lo_gid + 1`
        if [ "$lo_gid" -gt "$hi_gid" ]; then
	    if [ "$hi_gid" = "$MAXID" ]; then
	        echo "adduser: next gid would exceed maximum $MAXID." >&2
	        echo "    too many groups." >&2
	        salida 3
	    fi
            GID=$lo_gid
            eval `addusersub`
        fi
    fi

    ###
    #	Create home directory (Yellow pages or local only)
    #	It is OK to create the immediate parent of the home directory
    ###

    h=`dirname $home`
    if [ ! -d $h ]; then
	mkdir $h; status=$?
	if [ $status -ne 0 ]; then
	    echo "adduser: cannot create home; cannot create $h!" >&2
	    salida 3
	fi
    fi

    # If home directory already exists, don't change attributes
    if [ -f $home ]; then
        echo "adduser: $home already exists as a file!" >&2
	salida 2
    fi
    if [ ! -d $home ]; then
	mkdir $home; status=$?
	if [ $status -ne 0 ]; then
	    echo "adduser: cannot create home for $user!" >&2
	    salida 3
	fi
	if [ -d $SKEL ]; then
            (
	      cd $SKEL
	      for i in std.*; do
		  dotfile=`expr "$i" : 'std\(.*\)'`
		  cp $i $home/$dotfile
	      done
	    )
	else
	    echo "Cannot find $SKEL; cannot copy standard .login, .profile, etc." >&2
	fi
	echo "New account for $user ($gcos1) - never logged in" > $home/.newacct
	chown $uid $home/.newacct
	chgrp $group $home/.newacct
	chmod 640 $home/.newacct
	f_doreadme

	chgrp $gid $home $home/README $home/.??*
	chown $uid $home $home/README $home/.??*
	chmod 750 $home 
	chmod 640 $home/README $home/.??*
	if [ -d $XSKEL ]; then
	    cp $XSKEL/.x11start $home
	    cp $XSKEL/Sample.twmrc $home/.twmrc
	    echo 'X -screen 0 -depth 8' > $home/.X11
	    chown $uid $home/.x11start $home/.twmrc $home/.X11
	    chgrp $group $home/.x11start $home/.twmrc $home/.X11
	    chmod 755 $home/.x11start $home/.X11
	    chmod 644 $home/.twmrc
	fi

	if [ "$folder" = 'yes' ] ; then
	    echo "Creating personal System Folder for $user ...\c"
	    systemfolder -u $user > /dev/null; status=$?
	    if [ "$status" != 0 ]; then
		echo "Error - could not create System Folder for $user."
	    else
		echo ''
	    fi
	fi
    fi

    trap "salida" 2 15

    if [ "$interactive" = 'TRUE' ]; then
        if [ "$YP" != 'TRUE' ]; then
            f_reply "Require user $user to set password on initial login? [yes]" y
            case $reply in
            n)
                echo "Specify password for $user:"
                rm -f /etc/ptmp
                passwd $user
                if [ ! -f /etc/ptmp ]; then
                    touch /etc/ptmp
                else
                    echo 'Temporary file usurped!  Continue later!' >&2
                    rm -f /etc/gtmp
                    salida 2
                fi
                ;;
            esac
        fi
    fi
    set $userlist''
    if [ "$interactive" = 'TRUE' ]; then
	case $# in
	0) continue ;;
        esac
    else
	case $# in
	1) break ;;
        esac
    fi
    comment="Enter next user's login name (e.g. fred) [enter empty line to quit]"
    shift; userlist="$*"
    unset new newgroup newacct
done

salida 0
