1. ../common/test-common
2. ../common/real-thing
3
4# This test creates an empty executable file, checks it in with admin, and then
5# verifies that the resulting s-file is also executable.
6g=foo
7s=s.$g
8
9cleanup() {
10    cmd="rm -f ${g} ${s}"
11    echo "${cmd}" >> command.log
12    $cmd
13}
14cleanup
15
16expect_args() {
17    function_name="$1"
18    expected="$2"
19    got="$3"
20
21    detail="expected ${expected} arguments, but got ${got}"
22    if test "${got}" -lt "${expected}"; then
23	miscarry "Too few arguments to ${function_name}: ${detail}"
24    elif test "${got}" -gt "${expected}"; then
25	miscarry "Too many arguments to ${function_name}: ${detail}"
26    fi
27}
28
29setup() {
30    expect_args setup 3 $#
31    #label="$1"
32    #mask="$2"
33    #mode="$3"
34    cleanup
35    umask "${2}"
36    docommand --silent "${1}-setup0" "touch ${g}" IGNORE IGNORE IGNORE || miscarry "failed to create ${g}" &&
37    docommand --silent  "${1}-setup1" "chmod ${3} ${g}" 0 "" ""
38    docommand "${1}"        "${admin} -i${g} -n ${s}" 0 IGNORE IGNORE
39}
40
41
42should_support_execute_bits() {
43    expect_args should_support_execute_bits 0 $#
44    if "${TESTING_CSSC}"; then
45	true
46    else
47	case "`uname -s`" in
48	    SunOS) true;;
49	    *) false;;
50	esac
51    fi
52}
53
54if should_support_execute_bits; then
55    # Not using ! is a workaround for the fact that Solaris /bin/sh doesn't support it.
56    true
57else
58    echo "Your version of SCCS is not expected to support execute permissions; skipping."
59    exit 0
60fi
61
62file_permissions() {
63    expect_args file_permissions 1 $#
64    ls -ld "$1" 2> /dev/null | sed -n -e '1 s/^.\(.........\).*/\1/p'
65}
66
67is_owner_executable() {
68    expect_args is_owner_executable 1 $#
69    case `file_permissions "$1"` in
70	??x*) true;;
71	*) false;;
72    esac
73}
74
75is_group_executable() {
76    expect_args is_group_executable 1 $#
77    case `file_permissions "$1"` in
78	?????x*) true;;
79	*) false;;
80    esac
81}
82
83is_other_executable() {
84    expect_args is_other_executable 1 $#
85    case `file_permissions "$1"` in
86	????????x*) true;;
87	*) false;;
88    esac
89}
90
91execute_perms() {
92    expect_args execute_perms 1 $#
93    result=""
94    if is_owner_executable "$1"; then
95	result="${result}u"
96    fi
97    if is_group_executable "$1"; then
98	result="${result}g"
99    fi
100    if is_other_executable "$1"; then
101	result="${result}o"
102    fi
103    echo "${result}"
104}
105
106selfcheck() {
107    expect_args selfcheck 2 $#
108    chmod_mode="$1"
109    execute_perms_expected="$2"
110    shift 2
111    touch "${g}" || miscarry "self-check: cannot create ${g}"
112    chmod "${chmod_mode}" "${g}" || miscarry "self-check: cannot chmod ${chmod_mode} ${g}"
113    perms="`execute_perms ${g}`"
114    if test "${perms}" != "${execute_perms_expected}"; then
115	fail "self-check: ${g} should be have execute permissions for ${execute_perms_expected} but actually has them for ${perms:-nobody}"
116    fi
117}
118
119
120### Some self-checks
121selfcheck 0160 u
122selfcheck 0616  g
123selfcheck 0441   o
124selfcheck 0170 ug
125selfcheck 0171 ugo
126selfcheck 0071  go
127
128
129(
130    setup x01 0077 0700
131    test -f "${g}" || miscarry "where is ${g}?"
132    if is_owner_executable "$g"; then
133        # Not using ! is a workaround for the fact that Solaris /bin/sh doesn't support it.
134	true
135    else
136        miscarry "Cannot create an executable file"
137    fi
138
139    echo_nonl "${test_script}:x02..."
140    if test "`execute_perms ${s}`" = u; then
141        echo passed
142    else
143        fail "x02: ${s} should be owner-executable"
144    fi
145) || rv=1
146
147(
148    setup x03 0007 0770
149    echo_nonl "${test_script}:x04..."
150    if test "`execute_perms ${s}`" = ug; then
151        echo passed
152    else
153        fail "x04: ${s} should be owner- and group-executable"
154    fi
155) || rv=1
156
157(
158    setup x05 0000 0777
159    echo_nonl "${test_script}:x06..."
160    if test "`execute_perms ${s}`" = ugo; then
161        echo passed
162    else
163        fail "x06: ${s} should be owner-, group- and world-executable"
164    fi
165) || rv=1
166
167
168# The following tests verify that we DO set execute bits on the
169# history file which were not set on the original file (from which the
170# history file was created).  Solaris does this.
171#
172# The result of this is that when get is used on the resulting history
173# file, that file could be world-executable even if the original file
174# (offered via "admin -i") was not.  It might seem logical to avoid
175# following this example (since the execute bits on the original file
176# may have been set that way to avoid world-execute permissions).
177# However, the Principle of Least Astonishment guides us to treat the
178# execute bits in the same way as the read bits are treated (all
179# versions of SCCS create world-readable gotten files if the umask
180# allows it).
181#
182# These tests check the behaviours described above.
183(
184    setup x07 0000 0700
185
186    echo_nonl "${test_script}:x08..."
187    perms="`execute_perms ${s}`"
188    case "${perms}" in
189	ugo) echo passed;;
190	u|ug|ugo) fail "x08: ${s} should be mode 0777 when umask is 0 and the -i file is executable.";;
191	"") fail "x08: execute permissions not copied to history file at all";;
192	*) miscarry "unexpected execute perms ${perms} for file ${s}";;
193    esac || exit 1
194) || rv=1
195
196# On SCO OpenServer and CSSC, the 'x' flag, if set, makes the g-file executable.
197setup x09 0177 0600
198# The gfile exists but is not executable.
199docommand x10 "test -x ${g}" 1 "" ""
200
201if docommand x11 "${admin} -fx ${s}" IGNORE IGNORE IGNORE; then
202    # x-flag is suported. The s-file should still not be executable, since the x flag
203    # controls the mode of the gotten file, not the history file.
204    docommand x12 "test -x ${s}" 1 "" ""
205    docommand x13 "rm -f ${g}" 0 "" ""
206    docommand x14 "${get} ${s}" 0 IGNORE IGNORE
207    # The gotten file should be executable, now (i.e. controlled by the x flag)
208    docommand x15 "test -x ${g}" 0 "" ""
209    # The history file should still not be executable
210    docommand x16 "test -x ${s}" 1 "" ""
211    # Unset the x-flag
212    docommand x17 "${admin} -dx ${s}" IGNORE IGNORE IGNORE
213    # The history file should still not be executable
214    docommand x18 "test -x ${s}" 1 "" ""
215    # Get the file again, verify that it exists but is not executable.
216    docommand x19 "${get} ${s}" 0 IGNORE IGNORE
217    docommand x20 "test -f ${g}" 0 "" ""
218    docommand x21 "test -x ${g}" 1 "" ""
219else
220    # Cannot do the rest of the x-flag tests.
221    echo "Your version of SCCS does not support the 'x' flag; skipping some tests."
222fi
223
224# Verify that we correctly set the executable bits on the history file
225# when there is no argument to -i (and hence we are reading the
226# initial body from stdin).
227cleanup
228umask 077
229docommand x22 "touch ${g}" IGNORE IGNORE IGNORE || miscarry "failed to create ${g}" &&
230docommand x23 "chmod 0500 ${g}" 0 "" ""
231# We present the initial body via stdin.   It's executable.
232docommand x24 "${admin} -i -n ${s} < ${g}" 0 IGNORE IGNORE
233docommand x25 "test -x ${s}" 0 "" ""
234
235
236cleanup
237exit $rv
238