#!/bin/ksh -
#
# @(#)mk-afs-cli	1.52 (hursley) 6/12/98
# /afs/hursley.ibm.com/common/src/afs/@cell/asys/usr/local/sbin/mk-afs-cli/SCCS/s.mk-afs-cli
#
# NAME		mk-afs-cli
# AUTHOR	Paul Blackburn             http://acm.org/~mpb
# PURPOSE	Install AFS client
#		(based on hints in Transarc's AFS Installation Guide :-)
# USAGE		Normally invoked as part of system installation.
# ASSUMPTIONS	Make sure you have correctly defined AFS installation
#		parameters for your system. The file containing these
#		($AFSICF) is defined in:
#			 ${afs_install_base}/usr/local/sbin/mk-afs-cf
# REFERENCE
#		Transarc "AFS Installation Guide"
#
# HISTORY
#	1998-Mar-6 mpb Added support for rs_aix43

X=${afs_install_base}/usr/local/sbin/mk-afs-cf

if [[ ! -f ${X} ]]; then
	echo "fatal error: ${X} not found" >&2
	exit 1
fi

# source global config for AFS installation

. ${X}

tstamp "version 1.52 commenced on $(date '+%a %d %h %y')"

tstamp "Check if we already have AFS installed (idempotency rules! :-)"
doit "df | grep -q AFS"
if [[ ${retcode}  = 0 ]]; then
	fatal "AFS already installed!"
fi

if [[ -z "${afsclient}" ]]; then
	warning "Check: ${AFSICF}"
	warning "${HOST} is not defined as an AFS client"
	warning "Assuming ${HOST} is a client and continuing..."
fi

# Check we have AFS installation parameters

if [[ -z "${afscachevg}" ]]; then
	warning "afscachevg not defined for ${HOST}"
	afscachevg="rootvg"
	warning "defaulting to: ${afscachevg}"
fi

if [[ -z "${afscachename}" ]]; then
	warning "afscachename not defined for ${HOST}"
	afscachename="/usr/vice/cache"
	warning "defaulting to: ${afscachename}"
fi

if [[ -z "${afscachesize}" ]]; then
	warning "afscachesize not defined for ${HOST}"
	afscache="12"
	warning "defaulting to: ${afscache} (4MB physical partitions)"
fi

if [[ -z "${afsdoptions}" ]]; then
	warning "afsdoptions not defined for ${HOST}"
	afsdoptions="-stat 2000 -dcache 800 -daemons 3 -volumes 70"
	warning "defaulting to: ${afsdoptions}"
fi

if [[ -z "${afscellname}" ]]; then
	warning "afscellname not defined for ${HOST}."
	X=`echo ${HOSTNAME} | cut -d. -f2-`
	if [[ -z "${X}" ]]; then

		fatal "unable to compute default afscellname"
	fi
	warning "defaulting to: ${X}"
	afscellname=${X}
fi

if [[ -z "${afsimagedir}" ]]; then
	warning "afsimagedir not defined for ${HOST}"
	afsimagedir="/vol/afs33/tapeimages/$sysname"
	warning "defaulting to: ${afsimagedir}"
fi

if [[ -z "${afsfileserver}" ]]; then
	warning "Check: ${AFSICF}"
	warning "afsfileserver undefined"
	afsfileserver=ariel.aixssc.uk.ibm.com
	warning "defaulting to: ${afsfileserver}"
fi

# Check for fatal errors before getting too far...

need=2048
fs=/tmp
tstamp "Check we have enough (${need} kbytes) free space in ${fs}"
need_freespace ${fs} ${need}
if [[ $? -eq 0 ]]; then
	tstamp "Yes! we have enought room in ${fs} to proceed."
else
	warning "There is not enough free space in /tmp."
	fatal "Unable to proceed. We need ${need} kbytes free in ${fs}"
fi

need=2048
fs=/usr
tstamp "Check we have enough (${need} kbytes) free space in ${fs}"
need_freespace ${fs} ${need}
if [[ $? -eq 0 ]]; then
	tstamp "Yes! we have enought room in ${fs} to proceed."
else
	warning "There is not enough free space in /tmp."
	fatal "Unable to proceed. We need ${need} kbytes free in ${fs}"
fi

tstamp "Check we can ping afsfileserver=${afsfileserver}"
doit "ping ${afsfileserver} 56 1"
if [[ ${retcode} != 0 ]]; then
        fatal "Unable to ping ${afsfileserver}"
fi

if [[ -z "${afsimageserver}" ]]; then
	warning "Check: ${AFSICF}"
	warning "afsimageserver undefined"
	afsimageserver=afsimageserver.aixssc.uk.ibm.com
	warning "defaulting to: ${afsimageserver}"
fi

tstamp "Check we can ping afsimageserver=${afsimageserver}"
doit "ping ${afsimageserver} 56 1"
if [[ ${retcode} != 0 ]]; then
        fatal "Unable to ping ${afsimageserver}"
fi

tstamp "Check if we have any afsd's running"

ps -ef | fgrep afsd | grep -v grep | awk '{print $2}' >${TF}
if [[ -s ${TF} ]]; then
	warning "There are afsd's running, PIDs are:"
	cat ${TF}
	rm ${TF}
	warning "Put \"exit\" at top of /etc/rc.afs and reboot."
	warning "AFS cache manager afsds can only be killed by rebooting."
	fatal "You need to kill afsd's before running ${CMD} again.)"
fi

# Now we have all the parameters, we can get going...

tstamp "Check if we are running on a server or client"
D=/usr/afs/bin/dkload
if [[ -d ${D} ]]; then
    MTYPE="server"
else
    MTYPE="client"
fi
tstamp "This system is an AFS ${MTYPE}"

tstamp "Loading Files for a Machine of Existing System Type: ${sysname}"
tstamp "AFS Installation Guide, page 4-3"

if [[ -d /usr/vice/etc ]]; then
	doit "rm -rf /usr/vice/etc"
fi
doit "mkdir -p /usr/vice/etc"

TAPESET=set4.tar.Z
LOCAL=/tmp/${TAPESET}
REMOTE=${afsimagedir}/${TAPESET}
if [[ -f "${LOCAL}" ]]; then
        doit "rm ${LOCAL}"
fi

doit "tftp -g ${LOCAL} ${afsimageserver} ${REMOTE} image"

cd /usr/vice/etc
doit "pwd"
doit "compress -d <${LOCAL} | tar xvf -"
if [[ ${retcode} != 0 ]]; then
	fatal "problem un-tar-ing tapeset ${TAPESET}"
fi

doit "rm ${LOCAL}"

tstamp "AFS Installation Guide page 2-19"
tstamp "Virtual file system entry for AFS /etc/vfs?"
fgrep afs /etc/vfs > /dev/null
if [[ $? = 0 ]]; then
	tstamp "OK, we already have AFS entry in /etc/vfs"
else
	tstamp "Adding AFS entry to /etc/vfs..."
	echo \
"afs     4       none                    none                    remote"\
	>> /etc/vfs
fi

tstamp "Create /etc/rc.afs"
doit "mk-afs-rc"

tstamp "Add a call to /etc/rc.afs in /etc/inittab unless it's already there"

egrep "^rcafs:" /etc/inittab > /dev/null
if [[ $? != 0 ]]; then
	tstamp "Changing /etc/inittab to start AFS..."
	sed '/rctcpip/a\
rcafs:2:wait:/etc/rc.afs > /dev/console 2>&1  \# Start AFS Daemons' \
	/etc/inittab > /etc/inittab.new
	doit "mv /etc/inittab /etc/inittab.bak"
	doit "mv /etc/inittab.new /etc/inittab"
	doit "chmod 600 /etc/inittab"
	doit "fgrep rcafs /etc/inittab"
fi

tstamp "Defining Cell Membership"
tstamp "AFS Installation Guide, page 4-15"

doit "echo ${afscellname} >/usr/vice/etc/ThisCell"

tstamp "Creating the CellServDB File"
tstamp "AFS Installation Guide, page 4-15"

LOCAL=/usr/vice/etc/CellServDB
REMOTE=/usr/vice/etc/CellServDB

if [[ -s "${LOCAL}" ]]; then
	doit "rm ${LOCAL}"
fi
doit "tftp -g ${LOCAL} ${afsimageserver} ${REMOTE} image"

tstamp "Setting Up a Disk Cache"
tstamp "AFS Installation Guide, page 4-17"

if [[ -z "${afsmemcache}" ]]; then	# using disk memory cache
	lsfs ${afscachename} >/dev/null 2>&1
	if [[ $? = 0 ]]; then
		doit "umount ${afscachename}"
		doit "rmfs ${afscachename}"
	fi

	let cacheblocks=${afscachesize}\*8192

	doit "crfs -v jfs -g${afscachevg} -a size=${cacheblocks} \
		-m${afscachename} -Ayes -prw"
	doit "chfs -a mount=true ${afscachename}"
	doit "chfs -ulocalfs ${afscachename}"
	doit "mount ${afscachename}"
	doit "df ${afscachename}"
fi

# Compute a value for the cache size to save in /usr/vice/etc/cacheinfo
# For AIX 3.2 the size should be 80% of the filesystem size.
#
# In /usr/vice/cacheinfo, the cachesize is expressed in kilobytes.
# From qhost, afscachesize is in PP, there are 4096 KB in a PP:

let cachesize=\(\(${afscachesize}\*4096\)\*80\)/100

doit "echo /afs:${afscachename}:${cachesize} >/usr/vice/etc/cacheinfo"

tstamp "Creating /afs and Starting the Cache Manager"
tstamp "AFS Installation Guide, page 4-18"

doit "mkdir /afs"

X=/usr/sbin/bootinfo
if [[ -x "${X}" ]]; then
	BOOTDISK=$(${X} -b)
	if [[ ! -z "${BOOTDISK}" ]]; then
		if [[ -b /dev/${BOOTDISK} ]]; then
			tstamp "bosboot"
			cat <<eeooff

Make sure that bosboot image used to boot the system matches the
bosboot image held in /usr/lib/boot. Apparently, it is this image that
is used by nlist() in dkload to figure out the offsets to load the
kernel extensions.

If we don't do this then running afsd may crash/hang the system
(this has been observed on freshly installed RISC System/6000 model 220).

eeooff


			doit "bosboot -a -d /dev/${BOOTDISK}"
		else
			warning "not a block special device: /dev/${BOOTDISK}"
		fi
	else
		warning "invalid BOOTDISK: ${BOOTDISK}"
	fi
else
	warning "unable to execute: ${X}"
fi

doit "/bin/sh /etc/rc.afs"
doit "ls /afs"

tstamp "Linking /usr/afsws"
tstamp "AFS Installation Guide, page 4-21"

if [[ -f /usr/afsws ]]; then
	doit "mv /usr/afsws /usr/afsws-"
fi
if [[ -d /usr/afsws ]]; then
	doit "mv /usr/afsws /usr/afsws-"
fi

if [[ "${MTYPE}" = "client" ]]; then
	doit "ln -s /afs/${afscellname}/${sysname}/usr/afsws /usr/afsws"
fi

doit "mk-afs-login afs"

tstamp "Disable timed: AFS time service done via NTP and Cache Manager."
doit "stopsrc -s timed"

tstamp "Disable startup of timed in /etc/rc.tcpip"
ed - /etc/rc.tcpip << %
/timed
s/start/#start/
w
q
%
doit "grep timed /etc/rc.tcpip"

tstamp "AFS Commands Reference Manual, page 10-2"
if [[ "${sysname}" = "rs_aix32" ]]; then
	tstamp "enable ftpd with AFS authentication"
	doit "cp /usr/afsws/etc/ftpd /usr/etc/ftpd.afs"

	ed - /etc/inetd.conf << %
/^ftp
s/ftp/#ftp/
a
ftp	    stream	tcp	nowait	root /usr/etc/ftpd.afs	ftpd -l	-u 022
.
w
q
%

else
	tstamp "systype ${sysname} does not need ftpd changed for AFS."
	tstamp "Authentication for ${sysname} is specified by using the"
	tstamp "SYSTEM and registry attributes in /etc/security/user"
fi

doit "refresh -s inetd"
doit "grep ftp /etc/inetd.conf"

tstamp "AFS Commands Reference Manual, page 10-5"
tstamp "enable AFS token passing for rcmds"
ed - /etc/services << %
/^auth
a
# AFS Commands Reference Manual, page 10-5. Enable AFS token passing for rcmds
ta-rauth	601/tcp		rauth
.
w
q
%

F=/etc/inetd.conf.afs
tstamp "create  ${F}"
cat - << % > ${F}
# NAME		${F}
# AUTHOR	Paul Blackburn            http://acm.org/~mpb
# PURPOSE	enable use of AFS authenticated rcmds
# USAGE		/usr/etc/inetd.afs ${F}
# NOTES
#	Both the standard and AFS authenticating versions of rsh and rcp
#	work concurrently. To use the AFS version, place /usr/afsws/bin
#	at the start of your \$PATH.
#
#	/usr/etc/inetd.afs is started at boot time in /etc/rc.afs
#
#	For rs_aix32, rlogin is handled here (need login line below)
#	For rs_aix4[12], rlogin is handled by standard inetd
#
# SOURCE
#               ftp://ftp.transarc.com/pub/afs-contrib/tools/afs_install/
# REFERENCE
#		Transarc "AFS Commands Reference Manual", page 10-5

ta-rauth stream	tcp	nowait	root	internal		ta-rauth
%
case ${sysname} in
        rs_aix32 )
		cat - << % >> ${F}
shell	stream	tcp	nowait	root	/etc/rshd		rshd
login	stream	tcp	nowait	root	/usr/afsws/etc/rlogind	rlogind.afs
%
		file=/etc/inetd.conf
		tstamp "edit ${file}: comment out shell and login"
		ed - ${file} << %
/^shell
s/shell/#shell/
1
/^login
s/login/#login/
w
q
%

		;;
	rs_aix41 | rs_aix42 | rs_aix43 )
		cat - << % >> ${F}
shell	stream	tcp	nowait	root	/usr/sbin/rshd		rshd
%
		file=/etc/inetd.conf
		tstamp "edit ${file}: comment out shell"
		ed - ${file} << %
/^shell
s/shell/#shell/
w
q
%
		;;
esac

doit "cat ${F}"

doit "refresh -s inetd"

f=/usr/etc/inetd.afs
tstamp "start additional AFS authenticating ${f}"
if [[ -f ${f} ]]; then
	doit "rm -f ${f}- 2>&1 >/dev/null"
	doit "mv ${f} ${f}-"
fi
doit "cp /usr/afsws/etc/inetd ${f}"
doit "/usr/etc/inetd.afs ${F}"

df | grep -q AFS
if [[ $? = 0 ]]; then
	tstamp "AFS Cache Manager successfully started"
else
	warning "AFS Cache Manager failed to start"
fi

T=/tmp/${CMD}.mail.$$
cat <<eeooff >${T}
Greetings,
AFS client installation has completed on ${HOST}.
You will find a log of this process in:

        ${LOG}
--
Sincerely,
${CMD} program
eeooff
doit "mail -s \"${HOST}: ${CMD} completed\" ${NOTIFY} <${T}"
cat ${T}
rm ${T}

tstamp "completed"
