. "$BST_LIB" require uuencode sharutils/present # GNU sharutils 4.15.2 -- shar/unshar/uuencode/uudecode. # # Calibrated against a native x86_64 GNU sharutils 4.15.2 (Debian 1:4.15.2-4build1, # the same upstream release), so every red below is a target-only divergence rather # than an assertion written wrong. Two things drive the layout: # # * uuencode/uudecode are FULLY WORKING here and are pinned byte-exact -- an # encoder that corrupts its payload is worse than no encoder, so the # round-trip cases come first and use a payload carrying all 256 byte values. # * shar's DEFAULT mode and unshar are RED, both for one reason: popen(3) is # ENOSYS on wasm32-hwjs (brintos/linux#14). shar popens # "LC_ALL=C wc -c" for its character-count line and dies exit 4 leaving a # TRUNCATED archive; unshar popens the shell it feeds the archive to. The # reds are left FAILING on purpose so they flip green by themselves when the # platform fix lands. # # What keeps those reds honest is that shar itself is proven good on the same # image: --no-character-count and -V take no popen path and round-trip text, # binary and a DIRECTORY TREE byte-exact. So the port works; only the popen leg # is missing. # # Trap avoided: the mode in a uuencode header is umask-derived (664 native under # umask 002, 644 here under root's 022), so NO case asserts a default mode -- # only modes this file chmods explicitly. t=${TMPDIR:-/tmp}/bst-sharutils.$$ rm -rf "$t"; mkdir -p "$t" || { bst_notok sharutils/scratch "cannot mkdir $t"; return 2>/dev/null || exit 0; } cd "$t" || { bst_notok sharutils/scratch "cannot cd $t"; return 2>/dev/null || exit 0; } printf 'hello sharutils\nsecond line\n' > text.txt # every one of the 256 byte values -- the payload a uuencoder must survive i=0; : > bin.bin while [ "$i" -lt 256 ]; do printf "\\$(printf '%03o' "$i")" >> bin.bin; i=$((i+1)); done printf 'different\n' > other.txt mkdir -p tree/sub; printf 'alpha\n' > tree/a.txt; printf 'beta\n' > tree/sub/b.txt # ---- the comparison itself must be able to fail ------------------------------- # Without this, a cmp that answered 0 to everything would sweep every byte-exact # case below silently green. check_eq sharutils/control-payload-256 256 "$(wc -c < bin.bin | tr -d ' ')" check_rc sharutils/control-cmp-differs 1 cmp -s text.txt other.txt # ---- presence ------------------------------------------------------------------ check_out sharutils/uuencode-version "(GNU sharutils) 4.15.2" uuencode --version check_out sharutils/uudecode-version "(GNU sharutils) 4.15.2" uudecode --version check_out sharutils/shar-version "(GNU sharutils) 4.15.2" shar --version check_out sharutils/unshar-version "(GNU sharutils) 4.15.2" unshar --version # ---- uuencode/uudecode: byte-exactness first ----------------------------------- uuencode text.txt remote.txt < text.txt > enc.uu 2>/dev/null check_out sharutils/uuencode-header "begin " head -1 enc.uu check_out sharutils/uuencode-footer "end" tail -1 enc.uu uudecode -o dec.txt < enc.uu 2>/dev/null check sharutils/uu-roundtrip-text cmp -s text.txt dec.txt uuencode bin.bin rbin.bin < bin.bin > encb.uu 2>/dev/null uudecode -o decb.bin < encb.uu 2>/dev/null check sharutils/uu-roundtrip-binary cmp -s bin.bin decb.bin check_eq sharutils/uu-binary-size 256 "$(wc -c < decb.bin 2>/dev/null | tr -d ' ')" # base64 (-m) is the other encoding, and must be byte-exact for both payloads uuencode -m text.txt b64.txt < text.txt > encm.uu 2>/dev/null check_out sharutils/base64-header "begin-base64 " head -1 encm.uu uudecode -o decm.txt < encm.uu 2>/dev/null check sharutils/base64-roundtrip-text cmp -s text.txt decm.txt uuencode -m bin.bin rb64.bin < bin.bin > encmb.uu 2>/dev/null uudecode -o decmb.bin < encmb.uu 2>/dev/null check sharutils/base64-roundtrip-binary cmp -s bin.bin decmb.bin # mode bits ride in the header -- asserted only for modes set explicitly above cp text.txt m600.txt; chmod 600 m600.txt uuencode m600.txt m600.txt < m600.txt > enc600.uu 2>/dev/null check_out sharutils/mode-600 "begin 600 m600.txt" head -1 enc600.uu chmod 755 m600.txt uuencode m600.txt m755.txt < m600.txt > enc755.uu 2>/dev/null check_out sharutils/mode-755 "begin 755 m755.txt" head -1 enc755.uu # with no -o, uudecode writes the name carried in the header rm -f remote.txt uudecode < enc.uu 2>/dev/null check sharutils/uudecode-header-name cmp -s text.txt remote.txt # garbage in -> diagnosed, not silently accepted printf 'not a uuencoded file\n' > bad.uu check_rc sharutils/uudecode-rejects-garbage 2 sh -c 'uudecode -o /dev/null < bad.uu' # ---- shar: the paths that take no popen ---------------------------------------- # These are the proof that the PORT is sound; the popen reds below are the platform. shar --no-character-count text.txt > w1.shar 2>/dev/null check_out sharutils/shar-nocc-shebang "#!/bin/sh" head -1 w1.shar mkdir -p x1; (cd x1 && sh ../w1.shar) >/dev/null 2>&1 check sharutils/shar-nocc-roundtrip cmp -s text.txt x1/text.txt # -B forces uuencode for every file: the archive must actually carry uudecode, # and a 256-byte-value payload must survive the shell-script round trip. shar --no-character-count -B bin.bin > w2.shar 2>/dev/null check_out sharutils/shar-B-uses-uudecode "uudecode" grep uudecode w2.shar mkdir -p x2; (cd x2 && sh ../w2.shar) >/dev/null 2>&1 check sharutils/shar-B-roundtrip-binary cmp -s bin.bin x2/bin.bin # DIRECTORY RECURSION -- walktree(), which this port heap-allocates rather than # alloca'ing (0001-walktree-heap-name-not-alloca.patch, class hwjs-cc#15). If # that patch ever regresses, shar does not link at all; if the rewrite were # wrong, these two are what catch it. shar --no-character-count tree > w3.shar 2>/dev/null mkdir -p x3; (cd x3 && sh ../w3.shar) >/dev/null 2>&1 check sharutils/shar-tree-toplevel cmp -s tree/a.txt x3/tree/a.txt check sharutils/shar-tree-nested cmp -s tree/sub/b.txt x3/tree/sub/b.txt # the trailing-slash form is the other walktree entry (it strips the crumb) shar --no-character-count tree/ > w4.shar 2>/dev/null check_out sharutils/shar-tree-trailing-slash "tree/sub/b.txt" grep -o "tree/sub/b.txt" w4.shar # -V (vanilla) is the other popen-free mode shar -V text.txt > v1.shar 2>/dev/null mkdir -p y1; (cd y1 && sh ../v1.shar) >/dev/null 2>&1 check sharutils/shar-vanilla-roundtrip cmp -s text.txt y1/text.txt # ---- shar: header/output contracts a caller depends on ------------------------- # -o writes PREFIX.nn, NOT the bare name -- measured, not assumed. shar --no-character-count -o out.shar text.txt >/dev/null 2>&1 check sharutils/shar-output-prefix test -f out.shar.01 shar --no-character-count -n MYARCH -a -o na.shar text.txt >/dev/null 2>&1 check_out sharutils/shar-archive-name "Archive-name: MYARCH" grep -h Archive-name na.shar.01 # shar reports a missing input on stderr but still EXITS 0 -- a caller reading # only the status gets this wrong, so both halves are pinned. check_rc sharutils/shar-missing-rc 0 sh -c 'shar --no-character-count /no/such/file >/dev/null 2>&1' check_out sharutils/shar-missing-msg "No such file" sh -c 'shar --no-character-count /no/such/file 2>&1 >/dev/null' # unshar, by contrast, does signal via status check_rc sharutils/unshar-missing-rc 66 sh -c 'unshar /no/such/file >/dev/null 2>&1' # ---- RED: popen(3) is ENOSYS on wasm32-hwjs ------------------------------------ # brintos/linux#14. Left FAILING on purpose (not skipped) so they # flip green by themselves when the platform fix lands. Each asserts the value a # WORKING platform gives, so there is nothing to rewrite at that point. # # shar (default) popen("LC_ALL=C wc -c < FILE", "r") -> NULL # -> "shar fatal error: Could not popen command", exit 4, # and the archive on stdout is left truncated. # shar -C popen(compressor, "r") -> same # unshar popen(shell, "w") -> "fserr 38 # (Function not implemented) performing 'popen' on sh" check_rc sharutils/shar-default-mode 0 sh -c 'shar text.txt > d.shar 2>/dev/null' check_out sharutils/shar-character-count "wc -c" grep "wc -c" d.shar check_rc sharutils/shar-compact-gzip 0 sh -c 'shar -C gzip text.txt > cz.shar 2>/dev/null' check_rc sharutils/shar-compact-xz 0 sh -c 'shar -C xz text.txt > cx.shar 2>/dev/null' check_rc sharutils/shar-compact-bzip2 0 sh -c 'shar -C bzip2 text.txt > cb.shar 2>/dev/null' mkdir -p u1 check_rc sharutils/unshar-extract 0 sh -c 'unshar -d u1 w1.shar >/dev/null 2>&1' check sharutils/unshar-roundtrip cmp -s text.txt u1/text.txt cd /; rm -rf "$t"