:
#!/bin/sh

# undshar.sh (bundled with dshar V1.16)		by nide@nara-wu.ac.jp
#	Shell script on UNIX to extract dshar'ed files

#### Configuration part
Touch=0
 # If you have SystemV-like touch command, you can set it to 1
 # If you have it in /usr/5bin, you'd better set it to 2
FROMSJIS_def="nkf -e"
 # Default command to convert KANJI from SJIS
 # Note that nkf can't handle 1byte kana characters!
#### End of config

# main
Overwrite=0
Notexec=0
Textmode=0
ConvSJIS=0
FromSJIS_use="${FROMSJIS-$FROMSJIS_def}"
# Old sh doesn't know ':-' substitution
TrimCR="tr -d '\015\032'"
LC_CTYPE=C; export LC_CTYPE # to make locale void

while :; do
	case "$1" in
	 # Options must be specified separately
	-c)	Overwrite=1; shift;;
	-n)	Notexec=1; shift;;
	-t)	Textmode=1; shift;;
	-k)	ConvSJIS=1; shift;;
	-v)	FromSJIS_use="$2"; shift 2;;
	-v*)	FromSJIS_use="`expr X\"$1\" : '...\\(.*\\)'`"; shift;;
	--)	shift; break;;
	-)	break;;
	-*)
		echo Illegal option: "$1" 1>&2
		exit 1;;
	*)
		break;;
	esac
done

cat "$@" | tr -d '\015\032' | awk '# old awk will do
	BEGIN{
		overwrite = 0'$Overwrite'
		textmode = 0'$Textmode'
		convsjis = 0'$ConvSJIS'
		fromsjis = "'"$FromSJIS_use"'"
		trimcr = "'"$TrimCR"'"
		eofmark = "~EOF"
		tmpname = "'/usr/tmp/_tmp.$$XXX'"
		for(i = 0; i <= 16; i++)
			ctoi[substr("0123456789ABCDEF", i + 1, 1)] = i
		for(i = 0; i <= 6; i++)
			ctoi[substr("abcdef", i + 1, 1)] = i + 10
		# stoi["other string"] is 0
		print ":\n#!/bin/sh\nLC_CTYPE=C; export LC_CTYPE"
		printf "rm -f %s\n", tmpname
		if(convsjis){
			printf "echo Kanji conversion command: "
			printf "'\''\"%s\"'\''\n", fromsjis
		}
	}
	NR == 1, /^echo off[\t ]*$/{
		next
	}

	okflg == 0{
		if($0 ~ /^:\*$/){
			okflg = 1; next
		}
		if($0 !~ /^(:|[\t ]*$)/){
			cannot = 1; exit
		}
	}

	/^:end~of~arc/{
		endflg = 1; next
	}
	/^:[\t ]*\(You may put/, 1 == 0{
		if($0 !~ /^(:|[\t ]*$)/) igextflg = 1
		next
	}

	/^echo extracting/{
		if(catlevel) print eofmark; catlevel = 0
		for(; iflevel > 0; iflevel--) print "fi"
		filename = $3
		if(overwrite == 0){
			printf "if [ -f '\''%s'\'' ]; then\n", filename
			printf "\techo File already exists: "
			printf "skipping '\''%s'\''\n", filename
			printf "else\n"
			iflevel++
		}
		printf "echo extracting %s\n", filename
		next
	}
	/^if NOT EXIST/ && $5 == "%2"{
		dir = substr(filename, 1, length($6))
		printf "[ -d '\''%s'\'' ] ||\n", dir
		printf "\tmkdir '\''%s'\''\n", dir
		next
	}
	/^:\|$/{
		if(decodeflg == 0){
			decodeflg = 1
			printf "uudecode << '\''%s'\''\nbegin 644 ", eofmark
			catlevel++
			if(textmode || convsjis) print tmpname; \
			 else print filename
		} else {
			decodeflg = 0
			printf "`\nend\n%s\n", eofmark; catlevel = 0
			if(textmode || convsjis){
				if(textmode){ # includes text&&conv
					printf "%s", trimcr
				} else {
					printf "%s", fromsjis
				}
				printf " < '\''%s'\''", tmpname
				if(convsjis && textmode){
					printf " | %s", fromsjis
				}
				printf " > '\''%s'\'' &&\n", filename
				printf "\trm '\''%s'\'' ||\n\techo ", tmpname
				if(convsjis){
					printf "converting from ShiftJIS"
				} else {			
					printf "trailing '\''CR & ^Z'\''"
				}
				printf " of '\''%s'\'' failed\n", filename
			}
			printf "chmod u+r '\''%s'\'' 2>/dev/null\n", filename
			printf "[ -f '\''%s'\'' ] ||\n", filename
			printf "\techo failed extracting '\''%s'\''\n", \
			  filename
		}
		next
	}
	decodeflg != 0{
		if($0 !~ /^:/){
			cannot = 1; exit
		}
		printf "%c%s\n", 32 + int((length($0) - 1) * 3 / 4), \
		  substr($0, 2)
		next
	}
	/^if NOT ERR/ && $6 ~ /:[0-9A-Za-z]*[13579BDFbdf]\//{
		printf "chmod a-w '\''%s'\'' ||\n", filename
		printf "\techo restore attribute of '\''%s'\'' failed\n", \
		  filename
		next
	}
	/^if NOT ERR/ && $6 ~ /:[0-9A-Za-z]+\.$/{
		datestr = sprintf("%10s", $6)
		year = (int((ctoi[substr(datestr, 6, 1)] * 16 + \
			     ctoi[substr(datestr, 7, 1)]) / 2) + 1980) % 100
		mon  = (int((ctoi[substr(datestr, 7, 1)] * 16 + \
			     ctoi[substr(datestr, 8, 1)]) / 2)) % 16
		day  = (int((ctoi[substr(datestr, 8, 1)] * 16 + \
			     ctoi[substr(datestr, 9, 1)]))) % 32
		hour = (int((ctoi[substr(datestr, 2, 1)] * 16 + \
			     ctoi[substr(datestr, 3, 1)]) / 8)) % 32
		minu = (int((ctoi[substr(datestr, 3, 1)] * 16 + \
			     ctoi[substr(datestr, 4, 1)]) / 2)) % 64
		seco = (int((ctoi[substr(datestr, 4, 1)] * 32 + \
			     ctoi[substr(datestr, 5, 1)]) * 2)) % 64
		if(0'$Touch' == 0) printf ": "
		if(0'$Touch' == 2) printf "/usr/5bin/"
		printf "touch %02d%02d%02d%02d%02d '\''%s'\'' ||\n", \
		  mon, day, hour, minu, year, filename
		printf "\techo restore time-stamp of '\''%s'\'' failed\n", \
		  filename
		next
	}
	END{
		if(catlevel) print eofmark; catlevel = 0
		for(; iflevel > 0; iflevel--) print "fi"
		if(cannot){
			print "echo This archive cannot be unbundled by " \
				"this version of undshar.; exit 1"
			exit
		}
		if(!okflg){
			print "echo Archive not found '\''!?'\''; exit 1"
			exit
		}
		if(!endflg){
			print "echo Short archive'\''?!?'\''; exit 1"
			exit
		}
		if(igextflg){ # only warning
			print "echo Ignoring extra commands near EOF..."
		}
		print "exit 0 # Just in case..."
	}
' | {
	[ "$Notexec" = 1 ] && cat || sh
}
