#!/bin/sh



set -u
umask 0022
export LC_ALL=C
export PATH="$(command -p getconf PATH 2>/dev/null)${PATH+:}${PATH-}"
case $PATH in :*) PATH=${PATH#?} ;; esac
export UNIX_STD=2003 # to make HP-UX conform to POSIX

print_usage_and_exit() {
	cat <<-USAGE 1>&2
		Usage   : ${0##*/} [--by-myself] [options] [template [...]]
		Arg&Opts: Almost compatible with GNU mktemp
		          The following options are available and compatible with it
		            -d, -p <DIR>, -q, -u, -t, --suffix=<suff>
		          But --by-myself is the only original option, it prevent
		          from use the built-in same name command even if available
		Version : 2020-05-06 22:42:19 JST
		          (POSIX Bourne Shell/POSIX commands)
	USAGE
	exit 1
}
error_exit() {
	${2+:} false && echo "${0##*/}: $2" 1>&2
	exit $1
}

by_myself=0
case "${1:-}" in
'--by-myself')
	shift
	by_myself=1
	;;
*)
	export mydir=$(
		d=${0%/*}/
		[ "_$d" = "_$0/" ] || cd "$d"
		echo "$(pwd)"
	)
	path0=${PATH:-}
	PATH=$(printf '%s\n' "$path0" |
		tr ':' '\n' |
		awk '$0!=ENVIRON["mydir"]{print;}' |
		tr '\n' ':' |
		grep -v '^:$' |
		sed 's/:$//')
	CMD_builtin=$(command -v mktemp 2>/dev/null || :)
	case "$CMD_builtin" in '') by_myself=1 ;; esac
	PATH=$path0
	unset mydir
	;;
esac
case $by_myself in 0)
	exec "$CMD_builtin" ${1+"$@"}
	exit 1
	;;
esac

Dir_tmp=$(set | grep ^TMPDIR= | sed 's/^[^=]\{1,\}=//')
case "$Dir_tmp" in
'') Dir_tmp='/tmp' ;;
/) Dir_tmp='/.' ;;
*) Dir_tmp=${Dir_tmp%/} ;;
esac

chrs='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_'
max_retry_when_failed=10
LFs=$(printf '\\\n_')
LFs=${LFs%_}


optd=0
optu=0
optq=0
optt=0
opts=''
optmode=''
while [ $# -gt 0 ]; do
	case $# in 0) break ;; esac
	case "$optmode" in
	'') case "$1" in
		-[duqtp]*)
			s=$(printf '%s\n' "${1#-}" |
				awk '{d = "_"; u = "_"; q = "_";              #
                                 t = "_"; p = "_"; err = 0;              #
                                 for (i=1;i<=length($0);i++) {           #
                                   s = substr($0,i,1);                   #
                                   if      (s == "d") { d   = "d"; }     #
                                   else if (s == "u") { u   = "u"; }     #
                                   else if (s == "q") { q   = "q"; }     #
                                   else if (s == "t") { t   = "t"; }     #
                                   else if (s == "p") { p   =  p ; }     #
                                   else               { err =  1 ; }     #
                                 }                                       #
                                 p = (substr($0,i-1)=="p") ? "p" : "_";  #
                                 printf("%s%s%s%s%s%s",d,u,q,t,p,err); }')
			case "$s" in *1*) print_usage_and_exit ;; esac
			case "$s" in *d*) optd=1 ;; esac
			case "$s" in *u*) optu=1 ;; esac
			case "$s" in *q*) optq=1 ;; esac
			case "$s" in *t*) optt=1 ;; esac
			case "$s" in *p*) optmode='p' ;; esac
			shift
			continue
			;;
		--directory)
			optd=1
			shift
			continue
			;;
		--dry-run)
			optu=1
			shift
			continue
			;;
		--quiet)
			optq=1
			shift
			continue
			;;
		--tmpdir)
			shift
			continue
			;;
		--tmpdir=*)
			optmode='p'
			s=${1#--tmpdir=}
			;;
		--suffix=*)
			optmode='s'
			s=${1#--suffix=}
			;;
		-*) print_usage_and_exit ;;
		esac ;;
	*) s=$1 ;;
	esac
	case "$optmode" in
	p)
		[ -d "$s" ] || error_exit 1 'Invalid path by -p,--tmpdir option'
		Dir_tmp=${s%/}
		[ -n "$Dir_tmp" ] || Dir_tmp='/.'
		optmode=''
		shift
		continue
		;;
	s)
		{ printf '%s' "$s" | grep -q '/'; } && {
			error_exit 1 'Invalid suffix option'
		}
		opts=$s
		optmode=''
		shift
		continue
		;;
	esac
	break
done


random_string() {
	nw=$(echo "${1}*l(${#chrs})/11.09+1" | # 11.09=ln(65536)
		bc -l |
		sed 's/\..*$//')

	if [ -c /dev/urandom ]; then
		hstr=$(dd if=/dev/urandom bs=2 count=$nw 2>/dev/null |
			od -A n -t x2 -v |
			tr 'abcdef ' 'ABCDEF\n' |
			tr -Cd 0123456789ABCDEF)
	else
		hstr=$( (
			ps -Ao pid,etime,pcpu,vsz
			date
		) |
			od -t d4 -A n -v |
			sed 's/[^0-9]\{1,\}/'"$LFs"'/g' |
			grep '[0-9]' |
			tail -n 42 |
			sed 's/.*\(.\{8\}\)$/\1/g' |
			awk 'BEGIN{a=-2147483648;}                 #
                     {a+=$1;        }                 #
                END  {                                #
                  srand(a);                           #
                  for(i=0;i<'$nw';i++){               #
                    printf("%02X",int(rand()*65536)); #
                  }                                   #
                }')
	fi

	echo "obase=${#chrs};ibase=16;$hstr" |
		bc |
		tr -d '\\\n' |
		tr ' ' '\n' |
		awk 'BEGIN  {for(i=1;i<'$1';i++){print 0;}}  #
       /[0-9]/{print;                       }' |
		awk 'BEGIN  {ORS="";                         #
               s="'"$chrs"'";                  #
               for(i=0;i<length(s);i++){       #
                 c[i]=substr(s,i+1,1);         #
               }                        }      #
       /[0-9]/{print c[$0*1];           }' |
		tail -c $1
}


case $# in 0)
	optt=1
	set -- 'tmp.XXXXXXXXXX'
	;;
esac

err=0
for arg in "$@"; do

	Dir_trg=${arg%/*}
	case "$Dir_trg" in
	"$arg")
		case $optt in
		0)
			Dir_trg=''
			;;
		*)
			Dir_trg="$Dir_tmp/"
			case "$Dir_trg" in '/./') Dir_trg=/ ;; esac
			;;
		esac
		;;
	*)
		Dir_trg="$Dir_trg/"
		;;
	esac

	n=$max_retry_when_failed
	while [ $n -ge 0 ]; do

		Path_target=$arg
		s=$(printf '%s\n' "$Path_target" | sed 's/X*$//')
		i=$((${#Path_target} - ${#s}))
		case $i in
		0) : ;;
		*) Path_target="${s}$(random_string $i)" ;;
		esac
		Path_target="${Path_target}${opts}"
		case $optt in 1) Path_target="${Dir_tmp}/${Path_target}" ;; esac
		Path_target=$(printf '%s\n' "$Path_target" |
			sed 's!//!/!g' |
			sed 's!/./!/!g')
		case "$Path_target" in
		- | /* | ./* | ../*) : ;;
		*) Path_target="./$Path_target" ;;
		esac

		case $optd in
		0)
			(
				set -C
				umask 177
				: >"$Path_target"
			) 2>/dev/null || {
				[ -f "$Path_target" ] && {
					n=$((n - 1))
					continue
				}
				n=-1
				break
			}
			;;
		1)
			umask 077
			mkdir "$Path_target" 2>/dev/null || {
				[ -d "$Path_target" ] && {
					n=$((n - 1))
					continue
				}
				n=-1
				break
			}
			;;
		esac

		break
	done

	case "${optq}${n}" in
	'0-1')
		printf '%s\n' "${0##*/}: failed on $Dir_trg${Path_target##*/}" 1>&2
		err=1
		continue
		;;
	'1-1')
		err=1
		continue
		;;
	esac

	printf '%s%s\n' "$Dir_trg" "${Path_target##*/}"

	case $optu in 1) rm -rf "$Path_target" ;; esac

done


exit $err
