Files
Matteo Benedetto 090005f6b9 cellar-cli-c: client CLI di Cellar reimplementato in C (statico, retrocompatibile)
Reimplementazione fedele di cellar-cli.py (enne2/cellar @ f5216b1) in C99
POSIX.1-2008, mono-thread, senza dipendenze esterne: miniz e' vendored per
deflate/inflate raw, mentre contenitore gzip, multipart/form-data in streaming,
tar PAX/ustar, JSON e client HTTP/1.1 sono scritti a mano.

- 7 comandi (list, upload, download, install, scan-local, wizard-upload,
  wizard-install) con stdout/stderr/exit code identici al client Python
- 30/30 test di parita' (tests/parity_test.sh) contro due server mock
  indipendenti: output a confronto, alberi installati, interop tar con
  tarfile di Python e con GNU tar, archivio C equivalente a quello Python
- build statiche x86-64 / i686 / aarch64: nessun simbolo GLIBC richiesto,
  nessuna syscall moderna (statx/openat2/memfd_create/getrandom), LFS 64 bit,
  resolver DNS di riserva (hosts + query UDP) per glibc statica senza NSS
- miglioramento rispetto all'originale: upload multipart in streaming invece
  di leggere l'intero archivio in RAM
- divergenze volute documentate nel README (help piu' sintetico, mtime dei
  symlink non ripristinato come tarfile, EOF nei prompt, niente TLS)

Build: make | make 32 | make arm64 | make test | make verify
2026-09-20 17:29:14 +02:00

68 lines
2.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# Verifica i requisiti di portabilita' di un binario compilato:
# - tipo di ELF, architettura, ABI minima del kernel
# - statico o dinamico, librerie richieste
# - versioni di GLIBC richieste (max) come fa scripts/build-binaries.sh di Cellar
# - simboli di syscall "moderne" che romperebbero i kernel vecchi
set -uo pipefail
bin="${1:?uso: verify_binary.sh <binario>}"
[ -x "$bin" ] || { echo "non eseguibile: $bin"; exit 1; }
echo "== binario =="
file -b "$bin"
printf 'dimensione: %s\n' "$(du -h "$bin" | cut -f1)"
printf 'sha256: %s\n' "$(sha256sum "$bin" | cut -d' ' -f1)"
echo
echo "== link =="
ldd_out=$(ldd "$bin" 2>&1)
if grep -qiE "not a dynamic executable|non è un eseguibile dinamico" <<<"$ldd_out"; then
echo "STATICO: nessuna dipendenza a runtime ✔"
else
echo "DINAMICO — librerie:"
sed 's/^/ /' <<<"$ldd_out"
fi
echo
echo "== ABI minima del kernel (ELF note) =="
readelf -n "$bin" 2>/dev/null | grep -iE "ABI|OS:" | sed 's/^ */ /' || echo " (nessuna nota)"
echo
echo "== simboli GLIBC richiesti =="
versions=$(objdump -p "$bin" 2>/dev/null | grep -oE 'GLIBC_[0-9]+\.[0-9]+(\.[0-9]+)?' | sort -Vu)
if [ -z "$versions" ]; then
echo " nessuno (binario statico o solo simboli base)"
else
max=$(tail -1 <<<"$versions")
echo " massimo richiesto: $max"
sed 's/^/ /' <<<"$versions"
case "$max" in
GLIBC_2.1*|GLIBC_2.2|GLIBC_2.3|GLIBC_2.4|GLIBC_2.5|GLIBC_2.6|GLIBC_2.7|GLIBC_2.8|GLIBC_2.9|GLIBC_2.1[0-7])
echo " -> compatibile anche con distro molto vecchie (glibc <= 2.17)" ;;
*)
echo " ATTENZIONE: richiede una glibc piu' recente di 2.17 (CentOS 7 / Debian 8)" ;;
esac
fi
echo
echo "== syscall moderne (compatibilita' kernel vecchi) =="
if nm "$bin" 2>/dev/null | grep -qE '^[0-9a-f]+ [TtDd] '; then
hits=$(nm "$bin" 2>/dev/null | grep -oE '\b(statx|openat2|memfd_create|getrandom|pidfd_open|copy_file_range|renameat2|close_range)\b' | sort -u || true)
else
hits=$(objdump -T "$bin" 2>/dev/null | grep -oE '\b(statx|openat2|memfd_create|getrandom|pidfd_open|copy_file_range|renameat2|close_range)\b' | sort -u || true)
fi
if [ -z "$hits" ]; then
echo " nessuna: il binario usa solo syscall classiche ✔"
else
echo " presente/i: $(tr '\n' ' ' <<<"$hits")"
fi
echo
echo "== prova di esecuzione =="
if "$bin" --help >/dev/null 2>&1; then
echo " --help OK"
else
echo " --help FALLITO (probabile incompatibilita' di piattaforma)"
fi