:
#	@(#) fd.sh 21.2 89/11/10 
#
#	Copyright (C) The Santa Cruz Operation, 1986,1987,1988, 1989.
#	This Module contains Proprietary Information of
#	The Santa Cruz Operation, Microsoft Corporation
#	and AT&T, and should be treated as Confidential.
#

LANG=english_us.ascii
PATH=/bin:/usr/bin:/etc
export PATH LANG

# Define return values
: ${OK=0}  ${FAIL=1}  ${STOP=10}  ${HALT=11}

tmp="/tmp/fd$$"
FDPERMS="/usr/lib/mkdev/perms/FD"

# FUNCTION DEFINITIONS
#########################

# Define traps for critical and non critical code.
set_trap()  {	
	trap 'echo "Interrupted! Exiting ..."; cleanup 1' 1 2 3 15
}
unset_trap()  {
	trap '' 1 2 3 15
}

# Remove temp files and exit with the status passed as argument
#
# Usage: cleanup status
# References: $tmp indicates prefix of files to remove
# Notes: cleanup exits with whatever value it is passed.
#
cleanup() {
	trap '' 1 2 3 15
	umount $dev 2>/dev/null
	[ "$tmp" ] && rm -f $tmp*
	exit $1
}

# clear the screen if it is supported
clearscr() {
	# check if the terminal environment is set up
	[ "$TERM" ] && clear 2> /dev/null
}

# Prompt for yes or no answer - returns non-zero for no
getyn() {
	while	echo "\n$* (y/n) \c">&2
	do	read yn rest
		case $yn in
		[yY])	return $OK 			;;
		[nN])	return $FAIL			;;
		*)	echo "Please answer y or n" >&2	;;
		esac
	done
}

# Prompt with mesg, return non-zero on q. Also allows setting -x and +x,
# shell escapes and the passing of default values
prompt() {
	mesg=$1
	while	echo "\n${mesg} or q to quit: \c" >&2
	do	read cmd
		case $cmd in
		+x|-x)	set $cmd					;;
		-v)	# Print the values of requested variables
			read x
			for var in $x
			do
				eval echo \$$var
			done
			;;
		Q|q)	return $FAIL					;;
		!*)	eval `expr "$cmd" : "!\(.*\)"`			;;
		"")	# If there is a second argument use it
			# as the default, else loop until 'cmd' is set
			[ "$2" ] && { 
				cmd=$2
				return $OK
			}
			: continue
			;;
		*)	return $OK					;;
		esac
	done
}

# Simple prompt with argument, return non-zero on q
sprompt() {
	while	echo "\n$* or enter q to quit: \c" >&2
	do	read scmd
		case $scmd in
		Q|q)	return 1					;;
		"")	return 0					;;
		*)	continue					;;
		esac
	done
}

usage() {
	echo "\nUsage: $0 [48] [96] [135ds9] [135ds18]"
	cleanup $FAIL
}

# Set up variables based on floppy type.
# Note: Unix mkfs interprets size in 512K blocks.	
select() {
	case $1 in
		48)	tpi=48 size=720 spt=9 minor=4		
			descript="48ds9" 			;;
		96)	tpi=96 size=2400 spt=15 minor=52
			descript="96ds15"			;;
            135ds9)	tpi=135 size=1440 spt=9 minor=36	
			descript="135ds9"			;;
           135ds18)	tpi=135 size=2880 spt=18 minor=60	
			descript="135ds18"			;;
	         *)	usage					;;
	esac
}

# create a filesystem
mkfilesys() {
	mkfs -y $fstype $rdev $1 1 $spt > $tmp 2>&1 || {
		mv $tmp /tmp/FD.log
		echo "$0 Error: mkfs failed. See /tmp/FD.log for details."
		cleanup $FAIL
	}
}

# Create etc/default/boot file. 
# nswap set to 1000 to fool kernel 
# swplo value is based on current $nswap value (CHANGE IF $nswap CHANGES!)
mkbootstr() {
	mkdir /mnt/etc /mnt/etc/default
	fd96ds15="${boot}unix root=fd(52) swap=fd(52) pipe=fd(52) swplo=2200 nswap=1000 prompt=\"Insert root filesystem floppy and press <Return>\""
	fd135ds18="${boot}unix root=fd(60) swap=fd(60) pipe=fd(60) swplo=2680 nswap=1000 prompt=\"Insert root filesystem floppy and press <Return>\""
	eval defbootstr=\$fd$descript
	echo "DEFBOOTSTR=$defbootstr
fd96=$fd96ds15
fd135=$fd135ds18
hd=${boot}unix root=hd(40)
LOADUNIX=NO
FSCKFIX=YES
MULTIUSER=NO
PANICBOOT=NO
MAPKEY=NO" > /mnt/etc/default/boot
}

# create a bootable floppy
mkboot() {
	echo "\nCopying files to $dev ...\c"
	# install the boot block
	dd if=/etc/fd${tpi}ds${spt}boot0 of=$rdev bs=1k count=1 conv=sync > $tmp 2>&1 || {
		mv $tmp /tmp/FD.log
		echo "$0 Error: dd failed. See /tmp/FD.log for details."
		return $FAIL
	}
	if mount $fstype $dev /mnt > $tmp 2>&1 ; then 
		cp /boot /unix /mnt || cleanup $FAIL
		mkbootstr
	else
		echo "\n\nUnable to mount $dev."
		umount $dev 2>/dev/null
		return $FAIL
	fi
	echo
	umount $dev 
	return $?
}

# create a root filesystem floppy
mkroot() {
	# mount, install basic utilites, and unmount
	mount $fstype $dev /mnt > $tmp 2>&1 || return $FAIL

	mkdir  	/mnt/dev /mnt/mnt /mnt/tmp 
	[ -r $FDPERMS ] || {
		echo "\nCannot find $FDPERMS. Exiting ..."
		cleanup $FAIL
	}
	fixperm -l $FDPERMS | sed 's/^\.//p' > $tmp.list
	echo "\nCopying files to $dev root filesystem ...\c"
	cat $tmp.list | cpio -pdlm /mnt 2> /dev/null

	# Create special inittab and .profile files. 
	echo 'is:0:initdefault:\nr0:0:respawn:/bin/-sh </dev/console >/dev/console 2>&1' > /mnt/etc/inittab
	echo 'vd::sysinit:/altos/bin/vddaemon -e >/dev/console 2>&1' >> /mnt/etc/inittab
	echo ':\nSHELL=/bin/sh\nHOME=/\nPATH=/bin:/usr/bin:/etc:/altos/bin\nexport TERM PATH SHELL HOME\n./etc/TIMEZONE\n' > /mnt/.profile
	# Create empty mnttab and filesys so mount doesn't complain.
	> /mnt/etc/mnttab
	> /mnt/etc/default/filesys

	echo "\n\nCopying special files to $dev root filesystem ...\c"
	# Copy all /dev files that are not regular.
	cd /dev; find . -print | sed 's/^\.\///p;/^\./d' > $tmp.dev
	> $tmp.nodes
	for node in `cat $tmp.dev`
	do
		[ -f /dev/$node ] ||  echo $node >> $tmp.nodes
	done
	cat $tmp.nodes | cpio -pdlm /mnt/dev 2> /dev/null
	mv -f /mnt/dev/root /mnt/dev/hd0root
	mv -f /mnt/dev/rroot /mnt/dev/rhd0root
	mknod /mnt/dev/root b 2 $minor
	mknod /mnt/dev/rroot c 2 $minor
	echo
	# If they have any room left, stuff some more on the disk.
	cd /bin
	for file in "ed" "dd" "cat" "cp" "od" "find" "du"
	do
		freeblks=`df /mnt | sed 's/.*://;s/blocks.*//`
		fsize=`ls -s $file | sed "s/$file//`
		[ $fsize -gt $freeblks ] && break
		cp $file /mnt/bin/$file
	done
	# Set file permissions
	cd /mnt
	fixperm -c $FDPERMS
	cd /
	umount $dev
}

dohwconfig () {
a=`/etc/hwconfig name=floppy type 2> /dev/null`
cnt=0
for i in $a
do
	cnt=`expr $cnt + 1`
done

case $cnt in
	0) askuser ;;
	1) drive=0 ;;
	2) while :
	   do   echo "\nDo you want to use floppy drive 0 or floppy drive 1? \c"
		read x
		case $x in
			*0) drive=0 ;;
			*1) drive=1 ;;
			 *) echo "Answer 0 or 1"
			    continue ;;
		esac
	   break
           done ;;
	*) echo "\nEnter the number (0,1,2, etc) of the drive to use: \c"
	   read x
	   drive=$x ;;
esac
}

askuser () {
getyn "Does your system have two floppy drives?"
case $? in
	0) getyn "Do you want to create the new floppy on the second floppy \
drive?"
	   case $? in
		0) drive=1 	;;
		1) drive=0	;;
	   esac					;;
	1) drive=0				;;
esac
}

# At this time only type XENIX is allowed for boot/root. 
# Function is passed YES or NO to implement default XENIX for boot/root
get_fstype()  {
	fstype=
	if [ $1 = "YES" ]
	then
	getyn "Do you want to use the default file system type AFS?" || { 
		while :
		do prompt "Please enter a file system type from 
<AFS, S51K, XENIX>" || return $FAIL
			case $cmd in
			AFS|S51K|XENIX)		fstype="-f $cmd"
						break			;;
			*)	echo "$cmd is not valid. Try again" >&2
				continue				;;
			esac
		done
	}
	else
		fstype="-f XENIX"
	fi
return $OK
}

# main()
#########################

set_trap
cd /
clearscr
menu="\n\n\nFloppy Disk Filesystem Creation Program \n

	Choices for type of floppy filesystem.

	1. 48tpi, double sided, 9 sectors per track
	2. 96tpi, double sided, 15 sectors per track
 	3. 135tpi, double sided, 9 sectors per track
 	4. 135tpi, double sided, 18 sectors per track

Enter an option"

case $1 in
	48)	select "48"	 ;;
	96)	select "96"	 ;;	
    135ds9)	select "135ds9"	 ;;
   135ds18)	select "135ds18" ;;
	*)	while prompt "$menu" || cleanup $OK
		do	case $cmd in
			1)	select "48"			
				break			;;
			2)	select "96"			
				break			;;
 			3)	select "135ds9"		
 				break			;;
 			4)	select "135ds18"		
 				break			;;
			*)	usage			;;
			esac
		done
		;;
esac	

boot="fd($minor)"
root="fd($minor)"
pipe="fd($minor)"
swap="fd($minor)"

drive=
if [ -s "/usr/adm/hwconfig" ] 
then
	dohwconfig
else
	askuser
fi

dev=/dev/fd${drive}${tpi}ds${spt}
rdev=/dev/rfd${drive}${tpi}ds${spt}	

# Only filesystem and bootable floppy supported at this time.
menu="\nChoices for contents of floppy filesystem.

	1. Filesystem 
	2. Bootable only	  (96ds15 and 135ds18 only)
	3. Root filesystem only   (96ds15 and 135ds18 only)

Enter an option"

while	prompt "$menu" 
do	sprompt "Insert a $descript floppy into drive $drive.
Press <Return> to continue" || cleanup $OK

	getyn "Would you like to format the floppy first?" && format -f $rdev
	case $cmd in
		1)	# make filesystem only
			get_fstype YES  || continue
			mkfilesys $size || {
				echo "
Filesystem creation failed.  Try again." >&2
				continue
			}
			echo "\nFilesystem creation complete."
			;;
		2)	# Make boot floppy
			[ "$descript" = "96ds15" -o \
			  "$descript" = "135ds18" ] || {
				echo "$descript not supported for boot." >&2
				continue
			}
			get_fstype NO  || continue
			mkfilesys $size || {
				echo "
Filesystem creation failed.  Try again." >&2
				continue
			}
			echo "\nSuccessfully created filesystem."
			mkboot || {
				echo "
Bootable floppy creation failed. Try again." >&2
				/etc/umount $dev
				cleanup $FAIL
			}
			echo "\nBootable floppy creation complete."
			;;
		3)	# make root only
			[ "$descript" = "96ds15" -o \
			  "$descript" = "135ds18" ] || {
				echo "$descript not supported for boot." >&2
				continue
			}
			nswap=200
			swplo=`expr $size - $nswap`
			get_fstype NO || continue
			mkfilesys ${swplo}:640 || {
				echo "
Filesystem creation failed.  Try again." >&2
				continue
			}
			echo "\nSuccessfully created filesystem."
			mkroot	|| {
				echo "
Root filesystem floppy creation failed. Try again." >&2
				/etc/umount $dev
				cleanup $FAIL
			}
			echo "\nRoot filesystem floppy creation complete."
			;;
		*)	echo "$cmd not valid" >&2
			;;	
		esac
	umount $dev 2> /dev/null
	fsck -y $dev
	echo "\n$descript floppy created and checked successfully."
done
cleanup $OK

