diff options
author | Dave Reisner <d@falconindy.com> | 2011-06-09 20:34:17 +0200 |
---|---|---|
committer | Dave Reisner <d@falconindy.com> | 2011-06-16 20:27:02 +0200 |
commit | 5aa93f8ed37b0ded7a6dc393795441cec1e42d2b (patch) | |
tree | c0b65c1856691869f13673202672cb09f9b8f965 /lsinitcpio | |
parent | 031c99d6d1fd44bf6cc28395867b8adf432b9115 (diff) | |
download | mkinitcpio-5aa93f8ed37b0ded7a6dc393795441cec1e42d2b.tar.gz mkinitcpio-5aa93f8ed37b0ded7a6dc393795441cec1e42d2b.tar.xz |
lsinitcpio: new utility to dump contents of images
Signed-off-by: Dave Reisner <d@falconindy.com>
Diffstat (limited to 'lsinitcpio')
-rwxr-xr-x | lsinitcpio | 138 |
1 files changed, 138 insertions, 0 deletions
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<<USAGE +lsinitramfs %VERSION% +usage: ${0##*/} [options] <initramfs> + + 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: |