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