summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Hutchings <ben@decadent.org.uk>2016-12-15 21:20:48 +0000
committerBen Hutchings <ben@decadent.org.uk>2016-12-15 22:08:34 +0000
commit12744ebce67b6fd81e0722ac1f0057ef49f16158 (patch)
treefde454c529f0ebce28f1a869687084c8ce522cd0
parentf1f18a44fd2097818337f405ecc075ec5e232b8b (diff)
unmkinitramfs: Rewrite command syntax
I'm not comfortable with unmkinitramfs passing through everything to cpio, considering what a sharp tool cpio is. Instead of that, recognise and pass through the few specific options that are important. Always pass --preserve-modification-time --no-absolute-filenames --quiet. Take the initramfs filename as a mandatory argument rather than expecting a file on stdin, to be more consistent lsinitramfs and mkinitramfs do. Take an output directory as a mandatory argument (except when listing), rather than extracting to the current directory. Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rwxr-xr-xlsinitramfs6
-rwxr-xr-xunmkinitramfs88
-rw-r--r--unmkinitramfs.825
3 files changed, 72 insertions, 47 deletions
diff --git a/lsinitramfs b/lsinitramfs
index 14705ad..a96308d 100755
--- a/lsinitramfs
+++ b/lsinitramfs
@@ -12,7 +12,7 @@ if [ "$#" -eq 0 ] ; then
exit 1
fi
-cpio_args="--quiet --list"
+umi_opts="--list"
OPTIONS=`getopt -o hl --long help,long -n "$0" -- "$@"`
# Check for non-GNU getopt
@@ -27,7 +27,7 @@ while true; do
exit 0
;;
-l|--long)
- cpio_args="${cpio_args:+${cpio_args} --verbose}"
+ umi_opts="${umi_opts:+${umi_opts} --verbose}"
shift
;;
--)
@@ -41,5 +41,5 @@ while true; do
done
for initramfs in "$@" ; do
- unmkinitramfs $cpio_args < "$initramfs"
+ unmkinitramfs $umi_opts -- "$initramfs"
done
diff --git a/unmkinitramfs b/unmkinitramfs
index 0e163e9..12c0999 100755
--- a/unmkinitramfs
+++ b/unmkinitramfs
@@ -4,35 +4,29 @@ set -eu
usage()
{
- echo "Usage: $(basename "$0") [cpio options ...] < <initramfs file>"
+ echo "Usage: $(basename "$0") [-v] <initramfs file> <directory>"
}
-# Abort if stdin is a terminal.
-#
-# Although cpio supports this, the chance of someone actually keying in a cpio
-# archive on the terminal is negligible compared to the risk of someone who
-# forgot cpio's arcane argument convention.
-if [ -t 0 ] ; then
- echo "Error: stdin must be an initramfs" >&2
- usage >&2
- exit 1
-fi
-
# Extract a compressed cpio archive
xcpio()
{
- archive="$1" ; shift
+ archive="$1"
+ dir="$2"
+ shift 2
if zcat -t "$archive" >/dev/null 2>&1 ; then
- zcat "$archive" | cpio "$@"
+ zcat "$archive"
elif xzcat -t "$archive" >/dev/null 2>&1 ; then
- xzcat "$archive" | cpio "$@"
+ xzcat "$archive"
elif bzip2 -t "$archive" >/dev/null 2>&1 ; then
- bzip2 -c -d "$archive" | cpio "$@"
+ bzip2 -c -d "$archive"
elif lzop -t "$archive" >/dev/null 2>&1 ; then
- lzop -c -d "$archive" | cpio "$@"
+ lzop -c -d "$archive"
# Ignoring other data, which may be garbage at the end of the file
- fi
+ fi | (
+ test -z "$dir" || { mkdir -p -- "$dir" && cd -- "$dir"; }
+ cpio "$@"
+ )
}
# Read bytes out of a file, checking that they are valid hex digits
@@ -52,7 +46,9 @@ checkzero()
# Split an initramfs into archives and call xcpio on each
splitinitramfs()
{
- initramfs="$1" ; shift
+ 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
@@ -75,25 +71,59 @@ splitinitramfs()
if [ $offset -ne 0 ]; then
# uncompressed archive
- cpio -i "$@" < "$initramfs"
+ (
+ test -z "$dir" || { mkdir -p -- "$dir" && cd -- "$dir"; }
+ 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" -i "$@"
+ xcpio "$subarchive" "$dir" -i "$@"
else
- xcpio "$initramfs" -i "$@"
+ xcpio "$initramfs" "$dir" -i "$@"
fi
}
-# If we can get the name of the file passed in, use it. Otherwise, create one.
-stdin_filename=$(readlink /proc/$$/fd/0 2>/dev/null || true)
-if ! [ -r "$stdin_filename" ] ; then
- stdin_filename=$(mktemp ${TMPDIR:-/var/tmp}/uninitramfs_stdin_XXXXXX)
- trap "rm -f '$stdin_filename'" EXIT
- cat > "$stdin_filename"
+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 "$stdin_filename" "$@"
+splitinitramfs "$1" "${2:-}" $cpio_opts
diff --git a/unmkinitramfs.8 b/unmkinitramfs.8
index 74e63a9..1aeb55a 100644
--- a/unmkinitramfs.8
+++ b/unmkinitramfs.8
@@ -5,7 +5,7 @@ unmkinitramfs \- extract content from an initramfs image
.SH SYNOPSIS
.B unmkinitramfs
-.RI "" "[cpio options ...]" " < " <initramfsfile>
+.RI [ options ] " <initramfsfile> <directory>"
.br
.SH DESCRIPTION
@@ -19,27 +19,22 @@ in order.
.SH OPTIONS
-All options are passed through to
-.B cpio
-, after an initial
-.B \-i
-option which puts
-.B cpio
-into \*(lqextract\*(rq or \*(lqCopy-in\*(rq mode.
+.TP
+.B -h
+Display usage information and exit.
+
+.TP
+.B -v
+Display verbose messages about extraction.
+
.SH USAGE EXAMPLES
Extract initramfs content of current running kernel:
.PP
-.B unmkinitramfs < /boot/initrd.img-$(uname -r)
-
-Extract
-.I init
-from the initramfs verbosely and keep its mtime:
+.B unmkinitramfs /boot/initrd.img-$(uname -r) initramfs/
-.PP
-.B unmkinitramfs -m -v init < /boot/initrd.img-$(uname -r)
.SH BUGS
.BR unmkinitramfs