#!/bin/sh
#
# mkpkgdir:  make a package directory for use by dopackage
#	     from a tape or image directory
#
#

Myname=`basename "$0"`
Usage="mkpkgdir [ -s ] [ -v ] source dir
	where:
		source is tape device or image directory
			(e.g. /dev/rst1 or /image/install.10-4)
	and
		dir is directory to create and fill in

	-s indicates use symbolic links where possible
	-v turns on verbose progress reports"
#
# Main function - test arguments and verify valid call
#
main()
{
	# Initialize globals

	Image_flag=0
	Symlink_flag=0
	Verbose=:

	# Test for proper arguments

	while getopts sv arg
	do
		case "$arg" in
		s)
			Symlink_flag=1
			;;
		v)
			Verbose=""
			;;
		*)
			fatal "Unexpected option $arg"
			;;
		esac
	done
	shift `expr $OPTIND - 1`

	if [ $# -ne 2 ]
	then
		fatal "Usage: $Usage"
	fi

	SOURCE=$1
	DEST=$2

	# See that SOURCE is plausible

	if [ -d $SOURCE ]
	then
		if [ -f $SOURCE/INDEX ]
		then
			Image_flag=1
		else
			fatal "Couldn't find INDEX in directory $SOURCE"
		fi
	elif [ ! -c $SOURCE ]
	then
		fatal "source $SOURCE neither directory nor device"
	fi

	if [ $Image_flag -eq 0 ]
	then
		NSOURCE=/dev/nr`expr $SOURCE : '/dev/[n]*[r]*\(.*\)'`
		if [ X$NSOURCE != X$SOURCE ]
		then
			error "Using non-rewinding tape $NSOURCE"
			SOURCE=$NSOURCE
		fi
	fi

	if [ $Symlink_flag -eq 1 -a $Image_flag -ne 1 ]
	then
		fatal "Can't use -s option without an image directory"
	fi

	# Check DEST doesn't already exist

	if [ -f $DEST -o -d $DEST ]
	then
		fatal "destination $DEST already exists"
	fi

	# create the directory, then fill it in
	mkdir -p $DEST
	if [ $? -ne 0 ]
	then
		fatal "couln't make destination directory $DEST"
	fi

	if [ $Image_flag -eq 0 ]
	then
		make_TOC_from_tape
		get_pdfs
		get_files
	else
		make_TOC_from_INDEX
	fi
	exit 0
}

#
# make the TOC file from an image directory's INDEX
#
make_TOC_from_INDEX()
{
	$Verbose echo Creating TOC
	baseline=`awk '$2 == "P6-120" { print NR }' $SOURCE/INDEX`
	baseline=`expr $baseline + 2`
	state=0
	cat $SOURCE/Tape.P6-120/toc.0 |\
	while read hidden key value
	do
		if [ $hidden != "hidden" ]
		then
			value="$key $value"
			key=$hidden
			hidden=""
		fi

		rel_name=""
		case $state in
			0)
				if [ $key = "package" ]
				then state=1
				fi
				;;
			1)
				if [ $key = "special" ]
				then state=2
				elif [ $key = "start" ]
				then
					state=0
					name=`index_file_name $value`
					rel_name=`basename $name`

					# as long as we're here,
					# construct the pdf file
					make_pdf 0 $name $rel_name
				fi
				;;
			2)	if [ $key = "start" ]
				then
					state=0

					# grab the special file
					name=`index_file_name $value`
					rel_name=`basename $name`
					$Verbose echo Creating $rel_name
					if [ $Symlink_flag -eq 1 ]
					then ln -s $name $DEST/$rel_name
					else cp $name $DEST/$rel_name
					fi
				fi
				;;
			*)	fatal "Unexpected state $state"
		esac

		echo $hidden $key $value $rel_name >> $DEST/TOC

	done
}

#
# make a pdf file given file_no, name, and desired name
#
make_pdf()
{
	file_no=$1
	name=$2
	new_name=$3
	$Verbose echo Creating $new_name
	if [ $Image_flag -eq 1 ]
	then
		while read key typ loc siz
		do
			if [ $key = "position" ]
			then
				tar_name=`index_file_name $loc`
				rel_tar_name=`basename $tar_name`
				echo $key $typ $loc $siz $rel_tar_name >> $DEST/$new_name
				# as long as we're here, grab the file
				if [ ! -f $DEST/$rel_tar_name ]
				then
					$Verbose echo Creating $rel_tar_name
					if [ $Symlink_flag -eq 1 ]
					then ln -s $tar_name $DEST/$rel_tar_name
					else cp $tar_name $DEST/$rel_tar_name
					fi
				fi
			else
				echo $key $typ $loc $siz >> $DEST/$new_name
			fi
		done < $name
	else
		mt asf $file_no $SOURCE
		dd if=$SOURCE 2>/dev/null |	while read key typ loc siz
		do
			if [ $key = "position" ]
			then
				tar_name=`tape_file_name $loc`
				echo $key $typ $loc $siz $tar_name >> $DEST/$new_name
			else
				echo $key $typ $loc $siz >> $DEST/$new_name
			fi
		done
	fi
}

#
# index_file_name composes file name from *-n start or position indicator
# by referring to the associated INDEX file
#
index_file_name()
{
	fno=`file_number $1`

	# grab that line of INDEX
	lno=`expr $baseline + $fno`

	# convert INDEX name to file name
	index_name=`awk "NR == $lno" $SOURCE/INDEX`
	index_name=`echo $index_name | awk '{ print $3 }'`
	echo $index_name
}

#
# make the TOC file from reading a tape
#
make_TOC_from_tape()
{
	$Verbose echo Creating TOC
	mt -f $SOURCE rewind
	dd if=$SOURCE 2>/dev/null |	while read key value
	do
		if [ $key = "start" ]
		then
			name=`tape_file_name $value`
			echo $key $value $name >> $DEST/TOC
		else
			echo $key $value >> $DEST/TOC
		fi
	done
}

#
# tape_file_name composes file name from *-n start or position indicator
#
tape_file_name()
{
	file_no=`file_number $1`
	echo file.$file_no
}

#
# get the pdf files (tape only)
#
get_pdfs()
{
	state=0
	while read key value name
	do
		case $state in
			0)
				if [ $key = "package" ]
				then state=1
				fi
				;;
			1)
				if [ $key = "special" ]
				then state=2
				elif [ $key = "start" ]
				then
					state=0
					file_no=`file_number $value`
					make_pdf $file_no $name $name
				fi
				;;
			2)	if [ $key = "start" ]
				then state=0
				fi
				;;
			*)	fatal "Unexpected state $state"
		esac

	done < $DEST/TOC
}

#
# get the actual release files (tape only)
#
get_files()
{
	mt -f $SOURCE rewind
	mt -f $SOURCE fsf 1	# skip toc

	n=0
	while true
	do
		n=`expr $n + 1`
		if [ -f $DEST/file.$n ]
		then
			mt -f $SOURCE fsf 1
		else
			dd if=$SOURCE of=$DEST/file.$n 2>/dev/null
			if [ $? -ne 0 ]
			then break
			fi
			if [ ! -s $DEST/file.$n ]
			then
				rm $DEST/file.$n
				break
			fi
			$Verbose echo Creating file.$n
		fi
	done
	mt -f $SOURCE rewind
}

#
# fatal error - print message and exit
#

fatal()
{
	error "$*"
	exit 1
}

#
# error() prints an error message to stderr
#

error()
{
	echo "$Myname: $*" 1>&2
}

#
# file_number gives the file number n from a *-n string
#
file_number()
{
	n=`echo $1 | tr - /`
	echo `basename $n`
}

#
# Perform main function
#
main ${1+"$@"}
exit 0
