wok diff squashfs/stuff/lzma.u @ rev 4702
squashfs: add lzma support
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Sun Jan 03 18:38:54 2010 +0100 (2010-01-03) |
parents | |
children | 9f7f4d06661f |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/squashfs/stuff/lzma.u Sun Jan 03 18:38:54 2010 +0100 1.3 @@ -0,0 +1,2235 @@ 1.4 +--- squashfs-4.0/squashfs-tools/Makefile 1.5 ++++ squashfs-4.0/squashfs-tools/Makefile 1.6 +@@ -1,40 +1,76 @@ 1.7 ++# 1.8 ++# Building LZMA support 1.9 ++# Download LZMA sdk (4.65 used in development, other versions may work), 1.10 ++# set LZMA_DIR to unpacked source, and uncomment next line 1.11 ++LZMA_SUPPORT = 1 1.12 ++LZMA_DIR = ../LZMA/lzma465 1.13 ++ 1.14 ++#Compression default. 1.15 ++COMP_DEFAULT = gzip 1.16 ++ 1.17 ++INCLUDEDIR = -I. 1.18 + INSTALL_DIR = /usr/local/bin 1.19 + 1.20 +-INCLUDEDIR = . 1.21 ++MKSQUASHFS_OBJS = mksquashfs.o read_fs.o sort.o swap.o pseudo.o compressor.o \ 1.22 ++ gzip_wrapper.o 1.23 + 1.24 +-CFLAGS := -I$(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE -O2 1.25 ++UNSQUASHFS_OBJS = unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o \ 1.26 ++ unsquash-4.o swap.o compressor.o gzip_wrapper.o 1.27 + 1.28 ++CFLAGS = $(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ 1.29 ++ -D_GNU_SOURCE -DCOMP_DEFAULT=\"$(COMP_DEFAULT)\" -O2 -Wall 1.30 ++ 1.31 ++ifdef LZMA_SUPPORT 1.32 ++LZMA_OBJS = $(LZMA_DIR)/C/Alloc.o $(LZMA_DIR)/C/LzFind.o \ 1.33 ++ $(LZMA_DIR)/C/LzmaDec.o $(LZMA_DIR)/C/LzmaEnc.o $(LZMA_DIR)/C/LzmaLib.o 1.34 ++INCLUDEDIR += -I$(LZMA_DIR)/C 1.35 ++CFLAGS += -DLZMA_SUPPORT 1.36 ++MKSQUASHFS_OBJS += lzma_wrapper.o $(LZMA_OBJS) 1.37 ++UNSQUASHFS_OBJS += lzma_wrapper.o $(LZMA_OBJS) 1.38 ++endif 1.39 ++ 1.40 ++.PHONY: all 1.41 + all: mksquashfs unsquashfs 1.42 + 1.43 +-mksquashfs: mksquashfs.o read_fs.o sort.o swap.o pseudo.o 1.44 +- $(CC) mksquashfs.o read_fs.o sort.o swap.o pseudo.o -lz -lpthread -lm -o $@ 1.45 ++mksquashfs: $(MKSQUASHFS_OBJS) 1.46 ++ $(CC) $(MKSQUASHFS_OBJS) -lz -lpthread -lm -o $@ 1.47 + 1.48 +-mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h squashfs_swap.h Makefile 1.49 ++mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h \ 1.50 ++ squashfs_swap.h 1.51 + 1.52 +-read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h squashfs_swap.h Makefile 1.53 ++read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h squashfs_swap.h 1.54 + 1.55 +-sort.o: sort.c squashfs_fs.h global.h sort.h Makefile 1.56 ++sort.o: sort.c squashfs_fs.h global.h sort.h 1.57 + 1.58 +-swap.o: swap.c Makefile 1.59 ++swap.o: swap.c 1.60 + 1.61 +-pseudo.o: pseudo.c pseudo.h Makefile 1.62 ++pseudo.o: pseudo.c pseudo.h 1.63 + 1.64 +-unsquashfs: unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o 1.65 +- $(CC) unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o -lz -lpthread -lm -o $@ 1.66 ++compressor.o: compressor.c compressor.h 1.67 + 1.68 +-unsquashfs.o: unsquashfs.h unsquashfs.c squashfs_fs.h squashfs_swap.h squashfs_compat.h global.h Makefile 1.69 ++unsquashfs: $(UNSQUASHFS_OBJS) 1.70 ++ $(CC) $(UNSQUASHFS_OBJS) -lz -lpthread -lm -o $@ 1.71 + 1.72 +-unsquash-1.o: unsquashfs.h unsquash-1.c squashfs_fs.h squashfs_compat.h global.h Makefile 1.73 ++unsquashfs.o: unsquashfs.h unsquashfs.c squashfs_fs.h squashfs_swap.h \ 1.74 ++ squashfs_compat.h global.h 1.75 + 1.76 +-unsquash-2.o: unsquashfs.h unsquash-2.c unsquashfs.h squashfs_fs.h squashfs_compat.h global.h Makefile 1.77 ++unsquash-1.o: unsquashfs.h unsquash-1.c squashfs_fs.h squashfs_compat.h \ 1.78 ++ global.h 1.79 + 1.80 +-unsquash-3.o: unsquashfs.h unsquash-3.c squashfs_fs.h squashfs_compat.h global.h Makefile 1.81 ++unsquash-2.o: unsquashfs.h unsquash-2.c unsquashfs.h squashfs_fs.h \ 1.82 ++ squashfs_compat.h global.h 1.83 + 1.84 +-unsquash-4.o: unsquashfs.h unsquash-4.c squashfs_fs.h squashfs_swap.h global.h Makefile 1.85 ++unsquash-3.o: unsquashfs.h unsquash-3.c squashfs_fs.h squashfs_compat.h \ 1.86 ++ global.h 1.87 + 1.88 ++unsquash-4.o: unsquashfs.h unsquash-4.c squashfs_fs.h squashfs_swap.h \ 1.89 ++ global.h 1.90 ++ 1.91 ++.PHONY: clean 1.92 + clean: 1.93 + -rm -f *.o mksquashfs unsquashfs 1.94 + 1.95 ++.PHONY: install 1.96 + install: mksquashfs unsquashfs 1.97 + mkdir -p $(INSTALL_DIR) 1.98 + cp mksquashfs $(INSTALL_DIR) 1.99 + 1.100 +--- squashfs-4.0/squashfs-tools/compressor.c Thu Jan 1 01:00:00 1970 1.101 ++++ squashfs-4.0/squashfs-tools/compressor.c Sat Aug 29 03:05:34 2009 1.102 +@@ -0,0 +1,78 @@ 1.103 ++/* 1.104 ++ * 1.105 ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 1.106 ++ * Phillip Lougher <phillip@lougher.demon.co.uk> 1.107 ++ * 1.108 ++ * This program is free software; you can redistribute it and/or 1.109 ++ * modify it under the terms of the GNU General Public License 1.110 ++ * as published by the Free Software Foundation; either version 2, 1.111 ++ * or (at your option) any later version. 1.112 ++ * 1.113 ++ * This program is distributed in the hope that it will be useful, 1.114 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of 1.115 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.116 ++ * GNU General Public License for more details. 1.117 ++ * 1.118 ++ * You should have received a copy of the GNU General Public License 1.119 ++ * along with this program; if not, write to the Free Software 1.120 ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 1.121 ++ * 1.122 ++ * compressor.c 1.123 ++ */ 1.124 ++ 1.125 ++#include <stdio.h> 1.126 ++#include <string.h> 1.127 ++#include "compressor.h" 1.128 ++#include "squashfs_fs.h" 1.129 ++ 1.130 ++extern int gzip_compress(void **, char *, char *, int, int, int *); 1.131 ++extern int gzip_uncompress(char *, char *, int, int, int *); 1.132 ++extern int lzma_compress(void **, char *, char *, int, int, int *); 1.133 ++extern int lzma_uncompress(char *, char *, int, int, int *); 1.134 ++ 1.135 ++struct compressor compressor[] = { 1.136 ++ { gzip_compress, gzip_uncompress, ZLIB_COMPRESSION, "gzip", 1 }, 1.137 ++#ifdef LZMA_SUPPORT 1.138 ++ { lzma_compress, lzma_uncompress, LZMA_COMPRESSION, "lzma", 1 }, 1.139 ++#else 1.140 ++ { NULL, NULL, LZMA_COMPRESSION, "lzma", 0 }, 1.141 ++#endif 1.142 ++ { NULL, NULL , 0, "unknown", 0} 1.143 ++}; 1.144 ++ 1.145 ++ 1.146 ++struct compressor *lookup_compressor(char *name) 1.147 ++{ 1.148 ++ int i; 1.149 ++ 1.150 ++ for(i = 0; compressor[i].id; i++) 1.151 ++ if(strcmp(compressor[i].name, name) == 0) 1.152 ++ break; 1.153 ++ 1.154 ++ return &compressor[i]; 1.155 ++} 1.156 ++ 1.157 ++ 1.158 ++struct compressor *lookup_compressor_id(int id) 1.159 ++{ 1.160 ++ int i; 1.161 ++ 1.162 ++ for(i = 0; compressor[i].id; i++) 1.163 ++ if(id == compressor[i].id) 1.164 ++ break; 1.165 ++ 1.166 ++ return &compressor[i]; 1.167 ++} 1.168 ++ 1.169 ++ 1.170 ++void display_compressors(char *indent, char *def_comp) 1.171 ++{ 1.172 ++ int i; 1.173 ++ 1.174 ++ for(i = 0; compressor[i].id; i++) 1.175 ++ if(compressor[i].supported) 1.176 ++ fprintf(stderr, "%s\t%s%s\n", indent, 1.177 ++ compressor[i].name, 1.178 ++ strcmp(compressor[i].name, def_comp) == 0 ? 1.179 ++ " (default)" : ""); 1.180 ++} 1.181 + 1.182 +--- squashfs-4.0/squashfs-tools/compressor.h Thu Jan 1 01:00:00 1970 1.183 ++++ squashfs-4.0/squashfs-tools/compressor.h Mon Aug 24 20:28:04 2009 1.184 +@@ -0,0 +1,33 @@ 1.185 ++/* 1.186 ++ * 1.187 ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 1.188 ++ * Phillip Lougher <phillip@lougher.demon.co.uk> 1.189 ++ * 1.190 ++ * This program is free software; you can redistribute it and/or 1.191 ++ * modify it under the terms of the GNU General Public License 1.192 ++ * as published by the Free Software Foundation; either version 2, 1.193 ++ * or (at your option) any later version. 1.194 ++ * 1.195 ++ * This program is distributed in the hope that it will be useful, 1.196 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of 1.197 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.198 ++ * GNU General Public License for more details. 1.199 ++ * 1.200 ++ * You should have received a copy of the GNU General Public License 1.201 ++ * along with this program; if not, write to the Free Software 1.202 ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 1.203 ++ * 1.204 ++ * compressor.h 1.205 ++ */ 1.206 ++ 1.207 ++struct compressor { 1.208 ++ int (*compress)(void **, char *, char *, int, int, int *); 1.209 ++ int (*uncompress)(char *, char *, int, int, int *); 1.210 ++ int id; 1.211 ++ char *name; 1.212 ++ int supported; 1.213 ++}; 1.214 ++ 1.215 ++extern struct compressor *lookup_compressor(char *); 1.216 ++extern struct compressor *lookup_compressor_id(int); 1.217 ++extern void display_compressors(char *, char *); 1.218 + 1.219 +--- squashfs-4.0/squashfs-tools/gzip_wrapper.c Thu Jan 1 01:00:00 1970 1.220 ++++ squashfs-4.0/squashfs-tools/gzip_wrapper.c Fri Aug 7 22:12:53 2009 1.221 +@@ -0,0 +1,80 @@ 1.222 ++/* 1.223 ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 1.224 ++ * Phillip Lougher <phillip@lougher.demon.co.uk> 1.225 ++ * 1.226 ++ * This program is free software; you can redistribute it and/or 1.227 ++ * modify it under the terms of the GNU General Public License 1.228 ++ * as published by the Free Software Foundation; either version 2, 1.229 ++ * or (at your option) any later version. 1.230 ++ * 1.231 ++ * This program is distributed in the hope that it will be useful, 1.232 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of 1.233 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.234 ++ * GNU General Public License for more details. 1.235 ++ * 1.236 ++ * You should have received a copy of the GNU General Public License 1.237 ++ * along with this program; if not, write to the Free Software 1.238 ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 1.239 ++ * 1.240 ++ * gzip_wrapper.c 1.241 ++ */ 1.242 ++ 1.243 ++#include <stdlib.h> 1.244 ++#include <zlib.h> 1.245 ++ 1.246 ++int gzip_compress(void **strm, char *d, char *s, int size, int block_size, 1.247 ++ int *error) 1.248 ++{ 1.249 ++ int res = 0; 1.250 ++ z_stream *stream = *strm; 1.251 ++ 1.252 ++ if(stream == NULL) { 1.253 ++ if((stream = *strm = malloc(sizeof(z_stream))) == NULL) 1.254 ++ goto failed; 1.255 ++ 1.256 ++ stream->zalloc = Z_NULL; 1.257 ++ stream->zfree = Z_NULL; 1.258 ++ stream->opaque = 0; 1.259 ++ 1.260 ++ if((res = deflateInit(stream, 9)) != Z_OK) 1.261 ++ goto failed; 1.262 ++ } else if((res = deflateReset(stream)) != Z_OK) 1.263 ++ goto failed; 1.264 ++ 1.265 ++ stream->next_in = (unsigned char *) s; 1.266 ++ stream->avail_in = size; 1.267 ++ stream->next_out = (unsigned char *) d; 1.268 ++ stream->avail_out = block_size; 1.269 ++ 1.270 ++ res = deflate(stream, Z_FINISH); 1.271 ++ if(res == Z_STREAM_END) 1.272 ++ /* 1.273 ++ * Success, return the compressed size. 1.274 ++ */ 1.275 ++ return (int) stream->total_out; 1.276 ++ if(res == Z_OK) 1.277 ++ /* 1.278 ++ * Output buffer overflow. Return out of buffer space 1.279 ++ */ 1.280 ++ return 0; 1.281 ++failed: 1.282 ++ /* 1.283 ++ * All other errors return failure, with the compressor 1.284 ++ * specific error code in *error 1.285 ++ */ 1.286 ++ *error = res; 1.287 ++ return -1; 1.288 ++} 1.289 ++ 1.290 ++ 1.291 ++int gzip_uncompress(char *d, char *s, int size, int block_size, int *error) 1.292 ++{ 1.293 ++ int res; 1.294 ++ unsigned long bytes = block_size; 1.295 ++ 1.296 ++ res = uncompress((unsigned char *) d, &bytes, 1.297 ++ (const unsigned char *) s, size); 1.298 ++ 1.299 ++ *error = res; 1.300 ++ return res == Z_OK ? (int) bytes : -1; 1.301 ++} 1.302 + 1.303 +--- squashfs-4.0/squashfs-tools/lzma_wrapper.c Thu Jan 1 01:00:00 1970 1.304 ++++ squashfs-4.0/squashfs-tools/lzma_wrapper.c Wed Oct 14 05:32:57 2009 1.305 +@@ -0,0 +1,93 @@ 1.306 ++/* 1.307 ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 1.308 ++ * Phillip Lougher <phillip@lougher.demon.co.uk> 1.309 ++ * 1.310 ++ * This program is free software; you can redistribute it and/or 1.311 ++ * modify it under the terms of the GNU General Public License 1.312 ++ * as published by the Free Software Foundation; either version 2, 1.313 ++ * or (at your option) any later version. 1.314 ++ * 1.315 ++ * This program is distributed in the hope that it will be useful, 1.316 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of 1.317 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.318 ++ * GNU General Public License for more details. 1.319 ++ * 1.320 ++ * You should have received a copy of the GNU General Public License 1.321 ++ * along with this program; if not, write to the Free Software 1.322 ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 1.323 ++ * 1.324 ++ * lzma_wrapper.c 1.325 ++ */ 1.326 ++ 1.327 ++#include <LzmaLib.h> 1.328 ++ 1.329 ++#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8) 1.330 ++ 1.331 ++int lzma_compress(void **strm, char *dest, char *src, int size,int block_size, 1.332 ++ int *error) 1.333 ++{ 1.334 ++ unsigned char *d = (unsigned char *) dest, *s = (unsigned char *) src; 1.335 ++ size_t props_size = LZMA_PROPS_SIZE, 1.336 ++ outlen = block_size - LZMA_HEADER_SIZE; 1.337 ++ int res; 1.338 ++ 1.339 ++ res = LzmaCompress(d + LZMA_HEADER_SIZE, &outlen, s, size, d, 1.340 ++ &props_size, 5, block_size, 3, 0, 2, 32, 1); 1.341 ++ 1.342 ++ if(res == SZ_ERROR_OUTPUT_EOF) { 1.343 ++ /* 1.344 ++ * Output buffer overflow. Return out of buffer space error 1.345 ++ */ 1.346 ++ return 0; 1.347 ++ } 1.348 ++ 1.349 ++ if(res != SZ_OK) { 1.350 ++ /* 1.351 ++ * All other errors return failure, with the compressor 1.352 ++ * specific error code in *error 1.353 ++ */ 1.354 ++ *error = res; 1.355 ++ return -1; 1.356 ++ } 1.357 ++ 1.358 ++ /* 1.359 ++ * Fill in the 8 byte little endian uncompressed size field in the 1.360 ++ * LZMA header. 8 bytes is excessively large for squashfs but 1.361 ++ * this is the standard LZMA header and which is expected by the kernel 1.362 ++ * code 1.363 ++ */ 1.364 ++ d[LZMA_PROPS_SIZE] = size & 255; 1.365 ++ d[LZMA_PROPS_SIZE + 1] = (size >> 8) & 255; 1.366 ++ d[LZMA_PROPS_SIZE + 2] = (size >> 16) & 255; 1.367 ++ d[LZMA_PROPS_SIZE + 3] = (size >> 24) & 255; 1.368 ++ d[LZMA_PROPS_SIZE + 4] = 0; 1.369 ++ d[LZMA_PROPS_SIZE + 5] = 0; 1.370 ++ d[LZMA_PROPS_SIZE + 6] = 0; 1.371 ++ d[LZMA_PROPS_SIZE + 7] = 0; 1.372 ++ 1.373 ++ /* 1.374 ++ * Success, return the compressed size. Outlen returned by the LZMA 1.375 ++ * compressor does not include the LZMA header space 1.376 ++ */ 1.377 ++ return outlen + LZMA_HEADER_SIZE; 1.378 ++} 1.379 ++ 1.380 ++ 1.381 ++int lzma_uncompress(char *dest, char *src, int size, int block_size, 1.382 ++ int *error) 1.383 ++{ 1.384 ++ unsigned char *d = (unsigned char *) dest, *s = (unsigned char *) src; 1.385 ++ size_t outlen, inlen = size - LZMA_HEADER_SIZE; 1.386 ++ int res; 1.387 ++ 1.388 ++ outlen = s[LZMA_PROPS_SIZE] | 1.389 ++ (s[LZMA_PROPS_SIZE + 1] << 8) | 1.390 ++ (s[LZMA_PROPS_SIZE + 2] << 16) | 1.391 ++ (s[LZMA_PROPS_SIZE + 3] << 24); 1.392 ++ 1.393 ++ res = LzmaUncompress(d, &outlen, s + LZMA_HEADER_SIZE, &inlen, 1.394 ++ s, LZMA_PROPS_SIZE); 1.395 ++ 1.396 ++ *error = res; 1.397 ++ return res == SZ_OK ? outlen : -1; 1.398 ++} 1.399 + 1.400 +--- squashfs-4.0/squashfs-tools/mksquashfs.c Sun Apr 5 23:22:48 2009 1.401 ++++ squashfs-4.0/squashfs-tools/mksquashfs.c Tue Dec 8 19:02:54 2009 1.402 +@@ -36,7 +36,6 @@ 1.403 + #include <errno.h> 1.404 + #include <dirent.h> 1.405 + #include <string.h> 1.406 +-#include <zlib.h> 1.407 + #include <stdlib.h> 1.408 + #include <signal.h> 1.409 + #include <setjmp.h> 1.410 +@@ -47,6 +46,7 @@ 1.411 + #include <math.h> 1.412 + #include <regex.h> 1.413 + #include <fnmatch.h> 1.414 ++#include <sys/wait.h> 1.415 + 1.416 + #ifndef linux 1.417 + #define __BYTE_ORDER BYTE_ORDER 1.418 +@@ -64,6 +64,7 @@ 1.419 + #include "global.h" 1.420 + #include "sort.h" 1.421 + #include "pseudo.h" 1.422 ++#include "compressor.h" 1.423 + 1.424 + #ifdef SQUASHFS_TRACE 1.425 + #define TRACE(s, args...) do { \ 1.426 +@@ -245,10 +246,8 @@ 1.427 + /* list of root directory entries read from original filesystem */ 1.428 + int old_root_entries = 0; 1.429 + struct old_root_entry_info { 1.430 +- char name[SQUASHFS_NAME_LEN + 1]; 1.431 +- squashfs_inode inode; 1.432 +- int type; 1.433 +- int inode_number; 1.434 ++ char *name; 1.435 ++ struct inode_info inode; 1.436 + }; 1.437 + struct old_root_entry_info *old_root_entry; 1.438 + 1.439 +@@ -371,10 +370,15 @@ 1.440 + int reader_buffer_size; 1.441 + int fragment_buffer_size; 1.442 + 1.443 ++/* compression operations structure */ 1.444 ++static struct compressor *comp; 1.445 ++char *comp_name = COMP_DEFAULT; 1.446 ++ 1.447 + char *read_from_disk(long long start, unsigned int avail_bytes); 1.448 + void add_old_root_entry(char *name, squashfs_inode inode, int inode_number, 1.449 + int type); 1.450 +-extern int read_super(int fd, squashfs_super_block *sBlk, char *source); 1.451 ++extern struct compressor *read_super(int fd, squashfs_super_block *sBlk, 1.452 ++ char *source); 1.453 + extern long long read_filesystem(char *root_name, int fd, 1.454 + squashfs_super_block *sBlk, char **cinode_table, char **data_cache, 1.455 + char **cdirectory_table, char **directory_data_cache, 1.456 +@@ -831,83 +835,32 @@ 1.457 + } 1.458 + 1.459 + 1.460 +-unsigned int mangle2(z_stream **strm, char *d, char *s, int size, 1.461 ++int mangle2(void **strm, char *d, char *s, int size, 1.462 + int block_size, int uncompressed, int data_block) 1.463 + { 1.464 +- unsigned long c_byte; 1.465 +- unsigned int res; 1.466 +- z_stream *stream = *strm; 1.467 ++ int error, c_byte = 0; 1.468 + 1.469 +- if(uncompressed) 1.470 +- goto notcompressed; 1.471 +- 1.472 +- if(stream == NULL) { 1.473 +- if((stream = *strm = malloc(sizeof(z_stream))) == NULL) 1.474 +- BAD_ERROR("mangle::compress failed, not enough " 1.475 +- "memory\n"); 1.476 +- 1.477 +- stream->zalloc = Z_NULL; 1.478 +- stream->zfree = Z_NULL; 1.479 +- stream->opaque = 0; 1.480 +- 1.481 +- if((res = deflateInit(stream, 9)) != Z_OK) { 1.482 +- if(res == Z_MEM_ERROR) 1.483 +- BAD_ERROR("zlib::compress failed, not enough " 1.484 +- "memory\n"); 1.485 +- else if(res == Z_STREAM_ERROR) 1.486 +- BAD_ERROR("zlib::compress failed, not a valid " 1.487 +- "compression level\n"); 1.488 +- else if(res == Z_VERSION_ERROR) 1.489 +- BAD_ERROR("zlib::compress failed, incorrect " 1.490 +- "zlib version\n"); 1.491 +- else 1.492 +- BAD_ERROR("zlib::compress failed, unknown " 1.493 +- "error %d\n", res); 1.494 +- } 1.495 +- } else if((res = deflateReset(stream)) != Z_OK) { 1.496 +- if(res == Z_STREAM_ERROR) 1.497 +- BAD_ERROR("zlib::compress failed, stream state " 1.498 +- "inconsistent\n"); 1.499 +- else 1.500 +- BAD_ERROR("zlib::compress failed, unknown error %d\n", 1.501 +- res); 1.502 ++ if(!uncompressed) { 1.503 ++ c_byte = comp->compress(strm, d, s, size, block_size, &error); 1.504 ++ if(c_byte == -1) 1.505 ++ BAD_ERROR("mangle2:: %s compress failed with error " 1.506 ++ "code %d\n", comp->name, error); 1.507 + } 1.508 + 1.509 +- stream->next_in = (unsigned char *) s; 1.510 +- stream->avail_in = size; 1.511 +- stream->next_out = (unsigned char *) d; 1.512 +- stream->avail_out = block_size; 1.513 +- 1.514 +- res = deflate(stream, Z_FINISH); 1.515 +- if(res != Z_STREAM_END && res != Z_OK) { 1.516 +- if(res == Z_STREAM_ERROR) 1.517 +- BAD_ERROR("zlib::compress failed, stream state " 1.518 +- "inconsistent\n"); 1.519 +- else if(res == Z_BUF_ERROR) 1.520 +- BAD_ERROR("zlib::compress failed, no progress possible" 1.521 +- "\n"); 1.522 +- else 1.523 +- BAD_ERROR("zlib::compress failed, unknown error %d\n", 1.524 +- res); 1.525 +- } 1.526 +- 1.527 +- c_byte = stream->total_out; 1.528 +- 1.529 +- if(res != Z_STREAM_END || c_byte >= size) { 1.530 +-notcompressed: 1.531 ++ if(c_byte == 0 || c_byte >= size) { 1.532 + memcpy(d, s, size); 1.533 + return size | (data_block ? SQUASHFS_COMPRESSED_BIT_BLOCK : 1.534 + SQUASHFS_COMPRESSED_BIT); 1.535 + } 1.536 + 1.537 +- return (unsigned int) c_byte; 1.538 ++ return c_byte; 1.539 + } 1.540 + 1.541 + 1.542 +-unsigned int mangle(char *d, char *s, int size, int block_size, 1.543 ++int mangle(char *d, char *s, int size, int block_size, 1.544 + int uncompressed, int data_block) 1.545 + { 1.546 +- static z_stream *stream = NULL; 1.547 ++ static void *stream = NULL; 1.548 + 1.549 + return mangle2(&stream, d, s, size, block_size, uncompressed, 1.550 + data_block); 1.551 +@@ -1660,8 +1613,7 @@ 1.552 + pthread_mutex_unlock(&fragment_mutex); 1.553 + 1.554 + if(SQUASHFS_COMPRESSED_BLOCK(disk_fragment->size)) { 1.555 +- int res; 1.556 +- unsigned long bytes = block_size; 1.557 ++ int error, res; 1.558 + char *data; 1.559 + 1.560 + if(compressed_buffer) 1.561 +@@ -1669,19 +1621,11 @@ 1.562 + else 1.563 + data = read_from_disk(start_block, size); 1.564 + 1.565 +- res = uncompress((unsigned char *) buffer->data, &bytes, 1.566 +- (const unsigned char *) data, size); 1.567 +- if(res != Z_OK) { 1.568 +- if(res == Z_MEM_ERROR) 1.569 +- BAD_ERROR("zlib::uncompress failed, not enough " 1.570 +- "memory\n"); 1.571 +- else if(res == Z_BUF_ERROR) 1.572 +- BAD_ERROR("zlib::uncompress failed, not enough " 1.573 +- "room in output buffer\n"); 1.574 +- else 1.575 +- BAD_ERROR("zlib::uncompress failed," 1.576 +- " unknown error %d\n", res); 1.577 +- } 1.578 ++ res = comp->uncompress(buffer->data, data, size, block_size, 1.579 ++ &error); 1.580 ++ if(res == -1) 1.581 ++ BAD_ERROR("%s uncompress failed with error code %d\n", 1.582 ++ comp->name, error); 1.583 + } else if(compressed_buffer) 1.584 + memcpy(buffer->data, compressed_buffer->data, size); 1.585 + else 1.586 +@@ -1733,9 +1677,7 @@ 1.587 + entry->buffer->block = bytes; 1.588 + bytes += compressed_size; 1.589 + fragments_outstanding --; 1.590 +- pthread_mutex_unlock(&fragment_mutex); 1.591 + queue_put(to_writer, entry->buffer); 1.592 +- pthread_mutex_lock(&fragment_mutex); 1.593 + TRACE("fragment_locked writing fragment %d, compressed size %d" 1.594 + "\n", entry->fragment, compressed_size); 1.595 + free(entry); 1.596 +@@ -1758,6 +1700,8 @@ 1.597 + pthread_mutex_lock(&fragment_mutex); 1.598 + insert_fragment_list(&frag_locked_list, entry); 1.599 + pthread_mutex_unlock(&fragment_mutex); 1.600 ++ 1.601 ++ return TRUE; 1.602 + } 1.603 + 1.604 + 1.605 +@@ -1824,7 +1768,9 @@ 1.606 + unsigned short c_byte; 1.607 + char cbuffer[(SQUASHFS_METADATA_SIZE << 2) + 2]; 1.608 + 1.609 ++#ifdef SQUASHFS_TRACE 1.610 + long long obytes = bytes; 1.611 ++#endif 1.612 + 1.613 + for(i = 0; i < meta_blocks; i++) { 1.614 + int avail_bytes = length > SQUASHFS_METADATA_SIZE ? 1.615 +@@ -2170,11 +2116,85 @@ 1.616 + } 1.617 + 1.618 + 1.619 ++static int seq = 0; 1.620 ++void reader_read_process(struct dir_ent *dir_ent) 1.621 ++{ 1.622 ++ struct file_buffer *prev_buffer = NULL, *file_buffer; 1.623 ++ int status, res, byte, count = 0; 1.624 ++ int file = get_pseudo_file(dir_ent->inode->pseudo_id)->fd; 1.625 ++ int child = get_pseudo_file(dir_ent->inode->pseudo_id)->child; 1.626 ++ long long bytes = 0; 1.627 ++ 1.628 ++ while(1) { 1.629 ++ file_buffer = cache_get(reader_buffer, 0, 0); 1.630 ++ file_buffer->sequence = seq ++; 1.631 ++ 1.632 ++ byte = read_bytes(file, file_buffer->data, block_size); 1.633 ++ if(byte == -1) 1.634 ++ goto read_err; 1.635 ++ 1.636 ++ file_buffer->size = byte; 1.637 ++ file_buffer->file_size = -1; 1.638 ++ file_buffer->block = count ++; 1.639 ++ file_buffer->error = FALSE; 1.640 ++ file_buffer->fragment = FALSE; 1.641 ++ bytes += byte; 1.642 ++ 1.643 ++ if(byte == 0) 1.644 ++ break; 1.645 ++ 1.646 ++ /* 1.647 ++ * Update estimated_uncompressed block count. This is done 1.648 ++ * on every block rather than waiting for all blocks to be 1.649 ++ * read incase write_file_process() is running in parallel 1.650 ++ * with this. Otherwise cur uncompressed block count may 1.651 ++ * get ahead of the total uncompressed block count. 1.652 ++ */ 1.653 ++ estimated_uncompressed ++; 1.654 ++ 1.655 ++ if(prev_buffer) 1.656 ++ queue_put(from_reader, prev_buffer); 1.657 ++ prev_buffer = file_buffer; 1.658 ++ } 1.659 ++ 1.660 ++ /* 1.661 ++ * Update inode file size now that the size of the dynamic pseudo file 1.662 ++ * is known. This is needed for the -info option. 1.663 ++ */ 1.664 ++ dir_ent->inode->buf.st_size = bytes; 1.665 ++ 1.666 ++ res = waitpid(child, &status, 0); 1.667 ++ if(res == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) 1.668 ++ goto read_err; 1.669 ++ 1.670 ++ if(prev_buffer == NULL) 1.671 ++ prev_buffer = file_buffer; 1.672 ++ else { 1.673 ++ cache_block_put(file_buffer); 1.674 ++ seq --; 1.675 ++ } 1.676 ++ prev_buffer->file_size = bytes; 1.677 ++ prev_buffer->fragment = !no_fragments && 1.678 ++ (count == 2 || always_use_fragments) && (byte < block_size); 1.679 ++ queue_put(from_reader, prev_buffer); 1.680 ++ 1.681 ++ return; 1.682 ++ 1.683 ++read_err: 1.684 ++ if(prev_buffer) { 1.685 ++ cache_block_put(file_buffer); 1.686 ++ seq --; 1.687 ++ file_buffer = prev_buffer; 1.688 ++ } 1.689 ++ file_buffer->error = TRUE; 1.690 ++ queue_put(from_deflate, file_buffer); 1.691 ++} 1.692 ++ 1.693 ++ 1.694 + void reader_read_file(struct dir_ent *dir_ent) 1.695 + { 1.696 + struct stat *buf = &dir_ent->inode->buf, buf2; 1.697 + struct file_buffer *file_buffer; 1.698 +- static int index = 0; 1.699 + int blocks, byte, count, expected, file, frag_block; 1.700 + long long bytes, read_size; 1.701 + 1.702 +@@ -2202,7 +2222,7 @@ 1.703 + if(file_buffer) 1.704 + queue_put(from_reader, file_buffer); 1.705 + file_buffer = cache_get(reader_buffer, 0, 0); 1.706 +- file_buffer->sequence = index ++; 1.707 ++ file_buffer->sequence = seq ++; 1.708 + 1.709 + byte = file_buffer->size = read_bytes(file, file_buffer->data, 1.710 + block_size); 1.711 +@@ -2238,7 +2258,7 @@ 1.712 + 1.713 + read_err: 1.714 + file_buffer = cache_get(reader_buffer, 0, 0); 1.715 +- file_buffer->sequence = index ++; 1.716 ++ file_buffer->sequence = seq ++; 1.717 + read_err2: 1.718 + file_buffer->error = TRUE; 1.719 + queue_put(from_deflate, file_buffer); 1.720 +@@ -2262,9 +2282,14 @@ 1.721 + for(i = 0; i < dir->count; i++) { 1.722 + struct dir_ent *dir_ent = dir->list[i]; 1.723 + struct stat *buf = &dir_ent->inode->buf; 1.724 +- if(dir_ent->data) 1.725 ++ if(dir_ent->inode->root_entry) 1.726 + continue; 1.727 + 1.728 ++ if(dir_ent->inode->pseudo_file) { 1.729 ++ reader_read_process(dir_ent); 1.730 ++ continue; 1.731 ++ } 1.732 ++ 1.733 + switch(buf->st_mode & S_IFMT) { 1.734 + case S_IFREG: 1.735 + reader_read_file(dir_ent); 1.736 +@@ -2365,7 +2390,7 @@ 1.737 + 1.738 + void *deflator(void *arg) 1.739 + { 1.740 +- z_stream *stream = NULL; 1.741 ++ void *stream = NULL; 1.742 + int oldstate; 1.743 + 1.744 + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); 1.745 +@@ -2402,7 +2427,7 @@ 1.746 + 1.747 + void *frag_deflator(void *arg) 1.748 + { 1.749 +- z_stream *stream = NULL; 1.750 ++ void *stream = NULL; 1.751 + int oldstate; 1.752 + 1.753 + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); 1.754 +@@ -2426,8 +2451,8 @@ 1.755 + write_buffer->block = bytes; 1.756 + bytes += compressed_size; 1.757 + fragments_outstanding --; 1.758 +- pthread_mutex_unlock(&fragment_mutex); 1.759 + queue_put(to_writer, write_buffer); 1.760 ++ pthread_mutex_unlock(&fragment_mutex); 1.761 + TRACE("Writing fragment %lld, uncompressed size %d, " 1.762 + "compressed size %d\n", file_buffer->block, 1.763 + file_buffer->size, compressed_size); 1.764 +@@ -2674,6 +2699,98 @@ 1.765 + } 1.766 + 1.767 + 1.768 ++int write_file_process(squashfs_inode *inode, struct dir_ent *dir_ent, 1.769 ++ struct file_buffer *read_buffer, int *duplicate_file) 1.770 ++{ 1.771 ++ long long read_size, file_bytes, start; 1.772 ++ struct fragment *fragment; 1.773 ++ unsigned int *block_list = NULL; 1.774 ++ int block = 0, status; 1.775 ++ long long sparse = 0; 1.776 ++ struct file_buffer *fragment_buffer = NULL; 1.777 ++ 1.778 ++ *duplicate_file = FALSE; 1.779 ++ 1.780 ++ lock_fragments(); 1.781 ++ 1.782 ++ file_bytes = 0; 1.783 ++ start = bytes; 1.784 ++ while (1) { 1.785 ++ read_size = read_buffer->file_size; 1.786 ++ if(read_buffer->fragment && read_buffer->c_byte) 1.787 ++ fragment_buffer = read_buffer; 1.788 ++ else { 1.789 ++ block_list = realloc(block_list, (block + 1) * 1.790 ++ sizeof(unsigned int)); 1.791 ++ if(block_list == NULL) 1.792 ++ BAD_ERROR("Out of memory allocating block_list" 1.793 ++ "\n"); 1.794 ++ block_list[block ++] = read_buffer->c_byte; 1.795 ++ if(read_buffer->c_byte) { 1.796 ++ read_buffer->block = bytes; 1.797 ++ bytes += read_buffer->size; 1.798 ++ cache_rehash(read_buffer, read_buffer->block); 1.799 ++ file_bytes += read_buffer->size; 1.800 ++ queue_put(to_writer, read_buffer); 1.801 ++ } else { 1.802 ++ sparse += read_buffer->size; 1.803 ++ cache_block_put(read_buffer); 1.804 ++ } 1.805 ++ } 1.806 ++ inc_progress_bar(); 1.807 ++ 1.808 ++ if(read_size != -1) 1.809 ++ break; 1.810 ++ 1.811 ++ read_buffer = get_file_buffer(from_deflate); 1.812 ++ if(read_buffer->error) 1.813 ++ goto read_err; 1.814 ++ } 1.815 ++ 1.816 ++ unlock_fragments(); 1.817 ++ fragment = get_and_fill_fragment(fragment_buffer); 1.818 ++ cache_block_put(fragment_buffer); 1.819 ++ 1.820 ++ if(duplicate_checking) 1.821 ++ add_non_dup(read_size, file_bytes, block_list, start, fragment, 1.822 ++ 0, 0, FALSE); 1.823 ++ file_count ++; 1.824 ++ total_bytes += read_size; 1.825 ++ 1.826 ++ if(read_size < (1LL << 32) && start < (1LL << 32) && sparse == 0) 1.827 ++ create_inode(inode, dir_ent, SQUASHFS_FILE_TYPE, read_size, 1.828 ++ start, block, block_list, fragment, NULL, 0); 1.829 ++ else 1.830 ++ create_inode(inode, dir_ent, SQUASHFS_LREG_TYPE, read_size, 1.831 ++ start, block, block_list, fragment, NULL, sparse); 1.832 ++ 1.833 ++ if(duplicate_checking == FALSE) 1.834 ++ free(block_list); 1.835 ++ 1.836 ++ return 0; 1.837 ++ 1.838 ++read_err: 1.839 ++ cur_uncompressed -= block; 1.840 ++ status = read_buffer->error; 1.841 ++ bytes = start; 1.842 ++ if(!block_device) { 1.843 ++ int res; 1.844 ++ 1.845 ++ queue_put(to_writer, NULL); 1.846 ++ if(queue_get(from_writer) != 0) 1.847 ++ EXIT_MKSQUASHFS(); 1.848 ++ res = ftruncate(fd, bytes); 1.849 ++ if(res != 0) 1.850 ++ BAD_ERROR("Failed to truncate dest file because %s\n", 1.851 ++ strerror(errno)); 1.852 ++ } 1.853 ++ unlock_fragments(); 1.854 ++ free(block_list); 1.855 ++ cache_block_put(read_buffer); 1.856 ++ return status; 1.857 ++} 1.858 ++ 1.859 ++ 1.860 + int write_file_blocks(squashfs_inode *inode, struct dir_ent *dir_ent, 1.861 + long long read_size, struct file_buffer *read_buffer, 1.862 + int *duplicate_file) 1.863 +@@ -2941,7 +3058,10 @@ 1.864 + 1.865 + read_size = read_buffer->file_size; 1.866 + 1.867 +- if(read_size == 0) { 1.868 ++ if(read_size == -1) 1.869 ++ status = write_file_process(inode, dir_ent, read_buffer, 1.870 ++ duplicate_file); 1.871 ++ else if(read_size == 0) { 1.872 + write_file_empty(inode, dir_ent, duplicate_file); 1.873 + cache_block_put(read_buffer); 1.874 + } else if(read_buffer->fragment && read_buffer->c_byte) 1.875 +@@ -3036,6 +3156,8 @@ 1.876 + 1.877 + memcpy(&inode->buf, buf, sizeof(struct stat)); 1.878 + inode->read = FALSE; 1.879 ++ inode->root_entry = FALSE; 1.880 ++ inode->pseudo_file = FALSE; 1.881 + inode->inode = SQUASHFS_INVALID_BLK; 1.882 + inode->nlink = 1; 1.883 + 1.884 +@@ -3056,7 +3178,7 @@ 1.885 + 1.886 + 1.887 + inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir, 1.888 +- struct inode_info *inode_info, void *data, struct dir_info *dir) 1.889 ++ struct inode_info *inode_info, struct dir_info *dir) 1.890 + { 1.891 + if((dir->count % DIR_ENTRIES) == 0) { 1.892 + dir->list = realloc(dir->list, (dir->count + DIR_ENTRIES) * 1.893 +@@ -3075,8 +3197,7 @@ 1.894 + NULL; 1.895 + dir->list[dir->count]->inode = inode_info; 1.896 + dir->list[dir->count]->dir = sub_dir; 1.897 +- dir->list[dir->count]->our_dir = dir; 1.898 +- dir->list[dir->count++]->data = data; 1.899 ++ dir->list[dir->count++]->our_dir = dir; 1.900 + dir->byte_count += strlen(name) + sizeof(squashfs_dir_entry); 1.901 + } 1.902 + 1.903 +@@ -3128,10 +3249,10 @@ 1.904 + 1.905 + if(dir->count < old_root_entries) 1.906 + for(i = 0; i < old_root_entries; i++) { 1.907 +- if(old_root_entry[i].type == SQUASHFS_DIR_TYPE) 1.908 ++ if(old_root_entry[i].inode.type == SQUASHFS_DIR_TYPE) 1.909 + dir->directory_count ++; 1.910 +- add_dir_entry(old_root_entry[i].name, "", NULL, NULL, 1.911 +- &old_root_entry[i], dir); 1.912 ++ add_dir_entry(old_root_entry[i].name, "", NULL, 1.913 ++ &old_root_entry[i].inode, dir); 1.914 + } 1.915 + 1.916 + while(index < source) { 1.917 +@@ -3167,10 +3288,10 @@ 1.918 + 1.919 + if(dir->count < old_root_entries) 1.920 + for(i = 0; i < old_root_entries; i++) { 1.921 +- if(old_root_entry[i].type == SQUASHFS_DIR_TYPE) 1.922 ++ if(old_root_entry[i].inode.type == SQUASHFS_DIR_TYPE) 1.923 + dir->directory_count ++; 1.924 +- add_dir_entry(old_root_entry[i].name, "", NULL, NULL, 1.925 +- &old_root_entry[i], dir); 1.926 ++ add_dir_entry(old_root_entry[i].name, "", NULL, 1.927 ++ &old_root_entry[i].inode, dir); 1.928 + } 1.929 + 1.930 + if((d_name = readdir(dir->linuxdir)) != NULL) { 1.931 +@@ -3215,7 +3336,7 @@ 1.932 + int current_count; 1.933 + 1.934 + while((current_count = dir_info->current_count++) < dir_info->count) 1.935 +- if(dir_info->list[current_count]->data) 1.936 ++ if(dir_info->list[current_count]->inode->root_entry) 1.937 + continue; 1.938 + else 1.939 + return dir_info->list[current_count]; 1.940 +@@ -3240,11 +3361,11 @@ 1.941 + int current_count; 1.942 + 1.943 + while((current_count = dir_info->current_count++) < dir_info->count) 1.944 +- if(dir_info->list[current_count]->data) 1.945 +- add_dir(dir_info->list[current_count]->data->inode, 1.946 +- dir_info->list[current_count]->data->inode_number, 1.947 ++ if(dir_info->list[current_count]->inode->root_entry) 1.948 ++ add_dir(dir_info->list[current_count]->inode->inode, 1.949 ++ dir_info->list[current_count]->inode->inode_number, 1.950 + dir_info->list[current_count]->name, 1.951 +- dir_info->list[current_count]->data->type, dir); 1.952 ++ dir_info->list[current_count]->inode->type, dir); 1.953 + else 1.954 + return dir_info->list[current_count]; 1.955 + return NULL; 1.956 +@@ -3313,7 +3434,6 @@ 1.957 + dir_ent->name = dir_ent->pathname = strdup(pathname); 1.958 + dir_ent->dir = dir_info; 1.959 + dir_ent->our_dir = NULL; 1.960 +- dir_ent->data = NULL; 1.961 + dir_info->dir_ent = dir_ent; 1.962 + 1.963 + if(sorted) 1.964 +@@ -3383,7 +3503,7 @@ 1.965 + sub_dir = NULL; 1.966 + 1.967 + add_dir_entry(dir_name, filename, sub_dir, lookup_inode(&buf), 1.968 +- NULL, dir); 1.969 ++ dir); 1.970 + } 1.971 + 1.972 + scan1_freedir(dir); 1.973 +@@ -3399,7 +3519,7 @@ 1.974 + struct dir_ent *dir_ent; 1.975 + struct pseudo_entry *pseudo_ent; 1.976 + struct stat buf; 1.977 +- static pseudo_ino = 1; 1.978 ++ static int pseudo_ino = 1; 1.979 + 1.980 + if(dir == NULL && (dir = scan1_opendir("")) == NULL) 1.981 + return NULL; 1.982 +@@ -3415,6 +3535,29 @@ 1.983 + 1.984 + while((pseudo_ent = pseudo_readdir(pseudo)) != NULL) { 1.985 + dir_ent = scan2_lookup(dir, pseudo_ent->name); 1.986 ++ if(pseudo_ent->dev->type == 's') { 1.987 ++ struct stat *buf; 1.988 ++ if(dir_ent == NULL) { 1.989 ++ ERROR("Pseudo set file \"%s\" does not exist " 1.990 ++ "in source filesystem. Ignoring\n", 1.991 ++ pseudo_ent->pathname); 1.992 ++ continue; 1.993 ++ } 1.994 ++ if(dir_ent->inode->root_entry) { 1.995 ++ ERROR("Pseudo set file \"%s\" is a pre-existing" 1.996 ++ " file in the filesystem being appended" 1.997 ++ " to. It cannot be modified. " 1.998 ++ "Ignoring!\n", pseudo_ent->pathname); 1.999 ++ continue; 1.1000 ++ } 1.1001 ++ buf = &dir_ent->inode->buf; 1.1002 ++ buf->st_mode = (buf->st_mode & S_IFMT) | 1.1003 ++ pseudo_ent->dev->mode; 1.1004 ++ buf->st_uid = pseudo_ent->dev->uid; 1.1005 ++ buf->st_gid = pseudo_ent->dev->gid; 1.1006 ++ continue; 1.1007 ++ } 1.1008 ++ 1.1009 + if(dir_ent) { 1.1010 + ERROR("Pseudo file \"%s\" exists in source filesystem " 1.1011 + "\"%s\"\n", pseudo_ent->pathname, 1.1012 +@@ -3444,8 +3587,29 @@ 1.1013 + buf.st_mtime = time(NULL); 1.1014 + buf.st_ino = pseudo_ino ++; 1.1015 + 1.1016 +- add_dir_entry(pseudo_ent->name, pseudo_ent->pathname, sub_dir, 1.1017 +- lookup_inode(&buf), NULL, dir); 1.1018 ++ if(pseudo_ent->dev->type == 'f') { 1.1019 ++#ifdef USE_TMP_FILE 1.1020 ++ struct stat buf2; 1.1021 ++ int res = stat(pseudo_ent->dev->filename, &buf2); 1.1022 ++ if(res == -1) { 1.1023 ++ ERROR("Stat on pseudo file \"%s\" failed, " 1.1024 ++ "skipping...", pseudo_ent->pathname); 1.1025 ++ continue; 1.1026 ++ } 1.1027 ++ buf.st_size = buf2.st_size; 1.1028 ++ add_dir_entry(pseudo_ent->name, 1.1029 ++ pseudo_ent->dev->filename, sub_dir, 1.1030 ++ lookup_inode(&buf), dir); 1.1031 ++#else 1.1032 ++ struct inode_info *inode = lookup_inode(&buf); 1.1033 ++ inode->pseudo_id = pseudo_ent->dev->pseudo_id; 1.1034 ++ inode->pseudo_file = TRUE; 1.1035 ++ add_dir_entry(pseudo_ent->name, pseudo_ent->pathname, 1.1036 ++ sub_dir, inode, dir); 1.1037 ++#endif 1.1038 ++ } else 1.1039 ++ add_dir_entry(pseudo_ent->name, pseudo_ent->pathname, 1.1040 ++ sub_dir, lookup_inode(&buf), dir); 1.1041 + } 1.1042 + 1.1043 + scan2_freedir(dir); 1.1044 +@@ -3482,8 +3646,9 @@ 1.1045 + &duplicate_file); 1.1046 + INFO("file %s, uncompressed size %lld " 1.1047 + "bytes %s\n", filename, 1.1048 +- buf->st_size, duplicate_file ? 1.1049 +- "DUPLICATE" : ""); 1.1050 ++ (long long) buf->st_size, 1.1051 ++ duplicate_file ? "DUPLICATE" : 1.1052 ++ ""); 1.1053 + break; 1.1054 + 1.1055 + case S_IFDIR: 1.1056 +@@ -3557,6 +3722,7 @@ 1.1057 + INFO("file %s, uncompressed " 1.1058 + "size %lld bytes LINK" 1.1059 + "\n", filename, 1.1060 ++ (long long) 1.1061 + buf->st_size); 1.1062 + break; 1.1063 + case SQUASHFS_SYMLINK_TYPE: 1.1064 +@@ -3667,10 +3833,11 @@ 1.1065 + BAD_ERROR("Out of memory in old root directory entries " 1.1066 + "reallocation\n"); 1.1067 + 1.1068 +- strcpy(old_root_entry[old_root_entries].name, name); 1.1069 +- old_root_entry[old_root_entries].inode = inode; 1.1070 +- old_root_entry[old_root_entries].inode_number = inode_number; 1.1071 +- old_root_entry[old_root_entries++].type = type; 1.1072 ++ old_root_entry[old_root_entries].name = strdup(name); 1.1073 ++ old_root_entry[old_root_entries].inode.inode = inode; 1.1074 ++ old_root_entry[old_root_entries].inode.inode_number = inode_number; 1.1075 ++ old_root_entry[old_root_entries].inode.type = type; 1.1076 ++ old_root_entry[old_root_entries++].inode.root_entry = TRUE; 1.1077 + } 1.1078 + 1.1079 + 1.1080 +@@ -4137,7 +4304,7 @@ 1.1081 + 1.1082 + 1.1083 + #define VERSION() \ 1.1084 +- printf("mksquashfs version 4.0 (2009/04/05)\n");\ 1.1085 ++ printf("mksquashfs version 4.1-CVS (2009/12/08)\n");\ 1.1086 + printf("copyright (C) 2009 Phillip Lougher <phillip@lougher.demon.co.uk>\n\n"); \ 1.1087 + printf("This program is free software; you can redistribute it and/or\n");\ 1.1088 + printf("modify it under the terms of the GNU General Public License\n");\ 1.1089 +@@ -4172,26 +4339,28 @@ 1.1090 + source_path = argv + 1; 1.1091 + source = i - 2; 1.1092 + for(; i < argc; i++) { 1.1093 +- if(strcmp(argv[i], "-pf") == 0) { 1.1094 ++ if(strcmp(argv[i], "-comp") == 0) { 1.1095 + if(++i == argc) { 1.1096 +- ERROR("%s: -pf missing filename\n", argv[0]); 1.1097 ++ ERROR("%s: -comp missing compression type\n", 1.1098 ++ argv[0]); 1.1099 + exit(1); 1.1100 + } 1.1101 +- if(read_pseudo_file(&pseudo, argv[i]) == FALSE) { 1.1102 +- ERROR("Failed to parse pseudo file \"%s\"\n", 1.1103 +- argv[i]); 1.1104 ++ comp_name = argv[i]; 1.1105 ++ } else if(strcmp(argv[i], "-pf") == 0) { 1.1106 ++ if(++i == argc) { 1.1107 ++ ERROR("%s: -pf missing filename\n", argv[0]); 1.1108 + exit(1); 1.1109 + } 1.1110 ++ if(read_pseudo_file(&pseudo, argv[i]) == FALSE) 1.1111 ++ exit(1); 1.1112 + } else if(strcmp(argv[i], "-p") == 0) { 1.1113 + if(++i == argc) { 1.1114 + ERROR("%s: -p missing pseudo file definition\n", 1.1115 + argv[0]); 1.1116 + exit(1); 1.1117 + } 1.1118 +- if(read_pseudo_def(&pseudo, argv[i]) == FALSE) { 1.1119 +- ERROR("Failed to parse pseudo definition\n"); 1.1120 ++ if(read_pseudo_def(&pseudo, argv[i]) == FALSE) 1.1121 + exit(1); 1.1122 +- } 1.1123 + } else if(strcmp(argv[i], "-recover") == 0) { 1.1124 + if(++i == argc) { 1.1125 + ERROR("%s: -recover missing recovery file\n", 1.1126 +@@ -4394,34 +4563,16 @@ 1.1127 + printOptions: 1.1128 + ERROR("SYNTAX:%s source1 source2 ... dest [options] " 1.1129 + "[-e list of exclude\ndirs/files]\n", argv[0]); 1.1130 +- ERROR("\nOptions are\n"); 1.1131 +- ERROR("-version\t\tprint version, licence and " 1.1132 +- "copyright message\n"); 1.1133 +- ERROR("-recover <name>\t\trecover filesystem data " 1.1134 +- "using recovery file <name>\n"); 1.1135 +- ERROR("-no-recovery\t\tdon't generate a recovery " 1.1136 +- "file\n"); 1.1137 +- ERROR("-info\t\t\tprint files written to filesystem\n"); 1.1138 +- ERROR("-no-exports\t\tdon't make the filesystem " 1.1139 +- "exportable via NFS\n"); 1.1140 +- ERROR("-no-progress\t\tdon't display the progress " 1.1141 +- "bar\n"); 1.1142 +- ERROR("-no-sparse\t\tdon't detect sparse files\n"); 1.1143 ++ ERROR("\nFilesystem build options:\n"); 1.1144 ++ ERROR("-comp <comp>\t\tselect <comp> compression\n"); 1.1145 ++ ERROR("\t\t\tCompressors available:\n"); 1.1146 ++ display_compressors("\t\t\t", COMP_DEFAULT); 1.1147 + ERROR("-b <block_size>\t\tset data block to " 1.1148 + "<block_size>. Default %d bytes\n", 1.1149 + SQUASHFS_FILE_SIZE); 1.1150 +- ERROR("-processors <number>\tUse <number> processors." 1.1151 +- " By default will use number of\n"); 1.1152 +- ERROR("\t\t\tprocessors available\n"); 1.1153 +- ERROR("-read-queue <size>\tSet input queue to <size> " 1.1154 +- "Mbytes. Default %d Mbytes\n", 1.1155 +- READER_BUFFER_DEFAULT); 1.1156 +- ERROR("-write-queue <size>\tSet output queue to <size> " 1.1157 +- "Mbytes. Default %d Mbytes\n", 1.1158 +- WRITER_BUFFER_DEFAULT); 1.1159 +- ERROR("-fragment-queue <size>\tSet fagment queue to " 1.1160 +- "<size> Mbytes. Default %d Mbytes\n", 1.1161 +- FRAGMENT_BUFFER_DEFAULT); 1.1162 ++ ERROR("-no-exports\t\tdon't make the filesystem " 1.1163 ++ "exportable via NFS\n"); 1.1164 ++ ERROR("-no-sparse\t\tdon't detect sparse files\n"); 1.1165 + ERROR("-noI\t\t\tdo not compress inode table\n"); 1.1166 + ERROR("-noD\t\t\tdo not compress data blocks\n"); 1.1167 + ERROR("-noF\t\t\tdo not compress fragment blocks\n"); 1.1168 +@@ -4430,13 +4581,34 @@ 1.1169 + "files larger than block size\n"); 1.1170 + ERROR("-no-duplicates\t\tdo not perform duplicate " 1.1171 + "checking\n"); 1.1172 +- ERROR("-noappend\t\tdo not append to existing " 1.1173 +- "filesystem\n"); 1.1174 ++ ERROR("-all-root\t\tmake all files owned by root\n"); 1.1175 ++ ERROR("-force-uid uid\t\tset all file uids to uid\n"); 1.1176 ++ ERROR("-force-gid gid\t\tset all file gids to gid\n"); 1.1177 ++ ERROR("-nopad\t\t\tdo not pad filesystem to a multiple " 1.1178 ++ "of 4K\n"); 1.1179 + ERROR("-keep-as-directory\tif one source directory is " 1.1180 + "specified, create a root\n"); 1.1181 + ERROR("\t\t\tdirectory containing that directory, " 1.1182 + "rather than the\n"); 1.1183 + ERROR("\t\t\tcontents of the directory\n"); 1.1184 ++ ERROR("\nFilesystem filter options:\n"); 1.1185 ++ ERROR("-p <pseudo-definition>\tAdd pseudo file definition\n"); 1.1186 ++ ERROR("-pf <pseudo-file>\tAdd list of pseudo file definitions\n"); 1.1187 ++ ERROR("-sort <sort_file>\tsort files according to " 1.1188 ++ "priorities in <sort_file>. One\n"); 1.1189 ++ ERROR("\t\t\tfile or dir with priority per line. " 1.1190 ++ "Priority -32768 to\n"); 1.1191 ++ ERROR("\t\t\t32767, default priority 0\n"); 1.1192 ++ ERROR("-ef <exclude_file>\tlist of exclude dirs/files." 1.1193 ++ " One per line\n"); 1.1194 ++ ERROR("-wildcards\t\tAllow extended shell wildcards " 1.1195 ++ "(globbing) to be used in\n\t\t\texclude " 1.1196 ++ "dirs/files\n"); 1.1197 ++ ERROR("-regex\t\t\tAllow POSIX regular expressions to " 1.1198 ++ "be used in exclude\n\t\t\tdirs/files\n"); 1.1199 ++ ERROR("\nFilesystem append options:\n"); 1.1200 ++ ERROR("-noappend\t\tdo not append to existing " 1.1201 ++ "filesystem\n"); 1.1202 + ERROR("-root-becomes <name>\twhen appending source " 1.1203 + "files/directories, make the\n"); 1.1204 + ERROR("\t\t\toriginal root become a subdirectory in " 1.1205 +@@ -4444,11 +4616,29 @@ 1.1206 + ERROR("\t\t\tcalled <name>, rather than adding the new " 1.1207 + "source items\n"); 1.1208 + ERROR("\t\t\tto the original root\n"); 1.1209 +- ERROR("-all-root\t\tmake all files owned by root\n"); 1.1210 +- ERROR("-force-uid uid\t\tset all file uids to uid\n"); 1.1211 +- ERROR("-force-gid gid\t\tset all file gids to gid\n"); 1.1212 +- ERROR("-nopad\t\t\tdo not pad filesystem to a multiple " 1.1213 +- "of 4K\n"); 1.1214 ++ ERROR("\nMksquashfs runtime options:\n"); 1.1215 ++ ERROR("-version\t\tprint version, licence and " 1.1216 ++ "copyright message\n"); 1.1217 ++ ERROR("-recover <name>\t\trecover filesystem data " 1.1218 ++ "using recovery file <name>\n"); 1.1219 ++ ERROR("-no-recovery\t\tdon't generate a recovery " 1.1220 ++ "file\n"); 1.1221 ++ ERROR("-info\t\t\tprint files written to filesystem\n"); 1.1222 ++ ERROR("-no-progress\t\tdon't display the progress " 1.1223 ++ "bar\n"); 1.1224 ++ ERROR("-processors <number>\tUse <number> processors." 1.1225 ++ " By default will use number of\n"); 1.1226 ++ ERROR("\t\t\tprocessors available\n"); 1.1227 ++ ERROR("-read-queue <size>\tSet input queue to <size> " 1.1228 ++ "Mbytes. Default %d Mbytes\n", 1.1229 ++ READER_BUFFER_DEFAULT); 1.1230 ++ ERROR("-write-queue <size>\tSet output queue to <size> " 1.1231 ++ "Mbytes. Default %d Mbytes\n", 1.1232 ++ WRITER_BUFFER_DEFAULT); 1.1233 ++ ERROR("-fragment-queue <size>\tSet fagment queue to " 1.1234 ++ "<size> Mbytes. Default %d Mbytes\n", 1.1235 ++ FRAGMENT_BUFFER_DEFAULT); 1.1236 ++ ERROR("\nMiscellaneous options:\n"); 1.1237 + ERROR("-root-owned\t\talternative name for -all-root" 1.1238 + "\n"); 1.1239 + ERROR("-noInodeCompression\talternative name for -noI" 1.1240 +@@ -4457,20 +4647,8 @@ 1.1241 + "\n"); 1.1242 + ERROR("-noFragmentCompression\talternative name for " 1.1243 + "-noF\n"); 1.1244 +- ERROR("-sort <sort_file>\tsort files according to " 1.1245 +- "priorities in <sort_file>. One\n"); 1.1246 +- ERROR("\t\t\tfile or dir with priority per line. " 1.1247 +- "Priority -32768 to\n"); 1.1248 +- ERROR("\t\t\t32767, default priority 0\n"); 1.1249 +- ERROR("-ef <exclude_file>\tlist of exclude dirs/files." 1.1250 +- " One per line\n"); 1.1251 +- ERROR("-wildcards\t\tAllow extended shell wildcards " 1.1252 +- "(globbing) to be used in\n\t\t\texclude " 1.1253 +- "dirs/files\n"); 1.1254 +- ERROR("-regex\t\t\tAllow POSIX regular expressions to " 1.1255 +- "be used in exclude\n\t\t\tdirs/files\n"); 1.1256 +- ERROR("-p <pseudo-definition>\tAdd pseudo file definition\n"); 1.1257 +- ERROR("-pf <pseudo-file>\tAdd list of pseudo file definitions\n"); 1.1258 ++ ERROR("\nCompressors available:\n"); 1.1259 ++ display_compressors("", COMP_DEFAULT); 1.1260 + exit(1); 1.1261 + } 1.1262 + } 1.1263 +@@ -4548,11 +4726,10 @@ 1.1264 + fclose(fd); 1.1265 + } else if(strcmp(argv[i], "-e") == 0) 1.1266 + break; 1.1267 +- else if(strcmp(argv[i], "-b") == 0 || 1.1268 +- strcmp(argv[i], "-root-becomes") == 0 || 1.1269 ++ else if(strcmp(argv[i], "-root-becomes") == 0 || 1.1270 + strcmp(argv[i], "-sort") == 0 || 1.1271 + strcmp(argv[i], "-pf") == 0 || 1.1272 +- strcmp(argv[i], "-p") == 0) 1.1273 ++ strcmp(argv[i], "-comp") == 0) 1.1274 + i++; 1.1275 + 1.1276 + if(i != argc) { 1.1277 +@@ -4574,11 +4751,10 @@ 1.1278 + sorted ++; 1.1279 + } else if(strcmp(argv[i], "-e") == 0) 1.1280 + break; 1.1281 +- else if(strcmp(argv[i], "-b") == 0 || 1.1282 +- strcmp(argv[i], "-root-becomes") == 0 || 1.1283 ++ else if(strcmp(argv[i], "-root-becomes") == 0 || 1.1284 + strcmp(argv[i], "-ef") == 0 || 1.1285 + strcmp(argv[i], "-pf") == 0 || 1.1286 +- strcmp(argv[i], "-p") == 0) 1.1287 ++ strcmp(argv[i], "-comp") == 0) 1.1288 + i++; 1.1289 + 1.1290 + #ifdef SQUASHFS_TRACE 1.1291 +@@ -4586,7 +4762,8 @@ 1.1292 + #endif 1.1293 + 1.1294 + if(!delete) { 1.1295 +- if(read_super(fd, &sBlk, argv[source + 1]) == 0) { 1.1296 ++ comp = read_super(fd, &sBlk, argv[source + 1]); 1.1297 ++ if(comp == NULL) { 1.1298 + ERROR("Failed to read existing filesystem - will not " 1.1299 + "overwrite - ABORTING!\n"); 1.1300 + ERROR("To force Mksquashfs to write to this block " 1.1301 +@@ -4603,6 +4780,15 @@ 1.1302 + always_use_fragments = SQUASHFS_ALWAYS_FRAGMENTS(sBlk.flags); 1.1303 + duplicate_checking = SQUASHFS_DUPLICATES(sBlk.flags); 1.1304 + exportable = SQUASHFS_EXPORTABLE(sBlk.flags); 1.1305 ++ } else { 1.1306 ++ comp = lookup_compressor(comp_name); 1.1307 ++ if(!comp->supported) { 1.1308 ++ ERROR("FATAL_ERROR: Compressor \"%s\" is not " 1.1309 ++ "supported!\n", comp_name); 1.1310 ++ ERROR("Compressors available:\n"); 1.1311 ++ display_compressors("", COMP_DEFAULT); 1.1312 ++ EXIT_MKSQUASHFS(); 1.1313 ++ } 1.1314 + } 1.1315 + 1.1316 + initialise_threads(); 1.1317 +@@ -4648,8 +4834,8 @@ 1.1318 + "size %d\n", SQUASHFS_MAJOR, s_minor, argv[source + 1], 1.1319 + block_size); 1.1320 + printf("All -b, -noI, -noD, -noF, no-duplicates, no-fragments, " 1.1321 +- "-always-use-fragments and -exportable options ignored" 1.1322 +- "\n"); 1.1323 ++ "-always-use-fragments,\n-exportable and -comp options " 1.1324 ++ "ignored\n"); 1.1325 + printf("\nIf appending is not wanted, please re-run with " 1.1326 + "-noappend specified!\n\n"); 1.1327 + 1.1328 +@@ -4803,8 +4989,7 @@ 1.1329 + 1.1330 + sBlk.bytes_used = bytes; 1.1331 + 1.1332 +- /* Only compression supported */ 1.1333 +- sBlk.compression = ZLIB_COMPRESSION; 1.1334 ++ sBlk.compression = comp->id; 1.1335 + 1.1336 + /* Xattrs are not currently supported */ 1.1337 + sBlk.xattr_table_start = SQUASHFS_INVALID_BLK; 1.1338 +@@ -4820,6 +5005,8 @@ 1.1339 + 1.1340 + close(fd); 1.1341 + 1.1342 ++ delete_pseudo_files(); 1.1343 ++ 1.1344 + if(recovery_file[0] != '\0') 1.1345 + unlink(recovery_file); 1.1346 + 1.1347 +@@ -4827,9 +5014,9 @@ 1.1348 + * sizeof(unsigned short) + guid_count * sizeof(unsigned short) + 1.1349 + sizeof(squashfs_super_block); 1.1350 + 1.1351 +- printf("\n%sSquashfs %d.%d filesystem, data block size %d\n", 1.1352 +- exportable ? "Exportable " : "", SQUASHFS_MAJOR, SQUASHFS_MINOR, 1.1353 +- block_size); 1.1354 ++ printf("\n%sSquashfs %d.%d filesystem, %s compressed, data block size" 1.1355 ++ " %d\n", exportable ? "Exportable " : "", SQUASHFS_MAJOR, 1.1356 ++ SQUASHFS_MINOR, comp->name, block_size); 1.1357 + printf("\t%s data, %s metadata, %s fragments\n", 1.1358 + noD ? "uncompressed" : "compressed", noI ? "uncompressed" : 1.1359 + "compressed", no_fragments ? "no" : noF ? "uncompressed" : 1.1360 + 1.1361 +--- squashfs-4.0/squashfs-tools/par_mksquashfs/README Thu Jan 1 01:00:00 1970 1.1362 ++++ squashfs-4.0/squashfs-tools/par_mksquashfs/README Mon Nov 6 01:27:32 2006 1.1363 +@@ -0,0 +1,2 @@ 1.1364 ++par_mksquashfs is now the standard mksquashfs, and so this directory is now empty. 1.1365 ++ 1.1366 + 1.1367 +--- squashfs-4.0/squashfs-tools/pseudo.c Sun Apr 5 04:01:58 2009 1.1368 ++++ squashfs-4.0/squashfs-tools/pseudo.c Thu Sep 10 06:17:48 2009 1.1369 +@@ -30,6 +30,7 @@ 1.1370 + #include <string.h> 1.1371 + #include <stdlib.h> 1.1372 + #include <sys/types.h> 1.1373 ++#include <sys/wait.h> 1.1374 + 1.1375 + #include "pseudo.h" 1.1376 + 1.1377 +@@ -55,6 +56,9 @@ 1.1378 + #define TRUE 1 1.1379 + #define FALSE 0 1.1380 + 1.1381 ++struct pseudo_dev **pseudo_file = NULL; 1.1382 ++int pseudo_count = 0; 1.1383 ++ 1.1384 + static void dump_pseudo(struct pseudo *pseudo, char *string) 1.1385 + { 1.1386 + int i; 1.1387 +@@ -99,7 +103,7 @@ 1.1388 + char *target, char *alltarget) 1.1389 + { 1.1390 + char targname[1024]; 1.1391 +- int i, error; 1.1392 ++ int i; 1.1393 + 1.1394 + target = get_component(target, targname); 1.1395 + 1.1396 +@@ -128,12 +132,8 @@ 1.1397 + if(target[0] == '\0') { 1.1398 + /* at leaf pathname component */ 1.1399 + pseudo->name[i].pseudo = NULL; 1.1400 +- pseudo->name[i].dev = malloc(sizeof(struct pseudo_dev)); 1.1401 +- if(pseudo->name[i].dev == NULL) 1.1402 +- BAD_ERROR("failed to allocate pseudo file\n"); 1.1403 + pseudo->name[i].pathname = strdup(alltarget); 1.1404 +- memcpy(pseudo->name[i].dev, pseudo_dev, 1.1405 +- sizeof(struct pseudo_dev)); 1.1406 ++ pseudo->name[i].dev = pseudo_dev; 1.1407 + } else { 1.1408 + /* recurse adding child components */ 1.1409 + pseudo->name[i].dev = NULL; 1.1410 +@@ -169,15 +169,9 @@ 1.1411 + if(target[0] == '\0') { 1.1412 + if(pseudo->name[i].dev == NULL && 1.1413 + pseudo_dev->type == 'd') { 1.1414 +- pseudo->name[i].dev = 1.1415 +- malloc(sizeof(struct pseudo_dev)); 1.1416 +- if(pseudo->name[i].dev == NULL) 1.1417 +- BAD_ERROR("failed to allocate " 1.1418 +- "pseudo file\n"); 1.1419 + pseudo->name[i].pathname = 1.1420 + strdup(alltarget); 1.1421 +- memcpy(pseudo->name[i].dev, pseudo_dev, 1.1422 +- sizeof(struct pseudo_dev)); 1.1423 ++ pseudo->name[i].dev = pseudo_dev; 1.1424 + } else 1.1425 + ERROR("%s already exists as a " 1.1426 + "directory. Ignoring %s!\n", 1.1427 +@@ -229,16 +223,113 @@ 1.1428 + } 1.1429 + 1.1430 + 1.1431 ++int exec_file(char *command, struct pseudo_dev *dev) 1.1432 ++{ 1.1433 ++ int child, res; 1.1434 ++ static pid_t pid = -1; 1.1435 ++ int pipefd[2]; 1.1436 ++#ifdef USE_TMP_FILE 1.1437 ++ char filename[1024]; 1.1438 ++ int status; 1.1439 ++ static int number = 0; 1.1440 ++#endif 1.1441 ++ 1.1442 ++ if(pid == -1) 1.1443 ++ pid = getpid(); 1.1444 ++ 1.1445 ++#ifdef USE_TMP_FILE 1.1446 ++ sprintf(filename, "/tmp/squashfs_pseudo_%d_%d", pid, number ++); 1.1447 ++ pipefd[1] = open(filename, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU); 1.1448 ++ if(pipefd[1] == -1) { 1.1449 ++ printf("open failed\n"); 1.1450 ++ return -1; 1.1451 ++ } 1.1452 ++#else 1.1453 ++ res = pipe(pipefd); 1.1454 ++ if(res == -1) { 1.1455 ++ printf("pipe failed\n"); 1.1456 ++ return -1; 1.1457 ++ } 1.1458 ++#endif 1.1459 ++ 1.1460 ++ child = fork(); 1.1461 ++ if(child == -1) { 1.1462 ++ printf("fork failed\n"); 1.1463 ++ goto failed; 1.1464 ++ } 1.1465 ++ 1.1466 ++ if(child == 0) { 1.1467 ++ close(STDOUT_FILENO); 1.1468 ++ res = dup(pipefd[1]); 1.1469 ++ if(res == -1) { 1.1470 ++ printf("dup failed\n"); 1.1471 ++ exit(EXIT_FAILURE); 1.1472 ++ } 1.1473 ++ execl("/bin/sh", "sh", "-c", command, (char *) NULL); 1.1474 ++ printf("execl failed\n"); 1.1475 ++ exit(EXIT_FAILURE); 1.1476 ++ } 1.1477 ++ 1.1478 ++#ifdef USE_TMP_FILE 1.1479 ++ res = waitpid(child, &status, 0); 1.1480 ++ close(pipefd[1]); 1.1481 ++ if(res != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0) { 1.1482 ++ dev->filename = strdup(filename); 1.1483 ++ return 0; 1.1484 ++ } 1.1485 ++failed: 1.1486 ++ unlink(filename); 1.1487 ++ return -1; 1.1488 ++#else 1.1489 ++ close(pipefd[1]); 1.1490 ++ dev->fd = pipefd[0]; 1.1491 ++ dev->child = child; 1.1492 ++ return 0; 1.1493 ++failed: 1.1494 ++ return -1; 1.1495 ++#endif 1.1496 ++} 1.1497 ++ 1.1498 ++ 1.1499 ++void add_pseudo_file(struct pseudo_dev *dev) 1.1500 ++{ 1.1501 ++ pseudo_file = realloc(pseudo_file, (pseudo_count + 1) * 1.1502 ++ sizeof(struct pseudo_dev *)); 1.1503 ++ if(pseudo_file == NULL) 1.1504 ++ BAD_ERROR("Failed to realloc pseudo_file\n"); 1.1505 ++ 1.1506 ++ dev->pseudo_id = pseudo_count; 1.1507 ++ pseudo_file[pseudo_count ++] = dev; 1.1508 ++} 1.1509 ++ 1.1510 ++ 1.1511 ++void delete_pseudo_files() 1.1512 ++{ 1.1513 ++#ifdef USE_TMP_FILE 1.1514 ++ int i; 1.1515 ++ 1.1516 ++ for(i = 0; i < pseudo_count; i++) 1.1517 ++ unlink(pseudo_file[i]->filename); 1.1518 ++#endif 1.1519 ++} 1.1520 ++ 1.1521 ++ 1.1522 ++struct pseudo_dev *get_pseudo_file(int pseudo_id) 1.1523 ++{ 1.1524 ++ return pseudo_file[pseudo_id]; 1.1525 ++} 1.1526 ++ 1.1527 ++ 1.1528 + int read_pseudo_def(struct pseudo **pseudo, char *def) 1.1529 + { 1.1530 +- int n; 1.1531 ++ int n, bytes; 1.1532 + unsigned int major = 0, minor = 0, mode; 1.1533 + char filename[2048], type, suid[100], sgid[100], *ptr; 1.1534 + long long uid, gid; 1.1535 +- struct pseudo_dev dev; 1.1536 ++ struct pseudo_dev *dev; 1.1537 + 1.1538 +- n = sscanf(def, "%s %c %o %s %s %u %u", filename, &type, &mode, suid, sgid, 1.1539 +- &major, &minor); 1.1540 ++ n = sscanf(def, "%s %c %o %s %s %n", filename, &type, &mode, suid, 1.1541 ++ sgid, &bytes); 1.1542 + 1.1543 + if(n < 5) { 1.1544 + ERROR("Not enough or invalid arguments in pseudo file " 1.1545 +@@ -249,7 +340,9 @@ 1.1546 + switch(type) { 1.1547 + case 'b': 1.1548 + case 'c': 1.1549 +- if(n < 7) { 1.1550 ++ n = sscanf(def + bytes, "%u %u", &major, &minor); 1.1551 ++ 1.1552 ++ if(n < 2) { 1.1553 + ERROR("Not enough or invalid arguments in pseudo file " 1.1554 + "definition\n"); 1.1555 + goto error; 1.1556 +@@ -265,54 +358,59 @@ 1.1557 + goto error; 1.1558 + } 1.1559 + 1.1560 +- /* fall through */ 1.1561 +- case 'd': 1.1562 +- if(mode > 0777) { 1.1563 +- ERROR("Mode %o out of range\n", mode); 1.1564 ++ case 'f': 1.1565 ++ if(def[bytes] == '\0') { 1.1566 ++ ERROR("Not enough arguments in pseudo file " 1.1567 ++ "definition\n"); 1.1568 + goto error; 1.1569 +- } 1.1570 +- 1.1571 +- uid = strtoll(suid, &ptr, 10); 1.1572 +- if(*ptr == '\0') { 1.1573 +- if(uid < 0 || uid > ((1LL << 32) - 1)) { 1.1574 +- ERROR("Uid %s out of range\n", suid); 1.1575 +- goto error; 1.1576 +- } 1.1577 +- } else { 1.1578 +- struct passwd *pwuid = getpwnam(suid); 1.1579 +- if(pwuid) 1.1580 +- uid = pwuid->pw_uid; 1.1581 +- else { 1.1582 +- ERROR("Uid %s invalid uid or unknown user\n", 1.1583 +- suid); 1.1584 +- goto error; 1.1585 +- } 1.1586 +- } 1.1587 +- 1.1588 +- gid = strtoll(sgid, &ptr, 10); 1.1589 +- if(*ptr == '\0') { 1.1590 +- if(gid < 0 || gid > ((1LL << 32) - 1)) { 1.1591 +- ERROR("Gid %s out of range\n", sgid); 1.1592 +- goto error; 1.1593 +- } 1.1594 +- } else { 1.1595 +- struct group *grgid = getgrnam(sgid); 1.1596 +- if(grgid) 1.1597 +- gid = grgid->gr_gid; 1.1598 +- else { 1.1599 +- ERROR("Gid %s invalid uid or unknown user\n", 1.1600 +- sgid); 1.1601 +- goto error; 1.1602 +- } 1.1603 +- } 1.1604 +- 1.1605 ++ } 1.1606 + break; 1.1607 ++ case 'd': 1.1608 ++ case 'm': 1.1609 ++ break; 1.1610 + default: 1.1611 + ERROR("Unsupported type %c\n", type); 1.1612 + goto error; 1.1613 + } 1.1614 + 1.1615 + 1.1616 ++ if(mode > 0777) { 1.1617 ++ ERROR("Mode %o out of range\n", mode); 1.1618 ++ goto error; 1.1619 ++ } 1.1620 ++ 1.1621 ++ uid = strtoll(suid, &ptr, 10); 1.1622 ++ if(*ptr == '\0') { 1.1623 ++ if(uid < 0 || uid > ((1LL << 32) - 1)) { 1.1624 ++ ERROR("Uid %s out of range\n", suid); 1.1625 ++ goto error; 1.1626 ++ } 1.1627 ++ } else { 1.1628 ++ struct passwd *pwuid = getpwnam(suid); 1.1629 ++ if(pwuid) 1.1630 ++ uid = pwuid->pw_uid; 1.1631 ++ else { 1.1632 ++ ERROR("Uid %s invalid uid or unknown user\n", suid); 1.1633 ++ goto error; 1.1634 ++ } 1.1635 ++ } 1.1636 ++ 1.1637 ++ gid = strtoll(sgid, &ptr, 10); 1.1638 ++ if(*ptr == '\0') { 1.1639 ++ if(gid < 0 || gid > ((1LL << 32) - 1)) { 1.1640 ++ ERROR("Gid %s out of range\n", sgid); 1.1641 ++ goto error; 1.1642 ++ } 1.1643 ++ } else { 1.1644 ++ struct group *grgid = getgrnam(sgid); 1.1645 ++ if(grgid) 1.1646 ++ gid = grgid->gr_gid; 1.1647 ++ else { 1.1648 ++ ERROR("Gid %s invalid uid or unknown user\n", sgid); 1.1649 ++ goto error; 1.1650 ++ } 1.1651 ++ } 1.1652 ++ 1.1653 + switch(type) { 1.1654 + case 'b': 1.1655 + mode |= S_IFBLK; 1.1656 +@@ -323,16 +421,37 @@ 1.1657 + case 'd': 1.1658 + mode |= S_IFDIR; 1.1659 + break; 1.1660 ++ case 'f': 1.1661 ++ mode |= S_IFREG; 1.1662 ++ break; 1.1663 + } 1.1664 + 1.1665 +- dev.type = type; 1.1666 +- dev.mode = mode; 1.1667 +- dev.uid = uid; 1.1668 +- dev.gid = gid; 1.1669 +- dev.major = major; 1.1670 +- dev.minor = minor; 1.1671 ++ dev = malloc(sizeof(struct pseudo_dev)); 1.1672 ++ if(dev == NULL) 1.1673 ++ BAD_ERROR("Failed to create pseudo_dev\n"); 1.1674 + 1.1675 +- *pseudo = add_pseudo(*pseudo, &dev, filename, filename); 1.1676 ++ dev->type = type; 1.1677 ++ dev->mode = mode; 1.1678 ++ dev->uid = uid; 1.1679 ++ dev->gid = gid; 1.1680 ++ dev->major = major; 1.1681 ++ dev->minor = minor; 1.1682 ++ 1.1683 ++ if(type == 'f') { 1.1684 ++ int res; 1.1685 ++ 1.1686 ++ printf("Executing dynamic pseudo file\n"); 1.1687 ++ printf("\t\"%s\"\n", def); 1.1688 ++ res = exec_file(def + bytes, dev); 1.1689 ++ if(res == -1) { 1.1690 ++ ERROR("Failed to execute dynamic pseudo file definition" 1.1691 ++ " \"%s\"\n", def); 1.1692 ++ return FALSE; 1.1693 ++ } 1.1694 ++ add_pseudo_file(dev); 1.1695 ++ } 1.1696 ++ 1.1697 ++ *pseudo = add_pseudo(*pseudo, dev, filename, filename); 1.1698 + 1.1699 + return TRUE; 1.1700 + 1.1701 + 1.1702 +--- squashfs-4.0/squashfs-tools/pseudo.h Sat Apr 4 03:44:24 2009 1.1703 ++++ squashfs-4.0/squashfs-tools/pseudo.h Fri Sep 11 14:10:58 2009 1.1704 +@@ -27,6 +27,12 @@ 1.1705 + unsigned int gid; 1.1706 + unsigned int major; 1.1707 + unsigned int minor; 1.1708 ++ int pseudo_id; 1.1709 ++ int fd; 1.1710 ++ int child; 1.1711 ++#ifdef USE_TMP_FILE 1.1712 ++ char *filename; 1.1713 ++#endif 1.1714 + }; 1.1715 + 1.1716 + struct pseudo_entry { 1.1717 +@@ -46,3 +52,5 @@ 1.1718 + extern int read_pseudo_file(struct pseudo **, char *); 1.1719 + extern struct pseudo *pseudo_subdir(char *, struct pseudo *); 1.1720 + extern struct pseudo_entry *pseudo_readdir(struct pseudo *); 1.1721 ++extern struct pseudo_dev *get_pseudo_file(int); 1.1722 ++extern void delete_pseudo_files(); 1.1723 + 1.1724 +--- squashfs-4.0/squashfs-tools/read_fs.c Tue Mar 31 06:23:14 2009 1.1725 ++++ squashfs-4.0/squashfs-tools/read_fs.c Mon Aug 24 20:28:04 2009 1.1726 +@@ -36,7 +36,6 @@ 1.1727 + #include <fcntl.h> 1.1728 + #include <errno.h> 1.1729 + #include <string.h> 1.1730 +-#include <zlib.h> 1.1731 + #include <sys/mman.h> 1.1732 + 1.1733 + #ifndef linux 1.1734 +@@ -51,6 +50,7 @@ 1.1735 + #include "squashfs_swap.h" 1.1736 + #include "read_fs.h" 1.1737 + #include "global.h" 1.1738 ++#include "compressor.h" 1.1739 + 1.1740 + #include <stdlib.h> 1.1741 + 1.1742 +@@ -66,7 +66,9 @@ 1.1743 + fprintf(stderr, s, ## args); \ 1.1744 + } while(0) 1.1745 + 1.1746 +-int read_block(int fd, long long start, long long *next, unsigned char *block, 1.1747 ++static struct compressor *comp; 1.1748 ++ 1.1749 ++int read_block(int fd, long long start, long long *next, void *block, 1.1750 + squashfs_super_block *sBlk) 1.1751 + { 1.1752 + unsigned short c_byte; 1.1753 +@@ -77,32 +79,24 @@ 1.1754 + 1.1755 + if(SQUASHFS_COMPRESSED(c_byte)) { 1.1756 + char buffer[SQUASHFS_METADATA_SIZE]; 1.1757 +- int res; 1.1758 +- unsigned long bytes = SQUASHFS_METADATA_SIZE; 1.1759 ++ int error, res; 1.1760 + 1.1761 + c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); 1.1762 + read_destination(fd, start + offset, c_byte, buffer); 1.1763 + 1.1764 +- res = uncompress(block, &bytes, (const unsigned char *) buffer, 1.1765 +- c_byte); 1.1766 +- if(res != Z_OK) { 1.1767 +- if(res == Z_MEM_ERROR) 1.1768 +- ERROR("zlib::uncompress failed, not enough " 1.1769 +- "memory\n"); 1.1770 +- else if(res == Z_BUF_ERROR) 1.1771 +- ERROR("zlib::uncompress failed, not enough " 1.1772 +- "room in output buffer\n"); 1.1773 +- else 1.1774 +- ERROR("zlib::uncompress failed, unknown error " 1.1775 +- "%d\n", res); 1.1776 ++ res = comp->uncompress(block, buffer, c_byte, 1.1777 ++ SQUASHFS_METADATA_SIZE, &error); 1.1778 ++ if(res == -1) { 1.1779 ++ ERROR("%s uncompress failed with error code %d\n", 1.1780 ++ comp->name, error); 1.1781 + return 0; 1.1782 + } 1.1783 + if(next) 1.1784 + *next = start + offset + c_byte; 1.1785 +- return bytes; 1.1786 ++ return res; 1.1787 + } else { 1.1788 + c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); 1.1789 +- read_destination(fd, start + offset, c_byte, (char *) block); 1.1790 ++ read_destination(fd, start + offset, c_byte, block); 1.1791 + if(next) 1.1792 + *next = start + offset + c_byte; 1.1793 + return c_byte; 1.1794 +@@ -356,7 +350,7 @@ 1.1795 + } 1.1796 + 1.1797 + 1.1798 +-int read_super(int fd, squashfs_super_block *sBlk, char *source) 1.1799 ++struct compressor *read_super(int fd, squashfs_super_block *sBlk, char *source) 1.1800 + { 1.1801 + read_destination(fd, SQUASHFS_START, sizeof(squashfs_super_block), 1.1802 + (char *) sBlk); 1.1803 +@@ -388,8 +382,18 @@ 1.1804 + goto failed_mount; 1.1805 + } 1.1806 + 1.1807 ++ /* Check the compression type */ 1.1808 ++ comp = lookup_compressor_id(sBlk->compression); 1.1809 ++ if(!comp->supported) { 1.1810 ++ ERROR("Filesystem on %s uses %s compression, this is" 1.1811 ++ "unsupported by this version\n", source, comp->name); 1.1812 ++ display_compressors("", ""); 1.1813 ++ goto failed_mount; 1.1814 ++ } 1.1815 ++ 1.1816 + printf("Found a valid %sSQUASHFS superblock on %s.\n", 1.1817 + SQUASHFS_EXPORTABLE(sBlk->flags) ? "exportable " : "", source); 1.1818 ++ printf("\tCompression used %s\n", comp->name); 1.1819 + printf("\tInodes are %scompressed\n", 1.1820 + SQUASHFS_UNCOMPRESSED_INODES(sBlk->flags) ? "un" : ""); 1.1821 + printf("\tData is %scompressed\n", 1.1822 +@@ -417,10 +421,10 @@ 1.1823 + TRACE("sBlk->lookup_table_start %llx\n", sBlk->lookup_table_start); 1.1824 + printf("\n"); 1.1825 + 1.1826 +- return TRUE; 1.1827 ++ return comp; 1.1828 + 1.1829 + failed_mount: 1.1830 +- return FALSE; 1.1831 ++ return NULL; 1.1832 + } 1.1833 + 1.1834 + 1.1835 +@@ -514,12 +518,17 @@ 1.1836 + SQUASHFS_INSWAP_ID_BLOCKS(index, indexes); 1.1837 + 1.1838 + for(i = 0; i < indexes; i++) { 1.1839 +- int length; 1.1840 +- length = read_block(fd, index[i], NULL, 1.1841 ++ int length = read_block(fd, index[i], NULL, 1.1842 + ((unsigned char *) id_table) + 1.1843 + (i * SQUASHFS_METADATA_SIZE), sBlk); 1.1844 + TRACE("Read id table block %d, from 0x%llx, length %d\n", i, 1.1845 + index[i], length); 1.1846 ++ if(length == 0) { 1.1847 ++ ERROR("Failed to read id table block %d, from 0x%llx, " 1.1848 ++ "length %d\n", i, index[i], length); 1.1849 ++ free(id_table); 1.1850 ++ return NULL; 1.1851 ++ } 1.1852 + } 1.1853 + 1.1854 + SQUASHFS_INSWAP_INTS(id_table, sBlk->no_ids); 1.1855 +@@ -563,6 +572,13 @@ 1.1856 + (i * SQUASHFS_METADATA_SIZE), sBlk); 1.1857 + TRACE("Read fragment table block %d, from 0x%llx, length %d\n", 1.1858 + i, fragment_table_index[i], length); 1.1859 ++ if(length == 0) { 1.1860 ++ ERROR("Failed to read fragment table block %d, from " 1.1861 ++ "0x%llx, length %d\n", i, 1.1862 ++ fragment_table_index[i], length); 1.1863 ++ free(*fragment_table); 1.1864 ++ return 0; 1.1865 ++ } 1.1866 + } 1.1867 + 1.1868 + for(i = 0; i < sBlk->fragments; i++) 1.1869 +@@ -599,6 +615,13 @@ 1.1870 + (i * SQUASHFS_METADATA_SIZE), sBlk); 1.1871 + TRACE("Read inode lookup table block %d, from 0x%llx, length " 1.1872 + "%d\n", i, index[i], length); 1.1873 ++ if(length == 0) { 1.1874 ++ ERROR("Failed to read inode lookup table block %d, " 1.1875 ++ "from 0x%llx, length %d\n", i, index[i], 1.1876 ++ length); 1.1877 ++ free(*inode_lookup_table); 1.1878 ++ return 0; 1.1879 ++ } 1.1880 + } 1.1881 + 1.1882 + SQUASHFS_INSWAP_LONG_LONGS(*inode_lookup_table, sBlk->inodes); 1.1883 + 1.1884 +--- squashfs-4.0/squashfs-tools/sort.c Tue Mar 31 06:25:53 2009 1.1885 ++++ squashfs-4.0/squashfs-tools/sort.c Sat Aug 29 07:41:45 2009 1.1886 +@@ -198,7 +198,7 @@ 1.1887 + while(dir->current_count < dir->count) { 1.1888 + struct dir_ent *dir_ent = dir->list[dir->current_count++]; 1.1889 + struct stat *buf = &dir_ent->inode->buf; 1.1890 +- if(dir_ent->data) 1.1891 ++ if(dir_ent->inode->root_entry) 1.1892 + continue; 1.1893 + 1.1894 + switch(buf->st_mode & S_IFMT) { 1.1895 +@@ -254,6 +254,7 @@ 1.1896 + write_file(&inode, entry->dir, &duplicate_file); 1.1897 + INFO("file %s, uncompressed size %lld bytes %s" 1.1898 + "\n", entry->dir->pathname, 1.1899 ++ (long long) 1.1900 + entry->dir->inode->buf.st_size, 1.1901 + duplicate_file ? "DUPLICATE" : ""); 1.1902 + entry->dir->inode->inode = inode; 1.1903 +@@ -261,6 +262,7 @@ 1.1904 + } else 1.1905 + INFO("file %s, uncompressed size %lld bytes " 1.1906 + "LINK\n", entry->dir->pathname, 1.1907 ++ (long long) 1.1908 + entry->dir->inode->buf.st_size); 1.1909 + } 1.1910 + } 1.1911 + 1.1912 +--- squashfs-4.0/squashfs-tools/sort.h Sun Feb 8 13:02:53 2009 1.1913 ++++ squashfs-4.0/squashfs-tools/sort.h Thu Sep 10 05:50:01 2009 1.1914 +@@ -42,17 +42,19 @@ 1.1915 + struct inode_info *inode; 1.1916 + struct dir_info *dir; 1.1917 + struct dir_info *our_dir; 1.1918 +- struct old_root_entry_info *data; 1.1919 + }; 1.1920 + 1.1921 + struct inode_info { 1.1922 +- unsigned int nlink; 1.1923 + struct stat buf; 1.1924 ++ struct inode_info *next; 1.1925 + squashfs_inode inode; 1.1926 +- unsigned int type; 1.1927 + unsigned int inode_number; 1.1928 ++ unsigned int nlink; 1.1929 ++ int pseudo_id; 1.1930 ++ char type; 1.1931 + char read; 1.1932 +- struct inode_info *next; 1.1933 ++ char root_entry; 1.1934 ++ char pseudo_file; 1.1935 + }; 1.1936 + 1.1937 + struct priority_entry { 1.1938 + 1.1939 +--- squashfs-4.0/squashfs-tools/squashfs_compat.h Mon Mar 16 05:27:27 2009 1.1940 ++++ squashfs-4.0/squashfs-tools/squashfs_compat.h Tue Apr 21 02:52:24 2009 1.1941 +@@ -777,11 +777,10 @@ 1.1942 + #endif 1.1943 + 1.1944 + #define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\ 1.1945 +- int bits;\ 1.1946 +- int b_pos = pos % 8;\ 1.1947 +- unsigned long long val = 0;\ 1.1948 +- unsigned char *s = (unsigned char *)p + (pos / 8);\ 1.1949 +- unsigned char *d = ((unsigned char *) &val) + 7;\ 1.1950 ++ b_pos = pos % 8;\ 1.1951 ++ val = 0;\ 1.1952 ++ s = (unsigned char *)p + (pos / 8);\ 1.1953 ++ d = ((unsigned char *) &val) + 7;\ 1.1954 + for(bits = 0; bits < (tbits + b_pos); bits += 8) \ 1.1955 + *d-- = *s++;\ 1.1956 + value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\ 1.1957 + 1.1958 +--- squashfs-4.0/squashfs-tools/squashfs_fs.h Wed Mar 18 03:50:20 2009 1.1959 ++++ squashfs-4.0/squashfs-tools/squashfs_fs.h Thu Jul 30 06:45:38 2009 1.1960 +@@ -229,6 +229,7 @@ 1.1961 + typedef long long squashfs_inode_t; 1.1962 + 1.1963 + #define ZLIB_COMPRESSION 1 1.1964 ++#define LZMA_COMPRESSION 2 1.1965 + 1.1966 + struct squashfs_super_block { 1.1967 + unsigned int s_magic; 1.1968 + 1.1969 +--- squashfs-4.0/squashfs-tools/unsquash-3.c Tue Mar 31 06:35:10 2009 1.1970 ++++ squashfs-4.0/squashfs-tools/unsquash-3.c Tue Apr 21 02:58:22 2009 1.1971 +@@ -36,7 +36,7 @@ 1.1972 + sBlk.fragment_table_start); 1.1973 + 1.1974 + if(sBlk.fragments == 0) 1.1975 +- return; 1.1976 ++ return TRUE; 1.1977 + 1.1978 + if((fragment_table = malloc(sBlk.fragments * 1.1979 + sizeof(squashfs_fragment_entry_3))) == NULL) 1.1980 + 1.1981 +--- squashfs-4.0/squashfs-tools/unsquash-4.c Tue Mar 31 06:38:31 2009 1.1982 ++++ squashfs-4.0/squashfs-tools/unsquash-4.c Tue Apr 21 02:59:16 2009 1.1983 +@@ -38,7 +38,7 @@ 1.1984 + sBlk.fragment_table_start); 1.1985 + 1.1986 + if(sBlk.fragments == 0) 1.1987 +- return; 1.1988 ++ return TRUE; 1.1989 + 1.1990 + if((fragment_table = malloc(sBlk.fragments * 1.1991 + sizeof(squashfs_fragment_entry))) == NULL) 1.1992 + 1.1993 +--- squashfs-4.0/squashfs-tools/unsquashfs.c Sun Apr 5 23:23:06 2009 1.1994 ++++ squashfs-4.0/squashfs-tools/unsquashfs.c Sun Aug 30 16:10:31 2009 1.1995 +@@ -25,7 +25,10 @@ 1.1996 + #include "squashfs_swap.h" 1.1997 + #include "squashfs_compat.h" 1.1998 + #include "read_fs.h" 1.1999 ++#include "compressor.h" 1.2000 + 1.2001 ++#include <sys/sysinfo.h> 1.2002 ++ 1.2003 + struct cache *fragment_cache, *data_cache; 1.2004 + struct queue *to_reader, *to_deflate, *to_writer, *from_writer; 1.2005 + pthread_t *thread, *deflator_thread; 1.2006 +@@ -36,6 +39,7 @@ 1.2007 + 1.2008 + struct super_block sBlk; 1.2009 + squashfs_operations s_ops; 1.2010 ++struct compressor *comp; 1.2011 + 1.2012 + int bytes = 0, swap, file_count = 0, dir_count = 0, sym_count = 0, 1.2013 + dev_count = 0, fifo_count = 0; 1.2014 +@@ -590,31 +594,23 @@ 1.2015 + offset = 3; 1.2016 + if(SQUASHFS_COMPRESSED(c_byte)) { 1.2017 + char buffer[SQUASHFS_METADATA_SIZE]; 1.2018 +- int res; 1.2019 +- unsigned long bytes = SQUASHFS_METADATA_SIZE; 1.2020 ++ int error, res; 1.2021 + 1.2022 + c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); 1.2023 + if(read_bytes(start + offset, c_byte, buffer) == FALSE) 1.2024 + goto failed; 1.2025 + 1.2026 +- res = uncompress((unsigned char *) block, &bytes, 1.2027 +- (const unsigned char *) buffer, c_byte); 1.2028 ++ res = comp->uncompress(block, buffer, c_byte, 1.2029 ++ SQUASHFS_METADATA_SIZE, &error); 1.2030 + 1.2031 +- if(res != Z_OK) { 1.2032 +- if(res == Z_MEM_ERROR) 1.2033 +- ERROR("zlib::uncompress failed, not enough " 1.2034 +- "memory\n"); 1.2035 +- else if(res == Z_BUF_ERROR) 1.2036 +- ERROR("zlib::uncompress failed, not enough " 1.2037 +- "room in output buffer\n"); 1.2038 +- else 1.2039 +- ERROR("zlib::uncompress failed, unknown error " 1.2040 +- "%d\n", res); 1.2041 ++ if(res == -1) { 1.2042 ++ ERROR("%s uncompress failed with error code %d\n", 1.2043 ++ comp->name, error); 1.2044 + goto failed; 1.2045 + } 1.2046 + if(next) 1.2047 + *next = start + offset + c_byte; 1.2048 +- return bytes; 1.2049 ++ return res; 1.2050 + } else { 1.2051 + c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); 1.2052 + if(read_bytes(start + offset, c_byte, block) == FALSE) 1.2053 +@@ -632,36 +628,26 @@ 1.2054 + 1.2055 + int read_data_block(long long start, unsigned int size, char *block) 1.2056 + { 1.2057 +- int res; 1.2058 +- unsigned long bytes = block_size; 1.2059 ++ int error, res; 1.2060 + int c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(size); 1.2061 + 1.2062 + TRACE("read_data_block: block @0x%llx, %d %s bytes\n", start, 1.2063 +- SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte), 1.2064 +- SQUASHFS_COMPRESSED_BLOCK(c_byte) ? "compressed" : 1.2065 ++ c_byte, SQUASHFS_COMPRESSED_BLOCK(size) ? "compressed" : 1.2066 + "uncompressed"); 1.2067 + 1.2068 + if(SQUASHFS_COMPRESSED_BLOCK(size)) { 1.2069 + if(read_bytes(start, c_byte, data) == FALSE) 1.2070 + goto failed; 1.2071 + 1.2072 +- res = uncompress((unsigned char *) block, &bytes, 1.2073 +- (const unsigned char *) data, c_byte); 1.2074 ++ res = comp->uncompress(block, data, c_byte, block_size, &error); 1.2075 + 1.2076 +- if(res != Z_OK) { 1.2077 +- if(res == Z_MEM_ERROR) 1.2078 +- ERROR("zlib::uncompress failed, not enough " 1.2079 +- "memory\n"); 1.2080 +- else if(res == Z_BUF_ERROR) 1.2081 +- ERROR("zlib::uncompress failed, not enough " 1.2082 +- "room in output buffer\n"); 1.2083 +- else 1.2084 +- ERROR("zlib::uncompress failed, unknown error " 1.2085 +- "%d\n", res); 1.2086 ++ if(res == -1) { 1.2087 ++ ERROR("%s uncompress failed with error code %d\n", 1.2088 ++ comp->name, error); 1.2089 + goto failed; 1.2090 + } 1.2091 + 1.2092 +- return bytes; 1.2093 ++ return res; 1.2094 + } else { 1.2095 + if(read_bytes(start, c_byte, block) == FALSE) 1.2096 + goto failed; 1.2097 +@@ -671,7 +657,7 @@ 1.2098 + 1.2099 + failed: 1.2100 + ERROR("read_data_block: failed to read block @0x%llx, size %d\n", start, 1.2101 +- size); 1.2102 ++ c_byte); 1.2103 + return FALSE; 1.2104 + } 1.2105 + 1.2106 +@@ -1383,6 +1369,11 @@ 1.2107 + #endif 1.2108 + printf("Creation or last append time %s", mkfs_str ? mkfs_str : 1.2109 + "failed to get time\n"); 1.2110 ++ printf("Filesystem size %.2f Kbytes (%.2f Mbytes)\n", 1.2111 ++ sBlk.bytes_used / 1024.0, sBlk.bytes_used / (1024.0 * 1024.0)); 1.2112 ++ if(sBlk.s_major == 4) 1.2113 ++ printf("Compression %s\n", comp->name); 1.2114 ++ printf("Block size %d\n", sBlk.block_size); 1.2115 + printf("Filesystem is %sexportable via NFS\n", 1.2116 + SQUASHFS_EXPORTABLE(sBlk.flags) ? "" : "not "); 1.2117 + 1.2118 +@@ -1409,9 +1400,6 @@ 1.2119 + SQUASHFS_DUPLICATES(sBlk.flags) ? "" : "not "); 1.2120 + else 1.2121 + printf("Duplicates are removed\n"); 1.2122 +- printf("Filesystem size %.2f Kbytes (%.2f Mbytes)\n", 1.2123 +- sBlk.bytes_used / 1024.0, sBlk.bytes_used / (1024.0 * 1024.0)); 1.2124 +- printf("Block size %d\n", sBlk.block_size); 1.2125 + if(sBlk.s_major > 1) 1.2126 + printf("Number of fragments %d\n", sBlk.fragments); 1.2127 + printf("Number of inodes %d\n", sBlk.inodes); 1.2128 +@@ -1459,6 +1447,18 @@ 1.2129 + s_ops.read_inode = read_inode_4; 1.2130 + s_ops.read_uids_guids = read_uids_guids_4; 1.2131 + memcpy(&sBlk, &sBlk_4, sizeof(sBlk_4)); 1.2132 ++ 1.2133 ++ /* 1.2134 ++ * Check the compression type 1.2135 ++ */ 1.2136 ++ comp = lookup_compressor_id(sBlk.compression); 1.2137 ++ if(!comp->supported) { 1.2138 ++ ERROR("Filesystem uses %s compression, this is " 1.2139 ++ "unsupported by this version\n", comp->name); 1.2140 ++ ERROR("Decompressors available:\n"); 1.2141 ++ display_compressors("", ""); 1.2142 ++ goto failed_mount; 1.2143 ++ } 1.2144 + return TRUE; 1.2145 + } 1.2146 + 1.2147 +@@ -1548,6 +1548,11 @@ 1.2148 + goto failed_mount; 1.2149 + } 1.2150 + 1.2151 ++ /* 1.2152 ++ * 1.x, 2.x and 3.x filesystems use gzip compression. Gzip is always 1.2153 ++ * suppported. 1.2154 ++ */ 1.2155 ++ comp = lookup_compressor("gzip"); 1.2156 + return TRUE; 1.2157 + 1.2158 + failed_mount: 1.2159 +@@ -1707,32 +1712,24 @@ 1.2160 + 1.2161 + while(1) { 1.2162 + struct cache_entry *entry = queue_get(to_deflate); 1.2163 +- int res; 1.2164 +- unsigned long bytes = block_size; 1.2165 ++ int error, res; 1.2166 + 1.2167 +- res = uncompress((unsigned char *) tmp, &bytes, 1.2168 +- (const unsigned char *) entry->data, 1.2169 +- SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size)); 1.2170 ++ res = comp->uncompress(tmp, entry->data, 1.2171 ++ SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size), block_size, 1.2172 ++ &error); 1.2173 + 1.2174 +- if(res != Z_OK) { 1.2175 +- if(res == Z_MEM_ERROR) 1.2176 +- ERROR("zlib::uncompress failed, not enough" 1.2177 +- "memory\n"); 1.2178 +- else if(res == Z_BUF_ERROR) 1.2179 +- ERROR("zlib::uncompress failed, not enough " 1.2180 +- "room in output buffer\n"); 1.2181 +- else 1.2182 +- ERROR("zlib::uncompress failed, unknown error " 1.2183 +- "%d\n", res); 1.2184 +- } else 1.2185 +- memcpy(entry->data, tmp, bytes); 1.2186 ++ if(res == -1) 1.2187 ++ ERROR("%s uncompress failed with error code %d\n", 1.2188 ++ comp->name, error); 1.2189 ++ else 1.2190 ++ memcpy(entry->data, tmp, res); 1.2191 + 1.2192 + /* 1.2193 + * block has been either successfully decompressed, or an error 1.2194 + * occurred, clear pending flag, set error appropriately and 1.2195 + * wake up any threads waiting on this block 1.2196 + */ 1.2197 +- cache_block_ready(entry, res != Z_OK); 1.2198 ++ cache_block_ready(entry, res == -1); 1.2199 + } 1.2200 + } 1.2201 + 1.2202 +@@ -1913,7 +1910,7 @@ 1.2203 + 1.2204 + 1.2205 + #define VERSION() \ 1.2206 +- printf("unsquashfs version 4.0 (2009/04/05)\n");\ 1.2207 ++ printf("unsquashfs version 4.0 (CVS 2009/08/30)\n");\ 1.2208 + printf("copyright (C) 2009 Phillip Lougher <phillip@lougher.demon.co.uk>"\ 1.2209 + "\n\n");\ 1.2210 + printf("This program is free software; you can redistribute it and/or\n");\ 1.2211 +@@ -1938,7 +1935,6 @@ 1.2212 + int fragment_buffer_size = FRAGMENT_BUFFER_DEFAULT; 1.2213 + int data_buffer_size = DATA_BUFFER_DEFAULT; 1.2214 + char *b; 1.2215 +- struct winsize winsize; 1.2216 + 1.2217 + pthread_mutex_init(&screen_mutex, NULL); 1.2218 + root_process = geteuid() == 0; 1.2219 +@@ -2087,6 +2083,8 @@ 1.2220 + "regular expressions\n"); 1.2221 + ERROR("\t\t\t\trather than use the default shell " 1.2222 + "wildcard\n\t\t\t\texpansion (globbing)\n"); 1.2223 ++ ERROR("\nDecompressors available:\n"); 1.2224 ++ display_compressors("", ""); 1.2225 + } 1.2226 + exit(1); 1.2227 + } 1.2228 + 1.2229 +--- squashfs-4.0/squashfs-tools/unsquashfs.h Sun Mar 29 04:29:02 2009 1.2230 ++++ squashfs-4.0/squashfs-tools/unsquashfs.h Fri Jul 31 19:24:38 2009 1.2231 +@@ -31,7 +31,6 @@ 1.2232 + #include <fcntl.h> 1.2233 + #include <errno.h> 1.2234 + #include <string.h> 1.2235 +-#include <zlib.h> 1.2236 + #include <sys/mman.h> 1.2237 + #include <utime.h> 1.2238 + #include <pwd.h>