wok rev 7649
Add xz to squashfs tools.
author | Christopher Rogers <slaxemulator@gmail.com> |
---|---|
date | Tue Dec 14 21:34:46 2010 +0000 (2010-12-14) |
parents | f99ea44cc9f6 |
children | 1bea914df3b9 |
files | squashfs/receipt squashfs/stuff/xz.patch |
line diff
1.1 --- a/squashfs/receipt Tue Dec 14 21:27:30 2010 +0000 1.2 +++ b/squashfs/receipt Tue Dec 14 21:34:46 2010 +0000 1.3 @@ -16,9 +16,10 @@ 1.4 compile_rules() 1.5 { 1.6 mv ${PACKAGE}${VERSION} $src 2> /dev/null 1.7 - 1.8 + cd $src 1.9 + patch -Np1 -i ../stuff/xz.patch 1.10 cd $src/squashfs-tools 1.11 - sed -i 's|#XZ_SUPPORT = 1|XZ_SUPPORT = 1|g' Makefile 1.12 + #sed -i 's|#XZ_SUPPORT = 1|XZ_SUPPORT = 1|g' Makefile 1.13 mkdir -p ../_pkg/usr/sbin ../_pkg/sbin 1.14 make || return 1 1.15 cp mksquashfs ../_pkg/usr/sbin
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/squashfs/stuff/xz.patch Tue Dec 14 21:34:46 2010 +0000 2.3 @@ -0,0 +1,1432 @@ 2.4 +diff -r 2ab2996036dd squashfs-tools/Makefile 2.5 +--- a/squashfs-tools/Makefile Tue Dec 14 12:19:33 2010 +0000 2.6 ++++ b/squashfs-tools/Makefile Tue Dec 14 14:18:11 2010 +0000 2.7 +@@ -20,20 +20,33 @@ 2.8 + 2.9 + ########### Building LZMA support ############# 2.10 + # 2.11 +-# Both XZ Utils liblzma (http://tukaani.org/xz/) and LZMA SDK 2.12 ++# LZMA1 compression. 2.13 ++# 2.14 ++# Both XZ Utils liblzma (http://tukaani.org/xz/) and LZMA SDK 2.15 + # (http://www.7-zip.org/sdk.html) are supported 2.16 + # 2.17 + # To build using XZ Utils liblzma - install the library and uncomment 2.18 +-# the XZ_SUPPORT line below. 2.19 ++# the LZMA_XZ_SUPPORT line below. 2.20 + # 2.21 + # To build using the LZMA SDK (4.65 used in development, other versions may 2.22 + # work) - download and unpack it, uncomment and set LZMA_DIR to unpacked source, 2.23 + # and uncomment the LZMA_SUPPORT line below. 2.24 + # 2.25 +-#XZ_SUPPORT = 1 2.26 ++LZMA_XZ_SUPPORT = 1 2.27 + #LZMA_SUPPORT = 1 2.28 + #LZMA_DIR = ../../../LZMA/lzma465 2.29 + 2.30 ++########### Building XZ support ############# 2.31 ++# 2.32 ++# LZMA2 compression. 2.33 ++# 2.34 ++# XZ Utils liblzma (http://tukaani.org/xz/) is supported 2.35 ++# 2.36 ++# To build using XZ Utils liblzma - install the library and uncomment 2.37 ++# the XZ_SUPPORT line below. 2.38 ++# 2.39 ++XZ_SUPPORT = 1 2.40 ++ 2.41 + 2.42 + ############ Building LZO support ############## 2.43 + # 2.44 +@@ -109,12 +122,20 @@ 2.45 + COMPRESSORS += lzma 2.46 + endif 2.47 + 2.48 ++ifdef LZMA_XZ_SUPPORT 2.49 ++CFLAGS += -DLZMA_SUPPORT 2.50 ++MKSQUASHFS_OBJS += lzma_xz_wrapper.o 2.51 ++UNSQUASHFS_OBJS += lzma_xz_wrapper.o 2.52 ++LIBS += -llzma 2.53 ++COMPRESSORS += lzma 2.54 ++endif 2.55 ++ 2.56 + ifdef XZ_SUPPORT 2.57 +-CFLAGS += -DLZMA_SUPPORT 2.58 ++CFLAGS += -DXZ_SUPPORT 2.59 + MKSQUASHFS_OBJS += xz_wrapper.o 2.60 + UNSQUASHFS_OBJS += xz_wrapper.o 2.61 + LIBS += -llzma 2.62 +-COMPRESSORS += lzma 2.63 ++COMPRESSORS += xz 2.64 + endif 2.65 + 2.66 + ifdef LZO_SUPPORT 2.67 +@@ -149,11 +170,11 @@ 2.68 + endif 2.69 + 2.70 + # 2.71 +-# Both XZ_SUPPORT and LZMA_SUPPORT cannot be specified 2.72 ++# Both LZMA_XZ_SUPPORT and LZMA_SUPPORT cannot be specified 2.73 + # 2.74 +-ifdef XZ_SUPPORT 2.75 ++ifdef LZMA_XZ_SUPPORT 2.76 + ifdef LZMA_SUPPORT 2.77 +-$(error "Both XZ_SUPPORT and LZMA_SUPPORT cannot be specified") 2.78 ++$(error "Both LZMA_XZ_SUPPORT and LZMA_SUPPORT cannot be specified") 2.79 + endif 2.80 + endif 2.81 + 2.82 +@@ -161,7 +182,7 @@ 2.83 + # At least one compressor must have been selected 2.84 + # 2.85 + ifndef COMPRESSORS 2.86 +-$(error "No compressor selected! Select one or more of GZIP, LZMA, or LZO!") 2.87 ++$(error "No compressor selected! Select one or more of GZIP, LZMA, XZ or LZO!") 2.88 + endif 2.89 + 2.90 + # 2.91 +diff -r 2ab2996036dd squashfs-tools/compressor.c 2.92 +--- a/squashfs-tools/compressor.c Tue Dec 14 12:19:33 2010 +0000 2.93 ++++ b/squashfs-tools/compressor.c Tue Dec 14 14:18:11 2010 +0000 2.94 +@@ -25,31 +25,50 @@ 2.95 + #include "compressor.h" 2.96 + #include "squashfs_fs.h" 2.97 + 2.98 +-extern int gzip_compress(void **, char *, char *, int, int, int *); 2.99 +-extern int gzip_uncompress(char *, char *, int, int, int *); 2.100 +-extern int lzma_compress(void **, char *, char *, int, int, int *); 2.101 +-extern int lzma_uncompress(char *, char *, int, int, int *); 2.102 +-extern int lzo_compress(void **, char *, char *, int, int, int *); 2.103 +-extern int lzo_uncompress(char *, char *, int, int, int *); 2.104 +- 2.105 +-struct compressor compressor[] = { 2.106 +-#ifdef GZIP_SUPPORT 2.107 +- { gzip_compress, gzip_uncompress, ZLIB_COMPRESSION, "gzip", 1 }, 2.108 ++#ifndef GZIP_SUPPORT 2.109 ++static struct compressor gzip_comp_ops = { 2.110 ++ NULL, NULL, NULL, NULL, NULL, ZLIB_COMPRESSION, "gzip", 0 2.111 ++}; 2.112 + #else 2.113 +- { NULL, NULL, ZLIB_COMPRESSION, "gzip", 0 }, 2.114 +-#endif 2.115 +-#ifdef LZMA_SUPPORT 2.116 +- { lzma_compress, lzma_uncompress, LZMA_COMPRESSION, "lzma", 1 }, 2.117 +-#else 2.118 +- { NULL, NULL, LZMA_COMPRESSION, "lzma", 0 }, 2.119 +-#endif 2.120 +-#ifdef LZO_SUPPORT 2.121 +- { lzo_compress, lzo_uncompress, LZO_COMPRESSION, "lzo", 1 }, 2.122 +-#else 2.123 +- { NULL, NULL, LZO_COMPRESSION, "lzo", 0 }, 2.124 ++extern struct compressor gzip_comp_ops; 2.125 + #endif 2.126 + 2.127 +- { NULL, NULL , 0, "unknown", 0} 2.128 ++#ifndef LZMA_SUPPORT 2.129 ++static struct compressor lzma_comp_ops = { 2.130 ++ NULL, NULL, NULL, NULL, NULL, LZMA_COMPRESSION, "lzma", 0 2.131 ++}; 2.132 ++#else 2.133 ++extern struct compressor lzma_comp_ops; 2.134 ++#endif 2.135 ++ 2.136 ++#ifndef LZO_SUPPORT 2.137 ++static struct compressor lzo_comp_ops = { 2.138 ++ NULL, NULL, NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0 2.139 ++}; 2.140 ++#else 2.141 ++extern struct compressor lzo_comp_ops; 2.142 ++#endif 2.143 ++ 2.144 ++#ifndef XZ_SUPPORT 2.145 ++static struct compressor xz_comp_ops = { 2.146 ++ NULL, NULL, NULL, NULL, NULL, XZ_COMPRESSION, "xz", 0 2.147 ++}; 2.148 ++#else 2.149 ++extern struct compressor xz_comp_ops; 2.150 ++#endif 2.151 ++ 2.152 ++ 2.153 ++static struct compressor unknown_comp_ops = { 2.154 ++ NULL, NULL, NULL , NULL, NULL, 0, "unknown", 0 2.155 ++}; 2.156 ++ 2.157 ++ 2.158 ++struct compressor *compressor[] = { 2.159 ++ &gzip_comp_ops, 2.160 ++ &lzma_comp_ops, 2.161 ++ &lzo_comp_ops, 2.162 ++ &xz_comp_ops, 2.163 ++ &unknown_comp_ops 2.164 + }; 2.165 + 2.166 + 2.167 +@@ -57,11 +76,11 @@ 2.168 + { 2.169 + int i; 2.170 + 2.171 +- for(i = 0; compressor[i].id; i++) 2.172 +- if(strcmp(compressor[i].name, name) == 0) 2.173 ++ for(i = 0; compressor[i]->id; i++) 2.174 ++ if(strcmp(compressor[i]->name, name) == 0) 2.175 + break; 2.176 + 2.177 +- return &compressor[i]; 2.178 ++ return compressor[i]; 2.179 + } 2.180 + 2.181 + 2.182 +@@ -69,11 +88,11 @@ 2.183 + { 2.184 + int i; 2.185 + 2.186 +- for(i = 0; compressor[i].id; i++) 2.187 +- if(id == compressor[i].id) 2.188 ++ for(i = 0; compressor[i]->id; i++) 2.189 ++ if(id == compressor[i]->id) 2.190 + break; 2.191 + 2.192 +- return &compressor[i]; 2.193 ++ return compressor[i]; 2.194 + } 2.195 + 2.196 + 2.197 +@@ -81,10 +100,29 @@ 2.198 + { 2.199 + int i; 2.200 + 2.201 +- for(i = 0; compressor[i].id; i++) 2.202 +- if(compressor[i].supported) 2.203 ++ for(i = 0; compressor[i]->id; i++) 2.204 ++ if(compressor[i]->supported) 2.205 + fprintf(stderr, "%s\t%s%s\n", indent, 2.206 +- compressor[i].name, 2.207 +- strcmp(compressor[i].name, def_comp) == 0 ? 2.208 ++ compressor[i]->name, 2.209 ++ strcmp(compressor[i]->name, def_comp) == 0 ? 2.210 + " (default)" : ""); 2.211 + } 2.212 ++ 2.213 ++ 2.214 ++void display_compressor_usage(char *def_comp) 2.215 ++{ 2.216 ++ int i; 2.217 ++ 2.218 ++ for(i = 0; compressor[i]->id; i++) 2.219 ++ if(compressor[i]->supported) { 2.220 ++ char *str = strcmp(compressor[i]->name, def_comp) == 0 ? 2.221 ++ " (default)" : ""; 2.222 ++ if(compressor[i]->usage) { 2.223 ++ fprintf(stderr, "\t%s%s\n", 2.224 ++ compressor[i]->name, str); 2.225 ++ compressor[i]->usage(); 2.226 ++ } else 2.227 ++ fprintf(stderr, "\t%s (no options)%s\n", 2.228 ++ compressor[i]->name, str); 2.229 ++ } 2.230 ++} 2.231 +diff -r 2ab2996036dd squashfs-tools/compressor.h 2.232 +--- a/squashfs-tools/compressor.h Tue Dec 14 12:19:33 2010 +0000 2.233 ++++ b/squashfs-tools/compressor.h Tue Dec 14 14:18:11 2010 +0000 2.234 +@@ -21,8 +21,11 @@ 2.235 + */ 2.236 + 2.237 + struct compressor { 2.238 +- int (*compress)(void **, char *, char *, int, int, int *); 2.239 +- int (*uncompress)(char *, char *, int, int, int *); 2.240 ++ int (*init)(void **, int, int); 2.241 ++ int (*compress)(void *, void *, void *, int, int, int *); 2.242 ++ int (*uncompress)(void *, void *, int, int, int *); 2.243 ++ int (*options)(char **, int); 2.244 ++ void (*usage)(); 2.245 + int id; 2.246 + char *name; 2.247 + int supported; 2.248 +@@ -31,3 +34,25 @@ 2.249 + extern struct compressor *lookup_compressor(char *); 2.250 + extern struct compressor *lookup_compressor_id(int); 2.251 + extern void display_compressors(char *, char *); 2.252 ++extern void display_compressor_usage(char *); 2.253 ++ 2.254 ++static inline int compressor_options(struct compressor *comp, char *argv[], 2.255 ++ int argc) 2.256 ++{ 2.257 ++ if(comp->options == NULL) 2.258 ++ return -1; 2.259 ++ 2.260 ++ return comp->options(argv, argc); 2.261 ++} 2.262 ++ 2.263 ++ 2.264 ++static inline int compressor_init(struct compressor *comp, void **stream, 2.265 ++ int block_size, int flags) 2.266 ++{ 2.267 ++ if(comp->init == NULL) 2.268 ++ return 0; 2.269 ++ return comp->init(stream, block_size, flags); 2.270 ++} 2.271 ++ 2.272 ++ 2.273 ++ 2.274 +diff -r 2ab2996036dd squashfs-tools/gzip_wrapper.c 2.275 +--- a/squashfs-tools/gzip_wrapper.c Tue Dec 14 12:19:33 2010 +0000 2.276 ++++ b/squashfs-tools/gzip_wrapper.c Tue Dec 14 14:18:11 2010 +0000 2.277 +@@ -22,28 +22,48 @@ 2.278 + #include <stdlib.h> 2.279 + #include <zlib.h> 2.280 + 2.281 +-int gzip_compress(void **strm, char *d, char *s, int size, int block_size, 2.282 ++#include "squashfs_fs.h" 2.283 ++#include "compressor.h" 2.284 ++ 2.285 ++static int gzip_init(void **strm, int block_size, int flags) 2.286 ++{ 2.287 ++ int res; 2.288 ++ z_stream *stream; 2.289 ++ 2.290 ++ stream = *strm = malloc(sizeof(z_stream)); 2.291 ++ if(stream == NULL) 2.292 ++ goto failed; 2.293 ++ 2.294 ++ stream->zalloc = Z_NULL; 2.295 ++ stream->zfree = Z_NULL; 2.296 ++ stream->opaque = 0; 2.297 ++ 2.298 ++ res = deflateInit(stream, 9); 2.299 ++ if(res != Z_OK) 2.300 ++ goto failed2; 2.301 ++ 2.302 ++ return 0; 2.303 ++ 2.304 ++failed2: 2.305 ++ free(stream); 2.306 ++failed: 2.307 ++ return -1; 2.308 ++} 2.309 ++ 2.310 ++ 2.311 ++static int gzip_compress(void *strm, void *d, void *s, int size, int block_size, 2.312 + int *error) 2.313 + { 2.314 +- int res = 0; 2.315 +- z_stream *stream = *strm; 2.316 ++ int res; 2.317 ++ z_stream *stream = strm; 2.318 + 2.319 +- if(stream == NULL) { 2.320 +- if((stream = *strm = malloc(sizeof(z_stream))) == NULL) 2.321 +- goto failed; 2.322 +- 2.323 +- stream->zalloc = Z_NULL; 2.324 +- stream->zfree = Z_NULL; 2.325 +- stream->opaque = 0; 2.326 +- 2.327 +- if((res = deflateInit(stream, 9)) != Z_OK) 2.328 +- goto failed; 2.329 +- } else if((res = deflateReset(stream)) != Z_OK) 2.330 ++ res = deflateReset(stream); 2.331 ++ if(res != Z_OK) 2.332 + goto failed; 2.333 + 2.334 +- stream->next_in = (unsigned char *) s; 2.335 ++ stream->next_in = s; 2.336 + stream->avail_in = size; 2.337 +- stream->next_out = (unsigned char *) d; 2.338 ++ stream->next_out = d; 2.339 + stream->avail_out = block_size; 2.340 + 2.341 + res = deflate(stream, Z_FINISH); 2.342 +@@ -67,14 +87,26 @@ 2.343 + } 2.344 + 2.345 + 2.346 +-int gzip_uncompress(char *d, char *s, int size, int block_size, int *error) 2.347 ++static int gzip_uncompress(void *d, void *s, int size, int block_size, int *error) 2.348 + { 2.349 + int res; 2.350 + unsigned long bytes = block_size; 2.351 + 2.352 +- res = uncompress((unsigned char *) d, &bytes, 2.353 +- (const unsigned char *) s, size); 2.354 ++ res = uncompress(d, &bytes, s, size); 2.355 + 2.356 + *error = res; 2.357 + return res == Z_OK ? (int) bytes : -1; 2.358 + } 2.359 ++ 2.360 ++ 2.361 ++struct compressor gzip_comp_ops = { 2.362 ++ .init = gzip_init, 2.363 ++ .compress = gzip_compress, 2.364 ++ .uncompress = gzip_uncompress, 2.365 ++ .options = NULL, 2.366 ++ .usage = NULL, 2.367 ++ .id = ZLIB_COMPRESSION, 2.368 ++ .name = "gzip", 2.369 ++ .supported = 1 2.370 ++}; 2.371 ++ 2.372 +diff -r 2ab2996036dd squashfs-tools/lzma_wrapper.c 2.373 +--- a/squashfs-tools/lzma_wrapper.c Tue Dec 14 12:19:33 2010 +0000 2.374 ++++ b/squashfs-tools/lzma_wrapper.c Tue Dec 14 14:18:11 2010 +0000 2.375 +@@ -17,21 +17,27 @@ 2.376 + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 2.377 + * 2.378 + * lzma_wrapper.c 2.379 ++ * 2.380 ++ * Support for LZMA1 compression using LZMA SDK (4.65 used in 2.381 ++ * development, other versions may work) http://www.7-zip.org/sdk.html 2.382 + */ 2.383 + 2.384 + #include <LzmaLib.h> 2.385 + 2.386 ++#include "squashfs_fs.h" 2.387 ++#include "compressor.h" 2.388 ++ 2.389 + #define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8) 2.390 + 2.391 +-int lzma_compress(void **strm, char *dest, char *src, int size, int block_size, 2.392 ++static int lzma_compress(void *strm, void *dest, void *src, int size, int block_size, 2.393 + int *error) 2.394 + { 2.395 +- unsigned char *d = (unsigned char *) dest, *s = (unsigned char *) src; 2.396 ++ unsigned char *d = dest; 2.397 + size_t props_size = LZMA_PROPS_SIZE, 2.398 + outlen = block_size - LZMA_HEADER_SIZE; 2.399 + int res; 2.400 + 2.401 +- res = LzmaCompress(d + LZMA_HEADER_SIZE, &outlen, s, size, d, 2.402 ++ res = LzmaCompress(dest + LZMA_HEADER_SIZE, &outlen, src, size, dest, 2.403 + &props_size, 5, block_size, 3, 0, 2, 32, 1); 2.404 + 2.405 + if(res == SZ_ERROR_OUTPUT_EOF) { 2.406 +@@ -73,10 +79,10 @@ 2.407 + } 2.408 + 2.409 + 2.410 +-int lzma_uncompress(char *dest, char *src, int size, int block_size, 2.411 ++static int lzma_uncompress(void *dest, void *src, int size, int block_size, 2.412 + int *error) 2.413 + { 2.414 +- unsigned char *d = (unsigned char *) dest, *s = (unsigned char *) src; 2.415 ++ unsigned char *s = src; 2.416 + size_t outlen, inlen = size - LZMA_HEADER_SIZE; 2.417 + int res; 2.418 + 2.419 +@@ -85,9 +91,22 @@ 2.420 + (s[LZMA_PROPS_SIZE + 2] << 16) | 2.421 + (s[LZMA_PROPS_SIZE + 3] << 24); 2.422 + 2.423 +- res = LzmaUncompress(d, &outlen, s + LZMA_HEADER_SIZE, &inlen, 2.424 +- s, LZMA_PROPS_SIZE); 2.425 ++ res = LzmaUncompress(dest, &outlen, src + LZMA_HEADER_SIZE, &inlen, src, 2.426 ++ LZMA_PROPS_SIZE); 2.427 + 2.428 + *error = res; 2.429 + return res == SZ_OK ? outlen : -1; 2.430 + } 2.431 ++ 2.432 ++ 2.433 ++struct compressor lzma_comp_ops = { 2.434 ++ .init = NULL, 2.435 ++ .compress = lzma_compress, 2.436 ++ .uncompress = lzma_uncompress, 2.437 ++ .options = NULL, 2.438 ++ .usage = NULL, 2.439 ++ .id = LZMA_COMPRESSION, 2.440 ++ .name = "lzma", 2.441 ++ .supported = 1 2.442 ++}; 2.443 ++ 2.444 +diff -r 2ab2996036dd squashfs-tools/lzma_xz_wrapper.c 2.445 +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.446 ++++ b/squashfs-tools/lzma_xz_wrapper.c Tue Dec 14 14:18:11 2010 +0000 2.447 +@@ -0,0 +1,156 @@ 2.448 ++/* 2.449 ++ * Copyright (c) 2010 2.450 ++ * Phillip Lougher <phillip@lougher.demon.co.uk> 2.451 ++ * 2.452 ++ * This program is free software; you can redistribute it and/or 2.453 ++ * modify it under the terms of the GNU General Public License 2.454 ++ * as published by the Free Software Foundation; either version 2, 2.455 ++ * or (at your option) any later version. 2.456 ++ * 2.457 ++ * This program is distributed in the hope that it will be useful, 2.458 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of 2.459 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2.460 ++ * GNU General Public License for more details. 2.461 ++ * 2.462 ++ * You should have received a copy of the GNU General Public License 2.463 ++ * along with this program; if not, write to the Free Software 2.464 ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 2.465 ++ * 2.466 ++ * lzma_xz_wrapper.c 2.467 ++ * 2.468 ++ * Support for LZMA1 compression using XZ Utils liblzma http://tukaani.org/xz/ 2.469 ++ */ 2.470 ++ 2.471 ++#include <stdio.h> 2.472 ++#include <string.h> 2.473 ++#include <lzma.h> 2.474 ++ 2.475 ++#include "squashfs_fs.h" 2.476 ++#include "compressor.h" 2.477 ++ 2.478 ++#define LZMA_PROPS_SIZE 5 2.479 ++#define LZMA_UNCOMP_SIZE 8 2.480 ++#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + LZMA_UNCOMP_SIZE) 2.481 ++ 2.482 ++#define LZMA_OPTIONS 5 2.483 ++#define MEMLIMIT (32 * 1024 * 1024) 2.484 ++ 2.485 ++static int lzma_compress(void *dummy, void *dest, void *src, int size, 2.486 ++ int block_size, int *error) 2.487 ++{ 2.488 ++ unsigned char *d = (unsigned char *) dest; 2.489 ++ lzma_options_lzma opt; 2.490 ++ lzma_stream strm = LZMA_STREAM_INIT; 2.491 ++ int res; 2.492 ++ 2.493 ++ lzma_lzma_preset(&opt, LZMA_OPTIONS); 2.494 ++ opt.dict_size = block_size; 2.495 ++ res = lzma_alone_encoder(&strm, &opt); 2.496 ++ if(res != LZMA_OK) { 2.497 ++ lzma_end(&strm); 2.498 ++ goto failed; 2.499 ++ } 2.500 ++ 2.501 ++ strm.next_out = dest; 2.502 ++ strm.avail_out = block_size; 2.503 ++ strm.next_in = src; 2.504 ++ strm.avail_in = size; 2.505 ++ 2.506 ++ res = lzma_code(&strm, LZMA_FINISH); 2.507 ++ lzma_end(&strm); 2.508 ++ 2.509 ++ if(res == LZMA_STREAM_END) { 2.510 ++ /* 2.511 ++ * Fill in the 8 byte little endian uncompressed size field in 2.512 ++ * the LZMA header. 8 bytes is excessively large for squashfs 2.513 ++ * but this is the standard LZMA header and which is expected by 2.514 ++ * the kernel code 2.515 ++ */ 2.516 ++ 2.517 ++ d[LZMA_PROPS_SIZE] = size & 255; 2.518 ++ d[LZMA_PROPS_SIZE + 1] = (size >> 8) & 255; 2.519 ++ d[LZMA_PROPS_SIZE + 2] = (size >> 16) & 255; 2.520 ++ d[LZMA_PROPS_SIZE + 3] = (size >> 24) & 255; 2.521 ++ d[LZMA_PROPS_SIZE + 4] = 0; 2.522 ++ d[LZMA_PROPS_SIZE + 5] = 0; 2.523 ++ d[LZMA_PROPS_SIZE + 6] = 0; 2.524 ++ d[LZMA_PROPS_SIZE + 7] = 0; 2.525 ++ 2.526 ++ return (int) strm.total_out; 2.527 ++ } 2.528 ++ 2.529 ++ if(res == LZMA_OK) 2.530 ++ /* 2.531 ++ * Output buffer overflow. Return out of buffer space 2.532 ++ */ 2.533 ++ return 0; 2.534 ++ 2.535 ++failed: 2.536 ++ /* 2.537 ++ * All other errors return failure, with the compressor 2.538 ++ * specific error code in *error 2.539 ++ */ 2.540 ++ *error = res; 2.541 ++ return -1; 2.542 ++} 2.543 ++ 2.544 ++ 2.545 ++static int lzma_uncompress(void *dest, void *src, int size, int block_size, 2.546 ++ int *error) 2.547 ++{ 2.548 ++ lzma_stream strm = LZMA_STREAM_INIT; 2.549 ++ int uncompressed_size = 0, res; 2.550 ++ unsigned char lzma_header[LZMA_HEADER_SIZE]; 2.551 ++ 2.552 ++ res = lzma_alone_decoder(&strm, MEMLIMIT); 2.553 ++ if(res != LZMA_OK) { 2.554 ++ lzma_end(&strm); 2.555 ++ goto failed; 2.556 ++ } 2.557 ++ 2.558 ++ memcpy(lzma_header, src, LZMA_HEADER_SIZE); 2.559 ++ uncompressed_size = lzma_header[LZMA_PROPS_SIZE] | 2.560 ++ (lzma_header[LZMA_PROPS_SIZE + 1] << 8) | 2.561 ++ (lzma_header[LZMA_PROPS_SIZE + 2] << 16) | 2.562 ++ (lzma_header[LZMA_PROPS_SIZE + 3] << 24); 2.563 ++ memset(lzma_header + LZMA_PROPS_SIZE, 255, LZMA_UNCOMP_SIZE); 2.564 ++ 2.565 ++ strm.next_out = dest; 2.566 ++ strm.avail_out = block_size; 2.567 ++ strm.next_in = lzma_header; 2.568 ++ strm.avail_in = LZMA_HEADER_SIZE; 2.569 ++ 2.570 ++ res = lzma_code(&strm, LZMA_RUN); 2.571 ++ 2.572 ++ if(res != LZMA_OK || strm.avail_in != 0) { 2.573 ++ lzma_end(&strm); 2.574 ++ goto failed; 2.575 ++ } 2.576 ++ 2.577 ++ strm.next_in = src + LZMA_HEADER_SIZE; 2.578 ++ strm.avail_in = size - LZMA_HEADER_SIZE; 2.579 ++ 2.580 ++ res = lzma_code(&strm, LZMA_FINISH); 2.581 ++ lzma_end(&strm); 2.582 ++ 2.583 ++ if(res == LZMA_STREAM_END || (res == LZMA_OK && 2.584 ++ strm.total_out >= uncompressed_size && strm.avail_in == 0)) 2.585 ++ return uncompressed_size; 2.586 ++ 2.587 ++failed: 2.588 ++ *error = res; 2.589 ++ return -1; 2.590 ++} 2.591 ++ 2.592 ++ 2.593 ++struct compressor lzma_comp_ops = { 2.594 ++ .init = NULL, 2.595 ++ .compress = lzma_compress, 2.596 ++ .uncompress = lzma_uncompress, 2.597 ++ .options = NULL, 2.598 ++ .usage = NULL, 2.599 ++ .id = LZMA_COMPRESSION, 2.600 ++ .name = "lzma", 2.601 ++ .supported = 1 2.602 ++}; 2.603 ++ 2.604 +diff -r 2ab2996036dd squashfs-tools/lzo_wrapper.c 2.605 +--- a/squashfs-tools/lzo_wrapper.c Tue Dec 14 12:19:33 2010 +0000 2.606 ++++ b/squashfs-tools/lzo_wrapper.c Tue Dec 14 14:18:11 2010 +0000 2.607 +@@ -2,6 +2,9 @@ 2.608 + * Copyright (c) 2010 LG Electronics 2.609 + * Chan Jeong <chan.jeong@lge.com> 2.610 + * 2.611 ++ * All modifications Copyright (c) 2010 2.612 ++ * Phillip Lougher <phillip@lougher.demon.co.uk> 2.613 ++ * 2.614 + * This program is free software; you can redistribute it and/or 2.615 + * modify it under the terms of the GNU General Public License 2.616 + * as published by the Free Software Foundation; either version 2, 2.617 +@@ -25,6 +28,9 @@ 2.618 + #include <lzo/lzoconf.h> 2.619 + #include <lzo/lzo1x.h> 2.620 + 2.621 ++#include "squashfs_fs.h" 2.622 ++#include "compressor.h" 2.623 ++ 2.624 + /* worst-case expansion calculation during compression, 2.625 + see LZO FAQ for more information */ 2.626 + #define LZO_OUTPUT_BUFFER_SIZE(size) (size + (size/16) + 64 + 3) 2.627 +@@ -34,25 +40,39 @@ 2.628 + lzo_bytep out; 2.629 + }; 2.630 + 2.631 +-int lzo_compress(void **strm, char *d, char *s, int size, int block_size, 2.632 ++ 2.633 ++static int squashfs_lzo_init(void **strm, int block_size, int flags) 2.634 ++{ 2.635 ++ struct lzo_stream *stream; 2.636 ++ 2.637 ++ if((stream = *strm = malloc(sizeof(struct lzo_stream))) == NULL) 2.638 ++ goto failed; 2.639 ++ /* work memory for compression */ 2.640 ++ if((stream->wrkmem = malloc(LZO1X_999_MEM_COMPRESS)) == NULL) 2.641 ++ goto failed2; 2.642 ++ /* temporal output buffer */ 2.643 ++ if((stream->out = malloc(LZO_OUTPUT_BUFFER_SIZE(block_size))) == NULL) 2.644 ++ goto failed3; 2.645 ++ 2.646 ++ return 0; 2.647 ++ 2.648 ++failed3: 2.649 ++ free(stream->wrkmem); 2.650 ++failed2: 2.651 ++ free(stream); 2.652 ++failed: 2.653 ++ return -1; 2.654 ++} 2.655 ++ 2.656 ++ 2.657 ++static int lzo_compress(void *strm, void *d, void *s, int size, int block_size, 2.658 + int *error) 2.659 + { 2.660 +- int res = 0; 2.661 ++ int res; 2.662 + lzo_uint outlen; 2.663 +- struct lzo_stream *stream = *strm; 2.664 ++ struct lzo_stream *stream = strm; 2.665 + 2.666 +- if(stream == NULL) { 2.667 +- if((stream = *strm = malloc(sizeof(struct lzo_stream))) == NULL) 2.668 +- goto failed; 2.669 +- /* work memory for compression */ 2.670 +- if((stream->wrkmem = malloc(LZO1X_999_MEM_COMPRESS)) == NULL) 2.671 +- goto failed; 2.672 +- /* temporal output buffer */ 2.673 +- if((stream->out = malloc(LZO_OUTPUT_BUFFER_SIZE(block_size))) == NULL) 2.674 +- goto failed; 2.675 +- } 2.676 +- 2.677 +- res = lzo1x_999_compress((lzo_bytep)s, size, stream->out, &outlen, stream->wrkmem); 2.678 ++ res = lzo1x_999_compress(s, size, stream->out, &outlen, stream->wrkmem); 2.679 + if(res != LZO_E_OK) 2.680 + goto failed; 2.681 + if(outlen >= size) 2.682 +@@ -77,13 +97,26 @@ 2.683 + } 2.684 + 2.685 + 2.686 +-int lzo_uncompress(char *d, char *s, int size, int block_size, int *error) 2.687 ++static int lzo_uncompress(void *d, void *s, int size, int block_size, int *error) 2.688 + { 2.689 + int res; 2.690 + lzo_uint bytes = block_size; 2.691 + 2.692 +- res = lzo1x_decompress_safe((lzo_bytep)s, size, (lzo_bytep)d, &bytes, NULL); 2.693 ++ res = lzo1x_decompress_safe(s, size, d, &bytes, NULL); 2.694 + 2.695 + *error = res; 2.696 + return res == LZO_E_OK ? bytes : -1; 2.697 + } 2.698 ++ 2.699 ++ 2.700 ++struct compressor lzo_comp_ops = { 2.701 ++ .init = squashfs_lzo_init, 2.702 ++ .compress = lzo_compress, 2.703 ++ .uncompress = lzo_uncompress, 2.704 ++ .options = NULL, 2.705 ++ .usage = NULL, 2.706 ++ .id = LZO_COMPRESSION, 2.707 ++ .name = "lzo", 2.708 ++ .supported = 1 2.709 ++}; 2.710 ++ 2.711 +diff -r 2ab2996036dd squashfs-tools/mksquashfs.c 2.712 +--- a/squashfs-tools/mksquashfs.c Tue Dec 14 12:19:33 2010 +0000 2.713 ++++ b/squashfs-tools/mksquashfs.c Tue Dec 14 14:18:11 2010 +0000 2.714 +@@ -384,9 +384,10 @@ 2.715 + #define FRAGMENT_BUFFER_DEFAULT 64 2.716 + int writer_buffer_size; 2.717 + 2.718 +-/* compression operations structure */ 2.719 ++/* compression operations */ 2.720 + static struct compressor *comp; 2.721 +-char *comp_name = COMP_DEFAULT; 2.722 ++int compressor_opts_parsed = 0; 2.723 ++void *stream = NULL; 2.724 + 2.725 + /* xattr stats */ 2.726 + unsigned int xattr_bytes = 0, total_xattr_bytes = 0; 2.727 +@@ -859,7 +860,7 @@ 2.728 + } 2.729 + 2.730 + 2.731 +-int mangle2(void **strm, char *d, char *s, int size, 2.732 ++int mangle2(void *strm, char *d, char *s, int size, 2.733 + int block_size, int uncompressed, int data_block) 2.734 + { 2.735 + int error, c_byte = 0; 2.736 +@@ -884,9 +885,7 @@ 2.737 + int mangle(char *d, char *s, int size, int block_size, 2.738 + int uncompressed, int data_block) 2.739 + { 2.740 +- static void *stream = NULL; 2.741 +- 2.742 +- return mangle2(&stream, d, s, size, block_size, uncompressed, 2.743 ++ return mangle2(stream, d, s, size, block_size, uncompressed, 2.744 + data_block); 2.745 + } 2.746 + 2.747 +@@ -2556,11 +2555,15 @@ 2.748 + void *deflator(void *arg) 2.749 + { 2.750 + void *stream = NULL; 2.751 +- int oldstate; 2.752 ++ int res, oldstate; 2.753 + 2.754 + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); 2.755 + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); 2.756 + 2.757 ++ res = compressor_init(comp, &stream, block_size, 1); 2.758 ++ if(res) 2.759 ++ BAD_ERROR("deflator:: compressor_init failed\n"); 2.760 ++ 2.761 + while(1) { 2.762 + struct file_buffer *file_buffer = queue_get(from_reader); 2.763 + struct file_buffer *write_buffer; 2.764 +@@ -2573,7 +2576,7 @@ 2.765 + queue_put(from_deflate, file_buffer); 2.766 + } else { 2.767 + write_buffer = cache_get(writer_buffer, 0, 0); 2.768 +- write_buffer->c_byte = mangle2(&stream, 2.769 ++ write_buffer->c_byte = mangle2(stream, 2.770 + write_buffer->data, file_buffer->data, 2.771 + file_buffer->size, block_size, noD, 1); 2.772 + write_buffer->sequence = file_buffer->sequence; 2.773 +@@ -2593,11 +2596,15 @@ 2.774 + void *frag_deflator(void *arg) 2.775 + { 2.776 + void *stream = NULL; 2.777 +- int oldstate; 2.778 ++ int res, oldstate; 2.779 + 2.780 + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); 2.781 + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); 2.782 + 2.783 ++ res = compressor_init(comp, &stream, block_size, 1); 2.784 ++ if(res) 2.785 ++ BAD_ERROR("frag_deflator:: compressor_init failed\n"); 2.786 ++ 2.787 + while(1) { 2.788 + int c_byte, compressed_size; 2.789 + struct file_buffer *file_buffer = queue_get(to_frag); 2.790 +@@ -2605,7 +2612,7 @@ 2.791 + cache_get(writer_buffer, file_buffer->block + 2.792 + FRAG_INDEX, 1); 2.793 + 2.794 +- c_byte = mangle2(&stream, write_buffer->data, file_buffer->data, 2.795 ++ c_byte = mangle2(stream, write_buffer->data, file_buffer->data, 2.796 + file_buffer->size, block_size, noF, 1); 2.797 + compressed_size = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte); 2.798 + write_buffer->size = compressed_size; 2.799 +@@ -4501,7 +4508,7 @@ 2.800 + 2.801 + 2.802 + #define VERSION() \ 2.803 +- printf("mksquashfs version 4.1 (2010/09/19)\n");\ 2.804 ++ printf("mksquashfs version 4.1-CVS (2010/12/07)\n");\ 2.805 + printf("copyright (C) 2010 Phillip Lougher "\ 2.806 + "<phillip@lougher.demon.co.uk>\n\n"); \ 2.807 + printf("This program is free software; you can redistribute it and/or"\ 2.808 +@@ -4521,7 +4528,7 @@ 2.809 + int main(int argc, char *argv[]) 2.810 + { 2.811 + struct stat buf, source_buf; 2.812 +- int i; 2.813 ++ int res, i; 2.814 + squashfs_super_block sBlk; 2.815 + char *b, *root_name = NULL; 2.816 + int nopad = FALSE, keep_as_directory = FALSE; 2.817 +@@ -4542,14 +4549,50 @@ 2.818 + goto printOptions; 2.819 + source_path = argv + 1; 2.820 + source = i - 2; 2.821 ++ /* 2.822 ++ * lookup default compressor. Note the Makefile ensures the default 2.823 ++ * compressor has been built, and so we don't need to to check 2.824 ++ * for failure here 2.825 ++ */ 2.826 ++ comp = lookup_compressor(COMP_DEFAULT); 2.827 + for(; i < argc; i++) { 2.828 + if(strcmp(argv[i], "-comp") == 0) { 2.829 ++ if(compressor_opts_parsed) { 2.830 ++ ERROR("%s: -comp must appear before -X options" 2.831 ++ "\n", argv[0]); 2.832 ++ exit(1); 2.833 ++ } 2.834 + if(++i == argc) { 2.835 + ERROR("%s: -comp missing compression type\n", 2.836 + argv[0]); 2.837 + exit(1); 2.838 + } 2.839 +- comp_name = argv[i]; 2.840 ++ comp = lookup_compressor(argv[i]); 2.841 ++ if(!comp->supported) { 2.842 ++ ERROR("%s: Compressor \"%s\" is not supported!" 2.843 ++ "\n", argv[0], argv[i]); 2.844 ++ ERROR("%s: Compressors available:\n", argv[0]); 2.845 ++ display_compressors("", COMP_DEFAULT); 2.846 ++ exit(1); 2.847 ++ } 2.848 ++ 2.849 ++ } else if(strncmp(argv[i], "-X", 2) == 0) { 2.850 ++ int args = compressor_options(comp, argv + i, argc - i); 2.851 ++ if(args < 0) { 2.852 ++ if(args == -1) { 2.853 ++ ERROR("%s: Unrecognised compressor" 2.854 ++ " option %s\n", argv[0], 2.855 ++ argv[i]); 2.856 ++ ERROR("%s: Did you forget to specify" 2.857 ++ " -comp, or specify it after" 2.858 ++ " the compressor specific" 2.859 ++ " option?\n", argv[0]); 2.860 ++ } 2.861 ++ exit(1); 2.862 ++ } 2.863 ++ i += args; 2.864 ++ compressor_opts_parsed = 1; 2.865 ++ 2.866 + } else if(strcmp(argv[i], "-pf") == 0) { 2.867 + if(++i == argc) { 2.868 + ERROR("%s: -pf missing filename\n", argv[0]); 2.869 +@@ -4857,7 +4900,7 @@ 2.870 + ERROR("-write-queue <size>\tSet output queue to <size> " 2.871 + "Mbytes. Default %d Mbytes\n", 2.872 + WRITER_BUFFER_DEFAULT); 2.873 +- ERROR("-fragment-queue <size>\tSet fagment queue to " 2.874 ++ ERROR("-fragment-queue <size>\tSet fragment queue to " 2.875 + "<size> Mbytes. Default %d Mbytes\n", 2.876 + FRAGMENT_BUFFER_DEFAULT); 2.877 + ERROR("\nMiscellaneous options:\n"); 2.878 +@@ -4871,8 +4914,9 @@ 2.879 + "-noF\n"); 2.880 + ERROR("-noXattrCompression\talternative name for " 2.881 + "-noX\n"); 2.882 +- ERROR("\nCompressors available:\n"); 2.883 +- display_compressors("", COMP_DEFAULT); 2.884 ++ ERROR("\nCompressors available and compressor specific " 2.885 ++ "options:\n"); 2.886 ++ display_compressor_usage(COMP_DEFAULT); 2.887 + exit(1); 2.888 + } 2.889 + } 2.890 +@@ -5005,19 +5049,14 @@ 2.891 + always_use_fragments = SQUASHFS_ALWAYS_FRAGMENTS(sBlk.flags); 2.892 + duplicate_checking = SQUASHFS_DUPLICATES(sBlk.flags); 2.893 + exportable = SQUASHFS_EXPORTABLE(sBlk.flags); 2.894 +- } else { 2.895 +- comp = lookup_compressor(comp_name); 2.896 +- if(!comp->supported) { 2.897 +- ERROR("FATAL_ERROR: Compressor \"%s\" is not " 2.898 +- "supported!\n", comp_name); 2.899 +- ERROR("Compressors available:\n"); 2.900 +- display_compressors("", COMP_DEFAULT); 2.901 +- EXIT_MKSQUASHFS(); 2.902 +- } 2.903 + } 2.904 + 2.905 + initialise_threads(readb_mbytes, writeb_mbytes, fragmentb_mbytes); 2.906 + 2.907 ++ res = compressor_init(comp, &stream, SQUASHFS_METADATA_SIZE, 0); 2.908 ++ if(res) 2.909 ++ BAD_ERROR("compressor_init failed\n"); 2.910 ++ 2.911 + if(delete) { 2.912 + printf("Creating %d.%d filesystem on %s, block size %d.\n", 2.913 + SQUASHFS_MAJOR, s_minor, argv[source + 1], block_size); 2.914 +diff -r 2ab2996036dd squashfs-tools/read_fs.c 2.915 +--- a/squashfs-tools/read_fs.c Tue Dec 14 12:19:33 2010 +0000 2.916 ++++ b/squashfs-tools/read_fs.c Tue Dec 14 14:18:11 2010 +0000 2.917 +@@ -363,7 +363,8 @@ 2.918 + } 2.919 + } 2.920 + 2.921 +- return files; 2.922 ++ printf("Read existing filesystem, %d inodes scanned\n", files); 2.923 ++ return TRUE; 2.924 + 2.925 + 2.926 + failed: 2.927 +@@ -414,6 +415,7 @@ 2.928 + if(!comp->supported) { 2.929 + ERROR("Filesystem on %s uses %s compression, this is" 2.930 + "unsupported by this version\n", source, comp->name); 2.931 ++ ERROR("Compressors available:\n"); 2.932 + display_compressors("", ""); 2.933 + goto failed_mount; 2.934 + } 2.935 +@@ -691,7 +693,7 @@ 2.936 + SQUASHFS_INODE_BLK(sBlk->root_inode); 2.937 + unsigned int root_inode_offset = 2.938 + SQUASHFS_INODE_OFFSET(sBlk->root_inode); 2.939 +- unsigned int root_inode_block, files; 2.940 ++ unsigned int root_inode_block; 2.941 + squashfs_inode_header inode; 2.942 + unsigned int *id_table; 2.943 + int res; 2.944 +@@ -711,20 +713,18 @@ 2.945 + if(id_table == NULL) 2.946 + goto error; 2.947 + 2.948 +- if((files = scan_inode_table(fd, start, end, root_inode_start, 2.949 +- root_inode_offset, sBlk, &inode, &inode_table, 2.950 +- &root_inode_block, root_inode_size, uncompressed_file, 2.951 +- uncompressed_directory, file_count, sym_count, 2.952 +- dev_count, dir_count, fifo_count, sock_count, id_table)) 2.953 +- == 0) { 2.954 ++ res = scan_inode_table(fd, start, end, root_inode_start, 2.955 ++ root_inode_offset, sBlk, &inode, &inode_table, 2.956 ++ &root_inode_block, root_inode_size, uncompressed_file, 2.957 ++ uncompressed_directory, file_count, sym_count, dev_count, 2.958 ++ dir_count, fifo_count, sock_count, id_table); 2.959 ++ if(res == 0) { 2.960 + ERROR("read_filesystem: inode table read failed\n"); 2.961 + goto error; 2.962 + } 2.963 + 2.964 + *uncompressed_inode = root_inode_block; 2.965 + 2.966 +- printf("Read existing filesystem, %d inodes scanned\n", files); 2.967 +- 2.968 + if(inode.base.inode_type == SQUASHFS_DIR_TYPE || 2.969 + inode.base.inode_type == SQUASHFS_LDIR_TYPE) { 2.970 + if(inode.base.inode_type == SQUASHFS_DIR_TYPE) { 2.971 +diff -r 2ab2996036dd squashfs-tools/squashfs_fs.h 2.972 +--- a/squashfs-tools/squashfs_fs.h Tue Dec 14 12:19:33 2010 +0000 2.973 ++++ b/squashfs-tools/squashfs_fs.h Tue Dec 14 14:18:11 2010 +0000 2.974 +@@ -259,6 +259,7 @@ 2.975 + #define ZLIB_COMPRESSION 1 2.976 + #define LZMA_COMPRESSION 2 2.977 + #define LZO_COMPRESSION 3 2.978 ++#define XZ_COMPRESSION 4 2.979 + 2.980 + struct squashfs_super_block { 2.981 + unsigned int s_magic; 2.982 +diff -r 2ab2996036dd squashfs-tools/unsquash-1.c 2.983 +--- a/squashfs-tools/unsquash-1.c Tue Dec 14 12:19:33 2010 +0000 2.984 ++++ b/squashfs-tools/unsquash-1.c Tue Dec 14 14:18:11 2010 +0000 2.985 +@@ -138,7 +138,7 @@ 2.986 + 2.987 + i.data = inode->file_size; 2.988 + i.time = inode->mtime; 2.989 +- i.blocks = (inode->file_size + sBlk.s.block_size - 1) >> 2.990 ++ i.blocks = (i.data + sBlk.s.block_size - 1) >> 2.991 + sBlk.s.block_log; 2.992 + i.start = inode->start_block; 2.993 + i.block_ptr = block_ptr + sizeof(*inode); 2.994 +diff -r 2ab2996036dd squashfs-tools/unsquash-2.c 2.995 +--- a/squashfs-tools/unsquash-2.c Tue Dec 14 12:19:33 2010 +0000 2.996 ++++ b/squashfs-tools/unsquash-2.c Tue Dec 14 14:18:11 2010 +0000 2.997 +@@ -205,8 +205,8 @@ 2.998 + i.fragment = inode->fragment; 2.999 + i.offset = inode->offset; 2.1000 + i.blocks = inode->fragment == SQUASHFS_INVALID_FRAG ? 2.1001 +- (inode->file_size + sBlk.s.block_size - 1) >> 2.1002 +- sBlk.s.block_log : inode->file_size >> 2.1003 ++ (i.data + sBlk.s.block_size - 1) >> 2.1004 ++ sBlk.s.block_log : i.data >> 2.1005 + sBlk.s.block_log; 2.1006 + i.start = inode->start_block; 2.1007 + i.sparse = 0; 2.1008 +diff -r 2ab2996036dd squashfs-tools/unsquash-3.c 2.1009 +--- a/squashfs-tools/unsquash-3.c Tue Dec 14 12:19:33 2010 +0000 2.1010 ++++ b/squashfs-tools/unsquash-3.c Tue Dec 14 14:18:11 2010 +0000 2.1011 +@@ -188,9 +188,9 @@ 2.1012 + i.fragment = inode->fragment; 2.1013 + i.offset = inode->offset; 2.1014 + i.blocks = inode->fragment == SQUASHFS_INVALID_FRAG ? 2.1015 +- (inode->file_size + sBlk.s.block_size - 1) >> 2.1016 ++ (i.data + sBlk.s.block_size - 1) >> 2.1017 + sBlk.s.block_log : 2.1018 +- inode->file_size >> sBlk.s.block_log; 2.1019 ++ i.data >> sBlk.s.block_log; 2.1020 + i.start = inode->start_block; 2.1021 + i.sparse = 1; 2.1022 + i.block_ptr = block_ptr + sizeof(*inode); 2.1023 +diff -r 2ab2996036dd squashfs-tools/unsquash-4.c 2.1024 +--- a/squashfs-tools/unsquash-4.c Tue Dec 14 12:19:33 2010 +0000 2.1025 ++++ b/squashfs-tools/unsquash-4.c Tue Dec 14 14:18:11 2010 +0000 2.1026 +@@ -143,9 +143,9 @@ 2.1027 + i.fragment = inode->fragment; 2.1028 + i.offset = inode->offset; 2.1029 + i.blocks = inode->fragment == SQUASHFS_INVALID_FRAG ? 2.1030 +- (inode->file_size + sBlk.s.block_size - 1) >> 2.1031 ++ (i.data + sBlk.s.block_size - 1) >> 2.1032 + sBlk.s.block_log : 2.1033 +- inode->file_size >> sBlk.s.block_log; 2.1034 ++ i.data >> sBlk.s.block_log; 2.1035 + i.start = inode->start_block; 2.1036 + i.sparse = 0; 2.1037 + i.block_ptr = block_ptr + sizeof(*inode); 2.1038 +diff -r 2ab2996036dd squashfs-tools/unsquashfs.c 2.1039 +--- a/squashfs-tools/unsquashfs.c Tue Dec 14 12:19:33 2010 +0000 2.1040 ++++ b/squashfs-tools/unsquashfs.c Tue Dec 14 14:18:11 2010 +0000 2.1041 +@@ -737,7 +737,7 @@ 2.1042 + int lseek_broken = FALSE; 2.1043 + char *zero_data = NULL; 2.1044 + 2.1045 +-int write_block(int file_fd, char *buffer, int size, int hole, int sparse) 2.1046 ++int write_block(int file_fd, char *buffer, int size, long long hole, int sparse) 2.1047 + { 2.1048 + off_t off = hole; 2.1049 + 2.1050 +@@ -1299,9 +1299,12 @@ 2.1051 + print_filename(parent_name, i); 2.1052 + 2.1053 + if(!lsonly && mkdir(parent_name, (mode_t) dir->mode) == -1 && 2.1054 +- (!force || errno != EEXIST)) 2.1055 +- ERROR("dir_scan: failed to open directory %s, because %s\n", 2.1056 ++ (!force || errno != EEXIST)) { 2.1057 ++ ERROR("dir_scan: failed to make directory %s, because %s\n", 2.1058 + parent_name, strerror(errno)); 2.1059 ++ squashfs_closedir(dir); 2.1060 ++ return; 2.1061 ++ } 2.1062 + 2.1063 + while(squashfs_readdir(dir, &name, &start_block, &offset, &type)) { 2.1064 + TRACE("dir_scan: name %s, start_block %d, offset %d, type %d\n", 2.1065 +@@ -1604,7 +1607,7 @@ 2.1066 + while(1) { 2.1067 + struct squashfs_file *file = queue_get(to_writer); 2.1068 + int file_fd; 2.1069 +- int hole = 0; 2.1070 ++ long long hole = 0; 2.1071 + int failed = FALSE; 2.1072 + int error; 2.1073 + 2.1074 +@@ -1903,7 +1906,7 @@ 2.1075 + 2.1076 + 2.1077 + #define VERSION() \ 2.1078 +- printf("unsquashfs version 4.1 (2010/09/19)\n");\ 2.1079 ++ printf("unsquashfs version 4.1-CVS (2010/10/23)\n");\ 2.1080 + printf("copyright (C) 2010 Phillip Lougher "\ 2.1081 + "<phillip@lougher.demon.co.uk>\n\n");\ 2.1082 + printf("This program is free software; you can redistribute it and/or"\ 2.1083 +@@ -2081,7 +2084,7 @@ 2.1084 + ERROR("\t-da[ta-queue] <size>\tSet data queue to " 2.1085 + "<size> Mbytes. Default %d\n\t\t\t\tMbytes\n", 2.1086 + DATA_BUFFER_DEFAULT); 2.1087 +- ERROR("\t-fr[ag-queue] <size>\tSet fagment queue to " 2.1088 ++ ERROR("\t-fr[ag-queue] <size>\tSet fragment queue to " 2.1089 + "<size> Mbytes. Default %d\n\t\t\t\t Mbytes\n", 2.1090 + FRAGMENT_BUFFER_DEFAULT); 2.1091 + ERROR("\t-r[egex]\t\ttreat extract names as POSIX " 2.1092 +diff -r 2ab2996036dd squashfs-tools/unsquashfs_xattr.c 2.1093 +--- a/squashfs-tools/unsquashfs_xattr.c Tue Dec 14 12:19:33 2010 +0000 2.1094 ++++ b/squashfs-tools/unsquashfs_xattr.c Tue Dec 14 14:18:11 2010 +0000 2.1095 +@@ -25,7 +25,7 @@ 2.1096 + #include "unsquashfs.h" 2.1097 + #include "xattr.h" 2.1098 + 2.1099 +-#include <attr/xattr.h> 2.1100 ++#include <sys/xattr.h> 2.1101 + 2.1102 + extern int root_process; 2.1103 + 2.1104 +diff -r 2ab2996036dd squashfs-tools/xattr.c 2.1105 +--- a/squashfs-tools/xattr.c Tue Dec 14 12:19:33 2010 +0000 2.1106 ++++ b/squashfs-tools/xattr.c Tue Dec 14 14:18:11 2010 +0000 2.1107 +@@ -34,7 +34,7 @@ 2.1108 + #include <dirent.h> 2.1109 + #include <string.h> 2.1110 + #include <stdlib.h> 2.1111 +-#include <attr/xattr.h> 2.1112 ++#include <sys/xattr.h> 2.1113 + 2.1114 + #include "squashfs_fs.h" 2.1115 + #include "global.h" 2.1116 +@@ -219,6 +219,10 @@ 2.1117 + break; 2.1118 + } 2.1119 + xattr_list[i].vsize = vsize; 2.1120 ++ 2.1121 ++ TRACE("read_xattrs_from_system: filename %s, xattr name %s," 2.1122 ++ " vsize %d\n", filename, xattr_list[i].full_name, 2.1123 ++ xattr_list[i].vsize); 2.1124 + } 2.1125 + free(xattr_names); 2.1126 + *xattrs = xattr_list; 2.1127 +diff -r 2ab2996036dd squashfs-tools/xz_wrapper.c 2.1128 +--- a/squashfs-tools/xz_wrapper.c Tue Dec 14 12:19:33 2010 +0000 2.1129 ++++ b/squashfs-tools/xz_wrapper.c Tue Dec 14 14:18:11 2010 +0000 2.1130 +@@ -17,69 +17,192 @@ 2.1131 + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 2.1132 + * 2.1133 + * xz_wrapper.c 2.1134 ++ * 2.1135 ++ * Support for XZ (LZMA2) compression using XZ Utils liblzma http://tukaani.org/xz/ 2.1136 + */ 2.1137 + 2.1138 + #include <stdio.h> 2.1139 + #include <string.h> 2.1140 ++#include <stdlib.h> 2.1141 + #include <lzma.h> 2.1142 + 2.1143 +-#define LZMA_PROPS_SIZE 5 2.1144 +-#define LZMA_UNCOMP_SIZE 8 2.1145 +-#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + LZMA_UNCOMP_SIZE) 2.1146 ++#include "squashfs_fs.h" 2.1147 ++#include "compressor.h" 2.1148 + 2.1149 +-#define LZMA_OPTIONS 5 2.1150 + #define MEMLIMIT (32 * 1024 * 1024) 2.1151 + 2.1152 +-int lzma_compress(void **dummy, void *dest, void *src, int size, 2.1153 ++static struct bcj { 2.1154 ++ char *name; 2.1155 ++ lzma_vli id; 2.1156 ++ int selected; 2.1157 ++} bcj[] = { 2.1158 ++ { "x86", LZMA_FILTER_X86, 0 }, 2.1159 ++ { "powerpc", LZMA_FILTER_POWERPC, 0 }, 2.1160 ++ { "ia64", LZMA_FILTER_IA64, 0 }, 2.1161 ++ { "arm", LZMA_FILTER_ARM, 0 }, 2.1162 ++ { "armthumb", LZMA_FILTER_ARMTHUMB, 0 }, 2.1163 ++ { "sparc", LZMA_FILTER_SPARC, 0 }, 2.1164 ++ { NULL, LZMA_VLI_UNKNOWN, 0 } 2.1165 ++}; 2.1166 ++ 2.1167 ++struct filter { 2.1168 ++ void *buffer; 2.1169 ++ lzma_filter filter[3]; 2.1170 ++ size_t length; 2.1171 ++}; 2.1172 ++ 2.1173 ++struct xz_stream { 2.1174 ++ struct filter *filter; 2.1175 ++ int filters; 2.1176 ++ lzma_options_lzma opt; 2.1177 ++}; 2.1178 ++ 2.1179 ++static int filter_count = 1; 2.1180 ++ 2.1181 ++ 2.1182 ++static int xz_options(char *argv[], int argc) 2.1183 ++{ 2.1184 ++ int i; 2.1185 ++ char *name; 2.1186 ++ 2.1187 ++ if(strcmp(argv[0], "-Xbcj") == 0) { 2.1188 ++ if(argc < 2) { 2.1189 ++ fprintf(stderr, "xz: -Xbcj missing filter\n"); 2.1190 ++ goto failed; 2.1191 ++ } 2.1192 ++ 2.1193 ++ name = argv[1]; 2.1194 ++ while(name[0] != '\0') { 2.1195 ++ for(i = 0; bcj[i].name; i++) { 2.1196 ++ int n = strlen(bcj[i].name); 2.1197 ++ if((strncmp(name, bcj[i].name, n) == 0) && 2.1198 ++ (name[n] == '\0' || 2.1199 ++ name[n] == ',')) { 2.1200 ++ if(bcj[i].selected == 0) { 2.1201 ++ bcj[i].selected = 1; 2.1202 ++ filter_count++; 2.1203 ++ } 2.1204 ++ name += name[n] == ',' ? n + 1 : n; 2.1205 ++ break; 2.1206 ++ } 2.1207 ++ } 2.1208 ++ if(bcj[i].name == NULL) { 2.1209 ++ fprintf(stderr, "xz: -Xbcj unrecognised filter\n"); 2.1210 ++ goto failed; 2.1211 ++ } 2.1212 ++ } 2.1213 ++ 2.1214 ++ return 1; 2.1215 ++ } 2.1216 ++ 2.1217 ++ return -1; 2.1218 ++ 2.1219 ++failed: 2.1220 ++ return -2; 2.1221 ++} 2.1222 ++ 2.1223 ++ 2.1224 ++void xz_usage() 2.1225 ++{ 2.1226 ++ fprintf(stderr, "\t -Xbcj filter1,filter2,...,filterN\n"); 2.1227 ++ fprintf(stderr, "\t\tCompress using filter1,filter2,...,filterN in"); 2.1228 ++ fprintf(stderr, " turn\n\t\t(in addition to no filter), and choose"); 2.1229 ++ fprintf(stderr, " the best compression.\n"); 2.1230 ++ fprintf(stderr, "\t\tAvailable filters: x86, arm, armthumb,"); 2.1231 ++ fprintf(stderr, " powerpc, sparc, ia64\n"); 2.1232 ++} 2.1233 ++ 2.1234 ++ 2.1235 ++static int xz_init(void **strm, int block_size, int flags) 2.1236 ++{ 2.1237 ++ int i, j, filters = flags ? filter_count : 1; 2.1238 ++ struct filter *filter = malloc(filters * sizeof(struct filter)); 2.1239 ++ struct xz_stream *stream; 2.1240 ++ 2.1241 ++ if(filter == NULL) 2.1242 ++ goto failed; 2.1243 ++ 2.1244 ++ stream = *strm = malloc(sizeof(struct xz_stream)); 2.1245 ++ if(stream == NULL) 2.1246 ++ goto failed2; 2.1247 ++ 2.1248 ++ stream->filter = filter; 2.1249 ++ stream->filters = filters; 2.1250 ++ 2.1251 ++ memset(filter, 0, filters * sizeof(struct filter)); 2.1252 ++ 2.1253 ++ filter[0].filter[0].id = LZMA_FILTER_LZMA2; 2.1254 ++ filter[0].filter[0].options = &stream->opt; 2.1255 ++ filter[0].filter[1].id = LZMA_VLI_UNKNOWN; 2.1256 ++ 2.1257 ++ for(i = 0, j = 1; flags && bcj[i].name; i++) { 2.1258 ++ if(bcj[i].selected) { 2.1259 ++ filter[j].buffer = malloc(block_size); 2.1260 ++ if(filter[j].buffer == NULL) 2.1261 ++ goto failed3; 2.1262 ++ filter[j].filter[0].id = bcj[i].id; 2.1263 ++ filter[j].filter[1].id = LZMA_FILTER_LZMA2; 2.1264 ++ filter[j].filter[1].options = &stream->opt; 2.1265 ++ filter[j].filter[2].id = LZMA_VLI_UNKNOWN; 2.1266 ++ j++; 2.1267 ++ } 2.1268 ++ } 2.1269 ++ 2.1270 ++ return 0; 2.1271 ++ 2.1272 ++failed3: 2.1273 ++ for(i = 1; i < filters; i++) 2.1274 ++ free(filter[i].buffer); 2.1275 ++ free(stream); 2.1276 ++ 2.1277 ++failed2: 2.1278 ++ free(filter); 2.1279 ++ 2.1280 ++failed: 2.1281 ++ return -1; 2.1282 ++} 2.1283 ++ 2.1284 ++ 2.1285 ++static int xz_compress(void *strm, void *dest, void *src, int size, 2.1286 + int block_size, int *error) 2.1287 + { 2.1288 +- unsigned char *d = (unsigned char *) dest; 2.1289 +- lzma_options_lzma opt; 2.1290 +- lzma_stream strm = LZMA_STREAM_INIT; 2.1291 +- int res; 2.1292 ++ int i; 2.1293 ++ lzma_ret res = 0; 2.1294 ++ struct xz_stream *stream = strm; 2.1295 ++ struct filter *selected = NULL; 2.1296 + 2.1297 +- lzma_lzma_preset(&opt, LZMA_OPTIONS); 2.1298 +- opt.dict_size = block_size; 2.1299 +- res = lzma_alone_encoder(&strm, &opt); 2.1300 +- if(res != LZMA_OK) { 2.1301 +- lzma_end(&strm); 2.1302 +- goto failed; 2.1303 ++ stream->filter[0].buffer = dest; 2.1304 ++ 2.1305 ++ for(i = 0; i < stream->filters; i++) { 2.1306 ++ struct filter *filter = &stream->filter[i]; 2.1307 ++ 2.1308 ++ if(lzma_lzma_preset(&stream->opt, LZMA_PRESET_DEFAULT)) 2.1309 ++ goto failed; 2.1310 ++ 2.1311 ++ stream->opt.dict_size = block_size; 2.1312 ++ filter->length = 0; 2.1313 ++ res = lzma_stream_buffer_encode(filter->filter, 2.1314 ++ LZMA_CHECK_CRC32, NULL, src, size, filter->buffer, 2.1315 ++ &filter->length, block_size); 2.1316 ++ 2.1317 ++ if(res == LZMA_OK) { 2.1318 ++ if(!selected || selected->length > filter->length) 2.1319 ++ selected = filter; 2.1320 ++ } else if(res != LZMA_BUF_ERROR) 2.1321 ++ goto failed; 2.1322 + } 2.1323 + 2.1324 +- strm.next_out = dest; 2.1325 +- strm.avail_out = block_size; 2.1326 +- strm.next_in = src; 2.1327 +- strm.avail_in = size; 2.1328 +- 2.1329 +- res = lzma_code(&strm, LZMA_FINISH); 2.1330 +- lzma_end(&strm); 2.1331 +- 2.1332 +- if(res == LZMA_STREAM_END) { 2.1333 +- /* 2.1334 +- * Fill in the 8 byte little endian uncompressed size field in 2.1335 +- * the LZMA header. 8 bytes is excessively large for squashfs 2.1336 +- * but this is the standard LZMA header and which is expected by 2.1337 +- * the kernel code 2.1338 +- */ 2.1339 +- 2.1340 +- d[LZMA_PROPS_SIZE] = size & 255; 2.1341 +- d[LZMA_PROPS_SIZE + 1] = (size >> 8) & 255; 2.1342 +- d[LZMA_PROPS_SIZE + 2] = (size >> 16) & 255; 2.1343 +- d[LZMA_PROPS_SIZE + 3] = (size >> 24) & 255; 2.1344 +- d[LZMA_PROPS_SIZE + 4] = 0; 2.1345 +- d[LZMA_PROPS_SIZE + 5] = 0; 2.1346 +- d[LZMA_PROPS_SIZE + 6] = 0; 2.1347 +- d[LZMA_PROPS_SIZE + 7] = 0; 2.1348 +- 2.1349 +- return (int) strm.total_out; 2.1350 +- } 2.1351 +- 2.1352 +- if(res == LZMA_OK) 2.1353 ++ if(!selected) 2.1354 + /* 2.1355 + * Output buffer overflow. Return out of buffer space 2.1356 + */ 2.1357 + return 0; 2.1358 + 2.1359 ++ if(selected->buffer != dest) 2.1360 ++ memcpy(dest, selected->buffer, selected->length); 2.1361 ++ 2.1362 ++ return (int) selected->length; 2.1363 ++ 2.1364 + failed: 2.1365 + /* 2.1366 + * All other errors return failure, with the compressor 2.1367 +@@ -90,49 +213,29 @@ 2.1368 + } 2.1369 + 2.1370 + 2.1371 +-int lzma_uncompress(void *dest, void *src, int size, int block_size, 2.1372 ++static int xz_uncompress(void *dest, void *src, int size, int block_size, 2.1373 + int *error) 2.1374 + { 2.1375 +- lzma_stream strm = LZMA_STREAM_INIT; 2.1376 +- int uncompressed_size = 0, res; 2.1377 +- unsigned char lzma_header[LZMA_HEADER_SIZE]; 2.1378 ++ size_t src_pos = 0; 2.1379 ++ size_t dest_pos = 0; 2.1380 ++ uint64_t memlimit = MEMLIMIT; 2.1381 + 2.1382 +- res = lzma_alone_decoder(&strm, MEMLIMIT); 2.1383 +- if(res != LZMA_OK) { 2.1384 +- lzma_end(&strm); 2.1385 +- goto failed; 2.1386 +- } 2.1387 ++ lzma_ret res = lzma_stream_buffer_decode(&memlimit, 0, NULL, 2.1388 ++ src, &src_pos, size, dest, &dest_pos, block_size); 2.1389 + 2.1390 +- memcpy(lzma_header, src, LZMA_HEADER_SIZE); 2.1391 +- uncompressed_size = lzma_header[LZMA_PROPS_SIZE] | 2.1392 +- (lzma_header[LZMA_PROPS_SIZE + 1] << 8) | 2.1393 +- (lzma_header[LZMA_PROPS_SIZE + 2] << 16) | 2.1394 +- (lzma_header[LZMA_PROPS_SIZE + 3] << 24); 2.1395 +- memset(lzma_header + LZMA_PROPS_SIZE, 255, LZMA_UNCOMP_SIZE); 2.1396 ++ *error = res; 2.1397 ++ return res == LZMA_OK && size == (int) src_pos ? (int) dest_pos : -1; 2.1398 ++} 2.1399 + 2.1400 +- strm.next_out = dest; 2.1401 +- strm.avail_out = block_size; 2.1402 +- strm.next_in = lzma_header; 2.1403 +- strm.avail_in = LZMA_HEADER_SIZE; 2.1404 + 2.1405 +- res = lzma_code(&strm, LZMA_RUN); 2.1406 ++struct compressor xz_comp_ops = { 2.1407 ++ .init = xz_init, 2.1408 ++ .compress = xz_compress, 2.1409 ++ .uncompress = xz_uncompress, 2.1410 ++ .options = xz_options, 2.1411 ++ .usage = xz_usage, 2.1412 ++ .id = XZ_COMPRESSION, 2.1413 ++ .name = "xz", 2.1414 ++ .supported = 1 2.1415 ++}; 2.1416 + 2.1417 +- if(res != LZMA_OK || strm.avail_in != 0) { 2.1418 +- lzma_end(&strm); 2.1419 +- goto failed; 2.1420 +- } 2.1421 +- 2.1422 +- strm.next_in = src + LZMA_HEADER_SIZE; 2.1423 +- strm.avail_in = size - LZMA_HEADER_SIZE; 2.1424 +- 2.1425 +- res = lzma_code(&strm, LZMA_FINISH); 2.1426 +- lzma_end(&strm); 2.1427 +- 2.1428 +- if(res == LZMA_STREAM_END || (res == LZMA_OK && 2.1429 +- strm.total_out >= uncompressed_size && strm.avail_in == 0)) 2.1430 +- return uncompressed_size; 2.1431 +- 2.1432 +-failed: 2.1433 +- *error = res; 2.1434 +- return -1; 2.1435 +-}