From 5aa93f8ed37b0ded7a6dc393795441cec1e42d2b Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Thu, 9 Jun 2011 14:34:17 -0400 Subject: lsinitcpio: new utility to dump contents of images Signed-off-by: Dave Reisner --- lsinitcpio | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100755 lsinitcpio (limited to 'lsinitcpio') diff --git a/lsinitcpio b/lsinitcpio new file mode 100755 index 0000000..55061aa --- /dev/null +++ b/lsinitcpio @@ -0,0 +1,138 @@ +#!/bin/bash +# +# lsinitcpio - dump the contents of an initramfs image +# + +shopt -s extglob + +die() { + local mesg=$1; shift + printf "error: $mesg\n" "$@" + exit 1 +} + +usage() { + cat< + + Options: + -a analyze contents + -h display this help + -v more verbose output + -x extract image to disk + +USAGE + exit 1 +} + +in_array() { + local item needle=$1; shift + + for item; do + [[ "$item" == $needle ]] && return 0 # Found + done + return 1 # Not Found +} + +decomp() { + ${compress:-cat} ${compress:+-cd} "$@" +} + +declare verbose= +declare list='--list' + +while getopts ':ahvx' flag; do + case $flag in + a) analyze=1 ;; + h) usage ;; + v) verbose='--verbose' ;; + x) unset list ;; + \?) die "invalid option -- '$OPTARG'" ;; + esac +done +shift $(( OPTIND - 1 )) + +declare image=$1 + +[[ $image ]] || usage +[[ -f $image ]] || die "$image: No such file" + +# read compression type +case "$(file -b "$image")" in + data|LZMA*) compress=lzma ;; + gzip*) compress=gzip ;; + bzip2*) compress=bzip2 ;; + lzop*) compress=lzop ;; + XZ*) compress=xz ;; +esac + +if (( analyze )); then + declare -a binaries explicitmod modules foundhooks hooks + declare kernver ratio + + # calculate compression ratio + if [[ $compress ]]; then + TIMEFORMAT=%R decomptime=$({ time decomp "$image" >/dev/null; } 2>&1 ) + ratio=.$(( $(stat -c %s "$image") * 1000 / + $(decomp "$image" | bsdtar xOf - | wc -c) % 1000 )) + fi + + # read contents of image + while read -r line; do + if [[ $line = *.ko?(.gz) ]]; then # module + if [[ -z $kernver ]]; then + [[ $line =~ /lib/modules/([^/]+)/ ]] && kernver=${BASH_REMATCH[1]} + fi + line=${line##*/} + modules+=("${line%.ko?(.gz)}") + continue + elif [[ $line = ./hooks/* ]]; then + foundhooks+=("${line##*/}") + elif [[ $line = *@(/bin/|/sbin/)* ]]; then + binaries+=("${line#.}") + fi + done < <(decomp "$image" | bsdtar tf -) + + # source and read config + . <(decomp "$image" | bsdtar xOf - config) + explicitmod=($MODULES) + for hook in $HOOKS; do + in_array "$hook" "${foundhooks[@]}" && hooks=("$hook") + done + + # print results + printf '==> Image: %s\n' "$(readlink -e "$image")" + printf '==> Kernel: %s\n' "${kernver:-unknown}" + + if [[ $compress ]]; then + printf '==> Compressed with: %s\n' "$compress" + printf ' -> Compression ratio: %s\n' "$ratio" + printf ' -> Estimated decompression time: %ss\n' "$decomptime" + fi + printf '\n' + + if (( ${#modules[*]} )); then + printf '==> Included modules:\n' + for mod in "${modules[@]}"; do + printf ' %s' "$mod" + in_array "${mod//_/-}" "${explicitmod[@]//_/-}" && printf ' [explicit]' + printf '\n' + done | sort | column -c$(tput cols) + printf '\n' + fi + + printf '==> Included binaries:\n' + printf ' %s\n' "${binaries[@]}" + printf '\n' + + if (( ${#hooks[*]} )); then + printf '==> Hook run order:\n' + printf ' %s\n' "${hooks[@]}" + printf '\n' + fi +else + decomp "$image" | bsdcpio -i --quiet $verbose $list +fi + +# vim: set ft=sh ts=4 sw=4 et: -- cgit v1.2.3-24-g4f1b