#!/bin/sh

TAR=tar
GZIP=gzip
BZIP=bzip2

ERROR=error
AUTOMATIC=automatic

ZIPFLAGS=-cd
TARFLAGS=xf

USEZIP=${AUTOMATIC} # default

THISFILE=`basename $0`

# usage function
#

usage()
{
	echo "usage: ${THISFILE} [<flags>] <file_to_extract> [...]" 1>&2
	echo "       type \`${THISFILE} -h\` for help" 1>&2
	exit 1
}

# help function
#

help()
{
	echo ""
	echo "usage: ${THISFILE} [<flags>] <file_to_extract> [...]"
	echo ""
	echo "where <flags> can be:"
	echo ""
	echo "   -a     automatic archive type detection"
	echo "   -b     use ${BZIP} as a pipe for ${TAR}"
	echo "   -d     delete extracted archives"
	echo "   -g     use ${GZIP} as a pipe for ${TAR}"
	echo "   -h     this help"
	echo "   -k     keep extracted archives"
	echo "   -n     don't pipe; use ${TAR} directly"
	echo "   -q     more quiet"
	echo "   -v     more verbose"
	echo ""
	echo "Options are effective on arguments following them."
	echo "example: ${THISFILE} -b a.tar.bz2 -g b.tar.gz -a c.tgz d.tar \\"
	echo "            e.tar.bz2 -g f.irregular.extension -n g.tar"
	echo ""
	exit 0
}

# extract function
#

extract()
{
#	echo "entering extract()"   ###

	if [ ! -f "${FILE}" ]; then
		echo "${THISFILE}: ${FILE}: no such file" 1>&2
		ZIPPER=${ERROR}

	elif [ ! -r "${FILE}" ]; then
		echo "${THISFILE}: ${FILE}: can't read file" 1>&2
		ZIPPER=${ERROR}

	# it exists and is readable; now let's try to determine
	# the file type (if set to automatic)

	elif [ "${USEZIP}" = "${AUTOMATIC}" ]; then
		n=0
		TESTTAR=0
		for j in `echo ${FILE} |sed s/\\\./\.\ /g`; do
			n=`expr ${n} + 1`
		done
		EXT=`echo ${FILE} |cut -f ${n} -d \.`
		case ${EXT} in
			gz)
				ZIPPER=${GZIP}
				TESTTAR=1 ;;
			bz2)                 #bzip2 actually disallows any files without
				ZIPPER=${BZIP}  #a .bz2 suffix, so we won't bother testing
				TESTTAR=1 ;;    #.tbz, etc
			bz)
				ZIPPER=${BZIP}
				TESTTAR=1 ;;
			tgz)
				ZIPPER=${GZIP}
				TESTTAR=0 ;;
			Z)
				ZIPPER=${GZIP}
				TESTTAR=1 ;;
			tZ)
				ZIPPER=${GZIP}
				TESTTAR=0 ;;
			taZ)
				ZIPPER=${GZIP}
				TESTTAR=0 ;;
			tar)
				ZIPPER=""
				TESTTAR=0 ;;
			*)
				echo "${THISFILE}: ${FILE}: can't determine file type" 1>&2
				ZIPPER=${ERROR}
		esac

		if [ "${TESTTAR}" = 1 ]; then
			EXT=`echo ${FILE} |cut -f \`expr ${n} - 1 \` -d \.`
			if [ "${EXT}" != "tar" ]; then
				echo "${THISFILE}: ${FILE}: can't determine file type" 1>&2
				ZIPPER=${ERROR}
			fi
		fi

	else
		ZIPPER=${USEZIP}
	fi

	# now we do the acutal extraction
	#

	if [ "${ZIPPER}" != "" -a "${ZIPPER}" != "error" ]; then
		if [ "${VERBOSE}" = 1 ]; then
			echo "extracting ${FILE} with ${ZIPPER}..."
		fi
		${ZIPPER} ${ZIPFLAGS} ${FILE} | ${TAR} ${TARFLAGS}${VFLAG} -

	elif [ "${ZIPPER}" = "" ]; then
		if [ "${VERBOSE}" = 1 ]; then
			echo "extracting ${FILE}..."
		fi
		${TAR} ${TARFLAGS}${VFLAG} ${FILE}
	fi

	if [ "${DELETE}" = 1 ]; then
		if [ "${VERBOSE}" = 1 ]; then
			echo "removing ${FILE}..."
		fi
		rm ${FILE}
	fi
#	echo "leaving extract()"   ###
}



if [ $# -eq 0 ]; then
	usage
fi

# check for -h
for i in $*; do
	case $i in
	-h)
		help
		shift ;;
	--help)
		help
		shift ;;
	esac
done

for i in $*; do
#	echo "processing $i..."	###
	case $i in
	-v)
		if [ "${VERBOSE}" = 1 ]; then
			VFLAG=v
		else
			VERBOSE=1
		fi
		shift ;;
	-a)
		USEZIP=automatic
		shift ;;
	-b)
		USEZIP=${BZIP}
		shift ;;
	-d)
		if [ "${IGNORE_D}" != 1 ]; then
			DELETE=1
		fi
		shift ;;
	-g)
		USEZIP=${GZIP}
		shift ;;
	-k)
		DELETE=0
		shift ;;
	-n)
		USEZIP=""
		shift ;;
	-q)
		if [ "${VERBOSE}" = 1 ]; then
			if [ "${VFLAG}" = "v" ]; then
				VFLAG=
			else
				VERBOSE=0
			fi
		fi
		shift ;;
	-*)
		echo "${THISFILE}: unknown flag: $i -- ignoring this and all -d flags" 1>&2
		DELETE=0
		IGNORE_D=1
		shift ;;
	*)
		FILE=$i
		extract
		shift
	esac
done


