/usr/bin/unmkinitramfs is in initramfs-tools-core 0.130ubuntu3.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | #!/bin/sh
set -eu
usage()
{
echo "Usage: $(basename "$0") [-v] <initramfs file> <directory>"
}
# Extract a compressed cpio archive
xcpio()
{
archive="$1"
dir="$2"
shift 2
if zcat -t "$archive" >/dev/null 2>&1 ; then
zcat "$archive"
elif xzcat -t "$archive" >/dev/null 2>&1 ; then
xzcat "$archive"
elif bzip2 -t "$archive" >/dev/null 2>&1 ; then
bzip2 -c -d "$archive"
elif lzop -t "$archive" >/dev/null 2>&1 ; then
lzop -c -d "$archive"
# Ignoring other data, which may be garbage at the end of the file
fi | (
if [ -n "$dir" ]; then
mkdir -p -- "$dir"
cd -- "$dir"
fi
cpio "$@"
)
}
# Read bytes out of a file, checking that they are valid hex digits
readhex()
{
dd < "$1" bs=1 skip="$2" count="$3" 2> /dev/null | \
LANG=C grep -E "^[0-9A-Fa-f]{$3}\$"
}
# Check for a zero byte in a file
checkzero()
{
dd < "$1" bs=1 skip="$2" count=1 2> /dev/null | \
LANG=C grep -q -z '^$'
}
# Split an initramfs into archives and call xcpio on each
splitinitramfs()
{
initramfs="$1"
dir="$2"
shift 2
# There may be a prepended uncompressed archive. cpio
# won't tell us the true size of this so we have to
# parse the headers and padding ourselves. This is
# very roughly based on linux/lib/earlycpio.c
offset=0
while true; do
if checkzero "$initramfs" $offset; then
offset=$((offset + 4))
continue
fi
magic="$(readhex "$initramfs" $offset 6)" || break
test $magic = 070701 || test $magic = 070702 || break
namesize=0x$(readhex "$initramfs" $((offset + 94)) 8)
filesize=0x$(readhex "$initramfs" $((offset + 54)) 8)
offset=$(((offset + 110)))
offset=$(((offset + $namesize + 3) & ~3))
offset=$(((offset + $filesize + 3) & ~3))
done
if [ $offset -ne 0 ]; then
# uncompressed archive
(
if [ -n "$dir" ]; then
mkdir -p -- "$dir/early"
cd -- "$dir/early"
fi
cpio -i "$@"
) < "$initramfs"
# main archive
subarchive=$(mktemp ${TMPDIR:-/var/tmp}/unmkinitramfs_XXXXXX)
trap "rm -f '$subarchive'" EXIT
dd < "$initramfs" bs="$offset" skip=1 2> /dev/null \
> $subarchive
xcpio "$subarchive" "${dir:+$dir/main}" -i "$@"
else
xcpio "$initramfs" "$dir" -i "$@"
fi
}
OPTIONS=`getopt -o hv --long help,list,verbose -n "$0" -- "$@"`
# Check for non-GNU getopt
if [ $? != 0 ] ; then echo "W: non-GNU getopt" >&2 ; exit 1 ; fi
cpio_opts="--preserve-modification-time --no-absolute-filenames --quiet"
expected_args=2
eval set -- "$OPTIONS"
while true; do
case "$1" in
-h|--help)
usage
exit 0
;;
--list)
# For lsinitramfs
cpio_opts="${cpio_opts:+${cpio_opts} --list}"
expected_args=1
shift
;;
-v|--verbose)
cpio_opts="${cpio_opts:+${cpio_opts} --verbose}"
shift
;;
--)
shift
break
;;
*)
echo "Internal error!" >&2
exit 1
esac
done
if [ $# -ne $expected_args ]; then
usage
exit 2
fi
splitinitramfs "$1" "${2:-}" $cpio_opts
|