|
|
|
@ -6,9 +6,14 @@
@@ -6,9 +6,14 @@
|
|
|
|
|
# super-simple "file" that only identifies archives. |
|
|
|
|
# works with stdin if $1 is not set. |
|
|
|
|
det_archive() { |
|
|
|
|
# NOTE: echo -e works in ash and bash, but not dash |
|
|
|
|
local bz="BZh" xz="$(echo -e '\xfd7zXZ')" gz="$(echo -e '\x1f\x8b')" zs="$(echo -e '\x28\xB5\x2F\xFD')" |
|
|
|
|
local headerblock="$(dd ${1:+if=$1} bs=262 count=1 2> /dev/null)" |
|
|
|
|
# NOTE: internal echo -e works in ash and bash, but not dash |
|
|
|
|
local bz xz gz zs |
|
|
|
|
local headerblock |
|
|
|
|
bz="BZh" |
|
|
|
|
xz="$(/bin/echo -e '\xfd7zXZ')" |
|
|
|
|
gz="$(/bin/echo -e '\x1f\x8b')" |
|
|
|
|
zs="$(/bin/echo -e '\x28\xB5\x2F\xFD')" |
|
|
|
|
headerblock="$(dd ${1:+if=$1} bs=262 count=1 2> /dev/null)" |
|
|
|
|
case "$headerblock" in |
|
|
|
|
$xz*) echo "xz" ;; |
|
|
|
|
$gz*) echo "gzip" ;; |
|
|
|
@ -21,10 +26,11 @@ det_archive() {
@@ -21,10 +26,11 @@ det_archive() {
|
|
|
|
|
|
|
|
|
|
# determine filesystem type for a filesystem image |
|
|
|
|
det_fs_img() { |
|
|
|
|
local dev=$(losetup --find --show "$1") rv="" |
|
|
|
|
det_fs $dev |
|
|
|
|
local dev |
|
|
|
|
dev=$(losetup --find --show "$1") rv="" |
|
|
|
|
det_fs "$dev" |
|
|
|
|
rv=$? |
|
|
|
|
losetup -d $dev |
|
|
|
|
losetup -d "$dev" |
|
|
|
|
return $rv |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -32,41 +38,44 @@ det_fs_img() {
@@ -32,41 +38,44 @@ det_fs_img() {
|
|
|
|
|
# unpack a (possibly compressed) cpio/tar archive |
|
|
|
|
unpack_archive() { |
|
|
|
|
local img="$1" outdir="$2" archiver="" decompr="" |
|
|
|
|
local ft="$(det_archive $img)" |
|
|
|
|
local ft |
|
|
|
|
ft="$(det_archive "$img")" |
|
|
|
|
case "$ft" in |
|
|
|
|
xz | gzip | bzip2 | zstd) decompr="$ft -dc" ;; |
|
|
|
|
cpio | tar) decompr="cat" ;; |
|
|
|
|
*) return 1 ;; |
|
|
|
|
esac |
|
|
|
|
ft="$($decompr $img | det_archive)" |
|
|
|
|
ft="$($decompr "$img" | det_archive)" |
|
|
|
|
case "$ft" in |
|
|
|
|
cpio) archiver="cpio -iumd" ;; |
|
|
|
|
tar) archiver="tar -xf -" ;; |
|
|
|
|
*) return 2 ;; |
|
|
|
|
esac |
|
|
|
|
mkdir -p $outdir |
|
|
|
|
mkdir -p "$outdir" |
|
|
|
|
( |
|
|
|
|
cd $outdir |
|
|
|
|
cd "$outdir" || exit |
|
|
|
|
$decompr | $archiver 2> /dev/null |
|
|
|
|
) < $img |
|
|
|
|
) < "$img" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# unpack_fs FSIMAGE OUTDIR |
|
|
|
|
# unpack a filesystem image |
|
|
|
|
unpack_fs() { |
|
|
|
|
local img="$1" outdir="$2" mnt="$(mkuniqdir /tmp unpack_fs.)" |
|
|
|
|
mount -o loop $img $mnt || { |
|
|
|
|
rmdir $mnt |
|
|
|
|
local img="$1" outdir="$2" |
|
|
|
|
local mnt |
|
|
|
|
mnt="$(mkuniqdir /tmp unpack_fs.)" |
|
|
|
|
mount -o loop "$img" "$mnt" || { |
|
|
|
|
rmdir "$mnt" |
|
|
|
|
return 1 |
|
|
|
|
} |
|
|
|
|
mkdir -p $outdir |
|
|
|
|
mkdir -p "$outdir" |
|
|
|
|
outdir="$( |
|
|
|
|
cd $outdir |
|
|
|
|
cd "$outdir" || exit |
|
|
|
|
pwd |
|
|
|
|
)" |
|
|
|
|
copytree $mnt $outdir |
|
|
|
|
umount $mnt |
|
|
|
|
rmdir $mnt |
|
|
|
|
copytree "$mnt" "$outdir" |
|
|
|
|
umount "$mnt" |
|
|
|
|
rmdir "$mnt" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# unpack an image file - compressed/uncompressed cpio/tar, filesystem, whatever |
|
|
|
@ -82,7 +91,7 @@ unpack_img() {
@@ -82,7 +91,7 @@ unpack_img() {
|
|
|
|
|
return 1 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if [ "$(det_archive $img)" ]; then |
|
|
|
|
if [ "$(det_archive "$img")" ]; then |
|
|
|
|
unpack_archive "$@" || { |
|
|
|
|
warn "can't unpack archive file!" |
|
|
|
|
return 1 |
|
|
|
|