Created
June 10, 2013 07:59
-
-
Save jkent/5747180 to your computer and use it in GitHub Desktop.
Adds support for an odd lzma image format to unsquashfs. To be used against http://sourceforge.net/projects/squashfs/files/squashfs/squashfs4.2/squashfs4.2.tar.gz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -Nrup squashfs-tools/compressor.c squashfs-tools/compressor.c | |
--- squashfs-tools/compressor.c 2011-02-11 09:49:24.000000000 -0600 | |
+++ squashfs-tools/compressor.c 2013-06-10 02:11:35.096301000 -0500 | |
@@ -59,6 +59,7 @@ static struct compressor xz_comp_ops = { | |
extern struct compressor xz_comp_ops; | |
#endif | |
+extern struct compressor special_comp_ops; | |
static struct compressor unknown_comp_ops = { | |
NULL, NULL, NULL , NULL, NULL, NULL, NULL, NULL, 0, "unknown", 0 | |
@@ -70,6 +71,7 @@ struct compressor *compressor[] = { | |
&lzma_comp_ops, | |
&lzo_comp_ops, | |
&xz_comp_ops, | |
+ &special_comp_ops, | |
&unknown_comp_ops | |
}; | |
diff -Nrup squashfs-tools/Makefile squashfs-tools/Makefile | |
--- squashfs-tools/Makefile 2011-02-28 14:04:15.000000000 -0600 | |
+++ squashfs-tools/Makefile 2013-06-10 02:46:36.640301000 -0500 | |
@@ -58,8 +58,8 @@ GZIP_SUPPORT = 1 | |
# and uncomment the LZMA_SUPPORT line below. | |
# | |
#LZMA_XZ_SUPPORT = 1 | |
-#LZMA_SUPPORT = 1 | |
-#LZMA_DIR = ../../../../LZMA/lzma465 | |
+LZMA_SUPPORT = 1 | |
+LZMA_DIR = ../../lzma465 | |
######## Specifying default compression ######## | |
# | |
@@ -120,9 +120,9 @@ LZMA_OBJS = $(LZMA_DIR)/C/Alloc.o $(LZMA | |
$(LZMA_DIR)/C/LzmaDec.o $(LZMA_DIR)/C/LzmaEnc.o $(LZMA_DIR)/C/LzmaLib.o | |
INCLUDEDIR += -I$(LZMA_DIR)/C | |
CFLAGS += -DLZMA_SUPPORT | |
-MKSQUASHFS_OBJS += lzma_wrapper.o $(LZMA_OBJS) | |
-UNSQUASHFS_OBJS += lzma_wrapper.o $(LZMA_OBJS) | |
-COMPRESSORS += lzma | |
+MKSQUASHFS_OBJS += lzma_wrapper.o special_wrapper.o $(LZMA_OBJS) | |
+UNSQUASHFS_OBJS += lzma_wrapper.o special_wrapper.o $(LZMA_OBJS) | |
+COMPRESSORS += lzma special | |
endif | |
ifeq ($(LZMA_XZ_SUPPORT),1) | |
diff -Nrup squashfs-tools/special_wrapper.c squashfs-tools/special_wrapper.c | |
--- squashfs-tools/special_wrapper.c 1969-12-31 18:00:00.000000000 -0600 | |
+++ squashfs-tools/special_wrapper.c 2013-06-10 02:30:40.624301000 -0500 | |
@@ -0,0 +1,132 @@ | |
+/* | |
+ * Copyright (c) 2009, 2010 | |
+ * Phillip Lougher <[email protected]> | |
+ * | |
+ * This program is free software; you can redistribute it and/or | |
+ * modify it under the terms of the GNU General Public License | |
+ * as published by the Free Software Foundation; either version 2, | |
+ * or (at your option) any later version. | |
+ * | |
+ * This program is distributed in the hope that it will be useful, | |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+ * GNU General Public License for more details. | |
+ * | |
+ * You should have received a copy of the GNU General Public License | |
+ * along with this program; if not, write to the Free Software | |
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
+ * | |
+ * lzma_wrapper.c | |
+ * | |
+ * Support for LZMA1 compression using LZMA SDK (4.65 used in | |
+ * development, other versions may work) http://www.7-zip.org/sdk.html | |
+ */ | |
+ | |
+#include <stdlib.h> | |
+#include <LzmaLib.h> | |
+#include <zlib.h> | |
+ | |
+#include "squashfs_fs.h" | |
+#include "compressor.h" | |
+ | |
+#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8) | |
+ | |
+static int gzip_init(void **strm, int block_size, int flags) | |
+{ | |
+ int res; | |
+ z_stream *stream; | |
+ | |
+ stream = *strm = malloc(sizeof(z_stream)); | |
+ if(stream == NULL) | |
+ goto failed; | |
+ | |
+ stream->zalloc = Z_NULL; | |
+ stream->zfree = Z_NULL; | |
+ stream->opaque = 0; | |
+ | |
+ res = deflateInit(stream, 9); | |
+ if(res != Z_OK) | |
+ goto failed2; | |
+ | |
+ return 0; | |
+ | |
+failed2: | |
+ free(stream); | |
+failed: | |
+ return -1; | |
+} | |
+ | |
+ | |
+static int special_init(void **strm, int block_size, int flags) | |
+{ | |
+ return gzip_init(strm, block_size, flags); | |
+} | |
+ | |
+ | |
+static int gzip_uncompress(void *d, void *s, int size, int block_size, int *error) | |
+{ | |
+ int res; | |
+ unsigned long bytes = block_size; | |
+ | |
+ res = uncompress(d, &bytes, s, size); | |
+ | |
+ *error = res; | |
+ return res == Z_OK ? (int) bytes : -1; | |
+} | |
+ | |
+ | |
+static int lzma_uncompress(void *dest, void *src, int size, int block_size, | |
+ int *error) | |
+{ | |
+ unsigned char *s = src; | |
+ size_t outlen, inlen = size - LZMA_HEADER_SIZE; | |
+ int res; | |
+ | |
+ outlen = s[LZMA_PROPS_SIZE] | | |
+ (s[LZMA_PROPS_SIZE + 1] << 8) | | |
+ (s[LZMA_PROPS_SIZE + 2] << 16) | | |
+ (s[LZMA_PROPS_SIZE + 3] << 24); | |
+ | |
+ res = LzmaUncompress(dest, &outlen, src + LZMA_HEADER_SIZE, &inlen, src, | |
+ LZMA_PROPS_SIZE); | |
+ | |
+ *error = res; | |
+ return res == SZ_OK ? outlen : -1; | |
+} | |
+ | |
+ | |
+static int special_uncompress(void *dest, void *src, int size, int block_size, | |
+ int *error) | |
+{ | |
+ unsigned char *s = src; | |
+ | |
+ switch (s[0]) { | |
+ case 0x5d: | |
+ return lzma_uncompress(dest, src, size, block_size, error); | |
+ case 0x78: | |
+ return gzip_uncompress(dest, src, size, block_size, error); | |
+ default: | |
+ return -1; | |
+ } | |
+} | |
+ | |
+ | |
+static int special_compress(void *strm, void *dest, void *src, int size, int block_size, | |
+ int *error) | |
+{ | |
+ *error = -1; | |
+ return -1; | |
+} | |
+ | |
+ | |
+struct compressor special_comp_ops = { | |
+ .init = special_init, | |
+ .compress = special_compress, | |
+ .uncompress = special_uncompress, | |
+ .options = NULL, | |
+ .usage = NULL, | |
+ .id = SPECIAL_COMPRESSION, | |
+ .name = "special", | |
+ .supported = 1 | |
+}; | |
+ | |
diff -Nrup squashfs-tools/squashfs_fs.h squashfs-tools/squashfs_fs.h | |
--- squashfs-tools/squashfs_fs.h 2011-02-11 09:49:24.000000000 -0600 | |
+++ squashfs-tools/squashfs_fs.h 2013-06-10 02:37:07.464301000 -0500 | |
@@ -28,6 +28,8 @@ | |
#define SQUASHFS_MINOR 0 | |
#define SQUASHFS_MAGIC 0x73717368 | |
#define SQUASHFS_MAGIC_SWAP 0x68737173 | |
+#define SQUASHFS_SPECIAL_MAGIC 0x71736873 | |
+#define SQUASHFS_SPECIAL_MAGIC_SWAP 0x73687371 | |
#define SQUASHFS_START 0 | |
/* size of metadata (inode and directory) blocks */ | |
@@ -274,6 +276,7 @@ typedef long long squashfs_inode; | |
#define LZMA_COMPRESSION 2 | |
#define LZO_COMPRESSION 3 | |
#define XZ_COMPRESSION 4 | |
+#define SPECIAL_COMPRESSION 5 | |
struct squashfs_super_block { | |
unsigned int s_magic; | |
diff -Nrup squashfs-tools/unsquashfs.c squashfs-tools/unsquashfs.c | |
--- squashfs-tools/unsquashfs.c 2011-02-28 16:27:06.000000000 -0600 | |
+++ squashfs-tools/unsquashfs.c 2013-06-10 02:41:59.740301000 -0500 | |
@@ -44,7 +44,7 @@ struct super_block sBlk; | |
squashfs_operations s_ops; | |
struct compressor *comp; | |
-int bytes = 0, swap, file_count = 0, dir_count = 0, sym_count = 0, | |
+int bytes = 0, swap, special, file_count = 0, dir_count = 0, sym_count = 0, | |
dev_count = 0, fifo_count = 0; | |
char *inode_table = NULL, *directory_table = NULL; | |
struct hash_table_entry *inode_table_hash[65536], *directory_table_hash[65536]; | |
@@ -1491,6 +1491,7 @@ int read_super(char *source) | |
* Check it is a SQUASHFS superblock | |
*/ | |
swap = 0; | |
+ special = 0; | |
if(sBlk_3.s_magic != SQUASHFS_MAGIC) { | |
if(sBlk_3.s_magic == SQUASHFS_MAGIC_SWAP) { | |
squashfs_super_block_3 sblk; | |
@@ -1499,7 +1500,17 @@ int read_super(char *source) | |
SQUASHFS_SWAP_SUPER_BLOCK_3(&sblk, &sBlk_3); | |
memcpy(&sBlk_3, &sblk, sizeof(squashfs_super_block_3)); | |
swap = 1; | |
- } else { | |
+ } else if (sBlk_3.s_magic == SQUASHFS_SPECIAL_MAGIC) { | |
+ special = 1; | |
+ } else if (sBlk_3.s_magic == SQUASHFS_SPECIAL_MAGIC_SWAP) { | |
+ squashfs_super_block_3 sblk; | |
+ ERROR("Reading a different endian SQUASHFS filesystem " | |
+ "on %s\n", source); | |
+ SQUASHFS_SWAP_SUPER_BLOCK_3(&sblk, &sBlk_3); | |
+ memcpy(&sBlk_3, &sblk, sizeof(squashfs_super_block_3)); | |
+ swap = 1; | |
+ special = 1; | |
+ } else { | |
ERROR("Can't find a SQUASHFS superblock on %s\n", | |
source); | |
goto failed_mount; | |
@@ -1570,7 +1581,11 @@ int read_super(char *source) | |
/* | |
* 1.x, 2.x and 3.x filesystems use gzip compression. | |
*/ | |
- comp = lookup_compressor("gzip"); | |
+ if (special) { | |
+ comp = lookup_compressor("special"); | |
+ } else { | |
+ comp = lookup_compressor("gzip"); | |
+ } | |
return TRUE; | |
failed_mount: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment