diff options
-rwxr-xr-x | lsinitcpio | 63 |
1 files changed, 45 insertions, 18 deletions
@@ -59,7 +59,6 @@ size_to_human() { }' } - OPT_SHORT='ahnvx' OPT_LONG=('analyze' 'help' 'nocolor' 'verbose' 'extract') @@ -127,6 +126,9 @@ if (( analyze )); then declare -a binaries explicitmod modules foundhooks hooks declare kernver ratio columns=$(tput cols) + workdir=$(mktemp -d --tmpdir="$TMPDIR" lsinitcpio.XXXXXX) + trap 'rm -rf "$workdir"' EXIT + # fallback in case tput failed us columns=${columns:-80} @@ -139,27 +141,52 @@ if (( analyze )); then ratio=.$(( zsize * 1000 / fullsize % 1000 )) fi - # read contents of image - while read -r line; do - if [[ $line = *.ko?(.?z) ]]; then - line=${line##*/} - modules+=("${line%.ko?(.?z)}") - elif [[ -z $kernver && $line =~ /lib/modules/([^/]+)/ ]]; then - kernver=${BASH_REMATCH[1]} - elif [[ $line = ./hooks/* ]]; then - foundhooks+=("${line##*/}") - elif [[ $line = *@(/?(s)bin/)* ]]; then - binaries+=("${line##*/}") - fi - done < <(decomp "$image" | bsdtar tf -) - - read -r version < <(decomp "$image" | bsdtar xOf - VERSION 2>/dev/null) + # decompress the image since we need to read from it multiple times + decomp "$image" | bsdtar -C "$workdir" -xf - + + # collect stats + kernver=("$workdir"/usr/lib/modules/*/) + kernver=${kernver%/} + kernver=${kernver##*/} + + modules=("$workdir/usr/lib/modules/$kernver"/kernel/*.ko*) + if [[ -f ${modules[0]} ]]; then + modules=("${modules[@]##*/}") + modules=("${modules[@]%.ko*}") + else + unset modules + fi + + foundhooks=("$workdir"/hooks/*) + [[ -f ${foundhooks[0]} ]] && foundhooks=("${foundhooks[@]##*/}") || unset foundhooks + + binaries=("$workdir"/usr/bin/*) + binaries=("${binaries[@]##*/}") + + read -r version < "$workdir/VERSION" # source and read config - . <(decomp "$image" | bsdtar xOf - config) + . "$workdir/config" + explicitmod=($MODULES) + for hook in $HOOKS; do - in_array "$hook" "${foundhooks[@]}" && hooks+=("$hook") + [[ -e $workdir/hooks/$hook ]] || continue + + mapfile -t funcs < \ + <(awk ' + /^[[:space:]]*[[:alnum:]_]+/ && /\([[:space:]]*\)/ { + match($1, /[[:alnum:]_]+/) + print substr($1, RSTART, RLENGTH) + }' "$workdir/hooks/$hook") + + for fn in "${funcs[@]}"; do + case $fn in + run_hook) + hooks+=("$hook") + ;; + esac + done done # print results |