# # NAME - util.sh # # DESCRIPTION # Utility routines for installation # # get_fs_info # # Get file system info for a path. Determines file system, where # mounted, and avail space. Uses df to find this info. Handles # various forms of df output. # # INPUT/OUTPUT # IN: $1 - path to check # OUT: FS - name of file system # OUT: MNT - mount point of file system # OUT: AVAIL - avail space on file system in kbytes get_fs_info() { set `$df $1 | $sed '1d'` case $ARCH in SunOS) FS=$1 MNT=$6 AVAIL=$4 ;; AIX) FS=$1 MNT=$7 AVAIL=$3 ;; HP-UX) FS=$1 MNT=$6 AVAIL=$4 ;; *) FS=$1 MNT=$6 AVAIL=$4 ;; esac } # path_existing_part # # Given a path, return the portion of it which actually exists # # INPUT/OUTPUT # IN: $1 - path to be processed # OUT: RETURN - set to the existing portion path_existing_part() { pep_path=$1 while test ! -d $pep_path ; do pep_path=`$expr match $pep_path '\(.*\)/'` if test "$pep_path" = "" ; then pep_path="/" ; fi done RETURN=$pep_path } # NAME - nfs_path_p # # DESCRIPTION # Given a path (which may or may not exist), determine # if it resides (or would reside) on an NFS file system. # # INPUT/OUTPUT # IN: $1 - path to be checked # OUT: RETURN - 0 if this is not an nfs filesystem; 1 if it is # OUT: FSHOST - set to machine which exports this nfs filesystem nfs_path_p() { path_existing_part $1 npp_path=$RETURN get_fs_info $npp_path FSHOST=`$expr match $FS '\(.*\):'` # # CHANGED FOR HPUX-10.x # FSHOST="" if test "$FSHOST" != "" ; then RETURN=1 ; else RETURN=0 ; fi } # create_path # # Attempts to create an entire path. If necessary, intermediate # directories are created. Handles both local and remote case. # # INPUT/OUTPUT # IN: $1 - path to create # OUT: RETURN - 0 if successful, 1 if not create_path() { cp_path=$1 nfs_path_p $cp_path while test ! -d $cp_path do cp_parent=$cp_path while test ! -d $cp_parent do cp_child=`echo $cp_parent | $sed 's:.*/::'` cp_parent=`echo $cp_parent | $sed 's:[^/]*$::'` if test $cp_parent != "/" ; then cp_parent=`echo $cp_parent | $sed 's:/$::'` fi done if test "$FSHOST" = "" ; then # echo "$mkdir $cp_parent/$cp_child" $mkdir $cp_parent/$cp_child > /dev/null 2>&1 else # echo "$rsh $FSHOST $mkdir $cp_parent/$cp_child" $rsh $FSHOST "$mkdir $cp_parent/$cp_child" > /dev/null 2>&1 fi if test ! -d $cp_parent/$cp_child ; then RETURN=1 return fi done RETURN=0 } # standard_steps # # This routine performs a standard set of steps to install a # piece of software. On entry, the following should have been # set up by the caller: # # PRODUCT string which describes software # DEFINSTALLDIR default install directory # DISKSPACE size of software in MB # VERFILE the software version file; used both to check # if software is already installed and version # VERSION version of software being installed # TARFILE the tarfile containing the software standard_steps() { STEP=1 WRITEPERMS=do_we_have_write_permission.$$ while test $STEP != 99 do case $STEP in # Invoke the software prologue 1) software_prologue STEP=2 ;; # See if software is installed in DEFINSTALLDIR prior # to asking user if it is installed somewhere else 2) if test -f $DEFINSTALLDIR/$VERFILE ; then INSTALLDIR=$DEFINSTALLDIR cat << EOM $PRODUCT is currently installed in $INSTALLDIR if you proceed, it will be overwritten. EOM QUESTION="Do you want to proceed" DEFAULT=y get_response ynq echo if test $RETURN = n ; then STEP=13 ; else STEP=4 ; fi # STEP=17 else STEP=4 # STEP=3 fi ;; # Ask user if software is installed somewhere 3) cat << EOM The default location of $PRODUCT is $DEFINSTALLDIR The software is not installed in this location. If the software is currently installed somewhere else, you should install this release of the software in the same place. EOM QUESTION="Has $PRODUCT been previously installed" DEFAULT=n get_response ynq if test $RETURN = n ; then STEP=4 ; else STEP=23 ; fi ;; # Ask user where they want to install software 4) QUESTION="Where should I install this software" DEFAULT=$DEFINSTALLDIR get_response INSTALLDIR=$RETURN STEP=6 # STEP=5 ;; # See if software is installed in INSTALLDIR prior to # putting it there 5) if test -f $INSTALLDIR/$VERFILE then cat << EOM $PRODUCT is already installed in $INSTALLDIR EOM STEP=17 else STEP=6 fi ;; # Check if INSTALLDIR file system has enough room. # Handle case where INSTALLDIR does not actually exist. 6) path_existing_part $INSTALLDIR get_fs_info $RETURN kbyte_check $INSTALLDIR $FS $AVAIL ${DISKSPACE}000 if test $RETURN -eq 1 ; then STEP=7 ; else STEP=12 ; fi ;; # INSTALLDIR file system has enough room. Does # INSTALLDIR exist? 7) if test -d $INSTALLDIR ; then STEP=8 ; else STEP=15 ; fi ;; # INSTALLDIR exists and there is sufficient space to install. # Check if access is via NFS 8) nfs_path_p $INSTALLDIR if test $RETURN -eq 1 ; then REMOTE=y ; STEP=8.1 else REMOTE=n ; STEP=9 fi ;; # Access to INSTALLDIR via NFS. Use of rsh necessary. Inform # user and verify that we have permission. 8.1) cat << EOM $INSTALLDIR is an NFS directory. Since the installation is being run from $HOSTNAME as root, a remote operation must be performed. Verifying that a remote operation will succeed... EOM check_remote_op $FSHOST if test $RETURN -eq 0 ; then STEP=8.2 ; else STEP=8.3 ; fi ;; # Necessary remote operations can be performed. Inform user. 8.2) cat << EOM Remote operations are permitted. EOM STEP=9 ;; # Inform user of no permission to perform remote operation 8.3) cat << EOM Remote operations are not permitted. Installation in $INSTALLDIR can NOT be done from this host. EOM QUESTION="" get_response STEP=13 ;; # Verify write permission in INSTALLDIR 9) if test $REMOTE = n ; then $touch $INSTALLDIR/$WRITEPERMS > /dev/null 2>&1 if test -f $INSTALLDIR/$WRITEPERMS ; then $rm $INSTALLDIR/$WRITEPERMS STEP=10 else STEP=9.1 fi else $rsh $FSHOST "$touch $INSTALLDIR/$WRITEPERMS" > /dev/null 2>&1 if test -f $INSTALLDIR/$WRITEPERMS ; then $rsh $FSHOST "$rm $INSTALLDIR/$WRITEPERMS" STEP=10 else STEP=9.1 fi fi ;; # No write permission in INSTALLDIR 9.1) cat << EOM I can NOT create files in $INSTALLDIR. You will have to change the permissions for this directory or choose a different location. EOM STEP=13 ;; # Confirm that extraction should proceed 10) cat << EOM $PRODUCT files will now be extracted into $INSTALLDIR EOM QUESTION="Do you want to proceed" DEFAULT=y get_response ynq echo if test $RETURN = n ; then STEP=13 ; else STEP=10.1 ; fi ;; # Extract files into INSTALLDIR. Use remote operation # if necessary. 10.1) cat << EOM Extracting files ... EOM if test $REMOTE = n ; then TFLOC=`$pwd` ( cd $INSTALLDIR ; $tar $TFLOC/$TARFILE ) else cat $TARFILE | $rsh $FSHOST "cd $INSTALLDIR ; $tar -" fi STEP=10.2 ;; # Files have been extracted. Notify user 10.2) cat << EOM The extraction is complete. EOM QUESTION="" get_response ynq STEP=11 ;; # Do software specific post-install steps 11) software_epilogue STEP=99 ;; # INSTALLDIR hasn't enough room, inform user of required room 12) cat << EOM $PRODUCT requires $DISKSPACE MB of disk space. EOM STEP=13 ;; # Determine if user wants to terminate installation 13) QUESTION="Do you want to terminate installation" DEFAULT=n get_response ynq if test $RETURN = n then STEP=4 else STEP=14 fi ;; # User has terminated installation 14) cat << EOM Installation has been CANCELLED. $PRODUCT was NOT installed. EOM exit ;; # INSTALLDIR does not exist. Inform user and ask if # it should be created. 15) cat << EOM $INSTALLDIR does not exist. EOM QUESTION="Should I create this directory" DEFAULT=y get_response ynq if test $RETURN = n ; then STEP=13 ; else STEP=15.1 ; fi ;; # User wants to create INSTALLDIR. 15.1) cat << EOM OK, I will try to create $INSTALLDIR. One moment please... EOM create_path $INSTALLDIR if test $RETURN -eq 1 ; then STEP=15.5 ; else STEP=15.2 ; fi ;; # INSTALLDIR was created. Inform user. 15.2) cat << EOM $INSTALLDIR has been created. EOM STEP=8 ;; # INSTALLDIR could not be created. Inform user. 15.5) cat << EOM The attempt to create $INSTALLDIR FAILED. EOM STEP=13 ;; # VERFILE exists, meaning that a version of PRODUCT # is already installed. Get the version number out # of VERFILE and compare to version being installed 17) INSTVER=`cat $INSTALLDIR/$VERFILE` cat << EOM The installed version is $INSTVER The version you are installing is $VERSION EOM if test $VERSION -gt $INSTVER ; then STEP=17.1 else STEP=17.2 fi ;; # Installed version is older. Inform user and # determine if user wants to upgrade. 17.1) cat << EOM The currently installed software is OLDER than the software you are installing. I can upgrade the software, but this will ERASE the currently installed software. Before performing an upgrade, it is STRONGLY recommended that you make a BACKUP copy of the currently installed software. EOM QUESTION="Do you want to upgrade now" DEFAULT=n get_response ynq if test $RETURN = y ; then STEP=7 ; else STEP=13 ; fi ;; # Installed version is newer. Inform user and # skip remaining steps. 17.2) cat << EOM The currently installed software is as new or newer than the software you are installing. No further action is required. EOM QUESTION= get_response VERSION=$INSTVER STEP=99 ;; # User has indicated that software is already installed. # Find out where. 23) echo echo $n "Where is $PRODUCT" $c QUESTION="installed" DEFAULT=$DEFINSTALLDIR get_response INSTALLDIR=$RETURN if test -f $INSTALLDIR/$VERFILE ; then STEP=17 else STEP=23.1 fi ;; # User has indicated that software is already installed, # but it doesn't appear to be where they said it is. 23.1) cat << EOM $PRODUCT does not appear to be installed in $INSTALLDIR Please check for typing errors. EOM STEP=3 ;; esac done } # find out architecture type . ./set_arch.sh # find out proper way to print an echo that does not have an END-OF-LINE ${rm} -f /tmp/.echotmp (echo "hi there\c" ; echo " ") > /tmp/.echotmp if ${grep} c /tmp/.echotmp > /dev/null 2>&1 ; then n='-n' c='' else n='' c='\c' fi ${rm} -f /tmp/.echotmp # get_response # print a prompt message and show the user the default value. # return the value enter, or a yes/no answer. # get_response() { ynq=$1 while [ 1 ] ; do RETURN="" if [ "$QUESTION" = "" ] ; then echo "" echo $n "Press to Continue $c" read response return else echo "" echo $n "$QUESTION [${DEFAULT}]? ${c}" read response if [ $? -ne 0 ] ; then terminate fi if [ "${ynq}" = "ynq" ] ; then case "${response}" in [Yy]*) RETURN="y" return ;; [Nn]*) RETURN="n" return ;; [Qq]*) terminate ;; \?) help_text ;; "") RETURN="${DEFAULT}" return ;; esac else case "${response}" in \?) help_text ;; "") RETURN="${DEFAULT}" return ;; .*) echo "" echo "Please enter an absolute pathname." ;; ~*) echo "" echo "Please enter an absolute pathname." ;; *) RETURN="$response" return ;; esac fi fi done } # NAME - kbyte_check # # DESCRIPTION # Determine if there exists enough space on the specified filesystem # such that the request being made can fit. # # IN/OUT # IN: $1 - pathname # IN: $2 - filesystem which resides # IN: $3 - amount of space on in kilobytes # IN: $4 - amount which is required in kilobytes # OUT: RETURN - 1 if enough space, 0 if not enough space # kbyte_check() { cat << EOM The pathname you have provided has the following characteristics: pathname = $1 filesystem = $2 available space (kbytes) = $3 EOM if [ $3 -ge $4 ] ; then echo "Space on '$2' is SUFFICIENT to" echo "install ${PRODUCT}." RETURN=1 else echo "Space on '$2' is INSUFFICIENT to" echo "install ${PRODUCT}." RETURN=0 fi } # check_remote_op # returns 0 if remote oper is possible, returns 1 if "Permission denied" # ie /.rhosts file is not setup right on the remote machine, returns 2 # if something else is wrong like remote m/c can't be reached # check_remote_op() { ${rsh} $1 echo hello > /tmp/bar.$$ 2>&1 output=`${sed} -n '/^hello$/p' /tmp/bar.$$` if [ "$output" = "hello" ] ; then RETURN=0 else ${grep} "Permission denied" /tmp/bar.$$ 1>/dev/null 2>&1 if [ "$?" = 0 ] ; then RETURN=1 else RETURN=2 fi fi ${rm} -f /tmp/bar.$$ } # terminate # terminate() { echo echo "Installation terminating." echo exit 0 }