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