squashfs4: Add support for LZMA Magic to unsquashfs

Some vendor firmwares use a different super block magic to indicate LZMA
compression. This patches adds support for detecting this and enable
extraction for those firmware's root filesystems.

SVN-Revision: 28489
This commit is contained in:
Jonas Gorski 2011-10-19 10:17:28 +00:00
parent b656b87d13
commit 90673a048c

View file

@ -0,0 +1,72 @@
--- a/squashfs-tools/squashfs_fs.h
+++ b/squashfs-tools/squashfs_fs.h
@@ -30,6 +30,13 @@
#define SQUASHFS_MAGIC_SWAP 0x68737173
#define SQUASHFS_START 0
+/*
+ * Squashfs + LZMA
+ */
+
+#define SQUASHFS_MAGIC_LZMA 0x71736873
+#define SQUASHFS_MAGIC_LZMA_SWAP 0x73687371
+
/* size of metadata (inode and directory) blocks */
#define SQUASHFS_METADATA_SIZE 8192
#define SQUASHFS_METADATA_LOG 13
--- a/squashfs-tools/unsquashfs.c
+++ b/squashfs-tools/unsquashfs.c
@@ -1463,10 +1463,12 @@ int read_super(char *source)
*/
read_fs_bytes(fd, SQUASHFS_START, sizeof(struct squashfs_super_block),
&sBlk_4);
- swap = sBlk_4.s_magic != SQUASHFS_MAGIC;
+ swap = (sBlk_4.s_magic != SQUASHFS_MAGIC &&
+ sBlk_4.s_magic != SQUASHFS_MAGIC_LZMA);
SQUASHFS_INSWAP_SUPER_BLOCK(&sBlk_4);
- if(sBlk_4.s_magic == SQUASHFS_MAGIC && sBlk_4.s_major == 4 &&
+ if((sBlk_4.s_magic == SQUASHFS_MAGIC ||
+ sBlk_4.s_magic == SQUASHFS_MAGIC_LZMA) && sBlk_4.s_major == 4 &&
sBlk_4.s_minor == 0) {
s_ops.squashfs_opendir = squashfs_opendir_4;
s_ops.read_fragment = read_fragment_4;
@@ -1479,7 +1481,11 @@ int read_super(char *source)
/*
* Check the compression type
*/
- comp = lookup_compressor_id(sBlk.s.compression);
+ if (sBlk_4.s_magic == SQUASHFS_MAGIC_LZMA)
+ comp = lookup_compressor("lzma");
+ else
+ comp = lookup_compressor_id(sBlk.s.compression);
+
return TRUE;
}
@@ -1494,8 +1500,10 @@ int read_super(char *source)
* Check it is a SQUASHFS superblock
*/
swap = 0;
- if(sBlk_3.s_magic != SQUASHFS_MAGIC) {
- if(sBlk_3.s_magic == SQUASHFS_MAGIC_SWAP) {
+ if(sBlk_3.s_magic != SQUASHFS_MAGIC &&
+ sBlk_3.s_magic != SQUASHFS_MAGIC_LZMA) {
+ if(sBlk_3.s_magic == SQUASHFS_MAGIC_SWAP ||
+ sBlk_3.s_magic == SQUASHFS_MAGIC_LZMA_SWAP) {
squashfs_super_block_3 sblk;
ERROR("Reading a different endian SQUASHFS filesystem "
"on %s\n", source);
@@ -1573,7 +1581,11 @@ int read_super(char *source)
/*
* 1.x, 2.x and 3.x filesystems use gzip compression.
*/
- comp = lookup_compressor("gzip");
+ if (sBlk.s.s_magic == SQUASHFS_MAGIC_LZMA)
+ comp = lookup_compressor("lzma");
+ else
+ comp = lookup_compressor("gzip");
+
return TRUE;
failed_mount: