dracut-systemd/dracut-initqueue: only start service if really needed
[dracut.git] / modules.d / 99img-lib / img-lib.sh
blob48e56ce72ec3081de063795243e7ef20c8132445
1 #!/bin/sh
2 # img-lib.sh: utilities for dealing with archives and filesystem images.
4 # TODO: identify/unpack rpm, deb, maybe others?
7 # super-simple "file" that only identifies archives.
8 # works with stdin if $1 is not set.
9 det_archive() {
10 # NOTE: echo -e works in ash and bash, but not dash
11 local bz="BZh" xz="$(echo -e '\xfd7zXZ')" gz="$(echo -e '\x1f\x8b')"
12 local headerblock="$(dd ${1:+if=$1} bs=262 count=1 2>/dev/null)"
13 case "$headerblock" in
14 $xz*) echo "xz" ;;
15 $gz*) echo "gzip" ;;
16 $bz*) echo "bzip2" ;;
17 07070*) echo "cpio" ;;
18 *ustar) echo "tar" ;;
19 esac
22 # determine filesystem type for a filesystem image
23 det_fs_img() {
24 local dev=$(losetup --find --show "$1") rv=""
25 det_fs $dev; rv=$?
26 losetup -d $dev
27 return $rv
30 # unpack_archive ARCHIVE OUTDIR
31 # unpack a (possibly compressed) cpio/tar archive
32 unpack_archive() {
33 local img="$1" outdir="$2" archiver="" decompr=""
34 local ft="$(det_archive $img)"
35 case "$ft" in
36 xz|gzip|bzip2) decompr="$ft -dc" ;;
37 cpio|tar) decompr="cat";;
38 *) return 1 ;;
39 esac
40 ft="$($decompr $img | det_archive)"
41 case "$ft" in
42 cpio) archiver="cpio -iumd" ;;
43 tar) archiver="tar -xf -" ;;
44 *) return 2 ;;
45 esac
46 mkdir -p $outdir
47 ( cd $outdir; $decompr | $archiver 2>/dev/null ) < $img
50 # unpack_fs FSIMAGE OUTDIR
51 # unpack a filesystem image
52 unpack_fs() {
53 local img="$1" outdir="$2" mnt="$(mkuniqdir /tmp unpack_fs.)"
54 mount -o loop $img $mnt || { rmdir $mnt; return 1; }
55 mkdir -p $outdir; outdir="$(cd $outdir; pwd)"
56 copytree $mnt $outdir
57 umount $mnt
58 rmdir $mnt
61 # unpack an image file - compressed/uncompressed cpio/tar, filesystem, whatever
62 # unpack_img IMAGEFILE OUTDIR
63 unpack_img() {
64 local img="$1" outdir="$2"
65 [ -r "$img" ] || { warn "can't read img!"; return 1; }
66 [ -n "$outdir" ] || { warn "unpack_img: no output dir given"; return 1; }
68 if [ "$(det_archive $img)" ]; then
69 unpack_archive "$@" || { warn "can't unpack archive file!"; return 1; }
70 else
71 unpack_fs "$@" || { warn "can't unpack filesystem image!"; return 1; }