@@ -31,78 +31,105 @@ CPIO_ARGS=("$@")
3131
3232# Consume zero bytes, the first nonzero byte read (if any) is repeated on stdout
3333consume_zeros () {
34- TRACE_FUNC
35- next_byte=' 00'
36- while [ " $next_byte " = " 00" ]; do
37- # if we reach EOF, next_byte becomes empty (dd does not fail)
38- next_byte=" $( dd bs=1 count=1 status=none | xxd -p | tr -d ' ' ) "
39- done
40- # if we finished due to nonzero byte (not EOF), then carry that byte
41- if [ -n " $next_byte " ]; then
42- echo -n " $next_byte " | xxd -p -r
43- fi
34+ TRACE_FUNC
35+ next_byte=' 00'
36+ while [ " $next_byte " = " 00" ]; do
37+ # if we reach EOF, next_byte becomes empty (dd does not fail)
38+ next_byte=" $( dd bs=1 count=1 status=none | xxd -p | tr -d ' ' ) "
39+ done
40+ # if we finished due to nonzero byte (not EOF), then carry that byte
41+ if [ -n " $next_byte " ]; then
42+ echo -n " $next_byte " | xxd -p -r
43+ fi
4444}
4545
4646unpack_cpio () {
47- TRACE_FUNC
48- (cd " $dest_dir " ; cpio -i " ${CPIO_ARGS[@]} " 2> /dev/null)
47+ TRACE_FUNC
48+ (
49+ cd " $dest_dir "
50+ cpio -i " ${CPIO_ARGS[@]} " 2> /dev/null
51+ )
4952}
5053
5154# unpack the first segment of an archive, then write the rest to another file
5255unpack_first_segment () {
53- TRACE_FUNC
54- unpack_archive=" $1 "
55- dest_dir=" $2 "
56- rest_archive=" $3 "
56+ TRACE_FUNC
57+ unpack_archive=" $1 "
58+ dest_dir=" $2 "
59+ rest_archive=" $3 "
5760
58- mkdir -p " $dest_dir "
61+ mkdir -p " $dest_dir "
5962
60- # peek the beginning of the file to determine what type of content is next
61- magic=" $( dd if=" $unpack_archive " bs=6 count=1 status=none | xxd -p) "
63+ # peek the beginning of the file to determine what type of content is next
64+ magic=" $( dd if=" $unpack_archive " bs=6 count=1 status=none | xxd -p) "
6265
63- # read this segment of the archive, then write the rest to the next file
64- (
65- # Magic values correspond to Linux init/initramfs.c (zero, cpio) and
66- # lib/decompress.c (gzip)
67- case " $magic " in
68- 00* )
69- DEBUG " archive segment $magic : uncompressed cpio"
70- # Skip zero bytes and copy the first nonzero byte
71- consume_zeros
72- # Copy the remaining data
73- cat
74- ;;
75- 303730373031* |303730373032* ) # plain cpio
76- DEBUG " archive segment $magic : plain cpio"
77- # Unpack the plain cpio, this stops reading after the trailer
78- unpack_cpio
79- # Copy the remaining data
80- cat
81- ;;
82- 1f8b* |1f9e* ) # gzip
83- DEBUG " archive segment $magic : gzip"
84- # gunzip won't stop when reaching the end of the gzipped member,
85- # so we can't read another segment after this. We can't
86- # reasonably determine the member length either, this requires
87- # walking all the compressed blocks.
88- gunzip | unpack_cpio
89- ;;
90- 28b5* ) # zstd
91- DEBUG " archive segment $magic : zstd"
92- # Like gunzip, this will not stop when reaching the end of the
93- # frame, and determining the frame length requires walking all
94- # of its blocks.
95- (zstd-decompress -d || true) | unpack_cpio
96- ;;
97- * ) # unknown
98- die " Can't decompress initramfs archive, unknown type: $magic "
99- ;;
100- esac
101- ) < " $unpack_archive " > " $rest_archive "
66+ # read this segment of the archive, then write the rest to the next file
67+ (
68+ # Magic values correspond to Linux init/initramfs.c (zero, cpio) and
69+ # lib/decompress.c (gzip)
70+ case " $magic " in
71+ 00* )
72+ DEBUG " archive segment $magic : uncompressed cpio"
73+ # Skip zero bytes and copy the first nonzero byte
74+ consume_zeros
75+ # Copy the remaining data
76+ cat
77+ ;;
78+ 303730373031* | 303730373032* ) # plain cpio
79+ DEBUG " archive segment $magic : plain cpio"
80+ # Unpack the plain cpio, this stops reading after the trailer
81+ unpack_cpio
82+ # Copy the remaining data
83+ cat
84+ ;;
85+ 1f8b* | 1f9e* ) # gzip
86+ DEBUG " archive segment $magic : gzip"
87+ # gunzip won't stop when reaching the end of the gzipped member,
88+ # so we can't read another segment after this. We can't
89+ # reasonably determine the member length either, this requires
90+ # walking all the compressed blocks.
91+ gunzip | unpack_cpio
92+ ;;
93+ fd37* ) # xz
94+ DEBUG " archive segment $magic : xz"
95+ unxz | unpack_cpio
96+ ;;
97+ 28b5* ) # zstd
98+ DEBUG " archive segment $magic : zstd"
99+ # Like gunzip, this will not stop when reaching the end of the
100+ # frame, and determining the frame length requires walking all
101+ # of its blocks.
102+ (zstd-decompress -d || true) | unpack_cpio
103+ ;;
104+ * ) # unknown
105+ die " Can't decompress initramfs archive, unknown type: $magic "
106+ # The following are magic values for other compression formats
107+ # but not added because not tested.
108+ # TODO: open an issue for unsupported magic number reported on die.
109+ #
110+ # 425a*) # bzip2
111+ # DEBUG "archive segment $magic: bzip2"
112+ # bunzip2 | unpack_cpio
113+ # ;;
114+ # 5d00*) # lzma
115+ # DEBUG "archive segment $magic: lzma"
116+ # unlzma | unpack_cpio
117+ # ;;
118+ # 894c*) # lzo
119+ # DEBUG "archive segment $magic: lzo"
120+ # lzop -d | unpack_cpio
121+ # ;;
122+ # 0221*) # lz4
123+ # DEBUG "archive segment $magic: lz4"
124+ # lz4 -d | unpack_cpio
125+ # ;;
126+ ;;
127+ esac
128+ ) < " $unpack_archive " > " $rest_archive "
102129
103- orig_size=" $( stat -c %s " $unpack_archive " ) "
104- rest_size=" $( stat -c %s " $rest_archive " ) "
105- DEBUG " archive segment $magic : $(( orig_size - rest_size)) bytes"
130+ orig_size=" $( stat -c %s " $unpack_archive " ) "
131+ rest_size=" $( stat -c %s " $rest_archive " ) "
132+ DEBUG " archive segment $magic : $(( orig_size - rest_size)) bytes"
106133}
107134
108135DEBUG " Unpacking $INITRAMFS_ARCHIVE to $DEST_DIR "
@@ -112,7 +139,7 @@ rest_archive="/tmp/unpack_initramfs_rest"
112139
113140# Break when there is no remaining data
114141while [ -s " $next_archive " ]; do
115- unpack_first_segment " $next_archive " " $DEST_DIR " " $rest_archive "
116- next_archive=" /tmp/unpack_initramfs_next"
117- mv " $rest_archive " " $next_archive "
142+ unpack_first_segment " $next_archive " " $DEST_DIR " " $rest_archive "
143+ next_archive=" /tmp/unpack_initramfs_next"
144+ mv " $rest_archive " " $next_archive "
118145done
0 commit comments