We read the image a number of times. Extract the image to a temp directory so we can just extract it once and use the filesystem to our advantage. This requires a temp dir which we can nuke on an EXIT trap, but the whole operation is sped is a bit, especially for larger images. The real goal of this is to make examination of the hooks easier. Since we now have multiple hook sets to contend with, dynamically tally up the available functions in the hook files so we can iterate over specific functions of interest in the output. Signed-off-by: Dave Reisner <dreisner@archlinux.org> --- lsinitcpio | 59 +++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/lsinitcpio b/lsinitcpio index 5abe37f..f33d9d3 100755 --- a/lsinitcpio +++ b/lsinitcpio @@ -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,48 @@ 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*) + modules=("${modules[@]##*/}") + modules=("${modules[@]%.ko*}") + + foundhooks=("$workdir"/hooks/*) + foundhooks=("${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 -- 1.7.10.2