#! /bin/sh # # INSTALL: script to add diskless architecture support and add clients # # @(#)INSTALL 1.1 88/06/08 4.0NFSSRC; from 1.22 88/03/11 D/NFS # # Copyright (c) 1987 by Sun Microsystems, Inc. # if id | grep -v root > /dev/null; then echo "You must become superuser to run $0" exit 1 fi HOME=/; export HOME PATH=/bin:/usr/bin:/etc:/usr/etc:/usr/etc/netdisk:/usr/bsd CMDNAME=$0 RELEASE="1.0" HOSTS="/etc/hosts" BOOTPARAMS="/etc/bootparams" YPMASTERPATH="/var/yp" # If $TAPE starts with /dev/ then $TAPEDEV will be that name. Otherwise # tape device name $TAPEDEV constructed from ${NRTAPE}${TAPE}${DEVNO} # NRTAPE is the prefix (including rooted path name) # TAPE is the driver type taken from input prompt # DEVNO is the suffix # The device name should be the non-rewinding tape device to use. NRTAPE="/dev/nr" DEVNO="0" # Specify default values for various paths here ROOTPATHDEF=/export/root SWAPPATHDEF=/export/swap DUMPPATHDEF=none HOMEPATHDEF=/home EXECDEF="" SWAPDEF="" CLIENTYPDEF="" echo echo " >>> Sun Diskless Client Installation Tool <<<" echo " >>> (for non-Sun Servers) <<<" echo " >>> Release $RELEASE <<<" # # Get system hostname and YP domain name # HOST=`hostname` DOMAIN=`domainname` # # Specify tape drive type : local or remote # If remote, specify tape host name # while :; do echo echo "Enter tape drive type ? [local | remote]: \c" read DRIVE; case "$DRIVE" in "local"|"l" ) TAPEHOST="" TAPE="/dev/nrtapens" break ;; "remote"|"r" ) while :; do echo;echo "Enter host of remote drive ? \c" read TAPEHOST; case "$TAPEHOST" in "" ) echo; echo "${CMDNAME}: invalid tape host." ;; * ) if [ "$DOMAIN" = "noname" -o "$DOMAIN" = "" ]; then grep "[ ]$TAPEHOST[ ]" /etc/hosts \ >/dev/null else ypmatch $TAPEHOST hosts >/dev/null fi case $? in 1) echo echo "${CMDNAME}: invalid tapehost." ;; *) break ;; esac ;; esac done # # Specify tape type : ar, st, mt, xt or /dev/something # while :; do echo \ "\nEnter remote tape type ? [ar[08] | st[08] | mt[08] | xt[08] | /dev/???]: \c" read TAPE; case "$TAPE" in ar | ar0 | nrar0 ) TAPE=ar break ;; ar8 | nrar8 ) TAPE=ar DEVNO=8 break ;; st | st0 | nrst0 ) TAPE=st break ;; st8 | nrst8 ) TAPE=st DEVNO=8 break ;; /dev/* ) break ;; mt | mt0 | nrmt0 | xt | xt0 | nrxt0 ) TAPE=mt break ;; mt8 | nrmt8 | xt8 | nrxt8 ) TAPE=mt DEVNO=8 break ;; * ) echo "${CMDNAME}: invalid tape type \"${TAPE}\"." ;; esac done break ;; * ) echo "${CMDNAME}: invalid tape drive type \"${DRIVE}\"." ;; esac done case $TAPE in /dev/* ) TAPEDEV=$TAPE ;; * ) TAPEDEV=${NRTAPE}${TAPE}${DEVNO} ;; esac # # Create a list of architecture types. Valid types are determined # from the release tapes. # ARCHLIST="" PATHLIST="" while :; do while :; do echo " Enter next architecture type to load [ sun4 | sun3 | ... | continue | done ]: \c" read ARCH; for i in ${ARCHLIST}; do case "$i" in "$ARCH") echo "\"${ARCH}\" already specified." break ;; esac done case "$i" in "$ARCH") ;; *) break ;; esac done case "$ARCH" in "" | "execs" | "clients" | "share" | "noshare" ) echo "${CMDNAME}: invalid architecture \"${ARCH}\"." ;; "done" ) break ;; "continue" | "c" ) # continue with setup_exec with data already gathered ARCH=continue case "$ARCHLIST" in "") if [ -f /tmp/ARCHLIST ]; then ARCHLIST=`cat /tmp/ARCHLIST` case "$ARCHLIST" in "") echo "No current architectures to use." ;; *) if [ -f /tmp/PATHLIST ]; then PATHLIST=`cat /tmp/PATHLIST` case "$PATHLIST" in "") ;; *) echo "Continuing with architecture(s)\c" for i in $ARCHLIST do case $i in execs | clients | share | noshare ) ;; * ) echo " $i\c" ;; esac done echo "" break ;; esac fi echo "No current pathlist to use." ;; esac else echo "No current architectures to use." fi ;; *) echo " Cannot continue after specifying additional architectures." ;; esac ;; * ) while :; do echo echo "Enter pathname for $ARCH executables ? \c" read EXEC; case "$EXEC" in "" ) case "$EXECDEF" in "") ;; *) EXEC=$EXECDEF echo "Using default \"$EXEC\"" ;; esac ;; esac case "$EXEC" in "" ) ;; */$ARCH | */$ARCH/* ) echo \ "Please give pathname without \"$ARCH\" at end." ;; /* ) rm -rf /tmp/*.${ARCH} if [ -d ${EXEC}/${ARCH}/bin ]; then echo " ${CMDNAME}: exec tree ${EXEC}/${ARCH} appears to exist already. You may select one of the following options: ignore continue as if this architecture had not been specified remove remove existing exec tree, then continue use continue, loading any new optional software specified clients continue with $ARCH clients, but use existing exec tree ? \c" while :; do read ans case "$ans" in "ignore" | "use" | "clients" ) break ;; "remove" ) echo "Removing ${EXEC}/${ARCH}..." rm -rf ${EXEC}/${ARCH} if [ -d ${EXEC}/${ARCH} ]; then echo \ " ${EXEC}/${ARCH} not removed; architecture ${ARCH} ignored" ans=ignore else ans=use fi break ;; * ) echo \ "Please enter \"ignore\" \"remove\" \"use\" or \"clients\" : \c" ;; esac done else ans=use fi # ans is one of ignore, use, or clients case "$ans" in "use" ) STATUS=error opt_software ${ARCH} ${TAPEDEV} ${TAPEHOST} case $? in 0 ) if [ -f /tmp/EXTRACTLIST.${ARCH} ]; then set `head -1 /tmp/EXTRACTLIST.${ARCH}` # args "IDENT <release> if [ $# = 3 -a "$1" = IDENT ]; then EXECDEF=$EXEC PATHLIST="${PATHLIST} ${EXEC}" while :; do echo " Load sharable objects in shared location ? [y/n] :\c" read ans case "$ans" in "y" | "yes" ) ans=share break ;; "n" | "no" ) ans=noshare break ;; * ) echo \ "Please answer yes or no." ;; esac done ARCHLIST="${ARCHLIST} $ans ${ARCH}" STATUS=ok fi fi ;; esac case $STATUS in error) echo " ${CMDNAME}: extraction error; $ARCH architecture entry ignored." ;; esac ;; "clients" ) EXECDEF=$EXEC PATHLIST="${PATHLIST} ${EXEC}" ARCHLIST="${ARCHLIST} clients ${ARCH}" ;; * ) # ignore echo "$ARCH architecture entry ignored." ;; esac break ;; * ) echo "Exec pathname must start with \"/\"" ;; esac done ;; esac done rm -rf /tmp/PATHLIST /tmp/ARCHLIST echo "$ARCHLIST" > /tmp/ARCHLIST echo "$PATHLIST" > /tmp/PATHLIST # # Gather client info # $RESET on input causes current client info to be reset and ignored # RESET="^" case $ARCH in continue) # already have client info. Skip to setup_exec. ;; *) # get client info for all ARCHSTATES (execs and clients) for ARCH in ${ARCHLIST}; do case $ARCH in share | noshare | execs | clients ) # ignore keywords ;; * ) while :; do case "$STATE" in reset) echo ">> $CLIENT entries ignored" ;; esac STATE=ok echo echo "Enter a $ARCH client name ? [ name | done ]: \c" read CLIENT; case "$CLIENT" in "" ) ;; "none" | "done" ) break ;; * ) # # Verify that host and ether entries are present # echo echo "Verifying Internet address..." rm -rf /tmp/ipaddr if [ "$DOMAIN" = "noname" -o "$DOMAIN" = "" ]; then grep "[ ]$CLIENT[ ]" /etc/hosts | grep -v "^#" else ypmatch $CLIENT hosts fi | awk '{ print $1 }' > /tmp/ipaddr IPADDR=`cat /tmp/ipaddr` rm -rf /tmp/ipaddr case "$IPADDR" in "") echo " ${CMDNAME}: can't find Internet address in /etc/hosts for \"${CLIENT}\"" echo STATE=reset ;; *) echo " $IPADDR $CLIENT" ;; esac # # Verify Ethernet address # echo echo "Verifying Ethernet address..." rm -rf /tmp/etheraddr if [ "$DOMAIN" = "noname" -o "$DOMAIN" = "" ]; then grep "[ ]$CLIENT[ ]" /etc/ethers | grep -v "^#" else ypmatch $CLIENT ethers fi | awk '{ print $1 }' > /tmp/etheraddr ETHERADDR=`cat /tmp/etheraddr` rm -rf /tmp/etheraddr case "$ETHERADDR" in "") echo " ${CMDNAME}: can't find Ethernet address in /etc/ethers for \"${CLIENT}\"\n" echo STATE=reset ;; *) echo " $ETHERADDR $CLIENT" ;; esac case $STATE in ok) while :; do echo echo \ "Enter YP mode of $CLIENT ? [ master | slave | client | none ]: \c" read CLIENTYP; case "$CLIENTYP" in "") case "$CLIENTYPDEF" in "") ;; *) CLIENTYP=$CLIENTYPDEF echo "Using default \"$CLIENTYP\"" break ;; esac ;; "master" | "slave" | "client" | "none" ) CLIENTYPDEF=$CLIENTYP break ;; "$RESET") STATE=reset break ;; * ) ;; esac done ;; esac case $STATE in ok) while :; do echo echo "Enter swap size of $CLIENT ? \c" read SWAP; case "$SWAP" in "$RESET") STATE=reset break ;; [0-9]* ) SWAPDEF=$SWAP break ;; *) if [ "$SWAP" = "" -a "$SWAPDEF" != "" ]; then SWAP=$SWAPDEF echo "Using default \"$SWAP\"" break fi echo " Swap size must start with a digit (\"$SWAP\" is not valid) Examples: 16M or 16m ==> 16 * 1048576 bytes 16K or 16k ==> 16 * 1000 bytes 16B or 16b ==> 16 * 512 bytes 16 ==> 16 bytes )" ;; esac done ;; esac case $STATE in ok) while :; do echo echo "Enter root pathname of $CLIENT ? \c" read ROOTPATH; case "$ROOTPATH" in "" ) case "$ROOTPATHDEF" in "") ;; *) ROOTPATH=$ROOTPATHDEF echo "Using default \"$ROOTPATH\"" break ;; esac ;; "$RESET") STATE=reset break ;; */$CLIENT ) echo \ "Please give pathname without \"$CLIENT\" at end." ;; /* ) ROOTPATHDEF=$ROOTPATH break ;; * ) echo \ "Root pathname must start with \"/\"" ;; esac done ;; esac case $STATE in ok) while :; do echo echo "Enter swap pathname of $CLIENT ? \c" read SWAPPATH; case "$SWAPPATH" in "" ) case "$SWAPPATHDEF" in "") ;; *) SWAPPATH=$SWAPPATHDEF echo "Using default \"$SWAPPATH\"" break ;; esac ;; "$RESET") STATE=reset break ;; */$CLIENT ) echo \ "Please give pathname without \"$CLIENT\" at end." ;; /* ) SWAPPATHDEF=$SWAPPATH break ;; * ) echo \ "Swap pathname must start with \"/\"" ;; esac done ;; esac case $STATE in ok) while :; do echo echo "Enter dump pathname of $CLIENT (or \"none\") ? \c" read DUMPPATH; case "$DUMPPATH" in "" ) case "$DUMPPATHDEF" in "") ;; *) DUMPPATH=$DUMPPATHDEF echo "Using default \"$DUMPPATH\"" break ;; esac ;; "$RESET") STATE=reset break ;; */$CLIENT ) echo \ "Please give pathname without \"$CLIENT\" at end." ;; /* | none ) DUMPPATHDEF=$DUMPPATH break ;; * ) echo \ "Dump pathname must start with \"/\"" ;; esac done ;; esac case $STATE in ok) while :; do echo echo "Enter home pathname of $CLIENT (or \"none\") ? \c" read HOMEPATH; case "$HOMEPATH" in "" ) case "$HOMEPATHDEF" in "") ;; *) HOMEPATH=$HOMEPATHDEF echo "Using default \"$HOMEPATH\"" break ;; esac ;; "$RESET") STATE=reset break ;; /* | none ) HOMEPATHDEF=$HOMEPATH break ;; * ) echo \ "Home pathname must start with \"/\"" ;; esac done ;; esac case $STATE in ok) while :; do echo echo "Information for $CLIENT ok ? [y/n] : \c" read ans case "$ans" in "y" | "yes" ) break ;; "n" | "no" ) STATE=reset break ;; * ) echo "Please answer yes or no." ;; esac done ;; esac case $STATE in ok) echo "$CLIENT" >> /tmp/CLIENT.${ARCH} echo "$IPADDR" >> /tmp/CLIENTIP.${ARCH} echo "$ETHERADDR" >> /tmp/CLIENTETHER.${ARCH} echo "$CLIENTYP" >> /tmp/CLIENTYP.${ARCH} echo "$SWAP" >> /tmp/SWAP.${ARCH} echo "$ROOTPATH" >> /tmp/ROOTPATH.${ARCH} echo "$SWAPPATH" >> /tmp/SWAPPATH.${ARCH} echo "$DUMPPATH" >> /tmp/DUMPPATH.${ARCH} echo "$HOMEPATH" >> /tmp/HOMEPATH.${ARCH} ;; esac ;; esac done ;; esac done ;; esac # # Prompt user attention last time before starting to build # while :; do echo;echo "Are you ready to start the installation ? [y/n] : \c" read READY; case "${READY}" in "y" | "yes" ) break ;; "n" | "no" ) echo " Installation procedure terminates. You may continue by running this script and entering \"continue\" at the first prompt for architecture type." exit 1 ;; * ) echo;echo "Please answer only yes or no." esac done # # Installation starts # ARCHSTATE=execs for CURRENTARCH in ${ARCHLIST}; do case $CURRENTARCH in execs | clients | share | noshare ) ARCHSTATE=$CURRENTARCH ;; * ) echo echo "Beginning Installation for the ${CURRENTARCH} architecture." # # get path and read in release tape # set $PATHLIST CURRENTPATH=$1 shift PATHLIST="$*" case "$ARCHSTATE" in execs | share ) SHAREPATH=${CURRENTPATH}/share ;; noshare ) SHAREPATH=none ;; * ) # if share directory exists, use it for clients if [ -d ${CURRENTPATH}/share ]; then SHAREPATH=${CURRENTPATH}/share else SHAREPATH=none fi ;; esac EXECPATH=${CURRENTPATH}/${CURRENTARCH} case "$ARCHSTATE" in execs | share | noshare ) setup_exec $CURRENTARCH $EXECPATH $DRIVE $TAPEHOST $TAPEDEV \ $SHAREPATH STATUS=$? ;; * ) # do not setup these execs echo echo "[${CURRENTARCH} executables already installed]" STATUS=0 ;; esac case ${STATUS} in 0) echo echo "Starting installation of ${CURRENTARCH} clients..." echo if [ -f /tmp/CLIENT.${CURRENTARCH} ]; then # # Read these files just once. # The 'set' hacks are used to avoid using 'expr' # counters, which are not built-in and take awhile # to do as the loops get bigger. # IPLIST=`cat /tmp/CLIENTIP.${CURRENTARCH}` ETHERLIST=`cat /tmp/CLIENTETHER.${CURRENTARCH}` YPLIST=`cat /tmp/CLIENTYP.${CURRENTARCH}` SWAPLIST=`cat /tmp/SWAP.${CURRENTARCH}` ROOTPATHLIST=`cat /tmp/ROOTPATH.${CURRENTARCH}` SWAPPATHLIST=`cat /tmp/SWAPPATH.${CURRENTARCH}` DUMPPATHLIST=`cat /tmp/DUMPPATH.${CURRENTARCH}` HOMEPATHLIST=`cat /tmp/HOMEPATH.${CURRENTARCH}` for i in `cat /tmp/CLIENT.${CURRENTARCH}`; do set $IPLIST IP=$1 shift IPLIST="$*" set $ETHERLIST ETHER=$1 shift ETHERLIST="$*" set $YPLIST YP=$1 shift YPLIST="$*" set $SWAPLIST SWAP=$1 shift SWAPLIST="$*" set $ROOTPATHLIST ROOTPATH=$1 shift ROOTPATHLIST="$*" set $SWAPPATHLIST SWAPPATH=$1 shift SWAPPATHLIST="$*" set $DUMPPATHLIST DUMPPATH=$1 shift DUMPPATHLIST="$*" set $HOMEPATHLIST HOMEPATH=$1 shift HOMEPATHLIST="$*" # # Create client # setup_client add/noYP $i $YP $SWAP \ $ROOTPATH $SWAPPATH $DUMPPATH \ $HOMEPATH $EXECPATH $SHAREPATH $CURRENTARCH case $? in 0) DIDACLIENT=yes ;; *) echo " ATTENTION: $CURRENTARCH client $i not installed." echo ;; esac done fi ;; *) echo echo "ATTENTION: exec installation for $CURRENTARCH failed." echo " $CURRENTARCH clients not installed." ;; esac ;; esac done case "$DIDACLIENT" in yes) if [ "$DOMAIN" != "noname" -a "$DOMAIN" != "" -a -f ${YPMASTERPATH}/bootparams.time ]; then echo echo "Updating bootparams YP map..." cd ${YPMASTERPATH} make bootparams elif [ "$DOMAIN" != "noname" -a "$DOMAIN" != "" -a ! -f ${YPMASTERPATH}/bootparams.time ]; then if [ ! -f ${YPMASTERPATH}/bootparams.time- ]; then echo " ATTENTION: /etc/bootparams on the yp master needs to be updated." fi fi ;; esac echo case "$ARCHLIST" in "") echo "Nothing to install!" ;; *) echo "Diskless Client Installation Completed." ;; esac exit 0