:
#
#	@(#) hdfuncs.sh 25.4 93/03/09 
#
#	Copyright (C) 1990-1993 The Santa Cruz Operation, Inc.
#		All Rights Reserved.
#	The information in this file is provided for the exclusive use of
#	the licensees of The Santa Cruz Operation, Inc.  Such users have the
#	right to use, modify, and incorporate this code into other products
#	for purposes authorized by the license agreement provided they include
#	this notice and the associated copyright notice with any such product.
#	The information in this file is provided "AS IS" without warranty.
#
#	mkdev/.hdfuncs - Hard Disk Configuration functions
#
# Common functions for mkdev hd and other disk install/prep scripts
# file should be sourced by front-end script
# warning: several environmental dependencies in both directions

#Link-kit access: needed for node.d and mscsi files
#Now support a new minor device numbering scheme for Dos partitions
#Added support of Dos logical drives in the extended Dos partition
link_root=/etc/conf
link_bin=$link_root/bin
mdev=$link_root/cf.d/mdevice
node_root=$link_root/node.d
mscsi=$link_root/cf.d/mscsi
hdlist=/usr/lib/mkdev/perms/HDLIST
dkconf=/usr/lib/mkdev/perms/DKINIT

# define some numbers and flags here
interactive=yes		# interactive or not
diskpercent=120		# nice round number used to calculate max badtrks (0.8%)
rootinstall=		# flag to say whether we're installing root disk
relink=0

tmp=/tmp/hd_
no_args=


# Standard functions

# set that the link-kit is installed
check_link () {
	dir=`pwd`
	cd /
	if [ -f /etc/perms/extmd ]
	then
		PERM=/etc/perms/extmd
	else
		echo "Cannot locate /etc/perms/extmd. This file\nis needed to verify Link Kit installation." 1>&2
		# or return 1
		cleanup $FAIL

	fi
	# test to see if link kit is installed
	until	fixperm -i -d LINK $PERM
	do	case $? in
		0) echo "fixperm returned 0 in Link Kit check"
 		   return 0					          ;;	
		4) echo "\nThe Link Kit is not installed." >&2	          ;;
		5) echo "\nThe Link Kit is only partially installed." >&2 ;;
		*) echo "\nError testing for Link Kit.  Exiting.">&2
		   cleanup $FAIL					  ;;
		esac

		# Not fully installed. Do so here
		getyn "Do you wish to install it now?" || {
			# answered no
			echo "
Disk devices cannot be installed without the Link Kit.
Re-invoke this mkdev script after installing the Link Kit.">&2
			cleanup $FAIL
		}

		# answered yes, so install link kit
		/bin/sh -c /etc/custom -o -i LINK || {
			# custom exited unsuccessfully
			error "custom failed to install Link Kit successfully.  Please try again."
			cleanup $FAIL
		}
	done
	cd $dir
	return 0
}

# functions specific to generic hard disk installations

# set next available disknum from hdlist 
set_disknum() {
	disknum=1
	[ -f $hdlist ] && {
		#check to see if device files already exist for this
	        #device; if so, use the old disk number
		set_node_d
		LAST=`grep -v "^#" $hdlist | grep " $node_d $minor_seed\$" `
		LAST=`expr "$LAST" : '\([0-9][0-9]*\)'`
		if [ "$LAST" ] 
		then
			disknum=$LAST
			echo "\nDisk already configured as disk number $disknum (/dev/dsk/${disknum}s0)"
			olddisk=1
		else
			LAST=`grep -v "^#" $hdlist | sort -n | tail -1`
			LAST=`expr "$LAST" : '\([0-9][0-9]*\)'`
			[ "$LAST" ] && disknum=`expr $LAST + 1`	
		fi
	}
        cdev=/dev/rdsk/${disknum}s0
}

#Determine appropriate node.d file for building device nodes with idmknod
set_node_d () {
	major_to_driver
	node_d=$node_root/$driver
}

#Add device node definitions to node.d file; create new set of device
#files using idmknod
#update $HDLIST
fix ()  {
	#determine driver node.d file
	set_node_d
	# backup old node.d  and hdlist file
	[ -f $node_d ] && cp $node_d ${node_d}.00 
	[ -f $hdlist ] && cp $hdlist ${hdlist}.00 
	[ -f $dkconf ] && cp $dkconf ${dkconf}.00 

	echotext="	
$driver dsk/${disknum}s0 b ${minor_0} sysinfo sysinfo 600
$driver dsk/${disknum}s1 b ${minor_1} sysinfo sysinfo 600
$driver dsk/${disknum}s2 b ${minor_2} sysinfo sysinfo 600
$driver dsk/${disknum}s3 b ${minor_3} sysinfo sysinfo 600
$driver dsk/${disknum}s4 b ${minor_4} sysinfo sysinfo 600
$driver dsk/${disknum}sa b ${minor_a} sysinfo sysinfo 600
$driver dsk/${disknum}sd b ${minor_d} dos sysinfo 640
$driver dsk/${disknum}sC b ${minor_C} dos sysinfo 640
$driver dsk/${disknum}sD b ${minor_D} dos sysinfo 640
$driver dsk/${disknum}sE b ${minor_E} dos sysinfo 640
$driver dsk/${disknum}sF b ${minor_F} dos sysinfo 640
$driver dsk/${disknum}sG b ${minor_G} dos sysinfo 640
$driver dsk/${disknum}sH b ${minor_H} dos sysinfo 640
$driver dsk/${disknum}sI b ${minor_I} dos sysinfo 640
$driver dsk/${disknum}sJ b ${minor_J} dos sysinfo 640
$driver rdsk/${disknum}s0 c ${minor_0} sysinfo sysinfo 600
$driver rdsk/${disknum}s1 c ${minor_1} sysinfo sysinfo 600
$driver rdsk/${disknum}s2 c ${minor_2} sysinfo sysinfo 600
$driver rdsk/${disknum}s3 c ${minor_3} sysinfo sysinfo 600
$driver rdsk/${disknum}s4 c ${minor_4} sysinfo sysinfo 600
$driver rdsk/${disknum}sa c ${minor_a} sysinfo sysinfo 600
$driver rdsk/${disknum}sd c ${minor_d} dos sysinfo 640
$driver rdsk/${disknum}sC c ${minor_C} dos sysinfo 640
$driver rdsk/${disknum}sD c ${minor_D} dos sysinfo 640
$driver rdsk/${disknum}sE c ${minor_E} dos sysinfo 640
$driver rdsk/${disknum}sF c ${minor_F} dos sysinfo 640
$driver rdsk/${disknum}sG c ${minor_G} dos sysinfo 640
$driver rdsk/${disknum}sH c ${minor_H} dos sysinfo 640
$driver rdsk/${disknum}sI c ${minor_I} dos sysinfo 640
$driver rdsk/${disknum}sJ c ${minor_J} dos sysinfo 640
"
	if [ "$disknum" = "1" -o "$disknum" = "2" -o "$disknum" = "3" ]
	then	echotext="$echotext
$driver hd${disknum}0 b ${minor_0} sysinfo sysinfo 600
$driver hd${disknum}1 b ${minor_1} sysinfo sysinfo 600
$driver hd${disknum}2 b ${minor_2} sysinfo sysinfo 600
$driver hd${disknum}3 b ${minor_3} sysinfo sysinfo 600
$driver hd${disknum}4 b ${minor_4} sysinfo sysinfo 600
$driver hd${disknum}a b ${minor_a} sysinfo sysinfo 600
$driver hd${disknum}d b ${minor_d} dos sysinfo 640
$driver rhd${disknum}0 c ${minor_0} sysinfo sysinfo 600
$driver rhd${disknum}1 c ${minor_1} sysinfo sysinfo 600
$driver rhd${disknum}2 c ${minor_2} sysinfo sysinfo 600
$driver rhd${disknum}3 c ${minor_3} sysinfo sysinfo 600
$driver rhd${disknum}4 c ${minor_4} sysinfo sysinfo 600
$driver rhd${disknum}a c ${minor_a} sysinfo sysinfo 600
$driver rhd${disknum}d c ${minor_d} dos sysinfo 640
"
	fi

	echo "$echotext"  >> $node_d 
	sort -u $node_d > ${tmp}4.$$
	mv ${tmp}4.$$ $node_d
	grep "$disknum $node_d $minor_seed" $hdlist > /dev/null 2>&1
	[ $? -ne 0 ] &&	echo "$disknum $node_d $minor_seed" >> $hdlist
	fixdone=TRUE

	#make nodes now using idmknod and tmp node.d directory
	tmpnodes=/tmp/hdnodes$$
	if [ -d $tmpnodes ]
	then
		rm -rf $tmpnodes/*
	else
		mkdir $tmpnodes
	fi
	echo "$echotext" > $tmpnodes/$driver
	#cleanup any old/conflicting ones (idmknod will die if conflicts)
	unsettrap
	rm -f /dev/dsk/${disknum}s* 2> /dev/null      
	rm -f /dev/rdsk/${disknum}s* 2> /dev/null      
	rm -f /dev/hd${disknum}? 2> /dev/null      
	rm -f /dev/rhd${disknum}? 2> /dev/null      
	#make the new ones
	$link_bin/idmknod -s -e $tmpnodes || {
		rm -rf $tmpnodes 
		error mknod_fail
	}
	settrap
	nodedone=TRUE
	rm -rf $tmpnodes 
}

# determine the root hard disk type
get_root_type () {
	rootdisk=
	cdev=

	# root: need to tickle the disk so that driver prints config info
	[ -n "$rootinstall" ] && dparam /dev/rdsk/0s0 > /dev/null 2>&1

	type=`sed -n "/%disk/s/.*\(type=.\).*/\1/p" < /dev/string/cfg`

	case $type in
	type=S*)	rootdisk=S  	;;
	type=E*)	rootdisk=E 	;;
	type=W*)	rootdisk=W 	;;
	type=I*)	rootdisk=I	;;
	*)		error root_fail	;;
	esac

	[ -n "$rootinstall" ] && newtype=$rootdisk
	return $OK
}

# set minor numbers for use by fix ()
# if scsi, set 'physical' argument for divvy
set_minors () {
	if [ "$newtype" = "S" ]
	then
		# SCSI installation
		# scsi_index set in scsi_config()
		physical=$scsi_index
	else 
		physical=$drivenum
	fi
	minor_seed=`expr $physical \* 64`
	minor_0=$minor_seed  
	minor_1=`expr $minor_seed + 15` 
	minor_2=`expr $minor_seed + 23` 
	minor_3=`expr $minor_seed + 31` 
	minor_4=`expr $minor_seed + 39` 
	minor_a=`expr $minor_seed + 47` 
	minor_C=`expr $minor_seed + 48` 
	minor_D=`expr $minor_seed + 49` 
	minor_E=`expr $minor_seed + 50` 
	minor_F=`expr $minor_seed + 51` 
	minor_G=`expr $minor_seed + 52` 
	minor_H=`expr $minor_seed + 53` 
	minor_I=`expr $minor_seed + 54` 
	minor_J=`expr $minor_seed + 55` 
	minor_d=$minor_C 

	set_exminors $minor_seed 
}

set_exminors()
{
	off=$1
	[ "$off" -gt 255 ]  && {
		off=`expr \( $off - \( $off % 256 \) \)`
		olddir=`pwd`
		cd $link_root/cf.d
		./configure -m $major -t -X $off && {
			./configure -m $major -b -c -a -X $off
			relink=`expr $relink + 1 `
		}
		cd $olddir
	}
}

# called with $OK (0) if successful; $FAIL (1) or other args on failure
cleanup () {
	[ "$rootinstall" = "TRUE" ] &&  {
		if [ "$1" != "0" ]
		then
			case $1 in
				fdisk_err) echo "/etc/fdisk failed." ;;
				batch_fdisk) echo "Cannot create a single, active UNIX virtual drive." ;;
			esac
			exit $FAIL
		fi
		exit $OK
	}

	# clean up perms file and remove unused disk devices
	rm -f ${tmp}?.$$ 2> /dev/null
	if [ "$1" != "0" ]
	then
		# new disk wasn't successfully accessed
		unsettrap
		[ "$fixdone" = "TRUE" ] && {
			# Restore previous node.d and hdlist files 
			[ -f ${hdlist}.00 ] && mv ${hdlist}.00 $hdlist
			[ -f ${node_d}.00 ] && mv ${node_d}.00 $node_d
			[ -f ${dkconf}.00 ] && mv ${dkconf}.00 $dkconf
		}

		# remove newly created devices
		[ "$nodedone" = "TRUE" -a "$olddisk" -ne 1 ] && {
			rm -f /dev/dsk/${disknum}s* 2> /dev/null      
			rm -f /dev/rdsk/${disknum}s* 2> /dev/null      
			rm -f /dev/hd${disknum}? 2> /dev/null      
			rm -f /dev/rhd${disknum}? 2> /dev/null      
		}
		settrap

		[ "$1" = "fdisk_err" ] &&  echo "/etc/fdisk failed." 
		exit $FAIL
	fi

	# non-root install successful
	# clean-up backup versions of node.d and hdlist files
	rm -f ${hdlist}.00
	rm -f ${node_d}.00
	rm -f ${dkconf}.00
	exit $OK
}


# Does the fdisk and, if necessary, does the badtrk as well
diskprep () {

	# set the character device of the disk we are interested in
	cdev=${cdev:-/dev/rdsk/0s0}

	# if a SCSI disk, only run fdisk
	[ "$newtype" = "S" -o "$newtype" = "I" ] &&  {
		if [ -n "$interactive" ]
		then	# do the interactive fdisk
			fdisk_interactive $cdev
		else	# do the non interactive fdisk
			batchfdisk || cleanup batch_fdisk
		fi
		return $OK
	}

	# $disknum is set in check_args()
	actdev=/dev/rdsk/${disknum:-0}sa

	# if on an OMTI controller, run fdisk and create space for badtrks
	[ "${newtype}$arch" = "EAT" ] &&  {
		if [ -n "$interactive" ]
		then	# do the interactive fdisk
			fdisk_interactive $cdev
		else	# do the non interactive fdisk
			batchfdisk || cleanup batch_fdisk
		fi
		batchbadtrk	# no args = don't do it, just make space
		return $OK
	}

	# Badtrack ST506 and ESDI disks. 

	# give this message on interactive use only
	[ -n "$interactive" ] && {
		echo "
The hard disk installation program will now invoke two disk
preparation utilities: fdisk and badtrk. 
Selecting 'q' at the main menu for each utility will exit
that utility and continue with the hard disk installation.

To exit the entire installation at these menus, press the <DEL> key."
	}

	# Partition the disk and badtrk the active virtual drive
	if [ -n "$interactive" ] 
	then 	# Loop until the user has partitioned around bad tracks
		until	
			fdisk_interactive $cdev
			/etc/badtrk -e -f $actdev
		do
			echo "
Please re-partition your disk, creating the active
UNIX partition after the bad area on the disk.\n"
		done
	else	# do the non-interactive fdisk and badtrk
		batchfdisk || cleanup batch_fdisk
		batchbadtrk FULL || {
			echo "
Reboot the system and restart the installation. 
At the prompt, choose the interactive hard disk initialization.

Please re-partition your disk, creating the active
UNIX partition after the bad area on the disk.

Exiting...\n" >&2
			cleanup $FAIL
		}
	fi
}

rundivvy () {
	divflags="-m"

	if [ -n "$rootinstall" ] 
	then
		# all root disks are physical 0
		physical=0
		# set the divvy root install flag
		divflags="-i"
		# set the divvy non-interactive flag here
		[ -n "$interactive" ] || divflags="$divflags -n"
		exec=exec
	else	exec=
	fi

	[ -n "$interactive" ] || echo "
Dividing UNIX partition into filesystem and swap divisions..."

	# invoke divvy
	$exec /etc/divvy $divflags $cdev || error divvy_err
}

# prevent confusion over selecting 'q' in the middle of the disk installation
utilmsg () {

	echo "\nThe hard disk installation program will now invoke $1.\
\nEntering 'q' at the following menu will exit $1,\n\
and the hard disk installation will continue. \
\n\nIf you wish to exit the entire installation at this menu,\n\
press the <DEL> key.\n"
}

rundparam () {

	# if root disk on SCSI or OMTI controller, need to dparam -w
	if [ "$newtype" = "S" -o "${newtype}$arch" = "EAT" ]
	then
		[ "$rootinstall" ] && dparam -w
	fi
		
	# invoke dkinit for ST506 and IDA and ESDI disks
	if [ "$newtype" = "W" -o "$newtype" = "I" -o "${newtype}$arch" = "EMC" ]
	then
		if [ -n "$interactive" ]
		then 	# use dkinit if interactive
			[ -f "$dkconf" ] && {
				echo $newtype $ctrlnum $drivenum $disknum >> $dkconf
			}
			utilmsg "/etc/dkinit"
			dkinit $drivenum $ctrlnum $newtype
		else	# write masterboot out only if noninteractive
			dparam -w
		fi
	fi
}

# run fdisk non-interactively
# WARNING: this will delete every existing NON-DOS virtual drive, 
# then create a single active UNIX virtual drive. 
# Don't try this at home, kids.
batchfdisk() {
#	we now cycle through 4 partitions and delete the next UNIX
#	or XENIX partition.  This depends on fdisk -p putting the 
#	partition number as the very first character in its output.
#	We used to assume partitions would "bubble up" so we could
#	always delete the first one, but the DOS would stay at entry
#	4.  This is no longer a valid assumption.
	fdisk -p | while read part
	do
		set `echo $part`
		if [ "$5" = "UNIX" -o "$5" = "XENIX" ]
		then
			fdisk -d $1 -f $cdev > /dev/null 2>&1
			break
		fi
	done

	# now create the single, active UNIX virtual drive
	fdisk -c 1 - - -f $cdev || return $FAIL

	# now make the single partition active
	fdisk -p | while read part
	do
		set `echo $part`
		if [ "$5" = "UNIX" -o "$5" = "XENIX" ]
		then
			fdisk -a $1 -f $cdev > /dev/null 2>&1 || return $FAIL
			break
		fi
	done

	# return and let the calling statement know everything is OK
	return $OK
}

# run badtrk non-interactively
# This will use a destructive, thorough scan by default, and
# will reserve N tracks for future badtracks
# argument indicates that actual badtracking is to be done 
# (not just make space for future badtracks)
batchbadtrk() {
	badtrkargs="-e -v"
	[ "$1" = "FULL" ] && {
	    badtrkargs="-e -v -s td"
	    echo "Scanning disk..."
	}

	# get the number of tracks in the virtual drive
	# we will use roughly 0.8 percent of the total disk
	set `fdisk -p`
	maxtracks=`expr $4 / $diskpercent`

	# do the non-interactive scan
	badtrk $badtrkargs -m $maxtracks -f $actdev || return $FAIL

	return $OK
}

error () {
      case $1 in
 	  bad_arg) a="Command line argument is invalid.\nInvoke mkdev hd -u\
 for a usage message."							    ;;
	 esdi_one) a="Can't add a second ESDI controller."		    ;;
         esdi_add) a="Can't add an ESDI controller to ST506 or SCSI system.";;
        st506_add) a="Can't add an ST506 controller to ESDI or SCSI system.";;
	st506_mca) a="Can't add a second ST506 controller on an MCA system.";;
	scsi_omti) a="Can't add a SCSI controller to an OMTI system."	    ;;
        esdi_disk) a="ESDI controllers support only disks 0 and 1." 	    ;;
       st506_disk) a="ST506 controllers support only disks 0 and 1." 	    ;;
           no_sed) a="/bin/sed is not installed. Install it and \
 reinvoke mkdev."  							    ;;
        divvy_err) a="divvy could not divide $cdev."			    ;;
	root_fail) a="Cannot determine root hard disk type."		    ;;
        link_fail) a="custom failed to install Link Kit successfully.  Please\
 try again." 								    ;;
	mknod_fail) a="idmknod could not create device nodes." ;;
	scsi_noconfig) a="Incomplete or incorrect scsi device configuration." ;;
	root_ida)  a="Cannot configure root hard disk.
Drive 0, controller 0 in use by primary IDA controller.
If you want to add an ST506 controller to a system with a
primary IDA controller, it must be the second controller."
     esac
     echo "\nError: $a\nInstallation exiting." 
     cleanup $FAIL
}

quitnow () {
	echo "\nDuring installation you may choose to overwrite all
or part of the present contents of your hard disk."

	while	echo "\nDo you wish to continue? (y/n) \c"
	do
		read x
		case $x in
		[Yy]*)	return $OK					 ;;
		[Nn]*)	echo "\nAborting initialization procedure.\n" 
		        cleanup $FAIL					 ;;
		*)	echo "\nPlease enter either 'y' or 'n'.\n"       ;;
		esac
	done
}

get_ndisk() {
	ndisk=
	olddir=`pwd`
	[ -d /etc/conf/cf.d -a -x /etc/conf/cf.d/configure ] \
		&& cd /etc/conf/cf.d || return $FAIL
	ndisk=`./configure -y NDISK` || {
		cd $olddir
		return $FAIL
	}
	cd $olddir
	return $OK
}

conf_ndisk() {
	get_ndisk
	[ -z "$ndisk" ] && return
	[ $ndisk -eq 0 ] && return
	new_ndisk=`expr $disknum + 1`
	export new_ndisk
	[ $new_ndisk -gt $ndisk ] && {
		echo "\nIncreasing kernel parameter NDISK from $ndisk to $new_ndisk"
		(cd /etc/conf/cf.d; ./configure NDISK=$new_ndisk)
		relink=`expr $relink + 1`
	}
}


major_to_driver()
{
	line=`grep  "[a-zA-Z][^	]*	$major	$major	" $mdev | head -1`
	driver=`expr "$line" : "\([^ 	]*\)"`
}

driver_to_major()
{
	line=`grep "^$driver" $mdev | head -1`
	major=`echo "$line" | awk '{print $6}'`
}

#Are we on an EISA bus machine?
is_eisa()
{
	set -- `uname -X | grep BusType`
	[ "$3" = "EISA" ] && return 0
	return 1
}

fdisk_interactive()
{
	fdisk_device=$1

	utilmsg "/etc/fdisk"
	/etc/fdisk -f $fdisk_device || cleanup fdisk_err
	getactive=`fdisk -p -f $fdisk_device`
	while [ 0 -eq `expr "$getactive" : '.*UNIX[ 	]*Active.*'` ] && getyn "Do you wish to specify an active UNIX partition?"
	do	/etc/fdisk -f $fdisk_device || cleanup fdisk_err
		getactive=`fdisk -p -f $fdisk_device`
	done
}

fdisk_badtrk_iqm ()
{
    #
    # entry for fdisk and badtrk (or scsibadblk) if called
    # with IQM variables set - ONLY during installation
    #
    if [ "$IQM_FDISK_INTERACTIVE" = "yes" ]
    then
	fdisk_interactive /dev/rdsk/0s0
    else
	fdisk_iqm
    fi

    badtrk_iqm ; stat=$?
    [ "$stat" = 0 ] || badtrk_errchk $stat
    # we can only get here if user repartitioned and badtrk worked fine
    term_echo "\n
Initialization of your disk drive partitions finished without error.
Continuing with filesystem setup.\n"
    return $OK
}

fdisk_iqm()
{
    #
    # non-interactive fdisk for use with IQM output
    #

    # delete any partitions that need to be deleted. 
    for partition in $IQM_DELETE_PART 	
    do
	    # blast away anything that might be there
	    for div in 0 1 2 3 4 5 6
	    do
		   divvy -D $div /dev/hd0$partition >/dev/null 2>&1
	    done
	    fdisk -d $partition  || {
		term_echo "Couldn't delete partition $partition"
		return $FAIL
	    }
    done	

    if [ "$IQM_DOS_PART" != "NOT" ]
    then
	set `echo $IQM_DOS_PART`
	fdisk  -t DOS -c $1 $2 $3 -f /dev/rdsk/0s0  || {
		term_echo "Couldn't create DOS partition"
		return $FAIL
	}
	# now "erase" the DOS filesystem setup, if applicable
	term_echo "Initializing the DOS partition ... \c"
	echo "\000\c" | dd of=/dev/hd01 bs=1024 conv=sync > /dev/null 2>&1
	term_echo "Done."
    fi

    if [ "$IQM_UNIX_PART" != "NOT" ]
    then
		set `echo $IQM_UNIX_PART`
		fdisk  -t UNIX -c $1 $2 $3 -f /dev/rdsk/0s0  || {
			term_echo "Couldn't create UNIX partition."
			return $FAIL
		}
    fi

    # now we need to activate the UNIX partition
    # if there is already an active UNIX partition, leave everything
    # alone.  If not, then activate the first UNIX partition.
    active=0
    fdisk -p | (while read part
    do
		set `echo $part`
		if [ "$5" = "UNIX" ] 
		then
		   [ "$6" = "Active" ] && {
			active=1
			break
		   }
		fi
    done
    return $active)

    # if we didn't find an active UNIX partition, activate the first one
    if [ $? -eq 0 ]
    then
		# activate the first UNIX partition
		fdisk -p | while read part
		do
			set `echo $part`
			if [ "$5" = "UNIX" ] 
			then
		   		fdisk -a $1 -f /dev/rdsk/0s0 || {
					term_echo "Couldn't activate UNIX partition"
					return $FAIL
		   		}
		   		break
			fi	
		done
    fi
}


badtrk_iqm()
{
    #
    # batch and interactive disk remapping, when IQM variables are set
    #
    # Badtrk is now an choice in IQM, which gives us the type of scanning
    # desired by the user. For now, let the user know that we are ignoring
    # any request to badtrk a SCSI drive.
    #

    if [ "$newtype" = "S" ] ; then		# SCSI drive
	if [ "$IQM_INSTALL_TYPE" = "fresh" ]
	then
	    term_echo "\n
Remapping of bad sectors on SCSI disk drives is not supported during
initial installation. Once your system if fully installed and running
in single-user mode, run the 'scsibadblk' program to check for errors
on your disk and save the data to alternate error-free sectors."
	fi
	return $OK
    elif [ "$newtype" = "EAT" ] ; then		# OMTI drive
	if [ "$IQM_INSTALL_TYPE" = "fresh" ]
	then
	    # setup the badtrk table from the IQM-generated size
            badtrk -e -m $IQM_NUM_BAD_TRACKS -f /dev/rdsk/0sa || return $ERROR
	fi
	return $OK
    else					# must be ST506 or ESDI drive
	if [ "$IQM_INSTALL_TYPE" = "fresh" ]
	then
	    if [ "XX$IQM_BADTRK_SCAN" != "XX" ]
	    then
		term_echo "\nBadtracking the hard disk. This will take a while ..."
		# setup the badtrk table from the IQM-generated size
		badtrk -e -m $IQM_NUM_BAD_TRACKS -f /dev/rdsk/0sa || return $ERROR
		# scan for badtrks with the scan type chosen by the user
		badtrk -v -s $IQM_BADTRK_SCAN -f /dev/rdsk/0sa || return $?
	    fi
	else
	    badtrk -f /dev/rdsk/0sa ; return $?
	fi
	return $OK
    fi
    return $FAIL 	# should never get here, so fail if we fall through
}

badtrk_errchk()
{
    case $1 in
	1)  	# error in the first few blocks of partition
		term_echo "
A bad disk track was found at the beginning of the Unix partition. The
system cannot be installed with this partition layout. You will need to
re-partition your disk, creating the active UNIX partition after the
bad area on this disk.\n"
		[ "$IQM_INSTALL_TYPE" = "fresh" ] && {
		    term_echo "
This will also change the size of the partition, so your original size
selections for the filesystems are no longer valid. After the disk
initialization is complete, you will enter the filesystem division
program to select new sizes for each of your desired filesystems.\n"
		    IQM_DIVVY_INTERACTIVE = "" ; export IQM_DIVVY_INTERACTIVE
		} || {
		    term_echo "
This will also change the size of the partition. Any filesystem data
which you are attempting to preserve in this partition will be lost.
It is recommended that you exit this installation, backup your data,
and then restart, choosing a different disk partition layout.\n"
		}
		while	term_echo "
Do you wish to re-partition your disk at this time? (y/n)  \c"
		do
		    read answer
		    case $answer in
		      [yY]*)	[ "$IQM_INSTALL_TYPE" = "repeat" ] && {
				    term_echo "
Confirm that you choose to continue the installation and lose any
data in 'preserved' filesystems. (y/n)  \c"
				    read answer
				    [ "$answer" = "y" -o "$answer" = "Y" ] || {
					cleanup $STOP
				    }
				}
				break ;;
		      [nN]*)	cleanup $STOP
				;;
		      *)	term_echo "
Please enter either 'y' or 'n'.\n"
				;;
		    esac
		done
		;;
	2)	# bad track table filled up before end of disk
		# This error return code does not exist today - 3/22/92
		;;
	-1)	# user DEL'ed out of program
		cleanup $STOP
		;;
	*)	# unknown error
		term_echo "
The disk badtrk program failed with an undetermined error. This
installation is unable to proceed at this time.
Call your Support Representative if you need assistance."
		cleanup $FAIL
		;;
    esac

    # Loop until the user has partitioned around bad tracks
    until	
	fdisk_interactive /dev/rdsk/0s0
        /etc/badtrk -e -f /dev/rdsk/0sa
    do
	while term_echo "
There is still a problem with your disk initialization. Do you wish
to re-partition your disk drive again? (y/n)  \c"
	do
	    read answer
	    case $answer in
		[yY]*)	break
			;;
		[nN]*)	cleanup $STOP
			;;
		*)	term_echo "
Please enter either 'y' or 'n'.\n"
			;;
	    esac
	done
    done
    return $OK
}

# This simply modifies and writes out a new divvy table.
divdisk_iqm ()
{
	if [ "$IQM_DIVVY_INTERACTIVE" = "yes" ]
	then
		term_echo "Running divvy interactively"
		 _term_echo=$?
		 $exec /etc/divvy -i /dev/rdsk/0s0 >&${_term_echo} 2>&1
		 [ $? = 0 ] || error divvy_err
		 return $OK
	fi

	for div in $IQM_DELETE_DIV
	do
		divvy -D $div /dev/rdsk/0sa || return $FAIL
	done

	set `echo $IQM_ROOT_DIV`	
	divvy -C $1 $2 $3 /dev/rdsk/0sa || {
		term_echo "Couldn't create the root division"
		return $FAIL
	}

	set `echo $IQM_SWAP_DIV`
	divvy -C $1 $2 $3 /dev/rdsk/0sa || {
		term_echo "Couldn't create the swap division"
		return $FAIL
	}
	swapend=$3

	if [ "$IQM_U_DIV" != "NOT" ] 
	then
		set `echo $IQM_U_DIV`	
		divvy -C $1 $2 $3 /dev/rdsk/0sa || {
			term_echo "Couldn't create the u division"
			return $FAIL
		}
	fi

	set `echo $IQM_RECOVER_DIV`
	divvy -C $1 $2 $3 /dev/rdsk/0sa || {
		term_echo "Couldn't create the recover division"
		return $FAIL
	}
	return $OK
}

makedir_iqm ()
{

	mkdir $1 || return $FAIL
	chmod $2 $1 || return $FAIL
	return $OK
}

# create the special device nodes.  
# takes: name c|b major base offset
# name is the name of the device
# c is for character device and b is for block device
# major is the major number of the device
# base is the base to the minor number of the device. In the case of
#    of a hard drive, it represents the physical drive and partition.
# offset will be added to base.  In the case of a hard drive, it
#    represents the division number.
mknode_iqm ()
{
	mknod /mnt/dev/$1 $2 $3 $4 || return $FAIL
	chmod $5 /mnt/dev/$1  || return $FAIL
	return $OK
}
	
mkfs_iqm ()
{
	/etc/mkfs -$1 -f $2 /dev/$3 $4 $5 $6 > /dev/null 2>&1 || return $FAIL
}
