Friendly UMASK wanted

Dave Decot decot at hpisod2.HP.COM
Sat Feb 3 11:31:16 AEST 1990


> X#!/bin/sh
> X# @(#)mask 1.0 90/02/02 Maarten Litmaath
> X# mask g-wx,o=
> X# mask -s

This does not conform to POSIX.2, in that it does not have an -o option
to force octal output, the + operation does not seem to work (it always sets
the involved mode parts to 0, regardless of the previous value), and most
importantly, the modes are interpreted upside down.  That is, this script
assumes:

   $ umask -o
   022
   $ umask -s
   u=,g=w,o=w


POSIX.2 requires:

   $ umask -o
   022
   $ umask -s
   u=rwx,g=rx,o=rx
   $ umask o+w,g-r
   $ umask -s
   u=rwx,g=x,o=rwx
   $ umask -o
   0060

Here's a version of Maarten's script that fixes the above problems.
The default output style when no arguments are present is
implementation-defined, as far as POSIX.2 is concerned, but I prefer
symbolic output by default, so my script does that.

Some versions of sh don't understand that "[-+=])" as a case label
means to test for -, but rather try to do something stupid with the -
(probably ranges), so I also changed that.

Dave
----------------

# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Dave Decot <decot at hpisod2> on Fri Feb  2 16:21:42 1990
#
# This archive contains:
#	mask	
#

unset LANG

echo x - mask
cat >mask <<'@EOF'
#!/bin/sh
# @(#)mask 1.0 90/02/02 Maarten Litmaath
# @(#)mask 1.1 90/02/03 Dave Decot
# mask g-wx,o=
# mask -s

USAGE="
name=`basename $0`
echo 'Usage: '\$name' mode' >&2
echo '   or: '\$name' [-s|-o]' >&2
echo 'mode: a symbolic string like \`g-wx,o='\\' >&2
echo '  or: the equivalent octal number' >&2
echo 'see chmod(1)' >&2
exit 1
"

case $# in
 0) arg="-s" ;;
 1) arg="$1" ;;
 *) eval "$USAGE" ;;
esac

modes_7=___
modes_6=__x
modes_5=_w_
modes_4=_wx
modes_3=r__
modes_2=r_x
modes_1=rw_
modes_0=rwx

expr x"$arg" : 'x.*[^0-9]' > /dev/null || {
	echo umask "$arg"
	exit 0
}

case "$arg" in
-s)	 style=symbolic ;;
-o)      style=octal ;;
-[rwx]*|x-*) ;;
-*)	  eval "$USAGE" ;;
x*)	  ;;
esac

set `umask \
  |  sed -e 's/^0*//' -e 's/^$/0/' -e 's/^.$/0&/' -e 's/^..$/0&/' -e 's/./& /g'`

output=`eval echo "u="'$'"modes_$1,g="'$'"modes_$2,o="'$'"modes_$3"`

case $style in
    symbolic) eval echo echo "$output" | tr -d _
	      exit 0 ;;
    octal)    echo umask
	      exit 0 ;;
esac

set -- `echo $output | sed -e "s/./& /g" -e "s/[=,ugo]//g"`

for i in u g o
do
    for j in r w x
    do
	eval ${i}_${j}=$1
	shift
    done
done

set -- "$arg"

set `
	echo x"$1" | sed -e 's/.//' -e 's/^[-+=]/a&/' \
		-e 's/,\\([-+=]\\)/,a\\1/g' \
		-e 's/[-=],/-rwx,/g' -e 's/[-=]$/-rwx/' \
		-e 's/+,/+rwx,/g' -e 's/+$/+rwx/' -e 's/./& /g' -e 's/$/,/'
`

groups=
perms=

for i
do
	case $i in
	[ugo])
		groups="$groups $i"
		;;
	a)
		groups="u g o"
		;;
	-)
		op=$i
		;;
	[+=])
		op=$i
		;;
	[rwx])
		perms="$perms $i"
		;;
	,)
		for group in $groups
		do
			case $op in
			=)
				eval ${group}_r=_
				eval ${group}_w=_
				eval ${group}_x=_
			esac
			for perm in $perms
			do
				case $op in
				-)
					bit=_
					;;
				*)
					bit=$perm
					;;
				esac
				eval ${group}_$perm=$bit
			done
		done
		groups=
		perms=
		;;
	*)
		eval "$USAGE"
	esac
done

___=7
__x=6
_w_=5
_wx=4
r__=3
r_x=2
rw_=1
rwx=0

eval echo umask 0\${$u_r$u_w$u_x}\${$g_r$g_w$g_x}\${$o_r$o_w$o_x}
@EOF

chmod 755 mask

exit 0



More information about the Comp.unix.questions mailing list