xref: /illumos-gate/usr/src/test/util-tests/tests/cpio/cpio_test.ksh (revision e00bdde3c6d406f40f53f3025defadc22f7ec31a)
1#!/usr/bin/ksh
2#
3# This file and its contents are supplied under the terms of the
4# Common Development and Distribution License ("CDDL"), version 1.0.
5# You may only use this file in accordance with the terms of version
6# 1.0 of the CDDL.
7#
8# A full copy of the text of the CDDL should have accompanied this
9# source.  A copy of the CDDL is also available via the Internet at
10# http://www.illumos.org/license/CDDL.
11#
12
13#
14# Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
15#
16
17set -e
18set -o pipefail
19export LC_ALL=C
20
21CPIO=${CPIO:-/usr/bin/cpio}
22SRCDIR=$(dirname $0)
23FILES=$SRCDIR/files
24
25typeset -i failures=0
26
27function errexit {
28	echo "$@" >&2
29	exit 1
30}
31
32function fail {
33	echo "FAIL: $@" >&2
34	((failures++))
35	true
36}
37
38function pass {
39	echo "PASS: $@"
40}
41
42function find_cmd {
43	typeset cmd="$1"
44	typeset var=$(echo $cmd | tr '[:lower:]' '[:upper:]')
45	typeset -n path="$var"
46	path=$(whence -fp "$cmd")
47	if (($? != 0)) || [ ! -x "$path" ]; then
48		errexit "Cannot find executable '$cmd' in PATH"
49	fi
50}
51
52TAR=/usr/bin/tar
53# This script uses a few commands which are not part of illumos and are
54# expected to be available in the path.
55find_cmd gtar
56find_cmd stat
57
58# Test cpio's handling of device nodes across different formats.
59# To do this, we need a device file to include in the archive.
60
61typeset -i maj
62typeset -i min
63
64# To allow this test to run without root privileges, and in a non-global zone,
65# we look for a suitable device for each one. Such a device must not have a
66# zero minor number and both major and minor must be small enough to fit within
67# the old SVR3 types, so we restrict both to 0x7f.
68if [[ $(zonename) == global ]]; then
69	DEVPATH=/devices/pseudo
70else
71	DEVPATH=/dev
72fi
73DEVICE=
74for device in $DEVPATH/*; do
75	[[ -c "$device" ]] || continue
76	set -- $($STAT -c '%Hr %Lr' $device)
77	maj=$1; min=$2
78	((maj == 0 || min == 0)) && continue
79	((maj > 0x7f || min > 0x7f)) && continue
80	DEVICE="$device"
81	break
82done
83[[ -z $DEVICE ]] && errexit "No suitable device node found for test"
84
85typeset expect_cpio=$(printf "%d,%3d" $maj $min)
86typeset expect_gtar=$(printf "%d,%d" $maj $min)
87
88echo "Using device $DEVICE (major=$maj/minor=$min) as test subject"
89
90stderr=$(mktemp)
91[ -f "$stderr" ] || errexit "Could not create temporary file"
92trap 'rm -f $stderr' EXIT
93function reset_err
94{
95	:>$stderr
96	exec 4>$stderr
97}
98
99# Create archives using tar and check that cpio can extract them.
100
101reset_err
102if { $TAR cf - $FILES 2>&4 | $CPIO -qH ustar -it 2>&4; } >/dev/null; then
103	pass "tar->cpio(files)"
104else
105	fail "tar->cpio(files) $@ [$(<$stderr)]"
106fi
107
108# Check that the major/minor of the device node are correctly transferred
109set -- $($TAR cf - $DEVICE 2>&4 | $CPIO -qH ustar -ivt 2>&4)
110if echo "$@" | egrep -s "$expect_cpio"; then
111	pass "tar->cpio()"
112else
113	fail "tar->cpio() $@ [$(<$stderr)]"
114fi
115
116# Create archives using GNU tar and check that cpio correctly extracts the
117# device nodes.
118
119for f in posix ustar; do
120	reset_err
121	if { $GTAR --format=$f -cf - $FILES 2>&4 | \
122	    $CPIO -qH ustar -it 2>&4; } >/dev/null; then
123		pass "gtar->cpio(files:$f)"
124	else
125		fail "gtar->cpio(files:$f) $@ [$(<$stderr)]"
126	fi
127
128	# Check that the major/minor of the device node are correctly
129	# transferred
130	reset_err
131	set -- $($GTAR --format=$f -cf - $DEVICE 2>&4 | \
132	    $CPIO -qH ustar -ivt 2>&4 | grep ${DEVICE#/})
133	if echo "$@" | egrep -s "$expect_cpio"; then
134		pass "gtar->cpio($f)"
135	else
136		fail "gtar->cpio($f) $@ [$(<$stderr)]"
137	fi
138done
139
140# Now the inverse, create the archives using cpio and confirm that GNU tar
141# can extract them.
142
143for f in tar ustar; do
144	reset_err
145	if { find $FILES | $CPIO -qH $f -o 2>&4 | \
146	    $GTAR tvf - 2>&4; } >/dev/null; then
147		pass "cpio->gtar(files:$f)"
148	else
149		fail "cpio->gtar(files:$f) $@ [$(<$stderr)]"
150	fi
151
152	# Check that the major/minor of the device node are correctly
153	# transferred.
154	reset_err
155	set -- $(echo $DEVICE | $CPIO -qH $f -o 2>&4 | $GTAR tvf - 2>&4)
156	if echo "$@" | egrep -s "$expect_gtar"; then
157		pass "cpio->gtar($f)"
158	else
159		fail "cpio->gtar($f) $@ [$(<$stderr)]"
160	fi
161done
162
163# Test extracting cpio-generated archives with cpio.
164
165for f in crc odc odc_sparse ascii_sparse ustar; do
166	reset_err
167	if { find $FILES | $CPIO -qH $f -o 2>&4 | \
168	    $CPIO -qH $f -ivt 2>&4; } >/dev/null; then
169		pass "cpio->cpio(files:$f)"
170	else
171		fail "cpio->cpio(files:$f) $@ [$(<$stderr)]"
172	fi
173
174	# Check that the major/minor of the device node are correctly
175	# transferred
176	reset_err
177	set -- $(echo $DEVICE | $CPIO -qH $f -o 2>&4 | \
178	    $CPIO -qH $f -ivt 2>&4 | grep ${DEVICE#/})
179	if echo "$@" | egrep -s "$expect_cpio"; then
180		pass "cpio->cpio($f)"
181	else
182		fail "cpio->cpio($f) $@ [$(<$stderr)]"
183	fi
184done
185
186# And a cpio archive with no format specified.
187
188reset_err
189if { find $FILES | $CPIO -qo 2>&4 | $CPIO -qivt 2>&4; } >/dev/null; then
190	pass "cpio->cpio(files:native)"
191else
192	fail "cpio->cpio(files:native) $@ [$(<$stderr)]"
193fi
194
195reset_err
196set -- $(echo $DEVICE | $CPIO -qo 2>&4 | $CPIO -qivt 2>&4 | grep ${DEVICE#/})
197if echo "$@" | egrep -s "$expect_cpio"; then
198	pass "cpio->cpio(native)"
199else
200	fail "cpio->cpio(native) $@ [$(<$stderr)]"
201fi
202
203# Test extracting cpio samples created on FreeBSD.
204# These all have maj/min 13/17 in them.
205
206expect_cpio=$(printf "%d,%3d" 13 17)
207for f in $FILES/freebsd.*.cpio; do
208	reset_err
209	format=${f%.*}
210	format=${format##*.}
211	[[ $format == pax || $format == ustar ]] && flags="-H ustar" || flags=
212	set -- $($CPIO -q $flags -ivt < $f 2>&4 | grep node | grep -v Pax)
213	if echo "$@" | egrep -s "$expect_cpio"; then
214		pass "freebsd->cpio($format)"
215	else
216		fail "freebsd->cpio($format) $@ [$(<$stderr)]"
217	fi
218done
219
220# This is a 'bar' file created on a SunOS 4.x system. It contains a
221# /dev/zero device node with major/minor 3/12
222
223reset_err
224expect_cpio=$(printf "%d,%3d" 3 12)
225
226set -- $($CPIO -qH bar -ivt < $FILES/zero.bar 2>&4 | grep test/zero | head -1)
227if echo "$@" | egrep -s "$expect_cpio"; then
228	pass "sunos->cpio(bar)"
229else
230	fail "sunos->cpio(bar) $@ [$(<$stderr)]"
231fi
232
233exit $FAILURES
234
235