Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 212454 Details for
Bug 207737
sys-fs/squashfs-tools - add lzma support
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
sys-fs/squashfs-tools/files/squashfs-tools-4.0-lzma.patch
squashfs-tools-4.0-lzma.patch (text/plain), 66.37 KB, created by
Jonathan-Christofer Demay
on 2009-12-08 15:03:18 UTC
(
hide
)
Description:
sys-fs/squashfs-tools/files/squashfs-tools-4.0-lzma.patch
Filename:
MIME Type:
Creator:
Jonathan-Christofer Demay
Created:
2009-12-08 15:03:18 UTC
Size:
66.37 KB
patch
obsolete
>diff -Naurp squashfs-tools/compressor.c squashfs-tools-lzma/compressor.c >--- squashfs-tools/compressor.c 1970-01-01 00:00:00.000000000 +0000 >+++ squashfs-tools-lzma/compressor.c 2009-10-20 04:03:37.000000000 +0000 >@@ -0,0 +1,78 @@ >+/* >+ * >+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 >+ * Phillip Lougher <phillip@lougher.demon.co.uk> >+ * >+ * 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. >+ * >+ * compressor.c >+ */ >+ >+#include <stdio.h> >+#include <string.h> >+#include "compressor.h" >+#include "squashfs_fs.h" >+ >+extern int gzip_compress(void **, char *, char *, int, int, int *); >+extern int gzip_uncompress(char *, char *, int, int, int *); >+extern int lzma_compress(void **, char *, char *, int, int, int *); >+extern int lzma_uncompress(char *, char *, int, int, int *); >+ >+struct compressor compressor[] = { >+ { gzip_compress, gzip_uncompress, ZLIB_COMPRESSION, "gzip", 1 }, >+#ifdef LZMA_SUPPORT >+ { lzma_compress, lzma_uncompress, LZMA_COMPRESSION, "lzma", 1 }, >+#else >+ { NULL, NULL, LZMA_COMPRESSION, "lzma", 0 }, >+#endif >+ { NULL, NULL , 0, "unknown", 0} >+}; >+ >+ >+struct compressor *lookup_compressor(char *name) >+{ >+ int i; >+ >+ for(i = 0; compressor[i].id; i++) >+ if(strcmp(compressor[i].name, name) == 0) >+ break; >+ >+ return &compressor[i]; >+} >+ >+ >+struct compressor *lookup_compressor_id(int id) >+{ >+ int i; >+ >+ for(i = 0; compressor[i].id; i++) >+ if(id == compressor[i].id) >+ break; >+ >+ return &compressor[i]; >+} >+ >+ >+void display_compressors(char *indent, char *def_comp) >+{ >+ int i; >+ >+ for(i = 0; compressor[i].id; i++) >+ if(compressor[i].supported) >+ fprintf(stderr, "%s\t%s%s\n", indent, >+ compressor[i].name, >+ strcmp(compressor[i].name, def_comp) == 0 ? >+ " (default)" : ""); >+} >diff -Naurp squashfs-tools/compressor.h squashfs-tools-lzma/compressor.h >--- squashfs-tools/compressor.h 1970-01-01 00:00:00.000000000 +0000 >+++ squashfs-tools-lzma/compressor.h 2009-10-20 04:03:37.000000000 +0000 >@@ -0,0 +1,33 @@ >+/* >+ * >+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 >+ * Phillip Lougher <phillip@lougher.demon.co.uk> >+ * >+ * 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. >+ * >+ * compressor.h >+ */ >+ >+struct compressor { >+ int (*compress)(void **, char *, char *, int, int, int *); >+ int (*uncompress)(char *, char *, int, int, int *); >+ int id; >+ char *name; >+ int supported; >+}; >+ >+extern struct compressor *lookup_compressor(char *); >+extern struct compressor *lookup_compressor_id(int); >+extern void display_compressors(char *, char *); >diff -Naurp squashfs-tools/gzip_wrapper.c squashfs-tools-lzma/gzip_wrapper.c >--- squashfs-tools/gzip_wrapper.c 1970-01-01 00:00:00.000000000 +0000 >+++ squashfs-tools-lzma/gzip_wrapper.c 2009-10-20 04:03:37.000000000 +0000 >@@ -0,0 +1,80 @@ >+/* >+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 >+ * Phillip Lougher <phillip@lougher.demon.co.uk> >+ * >+ * 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. >+ * >+ * gzip_wrapper.c >+ */ >+ >+#include <stdlib.h> >+#include <zlib.h> >+ >+int gzip_compress(void **strm, char *d, char *s, int size, int block_size, >+ int *error) >+{ >+ int res = 0; >+ z_stream *stream = *strm; >+ >+ if(stream == NULL) { >+ if((stream = *strm = malloc(sizeof(z_stream))) == NULL) >+ goto failed; >+ >+ stream->zalloc = Z_NULL; >+ stream->zfree = Z_NULL; >+ stream->opaque = 0; >+ >+ if((res = deflateInit(stream, 9)) != Z_OK) >+ goto failed; >+ } else if((res = deflateReset(stream)) != Z_OK) >+ goto failed; >+ >+ stream->next_in = (unsigned char *) s; >+ stream->avail_in = size; >+ stream->next_out = (unsigned char *) d; >+ stream->avail_out = block_size; >+ >+ res = deflate(stream, Z_FINISH); >+ if(res == Z_STREAM_END) >+ /* >+ * Success, return the compressed size. >+ */ >+ return (int) stream->total_out; >+ if(res == Z_OK) >+ /* >+ * Output buffer overflow. Return out of buffer space >+ */ >+ return 0; >+failed: >+ /* >+ * All other errors return failure, with the compressor >+ * specific error code in *error >+ */ >+ *error = res; >+ return -1; >+} >+ >+ >+int gzip_uncompress(char *d, char *s, int size, int block_size, int *error) >+{ >+ int res; >+ unsigned long bytes = block_size; >+ >+ res = uncompress((unsigned char *) d, &bytes, >+ (const unsigned char *) s, size); >+ >+ *error = res; >+ return res == Z_OK ? (int) bytes : -1; >+} >diff -Naurp squashfs-tools/lzma_wrapper.c squashfs-tools-lzma/lzma_wrapper.c >--- squashfs-tools/lzma_wrapper.c 1970-01-01 00:00:00.000000000 +0000 >+++ squashfs-tools-lzma/lzma_wrapper.c 2009-10-14 03:32:57.000000000 +0000 >@@ -0,0 +1,93 @@ >+/* >+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 >+ * Phillip Lougher <phillip@lougher.demon.co.uk> >+ * >+ * 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 >+ */ >+ >+#include <LzmaLib.h> >+ >+#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8) >+ >+int lzma_compress(void **strm, char *dest, char *src, int size,int block_size, >+ int *error) >+{ >+ unsigned char *d = (unsigned char *) dest, *s = (unsigned char *) src; >+ size_t props_size = LZMA_PROPS_SIZE, >+ outlen = block_size - LZMA_HEADER_SIZE; >+ int res; >+ >+ res = LzmaCompress(d + LZMA_HEADER_SIZE, &outlen, s, size, d, >+ &props_size, 5, block_size, 3, 0, 2, 32, 1); >+ >+ if(res == SZ_ERROR_OUTPUT_EOF) { >+ /* >+ * Output buffer overflow. Return out of buffer space error >+ */ >+ return 0; >+ } >+ >+ if(res != SZ_OK) { >+ /* >+ * All other errors return failure, with the compressor >+ * specific error code in *error >+ */ >+ *error = res; >+ return -1; >+ } >+ >+ /* >+ * Fill in the 8 byte little endian uncompressed size field in the >+ * LZMA header. 8 bytes is excessively large for squashfs but >+ * this is the standard LZMA header and which is expected by the kernel >+ * code >+ */ >+ d[LZMA_PROPS_SIZE] = size & 255; >+ d[LZMA_PROPS_SIZE + 1] = (size >> 8) & 255; >+ d[LZMA_PROPS_SIZE + 2] = (size >> 16) & 255; >+ d[LZMA_PROPS_SIZE + 3] = (size >> 24) & 255; >+ d[LZMA_PROPS_SIZE + 4] = 0; >+ d[LZMA_PROPS_SIZE + 5] = 0; >+ d[LZMA_PROPS_SIZE + 6] = 0; >+ d[LZMA_PROPS_SIZE + 7] = 0; >+ >+ /* >+ * Success, return the compressed size. Outlen returned by the LZMA >+ * compressor does not include the LZMA header space >+ */ >+ return outlen + LZMA_HEADER_SIZE; >+} >+ >+ >+int lzma_uncompress(char *dest, char *src, int size, int block_size, >+ int *error) >+{ >+ unsigned char *d = (unsigned char *) dest, *s = (unsigned char *) 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(d, &outlen, s + LZMA_HEADER_SIZE, &inlen, >+ s, LZMA_PROPS_SIZE); >+ >+ *error = res; >+ return res == SZ_OK ? outlen : -1; >+} >diff -Naurp squashfs-tools/Makefile squashfs-tools-lzma/Makefile >--- squashfs-tools/Makefile 2009-04-05 02:03:36.000000000 +0000 >+++ squashfs-tools-lzma/Makefile 2009-10-22 04:17:12.000000000 +0000 >@@ -1,40 +1,76 @@ >+# >+# Building LZMA support >+# Download LZMA sdk (4.65 used in development, other versions may work), >+# set LZMA_DIR to unpacked source, and uncomment next line >+LZMA_SUPPORT = 1 >+LZMA_DIR = ../../ >+ >+#Compression default. >+COMP_DEFAULT = gzip >+ >+INCLUDEDIR = -I. > INSTALL_DIR = /usr/local/bin > >-INCLUDEDIR = . >+MKSQUASHFS_OBJS = mksquashfs.o read_fs.o sort.o swap.o pseudo.o compressor.o \ >+ gzip_wrapper.o >+ >+UNSQUASHFS_OBJS = unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o \ >+ unsquash-4.o swap.o compressor.o gzip_wrapper.o > >-CFLAGS := -I$(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE -O2 >+CFLAGS := $(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ >+ -D_GNU_SOURCE -DCOMP_DEFAULT=\"$(COMP_DEFAULT)\" -O2 -Wall > >+ifdef LZMA_SUPPORT >+LZMA_OBJS = $(LZMA_DIR)/C/Alloc.o $(LZMA_DIR)/C/LzFind.o \ >+ $(LZMA_DIR)/C/LzmaDec.o $(LZMA_DIR)/C/LzmaEnc.o $(LZMA_DIR)/C/LzmaLib.o >+INCLUDEDIR += -I$(LZMA_DIR)/C >+CFLAGS += -DLZMA_SUPPORT -I../../C >+MKSQUASHFS_OBJS += lzma_wrapper.o $(LZMA_OBJS) >+UNSQUASHFS_OBJS += lzma_wrapper.o $(LZMA_OBJS) >+endif >+ >+.PHONY: all > all: mksquashfs unsquashfs > >-mksquashfs: mksquashfs.o read_fs.o sort.o swap.o pseudo.o >- $(CC) mksquashfs.o read_fs.o sort.o swap.o pseudo.o -lz -lpthread -lm -o $@ >+mksquashfs: $(MKSQUASHFS_OBJS) >+ $(CC) $(MKSQUASHFS_OBJS) -lz -lpthread -lm -o $@ >+ >+mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h \ >+ squashfs_swap.h > >-mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h squashfs_swap.h Makefile >+read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h squashfs_swap.h > >-read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h squashfs_swap.h Makefile >+sort.o: sort.c squashfs_fs.h global.h sort.h > >-sort.o: sort.c squashfs_fs.h global.h sort.h Makefile >+swap.o: swap.c > >-swap.o: swap.c Makefile >+pseudo.o: pseudo.c pseudo.h > >-pseudo.o: pseudo.c pseudo.h Makefile >+compressor.o: compressor.c compressor.h > >-unsquashfs: unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o >- $(CC) unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o -lz -lpthread -lm -o $@ >+unsquashfs: $(UNSQUASHFS_OBJS) >+ $(CC) $(UNSQUASHFS_OBJS) -lz -lpthread -lm -o $@ > >-unsquashfs.o: unsquashfs.h unsquashfs.c squashfs_fs.h squashfs_swap.h squashfs_compat.h global.h Makefile >+unsquashfs.o: unsquashfs.h unsquashfs.c squashfs_fs.h squashfs_swap.h \ >+ squashfs_compat.h global.h > >-unsquash-1.o: unsquashfs.h unsquash-1.c squashfs_fs.h squashfs_compat.h global.h Makefile >+unsquash-1.o: unsquashfs.h unsquash-1.c squashfs_fs.h squashfs_compat.h \ >+ global.h > >-unsquash-2.o: unsquashfs.h unsquash-2.c unsquashfs.h squashfs_fs.h squashfs_compat.h global.h Makefile >+unsquash-2.o: unsquashfs.h unsquash-2.c unsquashfs.h squashfs_fs.h \ >+ squashfs_compat.h global.h > >-unsquash-3.o: unsquashfs.h unsquash-3.c squashfs_fs.h squashfs_compat.h global.h Makefile >+unsquash-3.o: unsquashfs.h unsquash-3.c squashfs_fs.h squashfs_compat.h \ >+ global.h > >-unsquash-4.o: unsquashfs.h unsquash-4.c squashfs_fs.h squashfs_swap.h global.h Makefile >+unsquash-4.o: unsquashfs.h unsquash-4.c squashfs_fs.h squashfs_swap.h \ >+ global.h > >+.PHONY: clean > clean: > -rm -f *.o mksquashfs unsquashfs > >+.PHONY: install > install: mksquashfs unsquashfs > mkdir -p $(INSTALL_DIR) > cp mksquashfs $(INSTALL_DIR) >diff -Naurp squashfs-tools/mksquashfs.c squashfs-tools-lzma/mksquashfs.c >--- squashfs-tools/mksquashfs.c 2009-04-05 21:22:48.000000000 +0000 >+++ squashfs-tools-lzma/mksquashfs.c 2009-10-20 04:03:38.000000000 +0000 >@@ -36,7 +36,6 @@ > #include <errno.h> > #include <dirent.h> > #include <string.h> >-#include <zlib.h> > #include <stdlib.h> > #include <signal.h> > #include <setjmp.h> >@@ -47,6 +46,7 @@ > #include <math.h> > #include <regex.h> > #include <fnmatch.h> >+#include <sys/wait.h> > > #ifndef linux > #define __BYTE_ORDER BYTE_ORDER >@@ -64,6 +64,7 @@ > #include "global.h" > #include "sort.h" > #include "pseudo.h" >+#include "compressor.h" > > #ifdef SQUASHFS_TRACE > #define TRACE(s, args...) do { \ >@@ -245,10 +246,8 @@ char **source_path; > /* list of root directory entries read from original filesystem */ > int old_root_entries = 0; > struct old_root_entry_info { >- char name[SQUASHFS_NAME_LEN + 1]; >- squashfs_inode inode; >- int type; >- int inode_number; >+ char *name; >+ struct inode_info inode; > }; > struct old_root_entry_info *old_root_entry; > >@@ -371,10 +370,15 @@ int writer_buffer_size; > int reader_buffer_size; > int fragment_buffer_size; > >+/* compression operations structure */ >+static struct compressor *comp; >+char *comp_name = COMP_DEFAULT; >+ > char *read_from_disk(long long start, unsigned int avail_bytes); > void add_old_root_entry(char *name, squashfs_inode inode, int inode_number, > int type); >-extern int read_super(int fd, squashfs_super_block *sBlk, char *source); >+extern struct compressor *read_super(int fd, squashfs_super_block *sBlk, >+ char *source); > extern long long read_filesystem(char *root_name, int fd, > squashfs_super_block *sBlk, char **cinode_table, char **data_cache, > char **cdirectory_table, char **directory_data_cache, >@@ -831,83 +835,32 @@ void sigalrm_handler() > } > > >-unsigned int mangle2(z_stream **strm, char *d, char *s, int size, >+int mangle2(void **strm, char *d, char *s, int size, > int block_size, int uncompressed, int data_block) > { >- unsigned long c_byte; >- unsigned int res; >- z_stream *stream = *strm; >- >- if(uncompressed) >- goto notcompressed; >- >- if(stream == NULL) { >- if((stream = *strm = malloc(sizeof(z_stream))) == NULL) >- BAD_ERROR("mangle::compress failed, not enough " >- "memory\n"); >- >- stream->zalloc = Z_NULL; >- stream->zfree = Z_NULL; >- stream->opaque = 0; >- >- if((res = deflateInit(stream, 9)) != Z_OK) { >- if(res == Z_MEM_ERROR) >- BAD_ERROR("zlib::compress failed, not enough " >- "memory\n"); >- else if(res == Z_STREAM_ERROR) >- BAD_ERROR("zlib::compress failed, not a valid " >- "compression level\n"); >- else if(res == Z_VERSION_ERROR) >- BAD_ERROR("zlib::compress failed, incorrect " >- "zlib version\n"); >- else >- BAD_ERROR("zlib::compress failed, unknown " >- "error %d\n", res); >- } >- } else if((res = deflateReset(stream)) != Z_OK) { >- if(res == Z_STREAM_ERROR) >- BAD_ERROR("zlib::compress failed, stream state " >- "inconsistent\n"); >- else >- BAD_ERROR("zlib::compress failed, unknown error %d\n", >- res); >- } >+ int error, c_byte = 0; > >- stream->next_in = (unsigned char *) s; >- stream->avail_in = size; >- stream->next_out = (unsigned char *) d; >- stream->avail_out = block_size; >- >- res = deflate(stream, Z_FINISH); >- if(res != Z_STREAM_END && res != Z_OK) { >- if(res == Z_STREAM_ERROR) >- BAD_ERROR("zlib::compress failed, stream state " >- "inconsistent\n"); >- else if(res == Z_BUF_ERROR) >- BAD_ERROR("zlib::compress failed, no progress possible" >- "\n"); >- else >- BAD_ERROR("zlib::compress failed, unknown error %d\n", >- res); >+ if(!uncompressed) { >+ c_byte = comp->compress(strm, d, s, size, block_size, &error); >+ if(c_byte == -1) >+ BAD_ERROR("mangle2:: %s compress failed with error " >+ "code %d\n", comp->name, error); > } > >- c_byte = stream->total_out; >- >- if(res != Z_STREAM_END || c_byte >= size) { >-notcompressed: >+ if(c_byte == 0 || c_byte >= size) { > memcpy(d, s, size); > return size | (data_block ? SQUASHFS_COMPRESSED_BIT_BLOCK : > SQUASHFS_COMPRESSED_BIT); > } > >- return (unsigned int) c_byte; >+ return c_byte; > } > > >-unsigned int mangle(char *d, char *s, int size, int block_size, >+int mangle(char *d, char *s, int size, int block_size, > int uncompressed, int data_block) > { >- static z_stream *stream = NULL; >+ static void *stream = NULL; > > return mangle2(&stream, d, s, size, block_size, uncompressed, > data_block); >@@ -1660,8 +1613,7 @@ struct file_buffer *get_fragment(struct > pthread_mutex_unlock(&fragment_mutex); > > if(SQUASHFS_COMPRESSED_BLOCK(disk_fragment->size)) { >- int res; >- unsigned long bytes = block_size; >+ int error, res; > char *data; > > if(compressed_buffer) >@@ -1669,19 +1621,11 @@ struct file_buffer *get_fragment(struct > else > data = read_from_disk(start_block, size); > >- res = uncompress((unsigned char *) buffer->data, &bytes, >- (const unsigned char *) data, size); >- if(res != Z_OK) { >- if(res == Z_MEM_ERROR) >- BAD_ERROR("zlib::uncompress failed, not enough " >- "memory\n"); >- else if(res == Z_BUF_ERROR) >- BAD_ERROR("zlib::uncompress failed, not enough " >- "room in output buffer\n"); >- else >- BAD_ERROR("zlib::uncompress failed," >- " unknown error %d\n", res); >- } >+ res = comp->uncompress(buffer->data, data, size, block_size, >+ &error); >+ if(res == -1) >+ BAD_ERROR("%s uncompress failed with error code %d\n", >+ comp->name, error); > } else if(compressed_buffer) > memcpy(buffer->data, compressed_buffer->data, size); > else >@@ -1733,9 +1677,7 @@ void unlock_fragments() > entry->buffer->block = bytes; > bytes += compressed_size; > fragments_outstanding --; >- pthread_mutex_unlock(&fragment_mutex); > queue_put(to_writer, entry->buffer); >- pthread_mutex_lock(&fragment_mutex); > TRACE("fragment_locked writing fragment %d, compressed size %d" > "\n", entry->fragment, compressed_size); > free(entry); >@@ -1758,6 +1700,8 @@ int add_pending_fragment(struct file_buf > pthread_mutex_lock(&fragment_mutex); > insert_fragment_list(&frag_locked_list, entry); > pthread_mutex_unlock(&fragment_mutex); >+ >+ return TRUE; > } > > >@@ -1824,7 +1768,9 @@ long long generic_write_table(int length > unsigned short c_byte; > char cbuffer[(SQUASHFS_METADATA_SIZE << 2) + 2]; > >+#ifdef SQUASHFS_TRACE > long long obytes = bytes; >+#endif > > for(i = 0; i < meta_blocks; i++) { > int avail_bytes = length > SQUASHFS_METADATA_SIZE ? >@@ -2170,11 +2116,85 @@ struct file_info *duplicate(long long fi > } > > >+static int seq = 0; >+void reader_read_process(struct dir_ent *dir_ent) >+{ >+ struct file_buffer *prev_buffer = NULL, *file_buffer; >+ int status, res, byte, count = 0; >+ int file = get_pseudo_file(dir_ent->inode->pseudo_id)->fd; >+ int child = get_pseudo_file(dir_ent->inode->pseudo_id)->child; >+ long long bytes = 0; >+ >+ while(1) { >+ file_buffer = cache_get(reader_buffer, 0, 0); >+ file_buffer->sequence = seq ++; >+ >+ byte = read_bytes(file, file_buffer->data, block_size); >+ if(byte == -1) >+ goto read_err; >+ >+ file_buffer->size = byte; >+ file_buffer->file_size = -1; >+ file_buffer->block = count ++; >+ file_buffer->error = FALSE; >+ file_buffer->fragment = FALSE; >+ bytes += byte; >+ >+ if(byte == 0) >+ break; >+ >+ /* >+ * Update estimated_uncompressed block count. This is done >+ * on every block rather than waiting for all blocks to be >+ * read incase write_file_process() is running in parallel >+ * with this. Otherwise cur uncompressed block count may >+ * get ahead of the total uncompressed block count. >+ */ >+ estimated_uncompressed ++; >+ >+ if(prev_buffer) >+ queue_put(from_reader, prev_buffer); >+ prev_buffer = file_buffer; >+ } >+ >+ /* >+ * Update inode file size now that the size of the dynamic pseudo file >+ * is known. This is needed for the -info option. >+ */ >+ dir_ent->inode->buf.st_size = bytes; >+ >+ res = waitpid(child, &status, 0); >+ if(res == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) >+ goto read_err; >+ >+ if(prev_buffer == NULL) >+ prev_buffer = file_buffer; >+ else { >+ cache_block_put(file_buffer); >+ seq --; >+ } >+ prev_buffer->file_size = bytes; >+ prev_buffer->fragment = !no_fragments && >+ (count == 2 || always_use_fragments) && (byte < block_size); >+ queue_put(from_reader, prev_buffer); >+ >+ return; >+ >+read_err: >+ if(prev_buffer) { >+ cache_block_put(file_buffer); >+ seq --; >+ file_buffer = prev_buffer; >+ } >+ file_buffer->error = TRUE; >+ queue_put(from_deflate, file_buffer); >+} >+ >+ > void reader_read_file(struct dir_ent *dir_ent) > { > struct stat *buf = &dir_ent->inode->buf, buf2; > struct file_buffer *file_buffer; >- static int index = 0; > int blocks, byte, count, expected, file, frag_block; > long long bytes, read_size; > >@@ -2202,7 +2222,7 @@ again: > if(file_buffer) > queue_put(from_reader, file_buffer); > file_buffer = cache_get(reader_buffer, 0, 0); >- file_buffer->sequence = index ++; >+ file_buffer->sequence = seq ++; > > byte = file_buffer->size = read_bytes(file, file_buffer->data, > block_size); >@@ -2238,7 +2258,7 @@ again: > > read_err: > file_buffer = cache_get(reader_buffer, 0, 0); >- file_buffer->sequence = index ++; >+ file_buffer->sequence = seq ++; > read_err2: > file_buffer->error = TRUE; > queue_put(from_deflate, file_buffer); >@@ -2262,9 +2282,14 @@ void reader_scan(struct dir_info *dir) { > for(i = 0; i < dir->count; i++) { > struct dir_ent *dir_ent = dir->list[i]; > struct stat *buf = &dir_ent->inode->buf; >- if(dir_ent->data) >+ if(dir_ent->inode->root_entry) > continue; > >+ if(dir_ent->inode->pseudo_file) { >+ reader_read_process(dir_ent); >+ continue; >+ } >+ > switch(buf->st_mode & S_IFMT) { > case S_IFREG: > reader_read_file(dir_ent); >@@ -2365,7 +2390,7 @@ int all_zero(struct file_buffer *file_bu > > void *deflator(void *arg) > { >- z_stream *stream = NULL; >+ void *stream = NULL; > int oldstate; > > pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); >@@ -2402,7 +2427,7 @@ void *deflator(void *arg) > > void *frag_deflator(void *arg) > { >- z_stream *stream = NULL; >+ void *stream = NULL; > int oldstate; > > pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); >@@ -2426,8 +2451,8 @@ void *frag_deflator(void *arg) > write_buffer->block = bytes; > bytes += compressed_size; > fragments_outstanding --; >- pthread_mutex_unlock(&fragment_mutex); > queue_put(to_writer, write_buffer); >+ pthread_mutex_unlock(&fragment_mutex); > TRACE("Writing fragment %lld, uncompressed size %d, " > "compressed size %d\n", file_buffer->block, > file_buffer->size, compressed_size); >@@ -2674,6 +2699,98 @@ void write_file_frag(squashfs_inode *ino > } > > >+int write_file_process(squashfs_inode *inode, struct dir_ent *dir_ent, >+ struct file_buffer *read_buffer, int *duplicate_file) >+{ >+ long long read_size, file_bytes, start; >+ struct fragment *fragment; >+ unsigned int *block_list = NULL; >+ int block = 0, status; >+ long long sparse = 0; >+ struct file_buffer *fragment_buffer = NULL; >+ >+ *duplicate_file = FALSE; >+ >+ lock_fragments(); >+ >+ file_bytes = 0; >+ start = bytes; >+ while (1) { >+ read_size = read_buffer->file_size; >+ if(read_buffer->fragment && read_buffer->c_byte) >+ fragment_buffer = read_buffer; >+ else { >+ block_list = realloc(block_list, (block + 1) * >+ sizeof(unsigned int)); >+ if(block_list == NULL) >+ BAD_ERROR("Out of memory allocating block_list" >+ "\n"); >+ block_list[block ++] = read_buffer->c_byte; >+ if(read_buffer->c_byte) { >+ read_buffer->block = bytes; >+ bytes += read_buffer->size; >+ cache_rehash(read_buffer, read_buffer->block); >+ file_bytes += read_buffer->size; >+ queue_put(to_writer, read_buffer); >+ } else { >+ sparse += read_buffer->size; >+ cache_block_put(read_buffer); >+ } >+ } >+ inc_progress_bar(); >+ >+ if(read_size != -1) >+ break; >+ >+ read_buffer = get_file_buffer(from_deflate); >+ if(read_buffer->error) >+ goto read_err; >+ } >+ >+ unlock_fragments(); >+ fragment = get_and_fill_fragment(fragment_buffer); >+ cache_block_put(fragment_buffer); >+ >+ if(duplicate_checking) >+ add_non_dup(read_size, file_bytes, block_list, start, fragment, >+ 0, 0, FALSE); >+ file_count ++; >+ total_bytes += read_size; >+ >+ if(read_size < (1LL << 32) && start < (1LL << 32) && sparse == 0) >+ create_inode(inode, dir_ent, SQUASHFS_FILE_TYPE, read_size, >+ start, block, block_list, fragment, NULL, 0); >+ else >+ create_inode(inode, dir_ent, SQUASHFS_LREG_TYPE, read_size, >+ start, block, block_list, fragment, NULL, sparse); >+ >+ if(duplicate_checking == FALSE) >+ free(block_list); >+ >+ return 0; >+ >+read_err: >+ cur_uncompressed -= block; >+ status = read_buffer->error; >+ bytes = start; >+ if(!block_device) { >+ int res; >+ >+ queue_put(to_writer, NULL); >+ if(queue_get(from_writer) != 0) >+ EXIT_MKSQUASHFS(); >+ res = ftruncate(fd, bytes); >+ if(res != 0) >+ BAD_ERROR("Failed to truncate dest file because %s\n", >+ strerror(errno)); >+ } >+ unlock_fragments(); >+ free(block_list); >+ cache_block_put(read_buffer); >+ return status; >+} >+ >+ > int write_file_blocks(squashfs_inode *inode, struct dir_ent *dir_ent, > long long read_size, struct file_buffer *read_buffer, > int *duplicate_file) >@@ -2941,7 +3058,10 @@ again: > > read_size = read_buffer->file_size; > >- if(read_size == 0) { >+ if(read_size == -1) >+ status = write_file_process(inode, dir_ent, read_buffer, >+ duplicate_file); >+ else if(read_size == 0) { > write_file_empty(inode, dir_ent, duplicate_file); > cache_block_put(read_buffer); > } else if(read_buffer->fragment && read_buffer->c_byte) >@@ -3036,6 +3156,8 @@ struct inode_info *lookup_inode(struct s > > memcpy(&inode->buf, buf, sizeof(struct stat)); > inode->read = FALSE; >+ inode->root_entry = FALSE; >+ inode->pseudo_file = FALSE; > inode->inode = SQUASHFS_INVALID_BLK; > inode->nlink = 1; > >@@ -3056,7 +3178,7 @@ struct inode_info *lookup_inode(struct s > > > inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir, >- struct inode_info *inode_info, void *data, struct dir_info *dir) >+ struct inode_info *inode_info, struct dir_info *dir) > { > if((dir->count % DIR_ENTRIES) == 0) { > dir->list = realloc(dir->list, (dir->count + DIR_ENTRIES) * >@@ -3075,8 +3197,7 @@ inline void add_dir_entry(char *name, ch > NULL; > dir->list[dir->count]->inode = inode_info; > dir->list[dir->count]->dir = sub_dir; >- dir->list[dir->count]->our_dir = dir; >- dir->list[dir->count++]->data = data; >+ dir->list[dir->count++]->our_dir = dir; > dir->byte_count += strlen(name) + sizeof(squashfs_dir_entry); > } > >@@ -3128,10 +3249,10 @@ int scan1_encomp_readdir(char *pathname, > > if(dir->count < old_root_entries) > for(i = 0; i < old_root_entries; i++) { >- if(old_root_entry[i].type == SQUASHFS_DIR_TYPE) >+ if(old_root_entry[i].inode.type == SQUASHFS_DIR_TYPE) > dir->directory_count ++; >- add_dir_entry(old_root_entry[i].name, "", NULL, NULL, >- &old_root_entry[i], dir); >+ add_dir_entry(old_root_entry[i].name, "", NULL, >+ &old_root_entry[i].inode, dir); > } > > while(index < source) { >@@ -3167,10 +3288,10 @@ int scan1_single_readdir(char *pathname, > > if(dir->count < old_root_entries) > for(i = 0; i < old_root_entries; i++) { >- if(old_root_entry[i].type == SQUASHFS_DIR_TYPE) >+ if(old_root_entry[i].inode.type == SQUASHFS_DIR_TYPE) > dir->directory_count ++; >- add_dir_entry(old_root_entry[i].name, "", NULL, NULL, >- &old_root_entry[i], dir); >+ add_dir_entry(old_root_entry[i].name, "", NULL, >+ &old_root_entry[i].inode, dir); > } > > if((d_name = readdir(dir->linuxdir)) != NULL) { >@@ -3215,7 +3336,7 @@ struct dir_ent *scan2_readdir(struct dir > int current_count; > > while((current_count = dir_info->current_count++) < dir_info->count) >- if(dir_info->list[current_count]->data) >+ if(dir_info->list[current_count]->inode->root_entry) > continue; > else > return dir_info->list[current_count]; >@@ -3240,11 +3361,11 @@ struct dir_ent *scan3_readdir(struct dir > int current_count; > > while((current_count = dir_info->current_count++) < dir_info->count) >- if(dir_info->list[current_count]->data) >- add_dir(dir_info->list[current_count]->data->inode, >- dir_info->list[current_count]->data->inode_number, >+ if(dir_info->list[current_count]->inode->root_entry) >+ add_dir(dir_info->list[current_count]->inode->inode, >+ dir_info->list[current_count]->inode->inode_number, > dir_info->list[current_count]->name, >- dir_info->list[current_count]->data->type, dir); >+ dir_info->list[current_count]->inode->type, dir); > else > return dir_info->list[current_count]; > return NULL; >@@ -3313,7 +3434,6 @@ void dir_scan(squashfs_inode *inode, cha > dir_ent->name = dir_ent->pathname = strdup(pathname); > dir_ent->dir = dir_info; > dir_ent->our_dir = NULL; >- dir_ent->data = NULL; > dir_info->dir_ent = dir_ent; > > if(sorted) >@@ -3383,7 +3503,7 @@ struct dir_info *dir_scan1(char *pathnam > sub_dir = NULL; > > add_dir_entry(dir_name, filename, sub_dir, lookup_inode(&buf), >- NULL, dir); >+ dir); > } > > scan1_freedir(dir); >@@ -3399,7 +3519,7 @@ struct dir_info *dir_scan2(struct dir_in > struct dir_ent *dir_ent; > struct pseudo_entry *pseudo_ent; > struct stat buf; >- static pseudo_ino = 1; >+ static int pseudo_ino = 1; > > if(dir == NULL && (dir = scan1_opendir("")) == NULL) > return NULL; >@@ -3415,6 +3535,29 @@ struct dir_info *dir_scan2(struct dir_in > > while((pseudo_ent = pseudo_readdir(pseudo)) != NULL) { > dir_ent = scan2_lookup(dir, pseudo_ent->name); >+ if(pseudo_ent->dev->type == 's') { >+ struct stat *buf; >+ if(dir_ent == NULL) { >+ ERROR("Pseudo set file \"%s\" does not exist " >+ "in source filesystem. Ignoring\n", >+ pseudo_ent->pathname); >+ continue; >+ } >+ if(dir_ent->inode->root_entry) { >+ ERROR("Pseudo set file \"%s\" is a pre-existing" >+ " file in the filesystem being appended" >+ " to. It cannot be modified. " >+ "Ignoring!\n", pseudo_ent->pathname); >+ continue; >+ } >+ buf = &dir_ent->inode->buf; >+ buf->st_mode = (buf->st_mode & S_IFMT) | >+ pseudo_ent->dev->mode; >+ buf->st_uid = pseudo_ent->dev->uid; >+ buf->st_gid = pseudo_ent->dev->gid; >+ continue; >+ } >+ > if(dir_ent) { > ERROR("Pseudo file \"%s\" exists in source filesystem " > "\"%s\"\n", pseudo_ent->pathname, >@@ -3444,8 +3587,29 @@ struct dir_info *dir_scan2(struct dir_in > buf.st_mtime = time(NULL); > buf.st_ino = pseudo_ino ++; > >- add_dir_entry(pseudo_ent->name, pseudo_ent->pathname, sub_dir, >- lookup_inode(&buf), NULL, dir); >+ if(pseudo_ent->dev->type == 'f') { >+#ifdef USE_TMP_FILE >+ struct stat buf2; >+ int res = stat(pseudo_ent->dev->filename, &buf2); >+ if(res == -1) { >+ ERROR("Stat on pseudo file \"%s\" failed, " >+ "skipping...", pseudo_ent->pathname); >+ continue; >+ } >+ buf.st_size = buf2.st_size; >+ add_dir_entry(pseudo_ent->name, >+ pseudo_ent->dev->filename, sub_dir, >+ lookup_inode(&buf), dir); >+#else >+ struct inode_info *inode = lookup_inode(&buf); >+ inode->pseudo_id = pseudo_ent->dev->pseudo_id; >+ inode->pseudo_file = TRUE; >+ add_dir_entry(pseudo_ent->name, pseudo_ent->pathname, >+ sub_dir, inode, dir); >+#endif >+ } else >+ add_dir_entry(pseudo_ent->name, pseudo_ent->pathname, >+ sub_dir, lookup_inode(&buf), dir); > } > > scan2_freedir(dir); >@@ -3482,8 +3646,9 @@ void dir_scan3(squashfs_inode *inode, st > &duplicate_file); > INFO("file %s, uncompressed size %lld " > "bytes %s\n", filename, >- buf->st_size, duplicate_file ? >- "DUPLICATE" : ""); >+ (long long) buf->st_size, >+ duplicate_file ? "DUPLICATE" : >+ ""); > break; > > case S_IFDIR: >@@ -3557,6 +3722,7 @@ void dir_scan3(squashfs_inode *inode, st > INFO("file %s, uncompressed " > "size %lld bytes LINK" > "\n", filename, >+ (long long) > buf->st_size); > break; > case SQUASHFS_SYMLINK_TYPE: >@@ -3667,10 +3833,11 @@ void add_old_root_entry(char *name, squa > BAD_ERROR("Out of memory in old root directory entries " > "reallocation\n"); > >- strcpy(old_root_entry[old_root_entries].name, name); >- old_root_entry[old_root_entries].inode = inode; >- old_root_entry[old_root_entries].inode_number = inode_number; >- old_root_entry[old_root_entries++].type = type; >+ old_root_entry[old_root_entries].name = strdup(name); >+ old_root_entry[old_root_entries].inode.inode = inode; >+ old_root_entry[old_root_entries].inode.inode_number = inode_number; >+ old_root_entry[old_root_entries].inode.type = type; >+ old_root_entry[old_root_entries++].inode.root_entry = TRUE; > } > > >@@ -4172,26 +4339,28 @@ int main(int argc, char *argv[]) > source_path = argv + 1; > source = i - 2; > for(; i < argc; i++) { >- if(strcmp(argv[i], "-pf") == 0) { >+ if(strcmp(argv[i], "-comp") == 0) { > if(++i == argc) { >- ERROR("%s: -pf missing filename\n", argv[0]); >+ ERROR("%s: -comp missing compression type\n", >+ argv[0]); > exit(1); > } >- if(read_pseudo_file(&pseudo, argv[i]) == FALSE) { >- ERROR("Failed to parse pseudo file \"%s\"\n", >- argv[i]); >+ comp_name = argv[i]; >+ } else if(strcmp(argv[i], "-pf") == 0) { >+ if(++i == argc) { >+ ERROR("%s: -pf missing filename\n", argv[0]); > exit(1); > } >+ if(read_pseudo_file(&pseudo, argv[i]) == FALSE) >+ exit(1); > } else if(strcmp(argv[i], "-p") == 0) { > if(++i == argc) { > ERROR("%s: -p missing pseudo file definition\n", > argv[0]); > exit(1); > } >- if(read_pseudo_def(&pseudo, argv[i]) == FALSE) { >- ERROR("Failed to parse pseudo definition\n"); >+ if(read_pseudo_def(&pseudo, argv[i]) == FALSE) > exit(1); >- } > } else if(strcmp(argv[i], "-recover") == 0) { > if(++i == argc) { > ERROR("%s: -recover missing recovery file\n", >@@ -4394,34 +4563,16 @@ int main(int argc, char *argv[]) > printOptions: > ERROR("SYNTAX:%s source1 source2 ... dest [options] " > "[-e list of exclude\ndirs/files]\n", argv[0]); >- ERROR("\nOptions are\n"); >- ERROR("-version\t\tprint version, licence and " >- "copyright message\n"); >- ERROR("-recover <name>\t\trecover filesystem data " >- "using recovery file <name>\n"); >- ERROR("-no-recovery\t\tdon't generate a recovery " >- "file\n"); >- ERROR("-info\t\t\tprint files written to filesystem\n"); >- ERROR("-no-exports\t\tdon't make the filesystem " >- "exportable via NFS\n"); >- ERROR("-no-progress\t\tdon't display the progress " >- "bar\n"); >- ERROR("-no-sparse\t\tdon't detect sparse files\n"); >+ ERROR("\nFilesystem build options:\n"); >+ ERROR("-comp <comp>\t\tselect <comp> compression\n"); >+ ERROR("\t\t\tCompressors available:\n"); >+ display_compressors("\t\t\t", COMP_DEFAULT); > ERROR("-b <block_size>\t\tset data block to " > "<block_size>. Default %d bytes\n", > SQUASHFS_FILE_SIZE); >- ERROR("-processors <number>\tUse <number> processors." >- " By default will use number of\n"); >- ERROR("\t\t\tprocessors available\n"); >- ERROR("-read-queue <size>\tSet input queue to <size> " >- "Mbytes. Default %d Mbytes\n", >- READER_BUFFER_DEFAULT); >- ERROR("-write-queue <size>\tSet output queue to <size> " >- "Mbytes. Default %d Mbytes\n", >- WRITER_BUFFER_DEFAULT); >- ERROR("-fragment-queue <size>\tSet fagment queue to " >- "<size> Mbytes. Default %d Mbytes\n", >- FRAGMENT_BUFFER_DEFAULT); >+ ERROR("-no-exports\t\tdon't make the filesystem " >+ "exportable via NFS\n"); >+ ERROR("-no-sparse\t\tdon't detect sparse files\n"); > ERROR("-noI\t\t\tdo not compress inode table\n"); > ERROR("-noD\t\t\tdo not compress data blocks\n"); > ERROR("-noF\t\t\tdo not compress fragment blocks\n"); >@@ -4430,13 +4581,34 @@ printOptions: > "files larger than block size\n"); > ERROR("-no-duplicates\t\tdo not perform duplicate " > "checking\n"); >- ERROR("-noappend\t\tdo not append to existing " >- "filesystem\n"); >+ ERROR("-all-root\t\tmake all files owned by root\n"); >+ ERROR("-force-uid uid\t\tset all file uids to uid\n"); >+ ERROR("-force-gid gid\t\tset all file gids to gid\n"); >+ ERROR("-nopad\t\t\tdo not pad filesystem to a multiple " >+ "of 4K\n"); > ERROR("-keep-as-directory\tif one source directory is " > "specified, create a root\n"); > ERROR("\t\t\tdirectory containing that directory, " > "rather than the\n"); > ERROR("\t\t\tcontents of the directory\n"); >+ ERROR("\nFilesystem filter options:\n"); >+ ERROR("-p <pseudo-definition>\tAdd pseudo file definition\n"); >+ ERROR("-pf <pseudo-file>\tAdd list of pseudo file definitions\n"); >+ ERROR("-sort <sort_file>\tsort files according to " >+ "priorities in <sort_file>. One\n"); >+ ERROR("\t\t\tfile or dir with priority per line. " >+ "Priority -32768 to\n"); >+ ERROR("\t\t\t32767, default priority 0\n"); >+ ERROR("-ef <exclude_file>\tlist of exclude dirs/files." >+ " One per line\n"); >+ ERROR("-wildcards\t\tAllow extended shell wildcards " >+ "(globbing) to be used in\n\t\t\texclude " >+ "dirs/files\n"); >+ ERROR("-regex\t\t\tAllow POSIX regular expressions to " >+ "be used in exclude\n\t\t\tdirs/files\n"); >+ ERROR("\nFilesystem append options:\n"); >+ ERROR("-noappend\t\tdo not append to existing " >+ "filesystem\n"); > ERROR("-root-becomes <name>\twhen appending source " > "files/directories, make the\n"); > ERROR("\t\t\toriginal root become a subdirectory in " >@@ -4444,11 +4616,29 @@ printOptions: > ERROR("\t\t\tcalled <name>, rather than adding the new " > "source items\n"); > ERROR("\t\t\tto the original root\n"); >- ERROR("-all-root\t\tmake all files owned by root\n"); >- ERROR("-force-uid uid\t\tset all file uids to uid\n"); >- ERROR("-force-gid gid\t\tset all file gids to gid\n"); >- ERROR("-nopad\t\t\tdo not pad filesystem to a multiple " >- "of 4K\n"); >+ ERROR("\nMksquashfs runtime options:\n"); >+ ERROR("-version\t\tprint version, licence and " >+ "copyright message\n"); >+ ERROR("-recover <name>\t\trecover filesystem data " >+ "using recovery file <name>\n"); >+ ERROR("-no-recovery\t\tdon't generate a recovery " >+ "file\n"); >+ ERROR("-info\t\t\tprint files written to filesystem\n"); >+ ERROR("-no-progress\t\tdon't display the progress " >+ "bar\n"); >+ ERROR("-processors <number>\tUse <number> processors." >+ " By default will use number of\n"); >+ ERROR("\t\t\tprocessors available\n"); >+ ERROR("-read-queue <size>\tSet input queue to <size> " >+ "Mbytes. Default %d Mbytes\n", >+ READER_BUFFER_DEFAULT); >+ ERROR("-write-queue <size>\tSet output queue to <size> " >+ "Mbytes. Default %d Mbytes\n", >+ WRITER_BUFFER_DEFAULT); >+ ERROR("-fragment-queue <size>\tSet fagment queue to " >+ "<size> Mbytes. Default %d Mbytes\n", >+ FRAGMENT_BUFFER_DEFAULT); >+ ERROR("\nMiscellaneous options:\n"); > ERROR("-root-owned\t\talternative name for -all-root" > "\n"); > ERROR("-noInodeCompression\talternative name for -noI" >@@ -4457,20 +4647,6 @@ printOptions: > "\n"); > ERROR("-noFragmentCompression\talternative name for " > "-noF\n"); >- ERROR("-sort <sort_file>\tsort files according to " >- "priorities in <sort_file>. One\n"); >- ERROR("\t\t\tfile or dir with priority per line. " >- "Priority -32768 to\n"); >- ERROR("\t\t\t32767, default priority 0\n"); >- ERROR("-ef <exclude_file>\tlist of exclude dirs/files." >- " One per line\n"); >- ERROR("-wildcards\t\tAllow extended shell wildcards " >- "(globbing) to be used in\n\t\t\texclude " >- "dirs/files\n"); >- ERROR("-regex\t\t\tAllow POSIX regular expressions to " >- "be used in exclude\n\t\t\tdirs/files\n"); >- ERROR("-p <pseudo-definition>\tAdd pseudo file definition\n"); >- ERROR("-pf <pseudo-file>\tAdd list of pseudo file definitions\n"); > exit(1); > } > } >@@ -4548,11 +4724,10 @@ printOptions: > fclose(fd); > } else if(strcmp(argv[i], "-e") == 0) > break; >- else if(strcmp(argv[i], "-b") == 0 || >- strcmp(argv[i], "-root-becomes") == 0 || >+ else if(strcmp(argv[i], "-root-becomes") == 0 || > strcmp(argv[i], "-sort") == 0 || > strcmp(argv[i], "-pf") == 0 || >- strcmp(argv[i], "-p") == 0) >+ strcmp(argv[i], "-comp") == 0) > i++; > > if(i != argc) { >@@ -4574,11 +4749,10 @@ printOptions: > sorted ++; > } else if(strcmp(argv[i], "-e") == 0) > break; >- else if(strcmp(argv[i], "-b") == 0 || >- strcmp(argv[i], "-root-becomes") == 0 || >+ else if(strcmp(argv[i], "-root-becomes") == 0 || > strcmp(argv[i], "-ef") == 0 || > strcmp(argv[i], "-pf") == 0 || >- strcmp(argv[i], "-p") == 0) >+ strcmp(argv[i], "-comp") == 0) > i++; > > #ifdef SQUASHFS_TRACE >@@ -4586,7 +4760,8 @@ printOptions: > #endif > > if(!delete) { >- if(read_super(fd, &sBlk, argv[source + 1]) == 0) { >+ comp = read_super(fd, &sBlk, argv[source + 1]); >+ if(comp == NULL) { > ERROR("Failed to read existing filesystem - will not " > "overwrite - ABORTING!\n"); > ERROR("To force Mksquashfs to write to this block " >@@ -4603,6 +4778,15 @@ printOptions: > always_use_fragments = SQUASHFS_ALWAYS_FRAGMENTS(sBlk.flags); > duplicate_checking = SQUASHFS_DUPLICATES(sBlk.flags); > exportable = SQUASHFS_EXPORTABLE(sBlk.flags); >+ } else { >+ comp = lookup_compressor(comp_name); >+ if(!comp->supported) { >+ ERROR("FATAL_ERROR: Compressor \"%s\" is not " >+ "supported!\n", comp_name); >+ ERROR("Compressors available:\n"); >+ display_compressors("", COMP_DEFAULT); >+ EXIT_MKSQUASHFS(); >+ } > } > > initialise_threads(); >@@ -4648,8 +4832,8 @@ printOptions: > "size %d\n", SQUASHFS_MAJOR, s_minor, argv[source + 1], > block_size); > printf("All -b, -noI, -noD, -noF, no-duplicates, no-fragments, " >- "-always-use-fragments and -exportable options ignored" >- "\n"); >+ "-always-use-fragments,\n-exportable and -comp options " >+ "ignored\n"); > printf("\nIf appending is not wanted, please re-run with " > "-noappend specified!\n\n"); > >@@ -4803,8 +4987,7 @@ restore_filesystem: > > sBlk.bytes_used = bytes; > >- /* Only compression supported */ >- sBlk.compression = ZLIB_COMPRESSION; >+ sBlk.compression = comp->id; > > /* Xattrs are not currently supported */ > sBlk.xattr_table_start = SQUASHFS_INVALID_BLK; >@@ -4820,6 +5003,8 @@ restore_filesystem: > > close(fd); > >+ delete_pseudo_files(); >+ > if(recovery_file[0] != '\0') > unlink(recovery_file); > >@@ -4827,9 +5012,9 @@ restore_filesystem: > * sizeof(unsigned short) + guid_count * sizeof(unsigned short) + > sizeof(squashfs_super_block); > >- printf("\n%sSquashfs %d.%d filesystem, data block size %d\n", >- exportable ? "Exportable " : "", SQUASHFS_MAJOR, SQUASHFS_MINOR, >- block_size); >+ printf("\n%sSquashfs %d.%d filesystem, %s compressed, data block size" >+ " %d\n", exportable ? "Exportable " : "", SQUASHFS_MAJOR, >+ SQUASHFS_MINOR, comp->name, block_size); > printf("\t%s data, %s metadata, %s fragments\n", > noD ? "uncompressed" : "compressed", noI ? "uncompressed" : > "compressed", no_fragments ? "no" : noF ? "uncompressed" : >diff -Naurp squashfs-tools/pseudo.c squashfs-tools-lzma/pseudo.c >--- squashfs-tools/pseudo.c 2009-04-05 02:01:58.000000000 +0000 >+++ squashfs-tools-lzma/pseudo.c 2009-10-20 04:03:38.000000000 +0000 >@@ -30,6 +30,7 @@ > #include <string.h> > #include <stdlib.h> > #include <sys/types.h> >+#include <sys/wait.h> > > #include "pseudo.h" > >@@ -55,6 +56,9 @@ > #define TRUE 1 > #define FALSE 0 > >+struct pseudo_dev **pseudo_file = NULL; >+int pseudo_count = 0; >+ > static void dump_pseudo(struct pseudo *pseudo, char *string) > { > int i; >@@ -99,7 +103,7 @@ struct pseudo *add_pseudo(struct pseudo > char *target, char *alltarget) > { > char targname[1024]; >- int i, error; >+ int i; > > target = get_component(target, targname); > >@@ -128,12 +132,8 @@ struct pseudo *add_pseudo(struct pseudo > if(target[0] == '\0') { > /* at leaf pathname component */ > pseudo->name[i].pseudo = NULL; >- pseudo->name[i].dev = malloc(sizeof(struct pseudo_dev)); >- if(pseudo->name[i].dev == NULL) >- BAD_ERROR("failed to allocate pseudo file\n"); > pseudo->name[i].pathname = strdup(alltarget); >- memcpy(pseudo->name[i].dev, pseudo_dev, >- sizeof(struct pseudo_dev)); >+ pseudo->name[i].dev = pseudo_dev; > } else { > /* recurse adding child components */ > pseudo->name[i].dev = NULL; >@@ -169,15 +169,9 @@ struct pseudo *add_pseudo(struct pseudo > if(target[0] == '\0') { > if(pseudo->name[i].dev == NULL && > pseudo_dev->type == 'd') { >- pseudo->name[i].dev = >- malloc(sizeof(struct pseudo_dev)); >- if(pseudo->name[i].dev == NULL) >- BAD_ERROR("failed to allocate " >- "pseudo file\n"); > pseudo->name[i].pathname = > strdup(alltarget); >- memcpy(pseudo->name[i].dev, pseudo_dev, >- sizeof(struct pseudo_dev)); >+ pseudo->name[i].dev = pseudo_dev; > } else > ERROR("%s already exists as a " > "directory. Ignoring %s!\n", >@@ -229,16 +223,113 @@ struct pseudo_entry *pseudo_readdir(stru > } > > >+int exec_file(char *command, struct pseudo_dev *dev) >+{ >+ int child, res; >+ static pid_t pid = -1; >+ int pipefd[2]; >+#ifdef USE_TMP_FILE >+ char filename[1024]; >+ int status; >+ static int number = 0; >+#endif >+ >+ if(pid == -1) >+ pid = getpid(); >+ >+#ifdef USE_TMP_FILE >+ sprintf(filename, "/tmp/squashfs_pseudo_%d_%d", pid, number ++); >+ pipefd[1] = open(filename, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU); >+ if(pipefd[1] == -1) { >+ printf("open failed\n"); >+ return -1; >+ } >+#else >+ res = pipe(pipefd); >+ if(res == -1) { >+ printf("pipe failed\n"); >+ return -1; >+ } >+#endif >+ >+ child = fork(); >+ if(child == -1) { >+ printf("fork failed\n"); >+ goto failed; >+ } >+ >+ if(child == 0) { >+ close(STDOUT_FILENO); >+ res = dup(pipefd[1]); >+ if(res == -1) { >+ printf("dup failed\n"); >+ exit(EXIT_FAILURE); >+ } >+ execl("/bin/sh", "sh", "-c", command, (char *) NULL); >+ printf("execl failed\n"); >+ exit(EXIT_FAILURE); >+ } >+ >+#ifdef USE_TMP_FILE >+ res = waitpid(child, &status, 0); >+ close(pipefd[1]); >+ if(res != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0) { >+ dev->filename = strdup(filename); >+ return 0; >+ } >+failed: >+ unlink(filename); >+ return -1; >+#else >+ close(pipefd[1]); >+ dev->fd = pipefd[0]; >+ dev->child = child; >+ return 0; >+failed: >+ return -1; >+#endif >+} >+ >+ >+void add_pseudo_file(struct pseudo_dev *dev) >+{ >+ pseudo_file = realloc(pseudo_file, (pseudo_count + 1) * >+ sizeof(struct pseudo_dev *)); >+ if(pseudo_file == NULL) >+ BAD_ERROR("Failed to realloc pseudo_file\n"); >+ >+ dev->pseudo_id = pseudo_count; >+ pseudo_file[pseudo_count ++] = dev; >+} >+ >+ >+void delete_pseudo_files() >+{ >+#ifdef USE_TMP_FILE >+ int i; >+ >+ for(i = 0; i < pseudo_count; i++) >+ unlink(pseudo_file[i]->filename); >+#endif >+} >+ >+ >+struct pseudo_dev *get_pseudo_file(int pseudo_id) >+{ >+ return pseudo_file[pseudo_id]; >+} >+ >+ > int read_pseudo_def(struct pseudo **pseudo, char *def) > { >- int n; >+ int n, bytes; > unsigned int major = 0, minor = 0, mode; > char filename[2048], type, suid[100], sgid[100], *ptr; > long long uid, gid; >- struct pseudo_dev dev; >+ struct pseudo_dev *dev; > >- n = sscanf(def, "%s %c %o %s %s %u %u", filename, &type, &mode, suid, sgid, >- &major, &minor); >+ n = sscanf(def, "%s %c %o %s %s %n", filename, &type, &mode, suid, >+ sgid, &bytes); > > if(n < 5) { > ERROR("Not enough or invalid arguments in pseudo file " >@@ -249,7 +340,9 @@ int read_pseudo_def(struct pseudo **pseu > switch(type) { > case 'b': > case 'c': >- if(n < 7) { >+ n = sscanf(def + bytes, "%u %u", &major, &minor); >+ >+ if(n < 2) { > ERROR("Not enough or invalid arguments in pseudo file " > "definition\n"); > goto error; >@@ -265,47 +358,15 @@ int read_pseudo_def(struct pseudo **pseu > goto error; > } > >- /* fall through */ >- case 'd': >- if(mode > 0777) { >- ERROR("Mode %o out of range\n", mode); >+ case 'f': >+ if(def[bytes] == '\0') { >+ ERROR("Not enough arguments in pseudo file " >+ "definition\n"); > goto error; >- } >- >- uid = strtoll(suid, &ptr, 10); >- if(*ptr == '\0') { >- if(uid < 0 || uid > ((1LL << 32) - 1)) { >- ERROR("Uid %s out of range\n", suid); >- goto error; >- } >- } else { >- struct passwd *pwuid = getpwnam(suid); >- if(pwuid) >- uid = pwuid->pw_uid; >- else { >- ERROR("Uid %s invalid uid or unknown user\n", >- suid); >- goto error; >- } >- } >- >- gid = strtoll(sgid, &ptr, 10); >- if(*ptr == '\0') { >- if(gid < 0 || gid > ((1LL << 32) - 1)) { >- ERROR("Gid %s out of range\n", sgid); >- goto error; >- } >- } else { >- struct group *grgid = getgrnam(sgid); >- if(grgid) >- gid = grgid->gr_gid; >- else { >- ERROR("Gid %s invalid uid or unknown user\n", >- sgid); >- goto error; >- } >- } >- >+ } >+ break; >+ case 'd': >+ case 'm': > break; > default: > ERROR("Unsupported type %c\n", type); >@@ -313,6 +374,43 @@ int read_pseudo_def(struct pseudo **pseu > } > > >+ if(mode > 0777) { >+ ERROR("Mode %o out of range\n", mode); >+ goto error; >+ } >+ >+ uid = strtoll(suid, &ptr, 10); >+ if(*ptr == '\0') { >+ if(uid < 0 || uid > ((1LL << 32) - 1)) { >+ ERROR("Uid %s out of range\n", suid); >+ goto error; >+ } >+ } else { >+ struct passwd *pwuid = getpwnam(suid); >+ if(pwuid) >+ uid = pwuid->pw_uid; >+ else { >+ ERROR("Uid %s invalid uid or unknown user\n", suid); >+ goto error; >+ } >+ } >+ >+ gid = strtoll(sgid, &ptr, 10); >+ if(*ptr == '\0') { >+ if(gid < 0 || gid > ((1LL << 32) - 1)) { >+ ERROR("Gid %s out of range\n", sgid); >+ goto error; >+ } >+ } else { >+ struct group *grgid = getgrnam(sgid); >+ if(grgid) >+ gid = grgid->gr_gid; >+ else { >+ ERROR("Gid %s invalid uid or unknown user\n", sgid); >+ goto error; >+ } >+ } >+ > switch(type) { > case 'b': > mode |= S_IFBLK; >@@ -323,16 +421,37 @@ int read_pseudo_def(struct pseudo **pseu > case 'd': > mode |= S_IFDIR; > break; >+ case 'f': >+ mode |= S_IFREG; >+ break; > } > >- dev.type = type; >- dev.mode = mode; >- dev.uid = uid; >- dev.gid = gid; >- dev.major = major; >- dev.minor = minor; >+ dev = malloc(sizeof(struct pseudo_dev)); >+ if(dev == NULL) >+ BAD_ERROR("Failed to create pseudo_dev\n"); >+ >+ dev->type = type; >+ dev->mode = mode; >+ dev->uid = uid; >+ dev->gid = gid; >+ dev->major = major; >+ dev->minor = minor; >+ >+ if(type == 'f') { >+ int res; >+ >+ printf("Executing dynamic pseudo file\n"); >+ printf("\t\"%s\"\n", def); >+ res = exec_file(def + bytes, dev); >+ if(res == -1) { >+ ERROR("Failed to execute dynamic pseudo file definition" >+ " \"%s\"\n", def); >+ return FALSE; >+ } >+ add_pseudo_file(dev); >+ } > >- *pseudo = add_pseudo(*pseudo, &dev, filename, filename); >+ *pseudo = add_pseudo(*pseudo, dev, filename, filename); > > return TRUE; > >diff -Naurp squashfs-tools/pseudo.h squashfs-tools-lzma/pseudo.h >--- squashfs-tools/pseudo.h 2009-04-04 01:44:24.000000000 +0000 >+++ squashfs-tools-lzma/pseudo.h 2009-10-20 04:03:38.000000000 +0000 >@@ -27,6 +27,12 @@ struct pseudo_dev { > unsigned int gid; > unsigned int major; > unsigned int minor; >+ int pseudo_id; >+ int fd; >+ int child; >+#ifdef USE_TMP_FILE >+ char *filename; >+#endif > }; > > struct pseudo_entry { >@@ -46,3 +52,5 @@ extern int read_pseudo_def(struct pseudo > extern int read_pseudo_file(struct pseudo **, char *); > extern struct pseudo *pseudo_subdir(char *, struct pseudo *); > extern struct pseudo_entry *pseudo_readdir(struct pseudo *); >+extern struct pseudo_dev *get_pseudo_file(int); >+extern void delete_pseudo_files(); >diff -Naurp squashfs-tools/read_fs.c squashfs-tools-lzma/read_fs.c >--- squashfs-tools/read_fs.c 2009-03-31 04:23:14.000000000 +0000 >+++ squashfs-tools-lzma/read_fs.c 2009-10-20 04:03:38.000000000 +0000 >@@ -36,7 +36,6 @@ extern unsigned int get_guid(unsigned in > #include <fcntl.h> > #include <errno.h> > #include <string.h> >-#include <zlib.h> > #include <sys/mman.h> > > #ifndef linux >@@ -51,6 +50,7 @@ extern unsigned int get_guid(unsigned in > #include "squashfs_swap.h" > #include "read_fs.h" > #include "global.h" >+#include "compressor.h" > > #include <stdlib.h> > >@@ -66,7 +66,9 @@ extern unsigned int get_guid(unsigned in > fprintf(stderr, s, ## args); \ > } while(0) > >-int read_block(int fd, long long start, long long *next, unsigned char *block, >+static struct compressor *comp; >+ >+int read_block(int fd, long long start, long long *next, void *block, > squashfs_super_block *sBlk) > { > unsigned short c_byte; >@@ -77,32 +79,24 @@ int read_block(int fd, long long start, > > if(SQUASHFS_COMPRESSED(c_byte)) { > char buffer[SQUASHFS_METADATA_SIZE]; >- int res; >- unsigned long bytes = SQUASHFS_METADATA_SIZE; >+ int error, res; > > c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); > read_destination(fd, start + offset, c_byte, buffer); > >- res = uncompress(block, &bytes, (const unsigned char *) buffer, >- c_byte); >- if(res != Z_OK) { >- if(res == Z_MEM_ERROR) >- ERROR("zlib::uncompress failed, not enough " >- "memory\n"); >- else if(res == Z_BUF_ERROR) >- ERROR("zlib::uncompress failed, not enough " >- "room in output buffer\n"); >- else >- ERROR("zlib::uncompress failed, unknown error " >- "%d\n", res); >+ res = comp->uncompress(block, buffer, c_byte, >+ SQUASHFS_METADATA_SIZE, &error); >+ if(res == -1) { >+ ERROR("%s uncompress failed with error code %d\n", >+ comp->name, error); > return 0; > } > if(next) > *next = start + offset + c_byte; >- return bytes; >+ return res; > } else { > c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); >- read_destination(fd, start + offset, c_byte, (char *) block); >+ read_destination(fd, start + offset, c_byte, block); > if(next) > *next = start + offset + c_byte; > return c_byte; >@@ -356,7 +350,7 @@ failed: > } > > >-int read_super(int fd, squashfs_super_block *sBlk, char *source) >+struct compressor *read_super(int fd, squashfs_super_block *sBlk, char *source) > { > read_destination(fd, SQUASHFS_START, sizeof(squashfs_super_block), > (char *) sBlk); >@@ -388,8 +382,18 @@ int read_super(int fd, squashfs_super_bl > goto failed_mount; > } > >+ /* Check the compression type */ >+ comp = lookup_compressor_id(sBlk->compression); >+ if(!comp->supported) { >+ ERROR("Filesystem on %s uses %s compression, this is" >+ "unsupported by this version\n", source, comp->name); >+ display_compressors("", ""); >+ goto failed_mount; >+ } >+ > printf("Found a valid %sSQUASHFS superblock on %s.\n", > SQUASHFS_EXPORTABLE(sBlk->flags) ? "exportable " : "", source); >+ printf("\tCompression used %s\n", comp->name); > printf("\tInodes are %scompressed\n", > SQUASHFS_UNCOMPRESSED_INODES(sBlk->flags) ? "un" : ""); > printf("\tData is %scompressed\n", >@@ -417,10 +421,10 @@ int read_super(int fd, squashfs_super_bl > TRACE("sBlk->lookup_table_start %llx\n", sBlk->lookup_table_start); > printf("\n"); > >- return TRUE; >+ return comp; > > failed_mount: >- return FALSE; >+ return NULL; > } > > >@@ -514,12 +518,17 @@ unsigned int *read_id_table(int fd, squa > SQUASHFS_INSWAP_ID_BLOCKS(index, indexes); > > for(i = 0; i < indexes; i++) { >- int length; >- length = read_block(fd, index[i], NULL, >+ int length = read_block(fd, index[i], NULL, > ((unsigned char *) id_table) + > (i * SQUASHFS_METADATA_SIZE), sBlk); > TRACE("Read id table block %d, from 0x%llx, length %d\n", i, > index[i], length); >+ if(length == 0) { >+ ERROR("Failed to read id table block %d, from 0x%llx, " >+ "length %d\n", i, index[i], length); >+ free(id_table); >+ return NULL; >+ } > } > > SQUASHFS_INSWAP_INTS(id_table, sBlk->no_ids); >@@ -563,6 +572,13 @@ int read_fragment_table(int fd, squashfs > (i * SQUASHFS_METADATA_SIZE), sBlk); > TRACE("Read fragment table block %d, from 0x%llx, length %d\n", > i, fragment_table_index[i], length); >+ if(length == 0) { >+ ERROR("Failed to read fragment table block %d, from " >+ "0x%llx, length %d\n", i, >+ fragment_table_index[i], length); >+ free(*fragment_table); >+ return 0; >+ } > } > > for(i = 0; i < sBlk->fragments; i++) >@@ -599,6 +615,13 @@ int read_inode_lookup_table(int fd, squa > (i * SQUASHFS_METADATA_SIZE), sBlk); > TRACE("Read inode lookup table block %d, from 0x%llx, length " > "%d\n", i, index[i], length); >+ if(length == 0) { >+ ERROR("Failed to read inode lookup table block %d, " >+ "from 0x%llx, length %d\n", i, index[i], >+ length); >+ free(*inode_lookup_table); >+ return 0; >+ } > } > > SQUASHFS_INSWAP_LONG_LONGS(*inode_lookup_table, sBlk->inodes); >diff -Naurp squashfs-tools/sort.c squashfs-tools-lzma/sort.c >--- squashfs-tools/sort.c 2009-03-31 04:25:53.000000000 +0000 >+++ squashfs-tools-lzma/sort.c 2009-10-20 04:03:38.000000000 +0000 >@@ -198,7 +198,7 @@ void generate_file_priorities(struct dir > while(dir->current_count < dir->count) { > struct dir_ent *dir_ent = dir->list[dir->current_count++]; > struct stat *buf = &dir_ent->inode->buf; >- if(dir_ent->data) >+ if(dir_ent->inode->root_entry) > continue; > > switch(buf->st_mode & S_IFMT) { >@@ -254,6 +254,7 @@ void sort_files_and_write(struct dir_inf > write_file(&inode, entry->dir, &duplicate_file); > INFO("file %s, uncompressed size %lld bytes %s" > "\n", entry->dir->pathname, >+ (long long) > entry->dir->inode->buf.st_size, > duplicate_file ? "DUPLICATE" : ""); > entry->dir->inode->inode = inode; >@@ -261,6 +262,7 @@ void sort_files_and_write(struct dir_inf > } else > INFO("file %s, uncompressed size %lld bytes " > "LINK\n", entry->dir->pathname, >+ (long long) > entry->dir->inode->buf.st_size); > } > } >diff -Naurp squashfs-tools/sort.h squashfs-tools-lzma/sort.h >--- squashfs-tools/sort.h 2009-02-08 12:02:53.000000000 +0000 >+++ squashfs-tools-lzma/sort.h 2009-10-20 04:03:38.000000000 +0000 >@@ -42,17 +42,19 @@ struct dir_ent { > struct inode_info *inode; > struct dir_info *dir; > struct dir_info *our_dir; >- struct old_root_entry_info *data; > }; > > struct inode_info { >- unsigned int nlink; > struct stat buf; >+ struct inode_info *next; > squashfs_inode inode; >- unsigned int type; > unsigned int inode_number; >+ unsigned int nlink; >+ int pseudo_id; >+ char type; > char read; >- struct inode_info *next; >+ char root_entry; >+ char pseudo_file; > }; > > struct priority_entry { >diff -Naurp squashfs-tools/squashfs_compat.h squashfs-tools-lzma/squashfs_compat.h >--- squashfs-tools/squashfs_compat.h 2009-03-16 04:27:27.000000000 +0000 >+++ squashfs-tools-lzma/squashfs_compat.h 2009-10-20 04:03:38.000000000 +0000 >@@ -777,11 +777,10 @@ typedef union squashfs_inode_header_2 sq > #endif > > #define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\ >- int bits;\ >- int b_pos = pos % 8;\ >- unsigned long long val = 0;\ >- unsigned char *s = (unsigned char *)p + (pos / 8);\ >- unsigned char *d = ((unsigned char *) &val) + 7;\ >+ b_pos = pos % 8;\ >+ val = 0;\ >+ s = (unsigned char *)p + (pos / 8);\ >+ d = ((unsigned char *) &val) + 7;\ > for(bits = 0; bits < (tbits + b_pos); bits += 8) \ > *d-- = *s++;\ > value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\ >diff -Naurp squashfs-tools/squashfs_fs.h squashfs-tools-lzma/squashfs_fs.h >--- squashfs-tools/squashfs_fs.h 2009-03-18 02:50:20.000000000 +0000 >+++ squashfs-tools-lzma/squashfs_fs.h 2009-10-20 04:03:38.000000000 +0000 >@@ -229,6 +229,7 @@ typedef long long squashfs_block_t; > typedef long long squashfs_inode_t; > > #define ZLIB_COMPRESSION 1 >+#define LZMA_COMPRESSION 2 > > struct squashfs_super_block { > unsigned int s_magic; >diff -Naurp squashfs-tools/unsquash-3.c squashfs-tools-lzma/unsquash-3.c >--- squashfs-tools/unsquash-3.c 2009-03-31 04:35:10.000000000 +0000 >+++ squashfs-tools-lzma/unsquash-3.c 2009-10-20 04:03:38.000000000 +0000 >@@ -36,7 +36,7 @@ int read_fragment_table_3() > sBlk.fragment_table_start); > > if(sBlk.fragments == 0) >- return; >+ return TRUE; > > if((fragment_table = malloc(sBlk.fragments * > sizeof(squashfs_fragment_entry_3))) == NULL) >diff -Naurp squashfs-tools/unsquash-4.c squashfs-tools-lzma/unsquash-4.c >--- squashfs-tools/unsquash-4.c 2009-03-31 04:38:31.000000000 +0000 >+++ squashfs-tools-lzma/unsquash-4.c 2009-10-20 04:03:38.000000000 +0000 >@@ -38,7 +38,7 @@ int read_fragment_table_4() > sBlk.fragment_table_start); > > if(sBlk.fragments == 0) >- return; >+ return TRUE; > > if((fragment_table = malloc(sBlk.fragments * > sizeof(squashfs_fragment_entry))) == NULL) >diff -Naurp squashfs-tools/unsquashfs.c squashfs-tools-lzma/unsquashfs.c >--- squashfs-tools/unsquashfs.c 2009-04-05 21:23:06.000000000 +0000 >+++ squashfs-tools-lzma/unsquashfs.c 2009-10-20 04:03:39.000000000 +0000 >@@ -25,6 +25,9 @@ > #include "squashfs_swap.h" > #include "squashfs_compat.h" > #include "read_fs.h" >+#include "compressor.h" >+ >+#include <sys/sysinfo.h> > > struct cache *fragment_cache, *data_cache; > struct queue *to_reader, *to_deflate, *to_writer, *from_writer; >@@ -36,6 +39,7 @@ int processors = -1; > > struct super_block sBlk; > squashfs_operations s_ops; >+struct compressor *comp; > > int bytes = 0, swap, file_count = 0, dir_count = 0, sym_count = 0, > dev_count = 0, fifo_count = 0; >@@ -590,31 +594,23 @@ int read_block(long long start, long lon > offset = 3; > if(SQUASHFS_COMPRESSED(c_byte)) { > char buffer[SQUASHFS_METADATA_SIZE]; >- int res; >- unsigned long bytes = SQUASHFS_METADATA_SIZE; >+ int error, res; > > c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); > if(read_bytes(start + offset, c_byte, buffer) == FALSE) > goto failed; > >- res = uncompress((unsigned char *) block, &bytes, >- (const unsigned char *) buffer, c_byte); >+ res = comp->uncompress(block, buffer, c_byte, >+ SQUASHFS_METADATA_SIZE, &error); > >- if(res != Z_OK) { >- if(res == Z_MEM_ERROR) >- ERROR("zlib::uncompress failed, not enough " >- "memory\n"); >- else if(res == Z_BUF_ERROR) >- ERROR("zlib::uncompress failed, not enough " >- "room in output buffer\n"); >- else >- ERROR("zlib::uncompress failed, unknown error " >- "%d\n", res); >+ if(res == -1) { >+ ERROR("%s uncompress failed with error code %d\n", >+ comp->name, error); > goto failed; > } > if(next) > *next = start + offset + c_byte; >- return bytes; >+ return res; > } else { > c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); > if(read_bytes(start + offset, c_byte, block) == FALSE) >@@ -632,36 +628,26 @@ failed: > > int read_data_block(long long start, unsigned int size, char *block) > { >- int res; >- unsigned long bytes = block_size; >+ int error, res; > int c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(size); > > TRACE("read_data_block: block @0x%llx, %d %s bytes\n", start, >- SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte), >- SQUASHFS_COMPRESSED_BLOCK(c_byte) ? "compressed" : >+ c_byte, SQUASHFS_COMPRESSED_BLOCK(size) ? "compressed" : > "uncompressed"); > > if(SQUASHFS_COMPRESSED_BLOCK(size)) { > if(read_bytes(start, c_byte, data) == FALSE) > goto failed; > >- res = uncompress((unsigned char *) block, &bytes, >- (const unsigned char *) data, c_byte); >+ res = comp->uncompress(block, data, c_byte, block_size, &error); > >- if(res != Z_OK) { >- if(res == Z_MEM_ERROR) >- ERROR("zlib::uncompress failed, not enough " >- "memory\n"); >- else if(res == Z_BUF_ERROR) >- ERROR("zlib::uncompress failed, not enough " >- "room in output buffer\n"); >- else >- ERROR("zlib::uncompress failed, unknown error " >- "%d\n", res); >+ if(res == -1) { >+ ERROR("%s uncompress failed with error code %d\n", >+ comp->name, error); > goto failed; > } > >- return bytes; >+ return res; > } else { > if(read_bytes(start, c_byte, block) == FALSE) > goto failed; >@@ -671,7 +657,7 @@ int read_data_block(long long start, uns > > failed: > ERROR("read_data_block: failed to read block @0x%llx, size %d\n", start, >- size); >+ c_byte); > return FALSE; > } > >@@ -1383,6 +1369,11 @@ void squashfs_stat(char *source) > #endif > printf("Creation or last append time %s", mkfs_str ? mkfs_str : > "failed to get time\n"); >+ printf("Filesystem size %.2f Kbytes (%.2f Mbytes)\n", >+ sBlk.bytes_used / 1024.0, sBlk.bytes_used / (1024.0 * 1024.0)); >+ if(sBlk.s_major == 4) >+ printf("Compression %s\n", comp->name); >+ printf("Block size %d\n", sBlk.block_size); > printf("Filesystem is %sexportable via NFS\n", > SQUASHFS_EXPORTABLE(sBlk.flags) ? "" : "not "); > >@@ -1409,9 +1400,6 @@ void squashfs_stat(char *source) > SQUASHFS_DUPLICATES(sBlk.flags) ? "" : "not "); > else > printf("Duplicates are removed\n"); >- printf("Filesystem size %.2f Kbytes (%.2f Mbytes)\n", >- sBlk.bytes_used / 1024.0, sBlk.bytes_used / (1024.0 * 1024.0)); >- printf("Block size %d\n", sBlk.block_size); > if(sBlk.s_major > 1) > printf("Number of fragments %d\n", sBlk.fragments); > printf("Number of inodes %d\n", sBlk.inodes); >@@ -1459,6 +1447,18 @@ int read_super(char *source) > s_ops.read_inode = read_inode_4; > s_ops.read_uids_guids = read_uids_guids_4; > memcpy(&sBlk, &sBlk_4, sizeof(sBlk_4)); >+ >+ /* >+ * Check the compression type >+ */ >+ comp = lookup_compressor_id(sBlk.compression); >+ if(!comp->supported) { >+ ERROR("Filesystem uses %s compression, this is " >+ "unsupported by this version\n", comp->name); >+ ERROR("Decompressors available:\n"); >+ display_compressors("", ""); >+ goto failed_mount; >+ } > return TRUE; > } > >@@ -1548,6 +1548,11 @@ int read_super(char *source) > goto failed_mount; > } > >+ /* >+ * 1.x, 2.x and 3.x filesystems use gzip compression. Gzip is always >+ * suppported. >+ */ >+ comp = lookup_compressor("gzip"); > return TRUE; > > failed_mount: >@@ -1707,32 +1712,24 @@ void *deflator(void *arg) > > while(1) { > struct cache_entry *entry = queue_get(to_deflate); >- int res; >- unsigned long bytes = block_size; >+ int error, res; > >- res = uncompress((unsigned char *) tmp, &bytes, >- (const unsigned char *) entry->data, >- SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size)); >- >- if(res != Z_OK) { >- if(res == Z_MEM_ERROR) >- ERROR("zlib::uncompress failed, not enough" >- "memory\n"); >- else if(res == Z_BUF_ERROR) >- ERROR("zlib::uncompress failed, not enough " >- "room in output buffer\n"); >- else >- ERROR("zlib::uncompress failed, unknown error " >- "%d\n", res); >- } else >- memcpy(entry->data, tmp, bytes); >+ res = comp->uncompress(tmp, entry->data, >+ SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size), block_size, >+ &error); >+ >+ if(res == -1) >+ ERROR("%s uncompress failed with error code %d\n", >+ comp->name, error); >+ else >+ memcpy(entry->data, tmp, res); > > /* > * block has been either successfully decompressed, or an error > * occurred, clear pending flag, set error appropriately and > * wake up any threads waiting on this block > */ >- cache_block_ready(entry, res != Z_OK); >+ cache_block_ready(entry, res == -1); > } > } > >@@ -1938,7 +1935,6 @@ int main(int argc, char *argv[]) > int fragment_buffer_size = FRAGMENT_BUFFER_DEFAULT; > int data_buffer_size = DATA_BUFFER_DEFAULT; > char *b; >- struct winsize winsize; > > pthread_mutex_init(&screen_mutex, NULL); > root_process = geteuid() == 0; >@@ -2087,6 +2083,8 @@ options: > "regular expressions\n"); > ERROR("\t\t\t\trather than use the default shell " > "wildcard\n\t\t\t\texpansion (globbing)\n"); >+ ERROR("\nDecompressors available:\n"); >+ display_compressors("", ""); > } > exit(1); > } >diff -Naurp squashfs-tools/unsquashfs.h squashfs-tools-lzma/unsquashfs.h >--- squashfs-tools/unsquashfs.h 2009-03-29 02:29:02.000000000 +0000 >+++ squashfs-tools-lzma/unsquashfs.h 2009-10-20 04:03:39.000000000 +0000 >@@ -31,7 +31,6 @@ > #include <fcntl.h> > #include <errno.h> > #include <string.h> >-#include <zlib.h> > #include <sys/mman.h> > #include <utime.h> > #include <pwd.h>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 207737
:
141916
|
141918
|
141919
|
141920
|
141922
|
149004
|
171877
|
171897
|
171910
|
196292
|
212452
| 212454 |
212455