#!/bin/sh
# $Id: install-account.in,v 1.17 2011/04/15 18:37:00 rhansen Exp $

myname=$(basename "$0") || myname=$0
log() { printf '%s\n' "${myname}: $*"; }
warn() { log "WARNING: $*" >&2; }
error() { log "ERROR: $*" >&2; }
fatal() { error "$*"; exit 1; }
usage_fatal() { error "$*"; usage >&2; exit 1; }

system=`uname`

PATH=/usr/sbin:/sbin:$PATH; export PATH

HOME=/home; export HOME

case $system in
  FreeBSD)
	systype=bsd
	;;
  NetBSD)
	systype=bsd
	;;
  *)
	systype=unknown
	echo "Unknown system type $system"
	exit 1
	;;
esac

# assume bsd

[ `id -u` = 0 ] || fatal "Must be root."

[ $# -gt 0 ] || fatal "Usage: install-account tarball [tarball]*"

TMP=/etc/install-account.$$

# make a /usr/home if there is no home
[ -d /home ] || {
    log "Making /usr/home"
    mkdir -p /usr/home || fatal "unable to create /usr/home"
    ln -s usr/home / || fatal "unable to link /usr/home to /home"
}

do_install() {

  # extract the user's account tarball to a temporary directory
  cd $tmpdir || fatal "'cd ${tmpdir}' failed"
  tar xfzp ../$t || fatal "unable to extract account $t"
  [ "$(cat passwd | wc -l)" -eq 1 ] \
      || fatal "passwd extracted from ${t} should have one and only one line"

  # get the user's username and home directory
  u=`awk -F: '{print $1}' passwd` || fatal "unable to get username"
  h=$(awk -F : '{print $9}' passwd) || fatal "unable to get home directory"
  [ -r /etc/master.passwd ] || fatal "unable to read /etc/master.passwd"
  grep -q "^$u:" /etc/master.passwd && warn "passwd for $u already exists"

  # add the user to the system's account database.  the complicated ed
  # script ensures that if the user is already in the password
  # database, the user's entry isn't moved (e.g., to the bottom).
  # this is important if the account being added has the same UID as
  # another account (such as root and toor) because getpwuid() returns
  # the first match.  if the user isn't already in the databse, the
  # user is added at the end.
  EDITOR="ed -s" vipw <<EOF
\$a
${u}:dummy line to make sure there's a match
.
/^${u}:/a
____dummy before____
.
kx
.r passwd
ky
a
____dummy after____
.
kz
1,'xg/^${u}:/d
'z,\$g/^${u}:/d
'xd
'zd
w
EOF
  (exit $?) || fatal "failed to add ${u} to the system account database"
  log "$u added to passwd"

  # install the user's home directory and dotfiles
  [ -d "${h}" ] && warn "${h} already exists!"
  # untar anyway
  mkdir -p "${h}" || fatal "unable to create directory ${h}"
  (cd "${u}" && tar cf - .) | (
      cd "${h}" || fatal "unable to cd to ${h}"
      tar xfp - || fatal "unable to install user's files"
  ) || exit 1
  uid=`awk -F: '{print $3}' passwd` || fatal "unable to get uid"
  gid=`awk -F: '{print $4}' passwd` || fatal "unable to get gid"
  chown $uid.$gid "${h}" || fatal "unable to change ${h} ownership"
  chown -R $uid.$gid "${h}"/.ssh \
      || fatal "unable to change ${h}/.ssh ownership"
  log "${u} home directory created"

  cd ..
}

while [ $# -ge 1 ]; do
  t=$1
  [ -f "$t" ] || fatal "$t does not exist!"

  tmpdir=skel.$$
  rm -rf $tmpdir || fatal "unable to clean ${tmpdir}"
  mkdir $tmpdir || fatal "unable to create ${tmpdir}"

  (do_install) || exit 1

  rm -rf $tmpdir || fatal "unable to clean $tmpdir"

  shift
done
