#!/usr/bin/sh
#
# Copyright 1995 Sun Microsystems, Inc.
# All rights reserved.
#
#ident	"@(#)custom	1.43	95/12/08 SMI"

usage() {
	case $1 in
	-l)cat <<EOF >&2

USAGE:	customlist [-d device] [[-p perms_directory] permsfile/package] 
	-d <device> 	#List packages on specified device.  Without this option
	   	    	 all packages installed on the system will be listed. 
	-p <perms dir>  #Specfy perms directory from which to list a specific
			 packages' attributes.
   [permsfile/package]  #List specifed packages' attributes
EOF
		;;

	-a) cat <<EOF >&2

USAGE:	customadd -d device [package1,package2,...]
	-d 		#Specifies the device to add packages from.
	-n 		#Specifies that the device is not tape.
			 Increases Performance.
	-s 		#Specifies that customadd is being called from Sysadmin.
EOF
		;;

	-d) cat <<EOF >&2

USAGE:	customdelete [permsfile/package1,permsfile/package2,...] 

    [permsfile/package]	#Specifies package to delete.  Without this argument
			 A list of installed packages will be provided to 
			 make a selection from.
EOF
		;;
	-n) 
		echo "`usage -l``usage -a``usage -d`" >&2 ;;
	esac
clean
exit 1
}

clean() {
	rm -rf ${TMPFILE} ${TMPFILE2} /tmp/perm $INSTALLPKGS ${MAGIC_FILE} \
	       $PERMS_PKGS_FILE /tmp/$$vol*  /tmp/init.*% ${X_FILE} 
	if [ "$SYSADMIN" -eq "$TRUE" -a "$PROGNAME" != "customlist" ]
	then
		UI window free prep_init_rmv
		freevar CURR_WD SYSV3
		[ -n "$perms_file_flg" ] && freevar PERMS_FILE
		rm -f $PKGSFILE
	fi
	[ "$1" = "-e" ] && exit 0 
	return 0
}

#----------------------------------------------------------------------------#
# printit()
#	This function will print messages in either a UI format by making
#	UI procedure calls/commands or in a CLI format by simply echo'ing
# 	messages to the screen.  printit expects one of the following arguments
#		-i   	# informational message
#       	-ib   	# beep and wait for user to press key message
#		-eb	# beep and give scrolling error message
#		-q 	# beep and ask user a question, wait for key. The 
#			  return codes are: 
#				0	no
#			  	1	yes
#----------------------------------------------------------------------------#
printit() {
	status=0
	if [ "$SYSADMIN" -eq "$TRUE" ]
	then
		TEXTFILE=/tmp/textfile
		[ -n "$LOG_FILE" ] && echo "$2" >> $LOG_FILE
		case "$1" in
			-i) 	UI infomsg "$2" ;;

			-lib) 	UI infomsg "$2" 
				UI beep ;;

			-ib) 	echo "$2" > $TEXTFILE 
				[ -n "$3" -a -f "$3" ]  && cat $3 >> $TEXTFILE 
			     	UI beep 
			   	UI call notemsg "$TEXTFILE" ;;

			-eb) 	echo "$2" > $TEXTFILE 
				[ -n "$3" -a -f "$3" ]  && cat $3 >> $TEXTFILE 
				UI call errmsg "$TEXTFILE" ;;

			-leb) 	UI errmsg "$2" ;;

			-q)  	echo "$2?" > $TEXTFILE
				[ -n "$3" -a -f "$3" ]  && cat $3 >> $TEXTFILE 
				status=`UI dbox question $TEXTFILE NULL NULL` ;;

		esac
		rm -f $TEXTFILE
	else
		if [ "$1" = "-eb" ]
		then 
			echo "\007"   			#ring bell
			echo "`gettext '\nERROR: \n'`$2"  >&2
		# beep and wait for user to press key info message
		elif [ "$1" = "-ib" ] 
		then
			echo "\007"   			#ring bell
			ENTQ=`gettext "Press enter or q to quit:"`
			echo "\n$2  $ENTQ"
			read cont_key
			[ "$cont_key" = "q" -o "$cont_key" = "Q" ] && clean && exit 0
		elif [ "$1" = "-q" ] 
		then
			ERROR_LBL=`gettext '\nERROR: '`
			YN=`gettext '(y or n)? '`
			echo -n "${ERROR_MSG}\n${2} ${YN}"  >&2
			read answer
			while :
			do 
				case "$answer" in  
					y|Y) status=1 ; break ;;
					n|N) status=0 ; break ;;	
				esac
			done
		else
			echo "$2"
		fi
		[ -n "$3" -a -f "$3" ]  && cat $3
	fi
	return $status 
}

#----------------------------------------------------------------------------#
# setpermvals
#	Expects arguments in the form permsfile/pkgsubset.  It produces
#	statements of the form: 
#		PKGINST="product name" 
#		VERSION="release number" 
#		ARCH="type" 
#		SIZE="size of given package" 
#		NAME="Package description" 
#
#	It is useful to produce output in this form so that they can be
#	eval'd later.
#----------------------------------------------------------------------------#
setpermvals() {
	PKGSUBSET=`echo $2 | cut -d"/" -f2` 
	PERMSFILE=`echo $2 | cut -d"/" -f1` 
	echo CATEGORY=CUSTOM
	sed -n '/^#set=/s/#set="*\([^"]*\)"*/PKGINST="\1"/p
		/^#rel=/s/#rel="*\([^"]*\)"*/VERSION="\1"/p
		/^#typ=/s/#typ="*\([^"]*\)"*/ARCH="\1"/p
		/^#!'${PKGSUBSET}'/s/#!'$PKGSUBSET'[ 	]*\([0-9]*\)[ 	]*\(.*\)/SIZE="\1" \
NAME="\2"/p' $1/$PERMSFILE 
}
#---------------------------------------------------------------------
#list_inst_pkgs()
#	This function prints the list of packages currently installed
#	on the system.  The formatted output is in the form:
#	
#		<name_of_permsfile>/<package_subset>
#---------------------------------------------------------------------

list_inst_pkgs() {
	permsdir=$1
	if [ -n "$2" ] 
	then
		permsfiles="/etc/perms/$2"
	else
	# Get names of all perms files in specified directory.  "fixperm" will
	# fail if any files in the directory aren't valid, so added extra check
	# to increase chances of passing in only valid perms files to fixperm.
		permsfiles=`fgrep -l "#prd=" ${permsdir}/* 2>/dev/null`
		[ -z "$permsfiles" ] && return 1
	fi

	# To find out which packages have been installed on the system, run
	# "fixperm" to produce a list of the form: "PackageName <Yes|No|Part>".
	# Need to loop on each perms file to avoid problem with two packages
	# having the same name. 
	for permfile in $permsfiles
	do
		permname=`basename $permfile`
		# Get list of the installed packages and precede them by #!. 
		$fixperm_cmd -iv -uPERM $permfile 2>/dev/null | sed -n 's/^\([^ 	]*\)[ 	]*Yes/#!\1/p' > $TMPFILE
		# formats output "prd/pkgname: package description" 
		fgrep -f $TMPFILE $permfile 2>&1 | sed -n 's?^#!\([^ 	]*\)[ 	]*[ 	]*[0-9]*[ 	]*"*\([^"]*\)"*?'$permname'/\1: \2?p' 
	done
	return 0
}

#---------------------------------------------------------------------
#
#chk_volume:
#	Ensures that the correct volume is in the drive.  The 
#       desired volume is passed in as the first parameter.  This
#	function also sets the variable PERMS_FILE to the name of
# 	the perms file for the rest of the program.
#---------------------------------------------------------------------

chk_volume() {
	needvol="$1"
	# Make sure were given the correct volume #. 
	# This will set the variables "prd" and "vol".
	# NOTE: need to make work for multiple perms files
	eval `tarlist -s ${device} "./tmp/_lbl/prd=*/typ=*/rel=*/vol=*" 2>/dev/null | sed -n -e 's?.*prd=\([^/]*\).*vol=\(.*\)?prd=\1 ; vol=\2?p' -e '1q'`

	if [ "$SYSADMIN" -eq "$TRUE" -a "$vol" -eq 1 -a -z "$perms_file_flg" ]
	then
		setvar -ui PERMS_FILE "$prd"
		perms_file_flg=1
	else
		PERMS_FILE="$prd"
	fi
	if [ -z "$vol" -o "$needvol" -ne "$vol" ]
	then
		BADVOL_ERR=`gettext 'Incorrect volume, insert volume $needvol.'`
		eval printit -ib "\"${BADVOL_ERR}\""
		badflopcnt=`expr $badflopcnt + 1`  
		if [ "$badflopcnt" -ge 2 ] ; then
			BADVOL_MSG=`gettext '\nThis volume is still incorrect.\nDo you wish to continue'`
			printit -q "$BADVOL_MSG"
			if [ $? -eq 0 ] ; then
				[ "$needvol" = "01" ] && return 1
				printit -q "$REM_PKGS_MSG"
				[ $? -eq 1 ] && REM_PKGS=TRUE 
				return 1
			else 
				badflopcnt=0
				chk_volume $needvol
				return $?
			fi
		else
			chk_volume $needvol
			return $?
		fi
	else
		badflopcnt=0
	fi
	return 0
}

list_dev_pkgs() {
	device=$1

	if [ "$SYSADMIN" -eq "$FALSE" -o "$PROGNAME" != "customadd" ] ; then
		# Prompt user for volume #1 of distribution.
		INSERT_MSG=`gettext 'Insert distribution volume 01.'`
		printit -ib "$INSERT_MSG"
	fi

	# Verify that we were given the first volume.  Also sets PERMS_FILE 
	# variable to the name of the perms file for this product.
	chk_volume "01" 
	[ $? -ne 0 ] && return 1

	GETPKGS_MSG=`gettext "Retrieving package names..."` 
	printit -i "$GETPKGS_MSG"

	# Extract perms file, using quick tar to get first occurrence and stop 
	rm -rf /tmp/perms
	tar ${NOPT}xvpqf ${device} ./tmp/perms/${PERMS_FILE} 1>/dev/null 2>${ERROR_FILE}
	[ $? -ne 0 ] && eval printit -eb "\"$DEVICE_ERR\"" ${ERROR_FILE} && return 2

	# Get the name, size, and description (separated by white space) of 
	# each package listed in the perms file.
	sed -n 's/^#!\(.*\)/\1/p' ./tmp/perms/${PERMS_FILE} > ${PKGSFILE}
	[ $? -ne 0 ] && printit -eb "$BADMEDIA_ERR" && return 2

	# Some third party vendors don't follow the IBCS2 specs.  They have
        # only one package in the perms file and used the key word ALL to name
	# it.  We will try to compensate here, by not eliminating it.
	# NOTE - Need to fix for multiple perms files.
	num_pkgs=`cat ${PKGSFILE} | wc -l` 
	if [ "$num_pkgs" -gt 1 -a "${SYSADMIN}" -eq "$TRUE" ] 
	then
		sed '/^ALL.*/d' $PKGSFILE > $TMPFILE
		cp $TMPFILE $PKGSFILE
	fi
	return 0
}

chk_space() {
	# List of packages user wishes to install.
	INSTALLPKGS="$1"
	# List of packages on media, format: pkgname size description.
	DEVPKGSFILE="$2"
	# Extract package sizes by searching for "#!pkgname size desc" in perms.
	needed_space=`fgrep -f $INSTALLPKGS $DEVPKGSFILE | awk '
			BEGIN	{ total=0 }
				{ total += $2 }
			END	{ printf "%d\n", total }'`
	free_space=`df / | sed -n 's/.*:[ 	]*\([0-9]*\)[ 	]*.*/\1/p'`
	if [ "$needed_space" -gt "$free_space" ] 
	then
		SPACE_ERR=`gettext '\nThere is not enough space in the root File System to install the\nselected packages:\n\n\t\tSpace available in / is $free_space \n\t\tSpace needed in / is $needed_space \n\n'` 
		eval printit -ib "\"$SPACE_ERR\""
		return 1
	fi
	return 0
}

perms_size_prep() {			
	devpkgs="$1"
	# Precede each package with "#!" so we can extract it from perms file
	echo $devpkgs | sed -e 's/ //g' -e 's/,/\
/g' | tee $INSTALLPKGS | sed 's/^/#!/g' > $PERMS_PKGS_FILE 
	cd /tmp/perms
	tmppermfiles=`egrep -l -f $PERMS_PKGS_FILE *`
	# Make sure that we have enough space to install selected packages.
	chk_space "$INSTALLPKGS" "$PKGSFILE"
	[ $? -ne 0 ] && return 4
	cd /
	# For each permfile, check if it exists.  If it does and it's exactly
	# the same - overwrite it, else tell user to remove it and try again.
	for pfile in $tmppermfiles
	do
		if [ -r /etc/perms/$pfile ] 
		then
			# Set variables "ARCH, VERSION, PKGINST"
			eval `setpermvals "/etc/perms" $pfile/fakepackage` 
			prdold="$PKGINST"; relold="$VERSION"; typold="$ARCH"

			# Reset variables for new perms file
			eval `setpermvals  "/tmp/perms" $pfile/fakepackage` 

			# If perms file on media matches /etc/perms/file,move it
			if [ "$prdold" != "$PKGINST" -o "$relold" != "$VERSION" -o "$typold" != "$ARCH" ]
			then
				PERMS_ERR=`gettext '\n\nThe file $pfile already exists in the /etc/perms directory.\nIt is a different product, version, or release.  Remove it and try again.\n'`
				eval printit -eb "\"$PERMS_ERR\""
				return 3 
			fi
		fi

		# Get all prep.* initialization scripts, specified in PERM pkg.
		tmppfile=/tmp/perms/${pfile}
		awk '{ 
			if ( $1 == "PERM" && $5 != pmsfile && $6 == 01 ) 
				print $5
		}' pmsfile=.${tmppfile} ${tmppfile} > ${TMPFILE} 

		if [ -s "${TMPFILE}" ] ; then
			tar ${NOPT}xvpqf ${device} -I $TMPFILE 1>/dev/null 2>${ERROR_FILE}
			[ $? -ne 0 ] && eval printit -eb "\"$DEVICE_ERR\"" ${ERROR_FILE} && return 2
		fi

		#Install perms file on system
		cp ${tmppfile} /etc/perms/${pfile}
	done

	#Run prep.* initialization scripts
	for prepfile in "`echo /tmp/perms/prep.*`"
	do
		[ ! -x "$prepfile" ] && continue

		# Attempt to uncompress....
		zcat $prepfile > $prepfile%  2>/dev/null
		[ ! -s "$prepfile%" ] && mv $prepfile $prepfile% 
		chmod +x $prepfile%

		if [ "$SYSADMIN" -eq "$FALSE" ] ; then
			$prepfile%
			rc=$?
		else 
			log_sz_b=`wc -c $LOG_FILE`
			UI batch <<EOF
				infomsg %ExecPrep
				window title prep_init_rmv %custom_prep
				window select prep_init_rmv
				wexec /usr/bin/sh -c "cd / ; $prepfile% 2>&1" LOG $LOG_FILE
EOF
			# Check return status of prep script and logfile size
			# (since some scripts return 0 on failure).  Give user
			# a chance to view errors if they exist.
			rv=$?
			log_sz_a=`wc -c $LOG_FILE`
			if [ $rv -ne 0 -o "$log_sz_b" != "$log_sz_a" ] ; then  
				UI clrinfo
				printit -lib %contkey 
				UI waitkey
			fi
			UI cls
			UI window hide prep_init_rmv
		fi
	done
	return $rv
}

mk_vol_files() {
proc_pkgs="$1"
rm -rf /tmp/$$vol.*
volfile_prefix=/tmp/$$vol
	# tmppermfiles - is a listing of perm files to retrieve files from.  It
	# gets set in the function "perms_size_prep"
	for pmfile in $tmppermfiles
	do
		# Get file names comprising all the selected packages in
		# each perms file. Separate contents list to be extracted from
		# each volume into files (e.g. $$vol.01, $$vol.02, ...).   
		$fixperm_cmd -fw $proc_pkgs /etc/perms/$pmfile 2>>$LOG_FILE |
	 	 sort -u +1 +0 |
	    	awk '(NF < 2) || ($2 == 0)  { next } #missing or zero vol field
			$2 != vol { if (vol) print "EOF" vol
				  vol = $2
				  print "cat>>" t vol "<<\EOF" vol
				}
				{ print $1 }
		' t=${volfile_prefix}. - |
	      sh || { status="$status Fixperm/File List"; return 1; }
	done
}

# Usage: execinit files  
# Attempt to uncompress init. scripts and then execute them.
# Returns exit status of last file executed.
execinit() {
	for init_script in $*
	do	
		[ ! -x "$init_script" ] && continue
		# Attempt to uncompress....
		zcat $init_script > $init_script%  2>/dev/null
		[ ! -s $init_script% ] && mv $init_script $init_script% 
		chmod +x $init_script%

		log_sz_b=`wc -c $LOG_FILE`

		# Execute init script.
		if [ "$SYSADMIN" -eq "$TRUE" ]
		then
			
			UI batch <<EOF
				infomsg %ExecInit
				window title prep_init_rmv %custom_init
				window select prep_init_rmv
				wexec /usr/bin/sh -c "cd / ; $init_script% 2>&1" LOG $LOG_FILE
EOF
			# Check return status of init_script and logfile size
			# (since some scripts return 0 on failure).  Give user
			# a chance to view errors if they exist.
			init_retstat=$?
			log_sz_a=`wc -c $LOG_FILE`
			if [ $init_retstat -ne 0 -o "$log_sz_b" != "$log_sz_a" ]
			then  
				UI clrinfo
				printit -lib %contkey 
				UI waitkey
			fi
			UI cls
			UI window hide prep_init_rmv
		else
			/usr/bin/sh -c "$init_script%"; init_retstat=$?
		fi

		if [ "$init_retstat" -eq 10 ]
		then
			INIT_ERR=`gettext 'The init script $init_script returned code 10, indicating that processing should stop.'`
			eval printit -eb "\"$INIT_ERR\"" 
			clean 
			exit 10
		elif [ "$init_retstat" -ne 0 ]
		then
			INIT_ERR=`gettext 'The init script $init_script failed.'`
			eval printit -eb "\"$INIT_ERR\"" 
		fi
		rm -f $init_script $init_script%
	done
	return $init_retstat
}

# Given a list of packages, determine if each already exists on the system.
# If it exists, give user the chance to eliminate it from the list of to-be-
# installed packages.
pkgs_exist() {
	install_pkgs="$1"
	is_installed=""
	list_inst_pkgs /etc/perms > $TMPFILE2
	for sel_pkg in $install_pkgs 
	do
	 	pkg_no_dashd=`echo $sel_pkg | sed -n s'/^..//p'`
		for pfile in $tmppermfiles
		do
			# If this combination of package and perms file isn't valid, skip it
			grep "^#!$pkg_no_dashd" /tmp/perms/$pfile > /dev/null 2>&1 || continue
			is_installed=`fgrep "$pfile/$pkg_no_dashd:" $TMPFILE2` 
			if [ -n "$is_installed" ]
			then
				UI window select main
		 		pkgname=`echo "$is_installed" | cut -d":" -f2`	
				PKGEXISTS_QUES=`gettext '\nThe package $pkgname\nalready exists.  Do you want to overwrite it'` 
				eval printit -q "\"$PKGEXISTS_QUES\""
				if [ $? -eq 0 ]
				then
					# User doesn't want to overwrite, remove pkg
				 	process_pkgs=`echo "$process_pkgs" | sed 's/'$sel_pkg'[ ]*//g'`
					if [ -z "$process_pkgs" -o "$process_pkgs" = " " ]
					then
						clean 
						exit 0	
					fi
				fi
			fi
		done
	done
	return 0
}
#------------------------------------------------------------------------
#rmpkg()
# 	Removes all files from a specified package from the system.  If
#	a file resides in another package as well, it will NOT be removed.
#	Empty directories will be removed.  Perms files which no longer
#	contain any packages currently installed on the system are removed.
#
#	ARGS:
#		<name_of_permsfile>/<name_of_pkg> 
#
#
#------------------------------------------------------------------------
rmpkg() {
	INSTALLED_FILES=/tmp/install_files$$
	INSTALLED_PKGS=/tmp/install_pkgs$$
	PKG_FILES=/tmp/pkgs_files$$
	permfile="$1"
	del_pkgs="$2"

	# Call products remove script
	if [ -x "${permfile}.rmv" ]
	then
		if [ "$SYSADMIN" -eq "$TRUE" ]
		then
			UI batch <<EOF
				window title prep_init_rmv %custom_rmv
				window select prep_init_rmv
				wexec /usr/bin/sh -c "cd / ; ${permfile}.rmv $del_pkgs" 
				rv=$?
				if [ $rv -ne 0 ] ; then  
					UI clrinfo
					printit -leb %contkey 
					UI waitkey
				fi
				cls
				window hide prep_init_rmv
EOF
		else
			/usr/bin/sh -c "${permfile}.rmv $del_pkgs"
		fi
	fi
	
	# Get list of files that make up all the installed packages and place 
        # them in INSTALLED_FILES. Ignore files of the packages we are removing
	for del_pkg in $del_pkgs ; do
		echo "/$del_pkg:" 
	done > $TMPFILE
	fgrep -v -f $TMPFILE $PKGSFILE  > $INSTALLED_PKGS
	sed -n 's?^\([^/]*\)/\([^:]*\):.*?\1 \2?p' $INSTALLED_PKGS | 
		while read pfile dfile
		do
			$fixperm_cmd -f -d$dfile /etc/perms/$pfile >> $INSTALLED_FILES 2>/dev/null
		done


	# Get list of files that make up packages to be deleted
	for del_pkg in $del_pkgs ; do
		$fixperm_cmd -f -d$del_pkg /etc/perms/$permfile >>$PKG_FILES 2>/dev/null
	done

	# If any files of this package exist in another package, we must
	# eliminate the files one-by-one to ensure that we don't delete a
	# file that is a part of another package.
	if fgrep -f $PKG_FILES $INSTALLED_FILES >/dev/null 2>&1
	then
		while read rmfile
		do
			fgrep "$rmfile" $INSTALLED_FILES >/dev/null 2>&1
			[ "$?" -ne 0 ] && rm -f $rmfile
		done < $PKG_FILES
	else 
		[ -s "$PKG_FILES" ] && rm -rf `cat $PKG_FILES`
	fi

	rm -f $INSTALLED_FILES $INSTALLED_PKGS $PKG_FILES
}


# This function should only be called when custom is invoked from Sysadmin.
# It lists the packages on the device CUI style and allows the user to select.
get_pkgs_to_inst() {
	setvar -ui PKGSDESC_FILE "$1"
	perms_file=$2
	UI infomsg %PackageI

	# Get local values for yes,no and yes,no,view. 
	YES_NO_VIEW=${UITMPPATH}/yes_no_view.${CMD}		
	UI message lookup %YesNoView > $YES_NO_VIEW
	# $YES and $NO are set by sysadmin.sh
	setvar -ui VIEW `sed -n '3p' $YES_NO_VIEW`

	# The UI definitions for the scrolling form go in this file.
	SCROLL_FORM=${UITMPPATH}/scroll_form.${CMD}
	# Input for the scrolling form goes in these files. The first has
	# all the packages set to yes and the second has them all set to no.
	setvar -ui SCROLL_Y_INPUT ${UITMPPATH}/scroll_y_input.${CMD}
	setvar -ui SCROLL_N_INPUT ${UITMPPATH}/scroll_n_input.${CMD}
	# Currently PKGSDESC_FILE contains all the packages on the device,in the
	# format "Mnemonic  Size  Description". We need the input to the 
	# scrolling form to be in the format: "yes/no" "Mnemonic" "Description".
	sed -n 's/^[ 	]*\([^ 	]*\)[ 	]*[0-9]*[ 	]*"*\([^"]*\).*$/"'$YES'" "\1" "\2"/p' $PKGSDESC_FILE > $SCROLL_Y_INPUT &
	sed -n 's/^[ 	]*\([^ 	]*\)[ 	]*[0-9]*[ 	]*"*\([^"]*\).*$/"'$NO'" "\1" "\2"/p' $PKGSDESC_FILE > $SCROLL_N_INPUT 

	# Now make the scrolling form definition file.
	NUM_PACKAGES=`cat $PKGSDESC_FILE | wc -l`
	setvar -ui FORM_INPUT ${UITMPPATH}/form_input.${CMD}
	cp $SCROLL_N_INPUT $FORM_INPUT
	make_form ${FORM_INPUT} ${NUM_PACKAGES} ${SCROLL_FORM}
	UI file ${SCROLL_FORM} ${YES_NO_VIEW}

	# Set the space required by selected packages and space available on
	# the file system which user has chosen to install new packages in.
	KBYTES=`df -b / | awk '{ if ( NR == 2 ) print $2 }'`	# free kbytes
	setvar -ui SPACE_AVAIL `echo 2 k $KBYTES 1024/ p | dc` # MegaBytes
	SPACE_REQ=0

	# Get the total space required for all packages, in case user changes
	# defaults to yes.  The pkg specifier ALL in perms file contains size.
	TOTAL_BLOCKS=`sed -n 's/#!ALL[ 	]*\([0-9]*\).*/\1/p' ${perms_file}` 
	setvar -ui SPACE_REQ_ALL_MBYTES `echo 2 k ${TOTAL_BLOCKS} ${BLKSperMB}/ p | dc`  

	setvar -ui YN N
	UI batch <<-EOF
		clrinfo
		window select packages
		form edit packages ${SPACE_REQ} ${SPACE_AVAIL}
		form hide packages
		window hide packages
EOF

	eval `UI form get packages`

	UI batch <<-EOF
		window free packages
		form free packages
EOF
	freevar VIEW PKGSDESC_FILE SCROLL_Y_INPUT SCROLL_N_INPUT FORM_INPUT YN SPACE_REQ_ALL_MBYTES SPACE_AVAIL PERMS_FILE

	[ "${button}" = "cancel" ] && exit 1

	# dev_pkgs will hold a list of the package(s) we should install
	DevPkgs=`awk '
	{
		if ($1 == yes)
			printf("%s,", $2)
	}' yes="\"$YES\"" $FORM_INPUT`

 	# Drop the quotes & trailing comma
	eval echo $DevPkgs | sed 's/,$//'
}

###########################################################################
# main() :
#	This program may be called with the following names:
#		customadd
#		customlist
#		customdelete
#	See usage() function for a description of options.
###########################################################################
trap 'clean -e' 1 2 3 15

SYSV3=${SYSV3:-""} ; export SYSV3
ERROR_FILE=${ERROR_FILE:-/tmp/error_file$$}
PKGHDR_MSG=`gettext "\nName\tSize\tPackage Description\n"` 
LINE="---------------------------------------------------------\n"
ENTPKGS_MSG=`gettext "\n\nEnter a list of Package Names to install (separated by commas) or q to quit: "` 
PROGNAME=`basename $0`
TMPFILE=/tmp/custom.tmp$$
TMPFILE2=/tmp/custom.tmp2$$
INSTALLPKGS=/tmp/install_pkgs$$
PKGS=/tmp/all_pkgs$$
PERMS_PKGS_FILE=/tmp/perms_pkgs_file$$	
CUSTOM_LOG=/etc/perms/.custom_log
TRUE=1
FALSE=0
SYSADMIN=$FALSE
PKGSFILE=/tmp/selpkgs
device=
pkgs=
NOPT=
fixperm_cmd=/etc/fixperm
BLKSperMB=2048
perms_file_flg=


while getopts "nsd:p:" o 
do
	case $o in
	d)
		[ "$PROGNAME" = "customdelete" ] && usage -d && exit 1
		device=$OPTARG; 
		DEVICE_ERR=`gettext 'Error reading from device $device:'`
		[ ! -r $device ] && eval printit -eb "\"$DEVICE_ERR\"" && exit 1
		BADMEDIA_ERR=`gettext "Unable to retrieve package names from media!"` 
		;;

	n)	
		if [ "$PROGNAME" = "customadd" ] ; then
			NOPT=n
		elif [ "$PROGNAME" = "customlist" ] ; then
			usage -l && exit 1
		else
			usage -d && exit 1
		fi
		;;

	p) 
		if [ "$PROGNAME" = "customlist" ] ; then
			perms_dir=$OPTARG 
		elif [ "$PROGNAME" = "customadd" ] ; then
			usage -a && exit 1
		else
			usage -d && exit 1
		fi
 		;;

	s) 	SYSADMIN=$TRUE 
		. ${ADMROOT}/sysadmin_lib.sh

		if [ "$PROGNAME" != "customlist" ] ; then
			# This contains the function "make_form"
			[ "$PROGNAME" = "customadd" ] && . ../pkgadd_lib.sh
			UI define window prep_init_rmv 2  0 19 78 SINGLE %custom_prep
			setvar -ui CURR_WD `pwd`
			setvar -ui SYSV3 "$SYSV3"
		fi
		;;
	\?) 	usage -n && exit 1 ;;
	esac
done
shift `expr $OPTIND - 1`
pkgs="$*" 
dir=`pwd`

# Must be at root - even for listing because "fixperm" requires it.
cd /

case $PROGNAME in
customlist)	
	# Display a list of packages on the specified device.
	if [ -n "$device" ]
      	then
		list_dev_pkgs $device 
		[ $? -ne 0 ] && clean && exit 2
		echo "$PKGHDR_MSG\n$LINE"
		cat $PKGSFILE
	# Get the product information related to a pkg.
	# Output variables of the form prd=123, rel=2.1...
	elif [ -n "$pkgs" ]
	then
		perms_dir=${perms_dir:-/etc/perms}
		eval `setpermvals ${perms_dir} ${pkgs}`
		cat <<-EOF
			CATEGORY="$CATEGORY"
			PKGINST="$PKGINST"
			VERSION="$VERSION"
			ARCH="$ARCH"
			NAME="$NAME"
			SIZE=`echo 2 k $SIZE ${BLKSperMB}/ p | dc`
EOF
	if [ -f ${CUSTOM_LOG} ] ; then
			INSTDATE=`awk 'BEGIN { FS = "-" ; } {
						if ( $1 == "'$pkgs'") 
							val=$2	
					} END { print val }' ${CUSTOM_LOG}` 
			echo INSTDATE=\"$INSTDATE\"
	fi
	# List all the packages installed on the system.  
	else
		list_inst_pkgs /etc/perms
		[ $? -ne 0 ] && clean && exit 2
	fi
	;;

customadd) 	
	REM_PKGS=FALSE
	REM_PKGS_MSG=`gettext '\nWould you like to remove the files\nthat were just installed for this package'`
	badflopcnt=0 			#Used in chk_volume function.
	# Create logfile to record installation errors.
	[ ! -d /var/sadm/install/logs ] && mkdir -p /var/sadm/install/logs
	if [ -f /var/sadm/install/logs/log.[0-9]* ] ; then
		lognum=`ls -1 /var/sadm/install/logs/log.[0-9]* | awk 'BEGIN { FS = "." ; } {
				if ( NR == 1 || $2 > largest ) { largest = $2 } 
		 	} END { print largest }'`
	else
		lognum=0	
	fi
	logfile=`expr $lognum + 1`
	LOG_FILE=/var/sadm/install/logs/log.$logfile
	> $LOG_FILE

	[ -z "$device" ]  && usage -a  	
	# List all packages on the device in the file $PKGSFILE.  This function
	# also sets the $PERMS_FILE to the name of the perms file for this prd.
	list_dev_pkgs $device
	[ $? -ne 0 ] && clean && exit 2
	while :
	do
		# Display available packages and let user select
		if [ "$SYSADMIN" -eq "$FALSE" ]
		then
			echo "$PKGHDR_MSG\n$LINE"
			cat $PKGSFILE
			echo "$ENTPKGS_MSG"
			read dev_pkgs 
			[ "$dev_pkgs" = "q" -o "$dev_pkgs" = "Q" ] && clean && exit 0
			[ -z "$dev_pkgs" ] && continue	
			cat $PKGSFILE | awk '{print $1}' >$PKGS
			allflg=0
			for pk in `echo "$dev_pkgs" | tr "," " "`
			do
				[ "$pk" = "ALL" ] && allflg=1
				egrep "^$pk$" $PKGS > /dev/null
				if [ $? -ne 0 ] ; then
					BADPKG_ERR=`gettext 'The package $pkg is invalid.  Press enter to continue or q to quit:'`
					eval printit -eb "\"${BADPKG_ERR}\"" 
					read entkey
					[ "$entkey" = "q" -o "$entkey" = "Q" ] && clean && exit 0
					continue 2
				fi
			done
		else
			dev_pkgs=`get_pkgs_to_inst ${PKGSFILE} /tmp/perms/${PERMS_FILE}`
			[ $? -eq 1 ] && clean && exit 0
		fi

		# Get files in /tmp/perms directory
		# Check FS space 
		# Run "prep." scripts
		# Sets the variable "tmppermfiles" for the rest of the program
		perms_size_prep "$dev_pkgs"
		rc=$?
		[ "$rc" -eq 4 ] && continue 
		[ "$rc" -ne 0 ] && clean && exit $rc 
		break
	done

	# Place a -d in front of all packages so that fixperm
	# will process it and remove the commas from the list. 
	if [ "$SYSADMIN" -eq "$FALSE" -a  "$allflg" -eq 1 ] ; then
		process_pkgs=`cat $PKGS | sed -n 's/^/-d/p'` 
	else
		process_pkgs=`echo "$dev_pkgs" | sed -e 's/^[ 	]*/-d/' -e 's/[ 	]*,[ 	]*/ -d/g'` 
	fi

	# Check if any of the packages are already installed.
	# NOTE - need to fix for multiple perms files
	pkgs_exist "$process_pkgs"

	# Put the names of all the files which need to be 
	# extracted into separate files corresponding to which
	# volume contains it. For instance, put all the files
	# that need to be extracted from vol 01 in /tmp/vol.01
	mk_vol_files "$process_pkgs"


	# NOTE: The following code is used later to check for XENIX binaries
	# Make a list of all executable files in the perms file. 
	X_FILE=/tmp/x_files$$
	awk ' $2 ~ /^[xX]/ { print $5 }' /tmp/perms/${PERMS_FILE} >$X_FILE
	# Create our own magic file to detect Xenix binaries. 
	MAGIC_FILE=/tmp/magic$$
	cat <<-EOF >$MAGIC_FILE
		0	byte	0x80	XENIX 
		0	long	0x140	XENIX 
		0	short	0x140	XENIX 
		0	short	0x206	XENIX 
		0	short	0xff65	XENIX
	EOF

	
	# Now extract the files from each volume.
	vol_files=`echo /tmp/$$vol.*`
	rm -rf /tmp/init.*
	[ "$vol_files" = "/tmp/$$vol.*" ] && echo "INTERNAL ERROR"
	for volfile in $vol_files 
	do
		# NOTE - need to fix for multiple perms files
		# This will set the variable "PKGINST".
		eval `setpermvals "/etc/perms" $tmppermfiles/fakepackage` 
		vol_num=`echo $volfile | cut -d"." -f2`	
		GETVOL_MSG=`gettext '\nInsert $PKGINST \nvolume number $vol_num.'` 
		if [ "$vol_num" = "01" -a  "$SYSADMIN" -eq "$TRUE" ] ; then
			:
		else
			eval printit -ib "\"$GETVOL_MSG\""

			# Verify that we were given the correct volume.
			chk_volume $vol_num
			[ $? -ne 0 ] && break
		fi

		# Extract files
		EXTRACT_MSG=`gettext "Extracting files..."` 
		printit -i "$EXTRACT_MSG"

		until tar ${NOPT}xpf ${device} -I ${volfile} 2>${ERROR_FILE}
		do	
			EXTRACT_QUES=`gettext "\nExtraction of files failed (during execution of the tar command).\nWould you like to try again"` 
			printit -q "$EXTRACT_QUES"
			[ $? -eq 0 ]  && clean && exit 5
		done 

		[ "$SYSADMIN" -eq "$TRUE" ] && UI clrinfo 

		# Before completing the installation, verify that user has not
		# installed any Xenix Binaries.  First get executables 
		# installed from this volume and then see if they are XENIX.
		fgrep -f $volfile $X_FILE > $TMPFILE 
		file -f $TMPFILE -m $MAGIC_FILE | grep XENIX >>${LOG_FILE} 2>&1
		if [ $? -eq 0 ] ; then
			XENIX_MSG=`gettext '\nSome of the files installed appear to be XENIX binaries.\nSince XENIX binaries are not supported, the rest of the\ninstallation may fail or once installed the application\nmay not work.  These XENIX files are listed in the logfile:\n$LOG_FILE\n\nDo you wish to continue'`
			eval printit -q "\"$XENIX_MSG\""
			#printit -q "$XENIX_MSG"
			if [ $? -eq 0 ] ; then
				printit -q "$REM_PKGS_MSG"
				[ $? -eq 1 ] && REM_PKGS=TRUE 
				break
			fi
		fi
		# Execute init. scripts.  Must get all init.*
		# scripts instead of init.<product> because too
		# many vendors didn't follow the standard. 
		# (e.g Foxpro has init.FOXDEV as init. script)
		# WHATS THE POINT IN HAVING A STANDARD!!!!!!!
		execinit /tmp/init.*[!%]
	done
		
	# If there was an error, remove packages and exit. 
	if [ "$REM_PKGS" = "TRUE" ] ; then
		old_perms_flg=$perms_file_flg
		opt=  ; perms_file_flg= 
		clean
		[ "$SYSADMIN" -eq "$TRUE" ] && opt="-s"
		rem_pkgs=
		for rem_pkg in `echo $dev_pkgs | tr "," " "`
		do
			rem_pkgs="$rem_pkgs ${PERMS_FILE}/${rem_pkg}"
		done
		customdelete $opt ${rem_pkgs}
		exit 1
	fi

	FIXPERM_MSG=`gettext "\nChecking file permissions...\n"`
	printit -i "$FIXPERM_MSG"
	$fixperm_cmd -c $process_pkgs /etc/perms/$tmppermfiles >>$LOG_FILE 2>&1
	INSTALL_LOG_MSG=`gettext '\nA log of the installation has been\nstored in $LOG_FILE.'`
	eval printit -ib "\"$INSTALL_LOG_MSG\""
	dt=`date '+%m/%d/%y %H:%M:%S`
	for inst_pkg in $process_pkgs ; do
	 	pkg_no_dashd=`echo $inst_pkg | sed -n s'/^..//p'`
		echo ${PERMS_FILE}/${pkg_no_dashd}-"${dt}" >>${CUSTOM_LOG}
	done
	;;

customdelete) 
	pkg_num=1
	perms_lst=
	# Get listing of installed packages for "rmpkg" to use.
	if [ -n "${pkgs}" ] ; then
		printit -i %RemPkgs
		list_inst_pkgs /etc/perms > $PKGSFILE 
	# If not in Sysadmin and allow user to select packages for deletion.
	elif [ "$SYSADMIN" -eq "$FALSE" -a -z "${pkgs}" ] ; then
		list_inst_pkgs /etc/perms | tee $PKGSFILE |
	  	   	while read pkgname pkgdesc 
	  	   	do
				echo "$pkg_num) $pkgname $pkgdesc"
				pkg_num=`expr $pkg_num + 1`
	  	   	done
		total_pkgs=`cat $PKGSFILE | wc -l`	
		SELECT_MSG=`gettext "\nEnter a comma separated list of numbers corresponding to the packages you\nwould like to delete or q to quit:\n"`
		printit -i "$SELECT_MSG"
		# printit will set "$cont_key" to user's response
		for num in `echo "$cont_key" | tr "," " "` 
		do
			[ "$num" -lt 1 -o "$num" -gt "$total_pkgs" ] && continue 
			pkgstring=`sed -n ''$num'p' $PKGSFILE | cut -d":" -f1`
			pkgs="${pkgs} $pkgstring"
		done
		printit -i %RemPkgs
	fi

	for pkgpair in $pkgs
	do
		permsfilename=`echo $pkgpair | cut -d"/" -f1`
		pkgsubsets=`echo $pkgpair | cut -d"/" -f2`

		if [ "$pkgsubsets" = "ALL" ] ; then
			# Get a list of ALL the installed packages for product 
			pkgsubsets=`$fixperm_cmd -iv -uPERM /etc/perms/$permsfilename 2>/dev/null | sed -n 's/^\([^ 	]*\)[ 	]*Yes/\1/p'`
		fi

		if echo $perms_lst | grep " $permsfilename " >/dev/null 2>&1
		then
			:
		else
			perms_lst="$perms_lst $permsfilename "
		fi

		rmpkg "$permsfilename" "$pkgsubsets"
	done

	# Remove all empty directories.  This must be done after ALL files for
	# every package is removed, because dirs are only listed in one PKG but
	# files underneath that dir may be in subsequent packages.
	for pkgpair in $pkgs
	do
		permsfilename=`echo $pkgpair | cut -d"/" -f1`
		pkgsubsets=`echo $pkgpair | cut -d"/" -f2`
		if [ "$pkgsubsets" = "ALL" ] ; then
			# Get a list of ALL the installed packages for product 
			pkgsubsets=`$fixperm_cmd -iv -uPERM /etc/perms/$permsfilename 2>/dev/null | sed -n 's/^\([^ 	]*\)[ 	]*Yes/-d\1/p'`
			dirs=`$fixperm_cmd -D $pkgsubsets /etc/perms/$permsfilename 2>/dev/null | sort -r -`
		else
			dirs=`$fixperm_cmd -D -d$pkgsubsets /etc/perms/$permsfilename 2>/dev/null | sort -r -`
		fi
		rmdir -ps $dirs
	done

	# Remove the /etc/perms file if all pkgs have been deleted.
	# "perms_lst"  gets set in the function "rmpkg".
	rmperms=
	for pfile in $perms_lst
	do
		if [ -f /etc/perms/$pfile ] ; then
			rmperms=`$fixperm_cmd -iv /etc/perms/$pfile | 
				awk 'BEGIN { rem="YES"; } 
				{ 
				  if ($2 == "Part" || $2 == "Yes" ) { rem="NO" }				 } END { print rem }'`
			[ "$rmperms" = "YES" ]  && rm -f /etc/perms/$pfile
		fi
	done	
	;;

*)	usage -n ;;
esac
clean
exit 0
