Fix nasty bug in chmod, plus minor fixes.
[pkgusr] / usr / lib / pkgusr / chmod
1 #!/bin/bash
2 # Original...
3 # Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de>
4 # You may do everything with this code except misrepresent its origin.
5 # PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
6
7 # Copyright (C) 2014 Steve Youngs <steve@steveyoungs.com>
8 #  Handle all possible file modes as well as chmod options and symbolic
9 #  modes.
10
11 DAISY_CHAIN=""
12
13 for p in $(type -ap chmod) ; do
14     if [ ! $p -ef $0 ]; then
15         DAISY_CHAIN=$p
16         break
17     fi
18 done
19
20 if [ ! -n "$DAISY_CHAIN" ]; then
21     echo 1>&2 '***' Cannot find real ${0##*/} command 
22     exit 1
23 fi
24
25 if [ $(id -u) -eq 0 ]; then
26     echo 1>&2 '***' $(dirname $0) should not be in root\'s \$PATH
27     echo 1>&2 '***' call '"'$DAISY_CHAIN $@'"' directly.
28     exit 1
29 fi
30
31 # Save the original cmdline as we're gonna mess with it
32 cmdline="$@"
33
34 # Remove any options so $1 becomes the perm arg, however save the
35 # options for later
36 opts=""
37 while [ -n "$1" ]; do
38     case $1 in
39         (-[cfvR]|--[chnpqrsv]*) opts="$opts $1" ; shift ;;
40         (*) break ;;
41     esac
42 done
43
44 # $1 should now be the perm arg
45 perm=$1
46
47 # Octal or symbolic?  Nuke the nasty bits (setuid etc)
48 printf '%o' "0${perm}" &>/dev/null
49 if [ $? -ne 0 ]; then
50     perm=${perm//[st]/}
51 else
52     if [ ${perm} -gt 777 ]; then
53         perm=${perm/?/}
54     fi
55 fi
56
57 # If we changed the perm, report it and fix $@
58 if [ "${perm}" != "$1" ]; then
59     echo 1>&2 '***' chmod ${cmdline}
60     shift
61     set -- $perm "$@"
62 fi
63
64 # Finally, run the chmod
65 $DAISY_CHAIN ${opts} "$@" || exit $?
66 exit 0
67
68 # Local variables:
69 # sh-basic-offset: 4
70 # End: