# libarchive -- the multi-format surface, which is the whole reason the ticket # asks for this package. Every other archiver on this image speaks exactly one # format: GNU tar writes tar, zip writes zip, mksquashfs writes squashfs. One # library that reads and writes tar, cpio, zip, iso9660 and mtree behind a # single entry point is what unblocks the recipes waiting on it (cmake among # them), and a format it merely *links support for* is worth nothing until an # archive in that format has been written and read back on this target. # # NEITHER bsd tool owns its PATH name on this image. The recipe declares # ALTERNATIVE_PRIORITY 80 for both, and GNU tar (100) and GNU cpio (100) each # keep their link: /bin/tar is GNU tar and /bin/cpio is GNU cpio, with the # busybox applets at 50 last in both cases. bsdcpio held /bin/cpio only for as # long as busybox was its only rival. Everything below therefore invokes bsdcpio # by its own name, and the one check that resolves through PATH asserts the # GNU winner -- it goes red if the priorities are ever reordered. # # ISO9660 IS ASSERTED IN BOTH DIRECTIONS ON PURPOSE. It is the one format named # in the ticket that no other tool on this image can produce, and libarchive's # iso9660 writer and reader are separate implementations of the same standard -- # so writing an image and reading its directory record back is a real test of # both, not a tautology the way a single-codec round-trip can be. . "$BST_LIB" require bsdcpio libarchive/bsdcpio-present require bsdtar libarchive/bsdtar-present T=${TMPDIR:-/tmp}/bst-libarchive-f.$$ rm -rf "$T"; mkdir -p "$T/src/sub" "$T/out" has() { case "$3" in *"$2"*) bst_ok "$1" ;; *) bst_notok "$1" "want '$2' in: $(_bst_1line "$3")" ;; esac; } printf 'libarchive fixture\n' > "$T/src/top.txt" printf 'nested payload\n' > "$T/src/sub/nested.txt" V=$(bsdcpio --version 2>&1) has libarchive/cpio-version "bsdcpio 3.7.9" "$V" # Resolving through the PATH name (not the bsdcpio name) is the point: it asserts # which binary a caller typing `cpio` actually gets. GNU cpio at 100 outranks # bsdcpio at 80, so bsdcpio must be reached by its own name -- as it is below. if command -v cpio > /dev/null 2>&1; then has libarchive/cpio-path-is-gnu "GNU cpio" "$(cpio --version 2>&1)" else bst_notok libarchive/cpio-path-is-gnu "no cpio on PATH at all, though bsdcpio is installed" fi # ------------------------------------------------------------ bsdcpio round-trip # cpio takes its member list on stdin, so this is the one place a subshell is # cheaper than the alternative (rewriting absolute paths after extraction). ( cd "$T/src" && find . -print | bsdcpio -o > "$T/a.cpio" ) 2> /dev/null if [ -s "$T/a.cpio" ]; then bst_ok libarchive/cpio-create else bst_notok libarchive/cpio-create "bsdcpio -o produced no archive"; fi CLIST=$(bsdcpio -i -t < "$T/a.cpio" 2>&1) has libarchive/cpio-list-file "top.txt" "$CLIST" has libarchive/cpio-list-nested "sub/nested.txt" "$CLIST" ( cd "$T/out" && bsdcpio -i -d < "$T/a.cpio" ) > /dev/null 2>&1 check_eq libarchive/cpio-extract "libarchive fixture" "$(cat "$T/out/top.txt" 2>/dev/null)" check_eq libarchive/cpio-nested "nested payload" "$(cat "$T/out/sub/nested.txt" 2>/dev/null)" # ---------------------------------------------------- the write-format matrix # fmt <--format value> # write the same tree in that format, then read its table of contents back. # A format libarchive cannot write fails at create; one it can write but not # read fails at list -- the two are separate implementations and the two cases # keep them distinguishable. fmt() { _id=$1; _f=$2; _needle=$3; _a=$T/f.$_id if bsdtar -C "$T/src" --format="$_f" -cf "$_a" . 2> /dev/null && [ -s "$_a" ]; then bst_ok "libarchive/fmt-$_id-write" else bst_notok "libarchive/fmt-$_id-write" "bsdtar --format=$_f wrote nothing" fi has "libarchive/fmt-$_id-read" "$_needle" "$(bsdtar -tf "$_a" 2>&1)" } fmt pax pax top.txt fmt ustar ustar top.txt fmt gnutar gnutar top.txt fmt cpio cpio top.txt fmt zip zip top.txt fmt mtree mtree top.txt fmt iso9660 iso9660 top.txt # The iso9660 image must carry the standard's own identifier at the fixed # offset a real ISO reader looks for, or "wrote an iso" meant only "wrote a # file". dd + a case beats forking strings/od. ISOID=$(dd if="$T/f.iso9660" bs=1 skip=32769 count=5 2> /dev/null) check_eq libarchive/iso9660-magic "CD001" "$ISOID" # Content, not just the name in the listing: an iso9660 reader that recovered # the directory record but not the extent would pass fmt-iso9660-read alone. mkdir -p "$T/isoout" check libarchive/iso9660-extract bsdtar -C "$T/isoout" -xf "$T/f.iso9660" check_eq libarchive/iso9660-content "libarchive fixture" "$(cat "$T/isoout/top.txt" 2>/dev/null)" # ------------------------------- the zip we wrote, read by a DIFFERENT unzip # Info-ZIP unzip already ships here (92-unzip.test), so the zip writer can be # checked against an implementation that shares no code with it. if command -v unzip > /dev/null 2>&1; then has libarchive/zip-foreign-list "top.txt" "$(unzip -l "$T/f.zip" 2>&1)" mkdir -p "$T/zipout" unzip -o -q -d "$T/zipout" "$T/f.zip" > /dev/null 2>&1 check_eq libarchive/zip-foreign-content "libarchive fixture" "$(cat "$T/zipout/top.txt" 2>/dev/null)" else bst_skip libarchive/zip-foreign-list "Info-ZIP unzip is not on this image" fi # ------------------------------------------------------- the smaller two CLIs # bsdcat and bsdunzip ship in the main libarchive package rather than in their # own, so they are soft-guarded: absent means the package split moved, which is # worth a skip that names it rather than a require that ends the file. if command -v bsdcat > /dev/null 2>&1; then bsdtar -C "$T/src" -czf "$T/one.tar.gz" . 2> /dev/null # bsdcat decompresses a stream without interpreting the archive inside it, so # the tar header's own magic is what comes back out. has libarchive/bsdcat-decompress "ustar" "$(bsdcat "$T/one.tar.gz" 2>&1)" else bst_skip libarchive/bsdcat-decompress "bsdcat is not installed" fi if command -v bsdunzip > /dev/null 2>&1; then mkdir -p "$T/bzout" bsdunzip -o -d "$T/bzout" "$T/f.zip" > /dev/null 2>&1 check_eq libarchive/bsdunzip-extract "libarchive fixture" "$(cat "$T/bzout/top.txt" 2>/dev/null)" else bst_skip libarchive/bsdunzip-extract "bsdunzip is not installed" fi # ------------------------------------------------------------------- control # Non-zero bytes, deliberately -- see the note in 98-libarchive.test: a run of # zeroes is a valid empty archive to these readers, so a zeroes-based control # asserts the opposite of what it looks like it asserts. i=0 while [ $i -lt 128 ]; do printf 'NOT-A-CPIO-ARCHIVE-%d-qwertyuiopasdfghjkl\n' "$i" i=$((i + 1)) done > "$T/junk" if bsdcpio -i -t < "$T/junk" > /dev/null 2>&1; then bst_notok libarchive/cpio-reject-junk "bsdcpio listed non-archive text as a cpio archive" else bst_ok libarchive/cpio-reject-junk fi rm -rf "$T"