From c2dc60a94b01a1fff4a22db1c0569651afa6c959 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Wed, 19 Oct 2011 11:44:57 +0200 Subject: [PATCH] unsquashfs: add support for LZMA magics X-Face: z*RaLf`X<@C75u6Ig9}{oW$H;1_\2t5)({*|jhM/Vb;]yA5\I~93>J<_`<4)A{':UrE Some vendor (e.g. Thomson/Technicolor) use a different super block magic to indicate LZMA compression: qshs (0x71736873) - LZMA compression shsq (0x73687371) - LZMA compression, SWAPPED fields Add support for detecting this and enable extraction for filesystems from those firmwares. Signed-off-by: Jonas Gorski Tested-by: Antonio Ospite --- squashfs-tools/squashfs_fs.h | 6 ++++++ squashfs-tools/unsquashfs.c | 24 ++++++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/squashfs-tools/squashfs_fs.h b/squashfs-tools/squashfs_fs.h index d4fba1b..8462a6b 100644 --- a/squashfs-tools/squashfs_fs.h +++ b/squashfs-tools/squashfs_fs.h @@ -30,6 +30,12 @@ #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 diff --git a/squashfs-tools/unsquashfs.c b/squashfs-tools/unsquashfs.c index 320bead..7869a38 100644 --- a/squashfs-tools/unsquashfs.c +++ b/squashfs-tools/unsquashfs.c @@ -1516,10 +1516,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; @@ -1532,7 +1534,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; } @@ -1547,8 +1553,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); @@ -1626,7 +1634,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: -- 1.7.10.4