1# $FreeBSD$
2
3ntest=1
4
5confdir=${dir:-$(dirname "$0")}
6maindir=${dir:-$(dirname "$0")}
7while [ ! -r "$confdir/conf" -a "$confdir" != / ]; do
8	confdir=$(cd $confdir/..; pwd)
9done
10while [ "$maindir" != / ]; do
11	if [ -f "$maindir/pjdfstest" -a -x "$maindir/pjdfstest" ]; then
12		break
13	fi
14	maindir=$(cd $maindir/../; pwd)
15done
16fstest="${maindir}/pjdfstest"
17if ! . ${confdir}/conf; then
18	echo "not ok - could not source configuration file"
19	exit 1
20fi
21if [ ! -x $fstest ]; then
22	echo "not ok - could not find pjdfstest app"
23	exit 1
24fi
25
26requires_root()
27{
28	case "$(id -u)" in
29	0)
30		return 0
31		;;
32	*)
33		echo "not ok ${ntest} not root"
34		return 1
35		;;
36	esac
37}
38
39expect()
40{
41	e="${1}"
42	shift
43	r=`${fstest} $* 2>/dev/null | tail -1`
44	echo "${r}" | ${GREP} -Eq '^'${e}'$'
45	if [ $? -eq 0 ]; then
46		if [ -z "${todomsg}" ]; then
47			echo "ok ${ntest}"
48		else
49			echo "ok ${ntest} # TODO ${todomsg}"
50		fi
51	else
52		if [ -z "${todomsg}" ]; then
53			echo "not ok ${ntest} - tried '$*', expected ${e}, got ${r}"
54		else
55			echo "not ok ${ntest} # TODO ${todomsg}"
56		fi
57	fi
58	todomsg=""
59	ntest=$((ntest+1))
60}
61
62jexpect()
63{
64	s="${1}"
65	d="${2}"
66	e="${3}"
67
68	shift 3
69	r=`jail -s ${s} / pjdfstest 127.0.0.1 /bin/sh -c "cd ${d} && ${fstest} $* 2>/dev/null" 2>/dev/null | tail -1`
70	echo "${r}" | ${GREP} -Eq '^'${e}'$'
71	if [ $? -eq 0 ]; then
72		if [ -z "${todomsg}" ]; then
73			echo "ok ${ntest}"
74		else
75			echo "ok ${ntest} # TODO ${todomsg}"
76		fi
77	else
78		if [ -z "${todomsg}" ]; then
79			echo "not ok ${ntest} - tried '$*', expected ${e}, got ${r}"
80		else
81			echo "not ok ${ntest} # TODO ${todomsg}"
82		fi
83	fi
84	todomsg=""
85	ntest=$((ntest+1))
86}
87
88test_check()
89{
90	if [ $* ]; then
91		if [ -z "${todomsg}" ]; then
92			echo "ok ${ntest}"
93		else
94			echo "ok ${ntest} # TODO ${todomsg}"
95		fi
96	else
97		if [ -z "${todomsg}" ]; then
98			echo "not ok ${ntest}"
99		else
100			echo "not ok ${ntest} # TODO ${todomsg}"
101		fi
102	fi
103	todomsg=""
104	ntest=$((ntest+1))
105}
106
107todo()
108{
109	if [ "${os}" = "${1}" -o "${os}:${fs}" = "${1}" ]; then
110		todomsg="${2}"
111	fi
112}
113
114namegen()
115{
116	echo "pjdfstest_`dd if=/dev/urandom bs=1k count=1 2>/dev/null | openssl md5 | awk '{print $NF}'`"
117}
118
119namegen_len()
120{
121	len="${1}"
122
123	name=""
124	while :; do
125		namepart="`dd if=/dev/urandom bs=64 count=1 2>/dev/null | openssl md5 | awk '{print $NF}'`"
126		name="${name}${namepart}"
127		curlen=`printf "%s" "${name}" | wc -c`
128		[ ${curlen} -lt ${len} ] || break
129	done
130	name=`echo "${name}" | cut -b -${len}`
131	printf "%s" "${name}"
132}
133
134# POSIX:
135# {NAME_MAX}
136#     Maximum number of bytes in a filename (not including terminating null).
137namegen_max()
138{
139	name_max=`${fstest} pathconf . _PC_NAME_MAX`
140	namegen_len ${name_max}
141}
142
143# POSIX:
144# {PATH_MAX}
145#     Maximum number of bytes in a pathname, including the terminating null character.
146dirgen_max()
147{
148	name_max=`${fstest} pathconf . _PC_NAME_MAX`
149	complen=$((name_max/2))
150	path_max=`${fstest} pathconf . _PC_PATH_MAX`
151	# "...including the terminating null character."
152	path_max=$((path_max-1))
153
154	name=""
155	while :; do
156		name="${name}`namegen_len ${complen}`/"
157		curlen=`printf "%s" "${name}" | wc -c`
158		[ ${curlen} -lt ${path_max} ] || break
159	done
160	name=`echo "${name}" | cut -b -${path_max}`
161	name=`echo "${name}" | sed -E 's@/$@x@'`
162	printf "%s" "${name}"
163}
164
165quick_exit()
166{
167	echo "1..1"
168	echo "ok 1"
169	exit 0
170}
171
172supported()
173{
174	case "${1}" in
175	lchmod)
176		if [ "${os}" != "FreeBSD" ]; then
177			return 1
178		fi
179		;;
180	chflags)
181		if [ "${os}" != "FreeBSD" ]; then
182			return 1
183		fi
184		;;
185	chflags_SF_SNAPSHOT)
186		if [ "${os}" != "FreeBSD" -o "${fs}" != "UFS" ]; then
187			return 1
188		fi
189		;;
190	posix_fallocate)
191		if [ "${os}" != "FreeBSD" ]; then
192			return 1
193		fi
194		;;
195	stat_st_birthtime)
196		case "${os}" in
197		Darwin|FreeBSD)
198			;;
199		*)
200			return 1
201			;;
202		esac
203		;;
204	utimensat)
205		case ${os} in
206		Darwin)
207			return 1
208			;;
209		esac
210		;;
211	esac
212	return 0
213}
214
215require()
216{
217	if supported ${1}; then
218		return
219	fi
220	quick_exit
221}
222
223if [ "${os}" = "FreeBSD" ]; then
224mountpoint()
225{
226	df $1 | tail -1 | awk '{ print $6 }'
227}
228
229mount_options()
230{
231	mount -p | awk '$2 == "'$(mountpoint .)'" { print $4 }' | sed -e 's/,/ /g'
232}
233
234nfsv4acls()
235{
236	if mount_options | grep -q nfsv4acls; then
237		return 0
238	fi
239	return 1
240}
241
242noexec()
243{
244	if mount_options | grep -q noexec; then
245		return 0
246	fi
247	return 1
248}
249
250nosuid()
251{
252	if mount_options | grep -q nosuid; then
253		return 0
254	fi
255	return 1
256}
257else
258mountpoint()
259{
260	return 1
261}
262mount_options()
263{
264	return 1
265}
266nfsv4acls()
267{
268	return 1
269}
270noexec()
271{
272	return 1
273}
274nosuid()
275{
276	return 1
277}
278fi
279
280# usage:
281#	create_file <type> <name>
282#	create_file <type> <name> <mode>
283#	create_file <type> <name> <uid> <gid>
284#	create_file <type> <name> <mode> <uid> <gid>
285create_file() {
286	type="${1}"
287	name="${2}"
288
289	case "${type}" in
290	none)
291		return
292		;;
293	regular)
294		expect 0 create ${name} 0644
295		;;
296	dir)
297		expect 0 mkdir ${name} 0755
298		;;
299	fifo)
300		expect 0 mkfifo ${name} 0644
301		;;
302	block)
303		expect 0 mknod ${name} b 0644 1 2
304		;;
305	char)
306		expect 0 mknod ${name} c 0644 1 2
307		;;
308	socket)
309		expect 0 bind ${name}
310		;;
311	symlink)
312		expect 0 symlink test ${name}
313		;;
314	esac
315	if [ -n "${3}" -a -n "${4}" -a -n "${5}" ]; then
316		if [ "${type}" = symlink ]; then
317			expect 0 lchmod ${name} ${3}
318		else
319			expect 0 chmod ${name} ${3}
320		fi
321		expect 0 lchown ${name} ${4} ${5}
322	elif [ -n "${3}" -a -n "${4}" ]; then
323		expect 0 lchown ${name} ${3} ${4}
324	elif [ -n "${3}" ]; then
325		if [ "${type}" = symlink ]; then
326			expect 0 lchmod ${name} ${3}
327		else
328			expect 0 chmod ${name} ${3}
329		fi
330	fi
331}
332
333# Tests for whether or not a filesystem is mounted with a particular option
334# with -o, e.g. `mount -o noexec`.
335#
336# Parameters:
337# - mount_option - noatime, noexec, etc.
338#
339# Returns:
340# - 0 if mounted with the option.
341# - 1 otherwise.
342has_mount_option()
343{
344	local IFS=,
345	local mount_opt
346
347	local mount_option_search=$1
348
349	# XXX: mountpoint is defined in .../tests/sys/pjdfstest/tests/conf
350	for mount_opt in $(mount -d -p | awk '$2 == "'$mountpoint'" { print $4 }'); do
351		if [ "$mount_opt" = "$mount_option_search" ]; then
352			return 0
353		fi
354	done
355	return 1
356}
357
358# Filesystem must be mounted with -o exec
359requires_exec()
360{
361	if has_mount_option noexec; then
362		echo "1..0 # SKIP filesystem mounted with -o noexec"
363		exit 0
364	fi
365}
366