wok diff squashfs/stuff/xz.patch @ 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
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/squashfs/stuff/xz.patch	Tue Dec 14 21:34:46 2010 +0000
     1.3 @@ -0,0 +1,1432 @@
     1.4 +diff -r 2ab2996036dd squashfs-tools/Makefile
     1.5 +--- a/squashfs-tools/Makefile	Tue Dec 14 12:19:33 2010 +0000
     1.6 ++++ b/squashfs-tools/Makefile	Tue Dec 14 14:18:11 2010 +0000
     1.7 +@@ -20,20 +20,33 @@
     1.8 + 
     1.9 + ########### Building LZMA support #############
    1.10 + #
    1.11 +-# Both XZ Utils liblzma  (http://tukaani.org/xz/) and LZMA SDK
    1.12 ++# LZMA1 compression.
    1.13 ++#
    1.14 ++# Both XZ Utils liblzma (http://tukaani.org/xz/) and LZMA SDK
    1.15 + # (http://www.7-zip.org/sdk.html) are supported
    1.16 + #
    1.17 + # To build using XZ Utils liblzma - install the library and uncomment
    1.18 +-# the XZ_SUPPORT line below.
    1.19 ++# the LZMA_XZ_SUPPORT line below.
    1.20 + #
    1.21 + # To build using the LZMA SDK (4.65 used in development, other versions may
    1.22 + # work) - download and unpack it, uncomment and set LZMA_DIR to unpacked source,
    1.23 + # and uncomment the LZMA_SUPPORT line below.
    1.24 + #
    1.25 +-#XZ_SUPPORT = 1
    1.26 ++LZMA_XZ_SUPPORT = 1
    1.27 + #LZMA_SUPPORT = 1
    1.28 + #LZMA_DIR = ../../../LZMA/lzma465
    1.29 + 
    1.30 ++########### Building XZ support #############
    1.31 ++#
    1.32 ++# LZMA2 compression.
    1.33 ++#
    1.34 ++# XZ Utils liblzma (http://tukaani.org/xz/) is supported
    1.35 ++#
    1.36 ++# To build using XZ Utils liblzma - install the library and uncomment
    1.37 ++# the XZ_SUPPORT line below.
    1.38 ++#
    1.39 ++XZ_SUPPORT = 1
    1.40 ++
    1.41 + 
    1.42 + ############ Building LZO support ##############
    1.43 + #
    1.44 +@@ -109,12 +122,20 @@
    1.45 + COMPRESSORS += lzma
    1.46 + endif
    1.47 + 
    1.48 ++ifdef LZMA_XZ_SUPPORT
    1.49 ++CFLAGS += -DLZMA_SUPPORT
    1.50 ++MKSQUASHFS_OBJS += lzma_xz_wrapper.o
    1.51 ++UNSQUASHFS_OBJS += lzma_xz_wrapper.o
    1.52 ++LIBS += -llzma
    1.53 ++COMPRESSORS += lzma
    1.54 ++endif
    1.55 ++
    1.56 + ifdef XZ_SUPPORT
    1.57 +-CFLAGS += -DLZMA_SUPPORT
    1.58 ++CFLAGS += -DXZ_SUPPORT
    1.59 + MKSQUASHFS_OBJS += xz_wrapper.o
    1.60 + UNSQUASHFS_OBJS += xz_wrapper.o
    1.61 + LIBS += -llzma
    1.62 +-COMPRESSORS += lzma
    1.63 ++COMPRESSORS += xz
    1.64 + endif
    1.65 + 
    1.66 + ifdef LZO_SUPPORT
    1.67 +@@ -149,11 +170,11 @@
    1.68 + endif
    1.69 + 
    1.70 + #
    1.71 +-# Both XZ_SUPPORT and LZMA_SUPPORT cannot be specified
    1.72 ++# Both LZMA_XZ_SUPPORT and LZMA_SUPPORT cannot be specified
    1.73 + #
    1.74 +-ifdef XZ_SUPPORT
    1.75 ++ifdef LZMA_XZ_SUPPORT
    1.76 + ifdef LZMA_SUPPORT
    1.77 +-$(error "Both XZ_SUPPORT and LZMA_SUPPORT cannot be specified")
    1.78 ++$(error "Both LZMA_XZ_SUPPORT and LZMA_SUPPORT cannot be specified")
    1.79 + endif
    1.80 + endif
    1.81 + 
    1.82 +@@ -161,7 +182,7 @@
    1.83 + # At least one compressor must have been selected
    1.84 + #
    1.85 + ifndef COMPRESSORS
    1.86 +-$(error "No compressor selected! Select one or more of GZIP, LZMA, or LZO!")
    1.87 ++$(error "No compressor selected! Select one or more of GZIP, LZMA, XZ or LZO!")
    1.88 + endif
    1.89 + 
    1.90 + #
    1.91 +diff -r 2ab2996036dd squashfs-tools/compressor.c
    1.92 +--- a/squashfs-tools/compressor.c	Tue Dec 14 12:19:33 2010 +0000
    1.93 ++++ b/squashfs-tools/compressor.c	Tue Dec 14 14:18:11 2010 +0000
    1.94 +@@ -25,31 +25,50 @@
    1.95 + #include "compressor.h"
    1.96 + #include "squashfs_fs.h"
    1.97 + 
    1.98 +-extern int gzip_compress(void **, char *, char *, int, int, int *);
    1.99 +-extern int gzip_uncompress(char *, char *, int, int, int *);
   1.100 +-extern int lzma_compress(void **, char *, char *, int, int, int *);
   1.101 +-extern int lzma_uncompress(char *, char *, int, int, int *);
   1.102 +-extern int lzo_compress(void **, char *, char *, int, int, int *);
   1.103 +-extern int lzo_uncompress(char *, char *, int, int, int *);
   1.104 +-
   1.105 +-struct compressor compressor[] = {
   1.106 +-#ifdef GZIP_SUPPORT
   1.107 +-	{ gzip_compress, gzip_uncompress, ZLIB_COMPRESSION, "gzip", 1 },
   1.108 ++#ifndef GZIP_SUPPORT
   1.109 ++static struct compressor gzip_comp_ops =  {
   1.110 ++	NULL, NULL, NULL, NULL, NULL, ZLIB_COMPRESSION, "gzip", 0
   1.111 ++};
   1.112 + #else
   1.113 +-	{ NULL, NULL, ZLIB_COMPRESSION, "gzip", 0 },
   1.114 +-#endif
   1.115 +-#ifdef LZMA_SUPPORT
   1.116 +-	{ lzma_compress, lzma_uncompress, LZMA_COMPRESSION, "lzma", 1 },
   1.117 +-#else
   1.118 +-	{ NULL, NULL, LZMA_COMPRESSION, "lzma", 0 },
   1.119 +-#endif
   1.120 +-#ifdef LZO_SUPPORT
   1.121 +-	{ lzo_compress, lzo_uncompress, LZO_COMPRESSION, "lzo", 1 },
   1.122 +-#else
   1.123 +-	{ NULL, NULL, LZO_COMPRESSION, "lzo", 0 },
   1.124 ++extern struct compressor gzip_comp_ops;
   1.125 + #endif
   1.126 + 
   1.127 +-	{ NULL, NULL , 0, "unknown", 0}
   1.128 ++#ifndef LZMA_SUPPORT
   1.129 ++static struct compressor lzma_comp_ops = {
   1.130 ++	NULL, NULL, NULL, NULL, NULL, LZMA_COMPRESSION, "lzma", 0
   1.131 ++};
   1.132 ++#else
   1.133 ++extern struct compressor lzma_comp_ops;
   1.134 ++#endif
   1.135 ++
   1.136 ++#ifndef LZO_SUPPORT
   1.137 ++static struct compressor lzo_comp_ops = {
   1.138 ++	NULL, NULL, NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0
   1.139 ++};
   1.140 ++#else
   1.141 ++extern struct compressor lzo_comp_ops;
   1.142 ++#endif
   1.143 ++
   1.144 ++#ifndef XZ_SUPPORT
   1.145 ++static struct compressor xz_comp_ops = {
   1.146 ++	NULL, NULL, NULL, NULL, NULL, XZ_COMPRESSION, "xz", 0
   1.147 ++};
   1.148 ++#else
   1.149 ++extern struct compressor xz_comp_ops;
   1.150 ++#endif
   1.151 ++
   1.152 ++
   1.153 ++static struct compressor unknown_comp_ops = {
   1.154 ++	NULL, NULL, NULL , NULL, NULL, 0, "unknown", 0
   1.155 ++};
   1.156 ++
   1.157 ++
   1.158 ++struct compressor *compressor[] = {
   1.159 ++	&gzip_comp_ops,
   1.160 ++	&lzma_comp_ops,
   1.161 ++	&lzo_comp_ops,
   1.162 ++	&xz_comp_ops,
   1.163 ++	&unknown_comp_ops
   1.164 + };
   1.165 + 
   1.166 + 
   1.167 +@@ -57,11 +76,11 @@
   1.168 + {
   1.169 + 	int i;
   1.170 + 
   1.171 +-	for(i = 0; compressor[i].id; i++)
   1.172 +-		if(strcmp(compressor[i].name, name) == 0)
   1.173 ++	for(i = 0; compressor[i]->id; i++)
   1.174 ++		if(strcmp(compressor[i]->name, name) == 0)
   1.175 + 			break;
   1.176 + 
   1.177 +-	return &compressor[i];
   1.178 ++	return compressor[i];
   1.179 + }
   1.180 + 
   1.181 + 
   1.182 +@@ -69,11 +88,11 @@
   1.183 + {
   1.184 + 	int i;
   1.185 + 
   1.186 +-	for(i = 0; compressor[i].id; i++)
   1.187 +-		if(id == compressor[i].id)
   1.188 ++	for(i = 0; compressor[i]->id; i++)
   1.189 ++		if(id == compressor[i]->id)
   1.190 + 			break;
   1.191 + 
   1.192 +-	return &compressor[i];
   1.193 ++	return compressor[i];
   1.194 + }
   1.195 + 
   1.196 + 
   1.197 +@@ -81,10 +100,29 @@
   1.198 + {
   1.199 + 	int i;
   1.200 + 
   1.201 +-	for(i = 0; compressor[i].id; i++)
   1.202 +-		if(compressor[i].supported)
   1.203 ++	for(i = 0; compressor[i]->id; i++)
   1.204 ++		if(compressor[i]->supported)
   1.205 + 			fprintf(stderr, "%s\t%s%s\n", indent,
   1.206 +-				compressor[i].name,
   1.207 +-				strcmp(compressor[i].name, def_comp) == 0 ?
   1.208 ++				compressor[i]->name,
   1.209 ++				strcmp(compressor[i]->name, def_comp) == 0 ?
   1.210 + 				" (default)" : "");
   1.211 + }
   1.212 ++
   1.213 ++
   1.214 ++void display_compressor_usage(char *def_comp)
   1.215 ++{
   1.216 ++	int i;
   1.217 ++
   1.218 ++	for(i = 0; compressor[i]->id; i++)
   1.219 ++		if(compressor[i]->supported) {
   1.220 ++			char *str = strcmp(compressor[i]->name, def_comp) == 0 ?
   1.221 ++				" (default)" : "";
   1.222 ++			if(compressor[i]->usage) {
   1.223 ++				fprintf(stderr, "\t%s%s\n",
   1.224 ++					compressor[i]->name, str);
   1.225 ++				compressor[i]->usage();
   1.226 ++			} else
   1.227 ++				fprintf(stderr, "\t%s (no options)%s\n",
   1.228 ++					compressor[i]->name, str);
   1.229 ++		}
   1.230 ++}
   1.231 +diff -r 2ab2996036dd squashfs-tools/compressor.h
   1.232 +--- a/squashfs-tools/compressor.h	Tue Dec 14 12:19:33 2010 +0000
   1.233 ++++ b/squashfs-tools/compressor.h	Tue Dec 14 14:18:11 2010 +0000
   1.234 +@@ -21,8 +21,11 @@
   1.235 +  */
   1.236 + 
   1.237 + struct compressor {
   1.238 +-	int (*compress)(void **, char *, char *, int, int, int *);
   1.239 +-	int (*uncompress)(char *, char *, int, int, int *);
   1.240 ++	int (*init)(void **, int, int);
   1.241 ++	int (*compress)(void *, void *, void *, int, int, int *);
   1.242 ++	int (*uncompress)(void *, void *, int, int, int *);
   1.243 ++	int (*options)(char **, int);
   1.244 ++	void (*usage)();
   1.245 + 	int id;
   1.246 + 	char *name;
   1.247 + 	int supported;
   1.248 +@@ -31,3 +34,25 @@
   1.249 + extern struct compressor *lookup_compressor(char *);
   1.250 + extern struct compressor *lookup_compressor_id(int);
   1.251 + extern void display_compressors(char *, char *);
   1.252 ++extern void display_compressor_usage(char *);
   1.253 ++
   1.254 ++static inline int compressor_options(struct compressor *comp, char *argv[],
   1.255 ++	int argc)
   1.256 ++{
   1.257 ++	if(comp->options == NULL)
   1.258 ++		return -1;
   1.259 ++
   1.260 ++	return comp->options(argv, argc);
   1.261 ++}
   1.262 ++
   1.263 ++
   1.264 ++static inline int compressor_init(struct compressor *comp, void **stream,
   1.265 ++	int block_size, int flags)
   1.266 ++{
   1.267 ++	if(comp->init == NULL)
   1.268 ++		return 0;
   1.269 ++	return comp->init(stream, block_size, flags);
   1.270 ++}
   1.271 ++
   1.272 ++
   1.273 ++
   1.274 +diff -r 2ab2996036dd squashfs-tools/gzip_wrapper.c
   1.275 +--- a/squashfs-tools/gzip_wrapper.c	Tue Dec 14 12:19:33 2010 +0000
   1.276 ++++ b/squashfs-tools/gzip_wrapper.c	Tue Dec 14 14:18:11 2010 +0000
   1.277 +@@ -22,28 +22,48 @@
   1.278 + #include <stdlib.h>
   1.279 + #include <zlib.h>
   1.280 + 
   1.281 +-int gzip_compress(void **strm, char *d, char *s, int size, int block_size,
   1.282 ++#include "squashfs_fs.h"
   1.283 ++#include "compressor.h"
   1.284 ++
   1.285 ++static int gzip_init(void **strm, int block_size, int flags)
   1.286 ++{
   1.287 ++	int res;
   1.288 ++	z_stream *stream;
   1.289 ++
   1.290 ++	stream = *strm = malloc(sizeof(z_stream));
   1.291 ++	if(stream == NULL)
   1.292 ++		goto failed;
   1.293 ++
   1.294 ++	stream->zalloc = Z_NULL;
   1.295 ++	stream->zfree = Z_NULL;
   1.296 ++	stream->opaque = 0;
   1.297 ++
   1.298 ++	res = deflateInit(stream, 9);
   1.299 ++	if(res != Z_OK)
   1.300 ++		goto failed2;
   1.301 ++
   1.302 ++	return 0;
   1.303 ++
   1.304 ++failed2:
   1.305 ++	free(stream);
   1.306 ++failed:
   1.307 ++	return -1;
   1.308 ++}
   1.309 ++
   1.310 ++
   1.311 ++static int gzip_compress(void *strm, void *d, void *s, int size, int block_size,
   1.312 + 		int *error)
   1.313 + {
   1.314 +-	int res = 0;
   1.315 +-	z_stream *stream = *strm;
   1.316 ++	int res;
   1.317 ++	z_stream *stream = strm;
   1.318 + 
   1.319 +-	if(stream == NULL) {
   1.320 +-		if((stream = *strm = malloc(sizeof(z_stream))) == NULL)
   1.321 +-			goto failed;
   1.322 +-
   1.323 +-		stream->zalloc = Z_NULL;
   1.324 +-		stream->zfree = Z_NULL;
   1.325 +-		stream->opaque = 0;
   1.326 +-
   1.327 +-		if((res = deflateInit(stream, 9)) != Z_OK)
   1.328 +-			goto failed;
   1.329 +-	} else if((res = deflateReset(stream)) != Z_OK)
   1.330 ++	res = deflateReset(stream);
   1.331 ++	if(res != Z_OK)
   1.332 + 		goto failed;
   1.333 + 
   1.334 +-	stream->next_in = (unsigned char *) s;
   1.335 ++	stream->next_in = s;
   1.336 + 	stream->avail_in = size;
   1.337 +-	stream->next_out = (unsigned char *) d;
   1.338 ++	stream->next_out = d;
   1.339 + 	stream->avail_out = block_size;
   1.340 + 
   1.341 + 	res = deflate(stream, Z_FINISH);
   1.342 +@@ -67,14 +87,26 @@
   1.343 + }
   1.344 + 
   1.345 + 
   1.346 +-int gzip_uncompress(char *d, char *s, int size, int block_size, int *error)
   1.347 ++static int gzip_uncompress(void *d, void *s, int size, int block_size, int *error)
   1.348 + {
   1.349 + 	int res;
   1.350 + 	unsigned long bytes = block_size;
   1.351 + 
   1.352 +-	res = uncompress((unsigned char *) d, &bytes,
   1.353 +-		(const unsigned char *) s, size);
   1.354 ++	res = uncompress(d, &bytes, s, size);
   1.355 + 
   1.356 + 	*error = res;
   1.357 + 	return res == Z_OK ? (int) bytes : -1;
   1.358 + }
   1.359 ++
   1.360 ++
   1.361 ++struct compressor gzip_comp_ops = {
   1.362 ++	.init = gzip_init,
   1.363 ++	.compress = gzip_compress,
   1.364 ++	.uncompress = gzip_uncompress,
   1.365 ++	.options = NULL,
   1.366 ++	.usage = NULL,
   1.367 ++	.id = ZLIB_COMPRESSION,
   1.368 ++	.name = "gzip",
   1.369 ++	.supported = 1
   1.370 ++};
   1.371 ++
   1.372 +diff -r 2ab2996036dd squashfs-tools/lzma_wrapper.c
   1.373 +--- a/squashfs-tools/lzma_wrapper.c	Tue Dec 14 12:19:33 2010 +0000
   1.374 ++++ b/squashfs-tools/lzma_wrapper.c	Tue Dec 14 14:18:11 2010 +0000
   1.375 +@@ -17,21 +17,27 @@
   1.376 +  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   1.377 +  *
   1.378 +  * lzma_wrapper.c
   1.379 ++ *
   1.380 ++ * Support for LZMA1 compression using LZMA SDK (4.65 used in
   1.381 ++ * development, other versions may work) http://www.7-zip.org/sdk.html
   1.382 +  */
   1.383 + 
   1.384 + #include <LzmaLib.h>
   1.385 + 
   1.386 ++#include "squashfs_fs.h"
   1.387 ++#include "compressor.h"
   1.388 ++
   1.389 + #define LZMA_HEADER_SIZE	(LZMA_PROPS_SIZE + 8)
   1.390 + 
   1.391 +-int lzma_compress(void **strm, char *dest, char *src, int size, int block_size,
   1.392 ++static int lzma_compress(void *strm, void *dest, void *src, int size, int block_size,
   1.393 + 		int *error)
   1.394 + {
   1.395 +-	unsigned char *d = (unsigned char *) dest, *s = (unsigned char *) src;
   1.396 ++	unsigned char *d = dest;
   1.397 + 	size_t props_size = LZMA_PROPS_SIZE,
   1.398 + 		outlen = block_size - LZMA_HEADER_SIZE;
   1.399 + 	int res;
   1.400 + 
   1.401 +-	res = LzmaCompress(d + LZMA_HEADER_SIZE, &outlen, s, size, d,
   1.402 ++	res = LzmaCompress(dest + LZMA_HEADER_SIZE, &outlen, src, size, dest,
   1.403 + 		&props_size, 5, block_size, 3, 0, 2, 32, 1);
   1.404 + 	
   1.405 + 	if(res == SZ_ERROR_OUTPUT_EOF) {
   1.406 +@@ -73,10 +79,10 @@
   1.407 + }
   1.408 + 
   1.409 + 
   1.410 +-int lzma_uncompress(char *dest, char *src, int size, int block_size,
   1.411 ++static int lzma_uncompress(void *dest, void *src, int size, int block_size,
   1.412 + 	int *error)
   1.413 + {
   1.414 +-	unsigned char *d = (unsigned char *) dest, *s = (unsigned char *) src;
   1.415 ++	unsigned char *s = src;
   1.416 + 	size_t outlen, inlen = size - LZMA_HEADER_SIZE;
   1.417 + 	int res;
   1.418 + 
   1.419 +@@ -85,9 +91,22 @@
   1.420 + 		(s[LZMA_PROPS_SIZE + 2] << 16) |
   1.421 + 		(s[LZMA_PROPS_SIZE + 3] << 24);
   1.422 + 
   1.423 +-	res = LzmaUncompress(d, &outlen, s + LZMA_HEADER_SIZE, &inlen,
   1.424 +-		s, LZMA_PROPS_SIZE);
   1.425 ++	res = LzmaUncompress(dest, &outlen, src + LZMA_HEADER_SIZE, &inlen, src,
   1.426 ++		LZMA_PROPS_SIZE);
   1.427 + 	
   1.428 + 	*error = res;
   1.429 + 	return res == SZ_OK ? outlen : -1;
   1.430 + }
   1.431 ++
   1.432 ++
   1.433 ++struct compressor lzma_comp_ops = {
   1.434 ++	.init = NULL,
   1.435 ++	.compress = lzma_compress,
   1.436 ++	.uncompress = lzma_uncompress,
   1.437 ++	.options = NULL,
   1.438 ++	.usage = NULL,
   1.439 ++	.id = LZMA_COMPRESSION,
   1.440 ++	.name = "lzma",
   1.441 ++	.supported = 1
   1.442 ++};
   1.443 ++
   1.444 +diff -r 2ab2996036dd squashfs-tools/lzma_xz_wrapper.c
   1.445 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   1.446 ++++ b/squashfs-tools/lzma_xz_wrapper.c	Tue Dec 14 14:18:11 2010 +0000
   1.447 +@@ -0,0 +1,156 @@
   1.448 ++/*
   1.449 ++ * Copyright (c) 2010
   1.450 ++ * Phillip Lougher <phillip@lougher.demon.co.uk>
   1.451 ++ *
   1.452 ++ * This program is free software; you can redistribute it and/or
   1.453 ++ * modify it under the terms of the GNU General Public License
   1.454 ++ * as published by the Free Software Foundation; either version 2,
   1.455 ++ * or (at your option) any later version.
   1.456 ++ *
   1.457 ++ * This program is distributed in the hope that it will be useful,
   1.458 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
   1.459 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   1.460 ++ * GNU General Public License for more details.
   1.461 ++ *
   1.462 ++ * You should have received a copy of the GNU General Public License
   1.463 ++ * along with this program; if not, write to the Free Software
   1.464 ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   1.465 ++ *
   1.466 ++ * lzma_xz_wrapper.c
   1.467 ++ *
   1.468 ++ * Support for LZMA1 compression using XZ Utils liblzma http://tukaani.org/xz/
   1.469 ++ */
   1.470 ++
   1.471 ++#include <stdio.h>
   1.472 ++#include <string.h>
   1.473 ++#include <lzma.h>
   1.474 ++
   1.475 ++#include "squashfs_fs.h"
   1.476 ++#include "compressor.h"
   1.477 ++
   1.478 ++#define LZMA_PROPS_SIZE 5
   1.479 ++#define LZMA_UNCOMP_SIZE 8
   1.480 ++#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + LZMA_UNCOMP_SIZE)
   1.481 ++
   1.482 ++#define LZMA_OPTIONS 5
   1.483 ++#define MEMLIMIT (32 * 1024 * 1024)
   1.484 ++
   1.485 ++static int lzma_compress(void *dummy, void *dest, void *src,  int size,
   1.486 ++	int block_size, int *error)
   1.487 ++{
   1.488 ++	unsigned char *d = (unsigned char *) dest;
   1.489 ++	lzma_options_lzma opt;
   1.490 ++	lzma_stream strm = LZMA_STREAM_INIT;
   1.491 ++	int res;
   1.492 ++
   1.493 ++	lzma_lzma_preset(&opt, LZMA_OPTIONS);
   1.494 ++	opt.dict_size = block_size;
   1.495 ++	res = lzma_alone_encoder(&strm, &opt);
   1.496 ++	if(res != LZMA_OK) {
   1.497 ++		lzma_end(&strm);
   1.498 ++		goto failed;
   1.499 ++	}
   1.500 ++
   1.501 ++	strm.next_out = dest;
   1.502 ++	strm.avail_out = block_size;
   1.503 ++	strm.next_in = src;
   1.504 ++	strm.avail_in = size;
   1.505 ++
   1.506 ++	res = lzma_code(&strm, LZMA_FINISH);
   1.507 ++	lzma_end(&strm);
   1.508 ++
   1.509 ++	if(res == LZMA_STREAM_END) {
   1.510 ++		/*
   1.511 ++	 	 * Fill in the 8 byte little endian uncompressed size field in
   1.512 ++		 * the LZMA header.  8 bytes is excessively large for squashfs
   1.513 ++		 * but this is the standard LZMA header and which is expected by
   1.514 ++		 * the kernel code
   1.515 ++	 	 */
   1.516 ++
   1.517 ++		d[LZMA_PROPS_SIZE] = size & 255;
   1.518 ++		d[LZMA_PROPS_SIZE + 1] = (size >> 8) & 255;
   1.519 ++		d[LZMA_PROPS_SIZE + 2] = (size >> 16) & 255;
   1.520 ++		d[LZMA_PROPS_SIZE + 3] = (size >> 24) & 255;
   1.521 ++		d[LZMA_PROPS_SIZE + 4] = 0;
   1.522 ++		d[LZMA_PROPS_SIZE + 5] = 0;
   1.523 ++		d[LZMA_PROPS_SIZE + 6] = 0;
   1.524 ++		d[LZMA_PROPS_SIZE + 7] = 0;
   1.525 ++
   1.526 ++		return (int) strm.total_out;
   1.527 ++	}
   1.528 ++
   1.529 ++	if(res == LZMA_OK)
   1.530 ++		/*
   1.531 ++	 	 * Output buffer overflow.  Return out of buffer space
   1.532 ++	 	 */
   1.533 ++		return 0;
   1.534 ++
   1.535 ++failed:
   1.536 ++	/*
   1.537 ++	 * All other errors return failure, with the compressor
   1.538 ++	 * specific error code in *error
   1.539 ++	 */
   1.540 ++	*error = res;
   1.541 ++	return -1;
   1.542 ++}
   1.543 ++
   1.544 ++
   1.545 ++static int lzma_uncompress(void *dest, void *src, int size, int block_size,
   1.546 ++	int *error)
   1.547 ++{
   1.548 ++	lzma_stream strm = LZMA_STREAM_INIT;
   1.549 ++	int uncompressed_size = 0, res;
   1.550 ++	unsigned char lzma_header[LZMA_HEADER_SIZE];
   1.551 ++
   1.552 ++	res = lzma_alone_decoder(&strm, MEMLIMIT);
   1.553 ++	if(res != LZMA_OK) {
   1.554 ++		lzma_end(&strm);
   1.555 ++		goto failed;
   1.556 ++	}
   1.557 ++
   1.558 ++	memcpy(lzma_header, src, LZMA_HEADER_SIZE);
   1.559 ++	uncompressed_size = lzma_header[LZMA_PROPS_SIZE] |
   1.560 ++		(lzma_header[LZMA_PROPS_SIZE + 1] << 8) |
   1.561 ++		(lzma_header[LZMA_PROPS_SIZE + 2] << 16) |
   1.562 ++		(lzma_header[LZMA_PROPS_SIZE + 3] << 24);
   1.563 ++	memset(lzma_header + LZMA_PROPS_SIZE, 255, LZMA_UNCOMP_SIZE);
   1.564 ++
   1.565 ++	strm.next_out = dest;
   1.566 ++	strm.avail_out = block_size;
   1.567 ++	strm.next_in = lzma_header;
   1.568 ++	strm.avail_in = LZMA_HEADER_SIZE;
   1.569 ++
   1.570 ++	res = lzma_code(&strm, LZMA_RUN);
   1.571 ++
   1.572 ++	if(res != LZMA_OK || strm.avail_in != 0) {
   1.573 ++		lzma_end(&strm);
   1.574 ++		goto failed;
   1.575 ++	}
   1.576 ++
   1.577 ++	strm.next_in = src + LZMA_HEADER_SIZE;
   1.578 ++	strm.avail_in = size - LZMA_HEADER_SIZE;
   1.579 ++
   1.580 ++	res = lzma_code(&strm, LZMA_FINISH);
   1.581 ++	lzma_end(&strm);
   1.582 ++
   1.583 ++	if(res == LZMA_STREAM_END || (res == LZMA_OK &&
   1.584 ++		strm.total_out >= uncompressed_size && strm.avail_in == 0))
   1.585 ++		return uncompressed_size;
   1.586 ++
   1.587 ++failed:
   1.588 ++	*error = res;
   1.589 ++	return -1;
   1.590 ++}
   1.591 ++
   1.592 ++
   1.593 ++struct compressor lzma_comp_ops = {
   1.594 ++	.init = NULL,
   1.595 ++	.compress = lzma_compress,
   1.596 ++	.uncompress = lzma_uncompress,
   1.597 ++	.options = NULL,
   1.598 ++	.usage = NULL,
   1.599 ++	.id = LZMA_COMPRESSION,
   1.600 ++	.name = "lzma",
   1.601 ++	.supported = 1
   1.602 ++};
   1.603 ++
   1.604 +diff -r 2ab2996036dd squashfs-tools/lzo_wrapper.c
   1.605 +--- a/squashfs-tools/lzo_wrapper.c	Tue Dec 14 12:19:33 2010 +0000
   1.606 ++++ b/squashfs-tools/lzo_wrapper.c	Tue Dec 14 14:18:11 2010 +0000
   1.607 +@@ -2,6 +2,9 @@
   1.608 +  * Copyright (c) 2010 LG Electronics
   1.609 +  * Chan Jeong <chan.jeong@lge.com>
   1.610 +  *
   1.611 ++ * All modifications Copyright (c) 2010
   1.612 ++ * Phillip Lougher <phillip@lougher.demon.co.uk>
   1.613 ++ *
   1.614 +  * This program is free software; you can redistribute it and/or
   1.615 +  * modify it under the terms of the GNU General Public License
   1.616 +  * as published by the Free Software Foundation; either version 2,
   1.617 +@@ -25,6 +28,9 @@
   1.618 + #include <lzo/lzoconf.h>
   1.619 + #include <lzo/lzo1x.h>
   1.620 + 
   1.621 ++#include "squashfs_fs.h"
   1.622 ++#include "compressor.h"
   1.623 ++
   1.624 + /* worst-case expansion calculation during compression,
   1.625 +    see LZO FAQ for more information */
   1.626 + #define LZO_OUTPUT_BUFFER_SIZE(size)	(size + (size/16) + 64 + 3)
   1.627 +@@ -34,25 +40,39 @@
   1.628 + 	lzo_bytep out;
   1.629 + };
   1.630 + 
   1.631 +-int lzo_compress(void **strm, char *d, char *s, int size, int block_size,
   1.632 ++
   1.633 ++static int squashfs_lzo_init(void **strm, int block_size, int flags)
   1.634 ++{
   1.635 ++	struct lzo_stream *stream;
   1.636 ++
   1.637 ++	if((stream = *strm = malloc(sizeof(struct lzo_stream))) == NULL)
   1.638 ++		goto failed;
   1.639 ++	/* work memory for compression */
   1.640 ++	if((stream->wrkmem = malloc(LZO1X_999_MEM_COMPRESS)) == NULL)
   1.641 ++		goto failed2;
   1.642 ++	/* temporal output buffer */
   1.643 ++	if((stream->out = malloc(LZO_OUTPUT_BUFFER_SIZE(block_size))) == NULL)
   1.644 ++		goto failed3;
   1.645 ++
   1.646 ++	return 0;
   1.647 ++
   1.648 ++failed3:
   1.649 ++	free(stream->wrkmem);
   1.650 ++failed2:
   1.651 ++	free(stream);
   1.652 ++failed:
   1.653 ++	return -1;
   1.654 ++}
   1.655 ++
   1.656 ++
   1.657 ++static int lzo_compress(void *strm, void *d, void *s, int size, int block_size,
   1.658 + 		int *error)
   1.659 + {
   1.660 +-	int res = 0;
   1.661 ++	int res;
   1.662 + 	lzo_uint outlen;
   1.663 +-	struct lzo_stream *stream = *strm;
   1.664 ++	struct lzo_stream *stream = strm;
   1.665 + 
   1.666 +-	if(stream == NULL) {
   1.667 +-		if((stream = *strm = malloc(sizeof(struct lzo_stream))) == NULL)
   1.668 +-			goto failed;
   1.669 +-		/* work memory for compression */
   1.670 +-		if((stream->wrkmem = malloc(LZO1X_999_MEM_COMPRESS)) == NULL)
   1.671 +-			goto failed;
   1.672 +-		/* temporal output buffer */
   1.673 +-		if((stream->out = malloc(LZO_OUTPUT_BUFFER_SIZE(block_size))) == NULL)
   1.674 +-			goto failed;
   1.675 +-	}
   1.676 +-
   1.677 +-	res = lzo1x_999_compress((lzo_bytep)s, size, stream->out, &outlen, stream->wrkmem);
   1.678 ++	res = lzo1x_999_compress(s, size, stream->out, &outlen, stream->wrkmem);
   1.679 + 	if(res != LZO_E_OK)
   1.680 + 		goto failed;
   1.681 + 	if(outlen >= size)
   1.682 +@@ -77,13 +97,26 @@
   1.683 + }
   1.684 + 
   1.685 + 
   1.686 +-int lzo_uncompress(char *d, char *s, int size, int block_size, int *error)
   1.687 ++static int lzo_uncompress(void *d, void *s, int size, int block_size, int *error)
   1.688 + {
   1.689 + 	int res;
   1.690 + 	lzo_uint bytes = block_size;
   1.691 + 
   1.692 +-	res = lzo1x_decompress_safe((lzo_bytep)s, size, (lzo_bytep)d, &bytes, NULL);
   1.693 ++	res = lzo1x_decompress_safe(s, size, d, &bytes, NULL);
   1.694 + 
   1.695 + 	*error = res;
   1.696 + 	return res == LZO_E_OK ? bytes : -1;
   1.697 + }
   1.698 ++
   1.699 ++
   1.700 ++struct compressor lzo_comp_ops = {
   1.701 ++	.init = squashfs_lzo_init,
   1.702 ++	.compress = lzo_compress,
   1.703 ++	.uncompress = lzo_uncompress,
   1.704 ++	.options = NULL,
   1.705 ++	.usage = NULL,
   1.706 ++	.id = LZO_COMPRESSION,
   1.707 ++	.name = "lzo",
   1.708 ++	.supported = 1
   1.709 ++};
   1.710 ++
   1.711 +diff -r 2ab2996036dd squashfs-tools/mksquashfs.c
   1.712 +--- a/squashfs-tools/mksquashfs.c	Tue Dec 14 12:19:33 2010 +0000
   1.713 ++++ b/squashfs-tools/mksquashfs.c	Tue Dec 14 14:18:11 2010 +0000
   1.714 +@@ -384,9 +384,10 @@
   1.715 + #define FRAGMENT_BUFFER_DEFAULT 64
   1.716 + int writer_buffer_size;
   1.717 + 
   1.718 +-/* compression operations structure */
   1.719 ++/* compression operations */
   1.720 + static struct compressor *comp;
   1.721 +-char *comp_name = COMP_DEFAULT;
   1.722 ++int compressor_opts_parsed = 0;
   1.723 ++void *stream = NULL;
   1.724 + 
   1.725 + /* xattr stats */
   1.726 + unsigned int xattr_bytes = 0, total_xattr_bytes = 0;
   1.727 +@@ -859,7 +860,7 @@
   1.728 + }
   1.729 + 
   1.730 + 
   1.731 +-int mangle2(void **strm, char *d, char *s, int size,
   1.732 ++int mangle2(void *strm, char *d, char *s, int size,
   1.733 + 	int block_size, int uncompressed, int data_block)
   1.734 + {
   1.735 + 	int error, c_byte = 0;
   1.736 +@@ -884,9 +885,7 @@
   1.737 + int mangle(char *d, char *s, int size, int block_size,
   1.738 + 	int uncompressed, int data_block)
   1.739 + {
   1.740 +-	static void *stream = NULL;
   1.741 +-
   1.742 +-	return mangle2(&stream, d, s, size, block_size, uncompressed,
   1.743 ++	return mangle2(stream, d, s, size, block_size, uncompressed,
   1.744 + 		data_block);
   1.745 + }
   1.746 + 
   1.747 +@@ -2556,11 +2555,15 @@
   1.748 + void *deflator(void *arg)
   1.749 + {
   1.750 + 	void *stream = NULL;
   1.751 +-	int oldstate;
   1.752 ++	int res, oldstate;
   1.753 + 
   1.754 + 	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
   1.755 + 	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
   1.756 + 
   1.757 ++	res = compressor_init(comp, &stream, block_size, 1);
   1.758 ++	if(res)
   1.759 ++		BAD_ERROR("deflator:: compressor_init failed\n");
   1.760 ++
   1.761 + 	while(1) {
   1.762 + 		struct file_buffer *file_buffer = queue_get(from_reader);
   1.763 + 		struct file_buffer *write_buffer;
   1.764 +@@ -2573,7 +2576,7 @@
   1.765 + 			queue_put(from_deflate, file_buffer);
   1.766 + 		} else {
   1.767 + 			write_buffer = cache_get(writer_buffer, 0, 0);
   1.768 +-			write_buffer->c_byte = mangle2(&stream,
   1.769 ++			write_buffer->c_byte = mangle2(stream,
   1.770 + 				write_buffer->data, file_buffer->data,
   1.771 + 				file_buffer->size, block_size, noD, 1);
   1.772 + 			write_buffer->sequence = file_buffer->sequence;
   1.773 +@@ -2593,11 +2596,15 @@
   1.774 + void *frag_deflator(void *arg)
   1.775 + {
   1.776 + 	void *stream = NULL;
   1.777 +-	int oldstate;
   1.778 ++	int res, oldstate;
   1.779 + 
   1.780 + 	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
   1.781 + 	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate);
   1.782 + 
   1.783 ++	res = compressor_init(comp, &stream, block_size, 1);
   1.784 ++	if(res)
   1.785 ++		BAD_ERROR("frag_deflator:: compressor_init failed\n");
   1.786 ++
   1.787 + 	while(1) {
   1.788 + 		int c_byte, compressed_size;
   1.789 + 		struct file_buffer *file_buffer = queue_get(to_frag);
   1.790 +@@ -2605,7 +2612,7 @@
   1.791 + 			cache_get(writer_buffer, file_buffer->block +
   1.792 + 			FRAG_INDEX, 1);
   1.793 + 
   1.794 +-		c_byte = mangle2(&stream, write_buffer->data, file_buffer->data,
   1.795 ++		c_byte = mangle2(stream, write_buffer->data, file_buffer->data,
   1.796 + 			file_buffer->size, block_size, noF, 1);
   1.797 + 		compressed_size = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte);
   1.798 + 		write_buffer->size = compressed_size;
   1.799 +@@ -4501,7 +4508,7 @@
   1.800 + 
   1.801 + 
   1.802 + #define VERSION() \
   1.803 +-	printf("mksquashfs version 4.1 (2010/09/19)\n");\
   1.804 ++	printf("mksquashfs version 4.1-CVS (2010/12/07)\n");\
   1.805 + 	printf("copyright (C) 2010 Phillip Lougher "\
   1.806 + 		"<phillip@lougher.demon.co.uk>\n\n"); \
   1.807 + 	printf("This program is free software; you can redistribute it and/or"\
   1.808 +@@ -4521,7 +4528,7 @@
   1.809 + int main(int argc, char *argv[])
   1.810 + {
   1.811 + 	struct stat buf, source_buf;
   1.812 +-	int i;
   1.813 ++	int res, i;
   1.814 + 	squashfs_super_block sBlk;
   1.815 + 	char *b, *root_name = NULL;
   1.816 + 	int nopad = FALSE, keep_as_directory = FALSE;
   1.817 +@@ -4542,14 +4549,50 @@
   1.818 + 		goto printOptions;
   1.819 + 	source_path = argv + 1;
   1.820 + 	source = i - 2;
   1.821 ++	/*
   1.822 ++	 * lookup default compressor.  Note the Makefile ensures the default
   1.823 ++	 * compressor has been built, and so we don't need to to check
   1.824 ++	 * for failure here
   1.825 ++	 */
   1.826 ++	comp = lookup_compressor(COMP_DEFAULT);
   1.827 + 	for(; i < argc; i++) {
   1.828 + 		if(strcmp(argv[i], "-comp") == 0) {
   1.829 ++			if(compressor_opts_parsed) {
   1.830 ++				ERROR("%s: -comp must appear before -X options"
   1.831 ++					"\n", argv[0]);
   1.832 ++				exit(1);
   1.833 ++			}
   1.834 + 			if(++i == argc) {
   1.835 + 				ERROR("%s: -comp missing compression type\n",
   1.836 + 					argv[0]);
   1.837 + 				exit(1);
   1.838 + 			}
   1.839 +-			comp_name = argv[i];
   1.840 ++			comp = lookup_compressor(argv[i]);
   1.841 ++			if(!comp->supported) {
   1.842 ++				ERROR("%s: Compressor \"%s\" is not supported!"
   1.843 ++					"\n", argv[0], argv[i]);
   1.844 ++				ERROR("%s: Compressors available:\n", argv[0]);
   1.845 ++				display_compressors("", COMP_DEFAULT);
   1.846 ++				exit(1);
   1.847 ++			}
   1.848 ++
   1.849 ++		} else if(strncmp(argv[i], "-X", 2) == 0) {
   1.850 ++			int args = compressor_options(comp, argv + i, argc - i);
   1.851 ++			if(args < 0) {
   1.852 ++				if(args == -1) {
   1.853 ++					ERROR("%s: Unrecognised compressor"
   1.854 ++						" option %s\n", argv[0],
   1.855 ++						argv[i]);
   1.856 ++					ERROR("%s: Did you forget to specify"
   1.857 ++						" -comp, or specify it after"
   1.858 ++						" the compressor specific"
   1.859 ++						" option?\n", argv[0]);
   1.860 ++					}
   1.861 ++				exit(1);
   1.862 ++			}
   1.863 ++			i += args;
   1.864 ++			compressor_opts_parsed = 1;
   1.865 ++
   1.866 + 		} else if(strcmp(argv[i], "-pf") == 0) {
   1.867 + 			if(++i == argc) {
   1.868 + 				ERROR("%s: -pf missing filename\n", argv[0]);
   1.869 +@@ -4857,7 +4900,7 @@
   1.870 + 			ERROR("-write-queue <size>\tSet output queue to <size> "
   1.871 + 				"Mbytes.  Default %d Mbytes\n",
   1.872 + 				WRITER_BUFFER_DEFAULT);
   1.873 +-			ERROR("-fragment-queue <size>\tSet fagment queue to "
   1.874 ++			ERROR("-fragment-queue <size>\tSet fragment queue to "
   1.875 + 				"<size> Mbytes.  Default %d Mbytes\n",
   1.876 + 				FRAGMENT_BUFFER_DEFAULT);
   1.877 + 			ERROR("\nMiscellaneous options:\n");
   1.878 +@@ -4871,8 +4914,9 @@
   1.879 + 				"-noF\n");
   1.880 + 			ERROR("-noXattrCompression\talternative name for "
   1.881 + 				"-noX\n");
   1.882 +-			ERROR("\nCompressors available:\n");
   1.883 +-			display_compressors("", COMP_DEFAULT);
   1.884 ++			ERROR("\nCompressors available and compressor specific "
   1.885 ++				"options:\n");
   1.886 ++			display_compressor_usage(COMP_DEFAULT);
   1.887 + 			exit(1);
   1.888 + 		}
   1.889 + 	}
   1.890 +@@ -5005,19 +5049,14 @@
   1.891 + 		always_use_fragments = SQUASHFS_ALWAYS_FRAGMENTS(sBlk.flags);
   1.892 + 		duplicate_checking = SQUASHFS_DUPLICATES(sBlk.flags);
   1.893 + 		exportable = SQUASHFS_EXPORTABLE(sBlk.flags);
   1.894 +-	} else {
   1.895 +-		comp = lookup_compressor(comp_name);
   1.896 +-		if(!comp->supported) {
   1.897 +-			ERROR("FATAL_ERROR: Compressor \"%s\" is not "
   1.898 +-				"supported!\n", comp_name);
   1.899 +-			ERROR("Compressors available:\n");
   1.900 +-			display_compressors("", COMP_DEFAULT);
   1.901 +-			EXIT_MKSQUASHFS();
   1.902 +-		}
   1.903 + 	}
   1.904 + 
   1.905 + 	initialise_threads(readb_mbytes, writeb_mbytes, fragmentb_mbytes);
   1.906 + 
   1.907 ++	res = compressor_init(comp, &stream, SQUASHFS_METADATA_SIZE, 0);
   1.908 ++	if(res)
   1.909 ++		BAD_ERROR("compressor_init failed\n");
   1.910 ++
   1.911 + 	if(delete) {
   1.912 + 		printf("Creating %d.%d filesystem on %s, block size %d.\n",
   1.913 + 			SQUASHFS_MAJOR, s_minor, argv[source + 1], block_size);
   1.914 +diff -r 2ab2996036dd squashfs-tools/read_fs.c
   1.915 +--- a/squashfs-tools/read_fs.c	Tue Dec 14 12:19:33 2010 +0000
   1.916 ++++ b/squashfs-tools/read_fs.c	Tue Dec 14 14:18:11 2010 +0000
   1.917 +@@ -363,7 +363,8 @@
   1.918 + 		}
   1.919 + 	}
   1.920 + 	
   1.921 +-	return files;
   1.922 ++	printf("Read existing filesystem, %d inodes scanned\n", files);
   1.923 ++	return TRUE;
   1.924 + 
   1.925 + 
   1.926 + failed:
   1.927 +@@ -414,6 +415,7 @@
   1.928 + 	if(!comp->supported) {
   1.929 + 		ERROR("Filesystem on %s uses %s compression, this is"
   1.930 + 			"unsupported by this version\n", source, comp->name);
   1.931 ++		ERROR("Compressors available:\n");
   1.932 + 		display_compressors("", "");
   1.933 + 		goto failed_mount;
   1.934 + 	}
   1.935 +@@ -691,7 +693,7 @@
   1.936 + 		SQUASHFS_INODE_BLK(sBlk->root_inode);
   1.937 + 	unsigned int root_inode_offset =
   1.938 + 		SQUASHFS_INODE_OFFSET(sBlk->root_inode);
   1.939 +-	unsigned int root_inode_block, files;
   1.940 ++	unsigned int root_inode_block;
   1.941 + 	squashfs_inode_header inode;
   1.942 + 	unsigned int *id_table;
   1.943 + 	int res;
   1.944 +@@ -711,20 +713,18 @@
   1.945 + 	if(id_table == NULL)
   1.946 + 		goto error;
   1.947 + 
   1.948 +-	if((files = scan_inode_table(fd, start, end, root_inode_start,
   1.949 +-			root_inode_offset, sBlk, &inode, &inode_table,
   1.950 +-			&root_inode_block, root_inode_size, uncompressed_file,
   1.951 +-			uncompressed_directory, file_count, sym_count,
   1.952 +-			dev_count, dir_count, fifo_count, sock_count, id_table))
   1.953 +-			== 0) {
   1.954 ++	res = scan_inode_table(fd, start, end, root_inode_start,
   1.955 ++		root_inode_offset, sBlk, &inode, &inode_table,
   1.956 ++		&root_inode_block, root_inode_size, uncompressed_file,
   1.957 ++		uncompressed_directory, file_count, sym_count, dev_count,
   1.958 ++		dir_count, fifo_count, sock_count, id_table);
   1.959 ++	if(res == 0) {
   1.960 + 		ERROR("read_filesystem: inode table read failed\n");
   1.961 + 		goto error;
   1.962 + 	}
   1.963 + 
   1.964 + 	*uncompressed_inode = root_inode_block;
   1.965 + 
   1.966 +-	printf("Read existing filesystem, %d inodes scanned\n", files);
   1.967 +-
   1.968 + 	if(inode.base.inode_type == SQUASHFS_DIR_TYPE ||
   1.969 + 			inode.base.inode_type == SQUASHFS_LDIR_TYPE) {
   1.970 + 		if(inode.base.inode_type == SQUASHFS_DIR_TYPE) {
   1.971 +diff -r 2ab2996036dd squashfs-tools/squashfs_fs.h
   1.972 +--- a/squashfs-tools/squashfs_fs.h	Tue Dec 14 12:19:33 2010 +0000
   1.973 ++++ b/squashfs-tools/squashfs_fs.h	Tue Dec 14 14:18:11 2010 +0000
   1.974 +@@ -259,6 +259,7 @@
   1.975 + #define ZLIB_COMPRESSION	1
   1.976 + #define LZMA_COMPRESSION	2
   1.977 + #define LZO_COMPRESSION		3
   1.978 ++#define XZ_COMPRESSION		4
   1.979 + 
   1.980 + struct squashfs_super_block {
   1.981 + 	unsigned int		s_magic;
   1.982 +diff -r 2ab2996036dd squashfs-tools/unsquash-1.c
   1.983 +--- a/squashfs-tools/unsquash-1.c	Tue Dec 14 12:19:33 2010 +0000
   1.984 ++++ b/squashfs-tools/unsquash-1.c	Tue Dec 14 14:18:11 2010 +0000
   1.985 +@@ -138,7 +138,7 @@
   1.986 + 
   1.987 + 			i.data = inode->file_size;
   1.988 + 			i.time = inode->mtime;
   1.989 +-			i.blocks = (inode->file_size + sBlk.s.block_size - 1) >>
   1.990 ++			i.blocks = (i.data + sBlk.s.block_size - 1) >>
   1.991 + 				sBlk.s.block_log;
   1.992 + 			i.start = inode->start_block;
   1.993 + 			i.block_ptr = block_ptr + sizeof(*inode);
   1.994 +diff -r 2ab2996036dd squashfs-tools/unsquash-2.c
   1.995 +--- a/squashfs-tools/unsquash-2.c	Tue Dec 14 12:19:33 2010 +0000
   1.996 ++++ b/squashfs-tools/unsquash-2.c	Tue Dec 14 14:18:11 2010 +0000
   1.997 +@@ -205,8 +205,8 @@
   1.998 + 			i.fragment = inode->fragment;
   1.999 + 			i.offset = inode->offset;
  1.1000 + 			i.blocks = inode->fragment == SQUASHFS_INVALID_FRAG ?
  1.1001 +-				(inode->file_size + sBlk.s.block_size - 1) >>
  1.1002 +-				sBlk.s.block_log : inode->file_size >>
  1.1003 ++				(i.data + sBlk.s.block_size - 1) >>
  1.1004 ++				sBlk.s.block_log : i.data >>
  1.1005 + 				sBlk.s.block_log;
  1.1006 + 			i.start = inode->start_block;
  1.1007 + 			i.sparse = 0;
  1.1008 +diff -r 2ab2996036dd squashfs-tools/unsquash-3.c
  1.1009 +--- a/squashfs-tools/unsquash-3.c	Tue Dec 14 12:19:33 2010 +0000
  1.1010 ++++ b/squashfs-tools/unsquash-3.c	Tue Dec 14 14:18:11 2010 +0000
  1.1011 +@@ -188,9 +188,9 @@
  1.1012 + 			i.fragment = inode->fragment;
  1.1013 + 			i.offset = inode->offset;
  1.1014 + 			i.blocks = inode->fragment == SQUASHFS_INVALID_FRAG ?
  1.1015 +-				(inode->file_size + sBlk.s.block_size - 1) >>
  1.1016 ++				(i.data + sBlk.s.block_size - 1) >>
  1.1017 + 				sBlk.s.block_log :
  1.1018 +-				inode->file_size >> sBlk.s.block_log;
  1.1019 ++				i.data >> sBlk.s.block_log;
  1.1020 + 			i.start = inode->start_block;
  1.1021 + 			i.sparse = 1;
  1.1022 + 			i.block_ptr = block_ptr + sizeof(*inode);
  1.1023 +diff -r 2ab2996036dd squashfs-tools/unsquash-4.c
  1.1024 +--- a/squashfs-tools/unsquash-4.c	Tue Dec 14 12:19:33 2010 +0000
  1.1025 ++++ b/squashfs-tools/unsquash-4.c	Tue Dec 14 14:18:11 2010 +0000
  1.1026 +@@ -143,9 +143,9 @@
  1.1027 + 			i.fragment = inode->fragment;
  1.1028 + 			i.offset = inode->offset;
  1.1029 + 			i.blocks = inode->fragment == SQUASHFS_INVALID_FRAG ?
  1.1030 +-				(inode->file_size + sBlk.s.block_size - 1) >>
  1.1031 ++				(i.data + sBlk.s.block_size - 1) >>
  1.1032 + 				sBlk.s.block_log :
  1.1033 +-				inode->file_size >> sBlk.s.block_log;
  1.1034 ++				i.data >> sBlk.s.block_log;
  1.1035 + 			i.start = inode->start_block;
  1.1036 + 			i.sparse = 0;
  1.1037 + 			i.block_ptr = block_ptr + sizeof(*inode);
  1.1038 +diff -r 2ab2996036dd squashfs-tools/unsquashfs.c
  1.1039 +--- a/squashfs-tools/unsquashfs.c	Tue Dec 14 12:19:33 2010 +0000
  1.1040 ++++ b/squashfs-tools/unsquashfs.c	Tue Dec 14 14:18:11 2010 +0000
  1.1041 +@@ -737,7 +737,7 @@
  1.1042 + int lseek_broken = FALSE;
  1.1043 + char *zero_data = NULL;
  1.1044 + 
  1.1045 +-int write_block(int file_fd, char *buffer, int size, int hole, int sparse)
  1.1046 ++int write_block(int file_fd, char *buffer, int size, long long hole, int sparse)
  1.1047 + {
  1.1048 + 	off_t off = hole;
  1.1049 + 
  1.1050 +@@ -1299,9 +1299,12 @@
  1.1051 + 		print_filename(parent_name, i);
  1.1052 + 
  1.1053 + 	if(!lsonly && mkdir(parent_name, (mode_t) dir->mode) == -1 &&
  1.1054 +-			(!force || errno != EEXIST))
  1.1055 +-		ERROR("dir_scan: failed to open directory %s, because %s\n",
  1.1056 ++			(!force || errno != EEXIST)) {
  1.1057 ++		ERROR("dir_scan: failed to make directory %s, because %s\n",
  1.1058 + 			parent_name, strerror(errno));
  1.1059 ++		squashfs_closedir(dir);
  1.1060 ++		return;
  1.1061 ++	}
  1.1062 + 
  1.1063 + 	while(squashfs_readdir(dir, &name, &start_block, &offset, &type)) {
  1.1064 + 		TRACE("dir_scan: name %s, start_block %d, offset %d, type %d\n",
  1.1065 +@@ -1604,7 +1607,7 @@
  1.1066 + 	while(1) {
  1.1067 + 		struct squashfs_file *file = queue_get(to_writer);
  1.1068 + 		int file_fd;
  1.1069 +-		int hole = 0;
  1.1070 ++		long long hole = 0;
  1.1071 + 		int failed = FALSE;
  1.1072 + 		int error;
  1.1073 + 
  1.1074 +@@ -1903,7 +1906,7 @@
  1.1075 + 
  1.1076 + 
  1.1077 + #define VERSION() \
  1.1078 +-	printf("unsquashfs version 4.1 (2010/09/19)\n");\
  1.1079 ++	printf("unsquashfs version 4.1-CVS (2010/10/23)\n");\
  1.1080 + 	printf("copyright (C) 2010 Phillip Lougher "\
  1.1081 + 		"<phillip@lougher.demon.co.uk>\n\n");\
  1.1082 +     	printf("This program is free software; you can redistribute it and/or"\
  1.1083 +@@ -2081,7 +2084,7 @@
  1.1084 + 			ERROR("\t-da[ta-queue] <size>\tSet data queue to "
  1.1085 + 				"<size> Mbytes.  Default %d\n\t\t\t\tMbytes\n",
  1.1086 + 				DATA_BUFFER_DEFAULT);
  1.1087 +-			ERROR("\t-fr[ag-queue] <size>\tSet fagment queue to "
  1.1088 ++			ERROR("\t-fr[ag-queue] <size>\tSet fragment queue to "
  1.1089 + 				"<size> Mbytes.  Default %d\n\t\t\t\t Mbytes\n",
  1.1090 + 				FRAGMENT_BUFFER_DEFAULT);
  1.1091 + 			ERROR("\t-r[egex]\t\ttreat extract names as POSIX "
  1.1092 +diff -r 2ab2996036dd squashfs-tools/unsquashfs_xattr.c
  1.1093 +--- a/squashfs-tools/unsquashfs_xattr.c	Tue Dec 14 12:19:33 2010 +0000
  1.1094 ++++ b/squashfs-tools/unsquashfs_xattr.c	Tue Dec 14 14:18:11 2010 +0000
  1.1095 +@@ -25,7 +25,7 @@
  1.1096 + #include "unsquashfs.h"
  1.1097 + #include "xattr.h"
  1.1098 + 
  1.1099 +-#include <attr/xattr.h>
  1.1100 ++#include <sys/xattr.h>
  1.1101 + 
  1.1102 + extern int root_process;
  1.1103 + 
  1.1104 +diff -r 2ab2996036dd squashfs-tools/xattr.c
  1.1105 +--- a/squashfs-tools/xattr.c	Tue Dec 14 12:19:33 2010 +0000
  1.1106 ++++ b/squashfs-tools/xattr.c	Tue Dec 14 14:18:11 2010 +0000
  1.1107 +@@ -34,7 +34,7 @@
  1.1108 + #include <dirent.h>
  1.1109 + #include <string.h>
  1.1110 + #include <stdlib.h>
  1.1111 +-#include <attr/xattr.h>
  1.1112 ++#include <sys/xattr.h>
  1.1113 + 
  1.1114 + #include "squashfs_fs.h"
  1.1115 + #include "global.h"
  1.1116 +@@ -219,6 +219,10 @@
  1.1117 + 			break;
  1.1118 + 		}
  1.1119 + 		xattr_list[i].vsize = vsize;
  1.1120 ++
  1.1121 ++		TRACE("read_xattrs_from_system: filename %s, xattr name %s,"
  1.1122 ++			" vsize %d\n", filename, xattr_list[i].full_name,
  1.1123 ++			xattr_list[i].vsize);
  1.1124 + 	}
  1.1125 + 	free(xattr_names);
  1.1126 + 	*xattrs = xattr_list;
  1.1127 +diff -r 2ab2996036dd squashfs-tools/xz_wrapper.c
  1.1128 +--- a/squashfs-tools/xz_wrapper.c	Tue Dec 14 12:19:33 2010 +0000
  1.1129 ++++ b/squashfs-tools/xz_wrapper.c	Tue Dec 14 14:18:11 2010 +0000
  1.1130 +@@ -17,69 +17,192 @@
  1.1131 +  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  1.1132 +  *
  1.1133 +  * xz_wrapper.c
  1.1134 ++ *
  1.1135 ++ * Support for XZ (LZMA2) compression using XZ Utils liblzma http://tukaani.org/xz/
  1.1136 +  */
  1.1137 + 
  1.1138 + #include <stdio.h>
  1.1139 + #include <string.h>
  1.1140 ++#include <stdlib.h>
  1.1141 + #include <lzma.h>
  1.1142 + 
  1.1143 +-#define LZMA_PROPS_SIZE 5
  1.1144 +-#define LZMA_UNCOMP_SIZE 8
  1.1145 +-#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + LZMA_UNCOMP_SIZE)
  1.1146 ++#include "squashfs_fs.h"
  1.1147 ++#include "compressor.h"
  1.1148 + 
  1.1149 +-#define LZMA_OPTIONS 5
  1.1150 + #define MEMLIMIT (32 * 1024 * 1024)
  1.1151 + 
  1.1152 +-int lzma_compress(void **dummy, void *dest, void *src,  int size,
  1.1153 ++static struct bcj {
  1.1154 ++	char	 	*name;
  1.1155 ++	lzma_vli	id;
  1.1156 ++	int		selected;
  1.1157 ++} bcj[] = {
  1.1158 ++	{ "x86", LZMA_FILTER_X86, 0 },
  1.1159 ++	{ "powerpc", LZMA_FILTER_POWERPC, 0 },
  1.1160 ++	{ "ia64", LZMA_FILTER_IA64, 0 },
  1.1161 ++	{ "arm", LZMA_FILTER_ARM, 0 },
  1.1162 ++	{ "armthumb", LZMA_FILTER_ARMTHUMB, 0 },
  1.1163 ++	{ "sparc", LZMA_FILTER_SPARC, 0 },
  1.1164 ++	{ NULL, LZMA_VLI_UNKNOWN, 0 }
  1.1165 ++};
  1.1166 ++
  1.1167 ++struct filter {
  1.1168 ++	void		*buffer;
  1.1169 ++	lzma_filter	filter[3];
  1.1170 ++	size_t		length;
  1.1171 ++};
  1.1172 ++
  1.1173 ++struct xz_stream {
  1.1174 ++	struct filter	*filter;
  1.1175 ++	int		filters;
  1.1176 ++	lzma_options_lzma opt;
  1.1177 ++};
  1.1178 ++
  1.1179 ++static int filter_count = 1;
  1.1180 ++
  1.1181 ++
  1.1182 ++static int xz_options(char *argv[], int argc)
  1.1183 ++{
  1.1184 ++	int i;
  1.1185 ++	char *name;
  1.1186 ++
  1.1187 ++	if(strcmp(argv[0], "-Xbcj") == 0) {
  1.1188 ++		if(argc < 2) {
  1.1189 ++			fprintf(stderr, "xz: -Xbcj missing filter\n");
  1.1190 ++			goto failed;
  1.1191 ++		}
  1.1192 ++
  1.1193 ++		name = argv[1];
  1.1194 ++		while(name[0] != '\0') {
  1.1195 ++			for(i = 0; bcj[i].name; i++) {
  1.1196 ++				int n = strlen(bcj[i].name);
  1.1197 ++				if((strncmp(name, bcj[i].name, n) == 0) &&
  1.1198 ++						(name[n] == '\0' ||
  1.1199 ++						 name[n] == ',')) {
  1.1200 ++					if(bcj[i].selected == 0) {
  1.1201 ++				 		bcj[i].selected = 1;
  1.1202 ++						filter_count++;
  1.1203 ++					}
  1.1204 ++					name += name[n] == ',' ? n + 1 : n;
  1.1205 ++					break;
  1.1206 ++				}
  1.1207 ++			}
  1.1208 ++			if(bcj[i].name == NULL) {
  1.1209 ++				fprintf(stderr, "xz: -Xbcj unrecognised filter\n");
  1.1210 ++				goto failed;
  1.1211 ++			}
  1.1212 ++		}
  1.1213 ++	
  1.1214 ++		return 1;
  1.1215 ++	}
  1.1216 ++
  1.1217 ++	return -1;
  1.1218 ++	
  1.1219 ++failed:
  1.1220 ++	return -2;
  1.1221 ++}
  1.1222 ++		
  1.1223 ++
  1.1224 ++void xz_usage()
  1.1225 ++{
  1.1226 ++	fprintf(stderr, "\t  -Xbcj filter1,filter2,...,filterN\n");
  1.1227 ++	fprintf(stderr, "\t\tCompress using filter1,filter2,...,filterN in");
  1.1228 ++	fprintf(stderr, " turn\n\t\t(in addition to no filter), and choose");
  1.1229 ++	fprintf(stderr, " the best compression.\n");
  1.1230 ++	fprintf(stderr, "\t\tAvailable filters: x86, arm, armthumb,");
  1.1231 ++	fprintf(stderr, " powerpc, sparc, ia64\n");
  1.1232 ++}
  1.1233 ++
  1.1234 ++
  1.1235 ++static int xz_init(void **strm, int block_size, int flags)
  1.1236 ++{
  1.1237 ++	int i, j, filters = flags ? filter_count : 1;
  1.1238 ++	struct filter *filter = malloc(filters * sizeof(struct filter));
  1.1239 ++	struct xz_stream *stream;
  1.1240 ++
  1.1241 ++	if(filter == NULL)
  1.1242 ++		goto failed;
  1.1243 ++
  1.1244 ++	stream = *strm = malloc(sizeof(struct xz_stream));
  1.1245 ++	if(stream == NULL)
  1.1246 ++		goto failed2;
  1.1247 ++
  1.1248 ++	stream->filter = filter;
  1.1249 ++	stream->filters = filters;
  1.1250 ++
  1.1251 ++	memset(filter, 0, filters * sizeof(struct filter));
  1.1252 ++
  1.1253 ++	filter[0].filter[0].id = LZMA_FILTER_LZMA2;
  1.1254 ++	filter[0].filter[0].options = &stream->opt;
  1.1255 ++	filter[0].filter[1].id = LZMA_VLI_UNKNOWN;
  1.1256 ++
  1.1257 ++	for(i = 0, j = 1; flags && bcj[i].name; i++) {
  1.1258 ++		if(bcj[i].selected) {
  1.1259 ++			filter[j].buffer = malloc(block_size);
  1.1260 ++			if(filter[j].buffer == NULL)
  1.1261 ++				goto failed3;
  1.1262 ++			filter[j].filter[0].id = bcj[i].id;
  1.1263 ++			filter[j].filter[1].id = LZMA_FILTER_LZMA2;
  1.1264 ++			filter[j].filter[1].options = &stream->opt;
  1.1265 ++			filter[j].filter[2].id = LZMA_VLI_UNKNOWN;
  1.1266 ++			j++;
  1.1267 ++		}
  1.1268 ++	}
  1.1269 ++
  1.1270 ++	return 0;
  1.1271 ++
  1.1272 ++failed3:
  1.1273 ++	for(i = 1; i < filters; i++)
  1.1274 ++		free(filter[i].buffer);
  1.1275 ++	free(stream);
  1.1276 ++
  1.1277 ++failed2:
  1.1278 ++	free(filter);
  1.1279 ++
  1.1280 ++failed:
  1.1281 ++	return -1;
  1.1282 ++}
  1.1283 ++
  1.1284 ++
  1.1285 ++static int xz_compress(void *strm, void *dest, void *src,  int size,
  1.1286 + 	int block_size, int *error)
  1.1287 + {
  1.1288 +-	unsigned char *d = (unsigned char *) dest;
  1.1289 +-	lzma_options_lzma opt;
  1.1290 +-	lzma_stream strm = LZMA_STREAM_INIT;
  1.1291 +-	int res;
  1.1292 ++	int i;
  1.1293 ++        lzma_ret res = 0;
  1.1294 ++	struct xz_stream *stream = strm;
  1.1295 ++	struct filter *selected = NULL;
  1.1296 + 
  1.1297 +-	lzma_lzma_preset(&opt, LZMA_OPTIONS);
  1.1298 +-	opt.dict_size = block_size;
  1.1299 +-	res = lzma_alone_encoder(&strm, &opt);
  1.1300 +-	if(res != LZMA_OK) {
  1.1301 +-		lzma_end(&strm);
  1.1302 +-		goto failed;
  1.1303 ++	stream->filter[0].buffer = dest;
  1.1304 ++
  1.1305 ++	for(i = 0; i < stream->filters; i++) {
  1.1306 ++		struct filter *filter = &stream->filter[i];
  1.1307 ++
  1.1308 ++        	if(lzma_lzma_preset(&stream->opt, LZMA_PRESET_DEFAULT))
  1.1309 ++                	goto failed;
  1.1310 ++
  1.1311 ++		stream->opt.dict_size = block_size;
  1.1312 ++		filter->length = 0;
  1.1313 ++		res = lzma_stream_buffer_encode(filter->filter,
  1.1314 ++			LZMA_CHECK_CRC32, NULL, src, size, filter->buffer,
  1.1315 ++			&filter->length, block_size);
  1.1316 ++	
  1.1317 ++		if(res == LZMA_OK) {
  1.1318 ++			if(!selected || selected->length > filter->length)
  1.1319 ++				selected = filter;
  1.1320 ++		} else if(res != LZMA_BUF_ERROR)
  1.1321 ++			goto failed;
  1.1322 + 	}
  1.1323 + 
  1.1324 +-	strm.next_out = dest;
  1.1325 +-	strm.avail_out = block_size;
  1.1326 +-	strm.next_in = src;
  1.1327 +-	strm.avail_in = size;
  1.1328 +-
  1.1329 +-	res = lzma_code(&strm, LZMA_FINISH);
  1.1330 +-	lzma_end(&strm);
  1.1331 +-
  1.1332 +-	if(res == LZMA_STREAM_END) {
  1.1333 +-		/*
  1.1334 +-	 	 * Fill in the 8 byte little endian uncompressed size field in
  1.1335 +-		 * the LZMA header.  8 bytes is excessively large for squashfs
  1.1336 +-		 * but this is the standard LZMA header and which is expected by
  1.1337 +-		 * the kernel code
  1.1338 +-	 	 */
  1.1339 +-
  1.1340 +-		d[LZMA_PROPS_SIZE] = size & 255;
  1.1341 +-		d[LZMA_PROPS_SIZE + 1] = (size >> 8) & 255;
  1.1342 +-		d[LZMA_PROPS_SIZE + 2] = (size >> 16) & 255;
  1.1343 +-		d[LZMA_PROPS_SIZE + 3] = (size >> 24) & 255;
  1.1344 +-		d[LZMA_PROPS_SIZE + 4] = 0;
  1.1345 +-		d[LZMA_PROPS_SIZE + 5] = 0;
  1.1346 +-		d[LZMA_PROPS_SIZE + 6] = 0;
  1.1347 +-		d[LZMA_PROPS_SIZE + 7] = 0;
  1.1348 +-
  1.1349 +-		return (int) strm.total_out;
  1.1350 +-	}
  1.1351 +-
  1.1352 +-	if(res == LZMA_OK)
  1.1353 ++	if(!selected)
  1.1354 + 		/*
  1.1355 + 	 	 * Output buffer overflow.  Return out of buffer space
  1.1356 + 	 	 */
  1.1357 + 		return 0;
  1.1358 + 
  1.1359 ++	if(selected->buffer != dest)
  1.1360 ++		memcpy(dest, selected->buffer, selected->length);
  1.1361 ++
  1.1362 ++	return (int) selected->length;
  1.1363 ++
  1.1364 + failed:
  1.1365 + 	/*
  1.1366 + 	 * All other errors return failure, with the compressor
  1.1367 +@@ -90,49 +213,29 @@
  1.1368 + }
  1.1369 + 
  1.1370 + 
  1.1371 +-int lzma_uncompress(void *dest, void *src, int size, int block_size,
  1.1372 ++static int xz_uncompress(void *dest, void *src, int size, int block_size,
  1.1373 + 	int *error)
  1.1374 + {
  1.1375 +-	lzma_stream strm = LZMA_STREAM_INIT;
  1.1376 +-	int uncompressed_size = 0, res;
  1.1377 +-	unsigned char lzma_header[LZMA_HEADER_SIZE];
  1.1378 ++	size_t src_pos = 0;
  1.1379 ++	size_t dest_pos = 0;
  1.1380 ++	uint64_t memlimit = MEMLIMIT;
  1.1381 + 
  1.1382 +-	res = lzma_alone_decoder(&strm, MEMLIMIT);
  1.1383 +-	if(res != LZMA_OK) {
  1.1384 +-		lzma_end(&strm);
  1.1385 +-		goto failed;
  1.1386 +-	}
  1.1387 ++	lzma_ret res = lzma_stream_buffer_decode(&memlimit, 0, NULL,
  1.1388 ++			src, &src_pos, size, dest, &dest_pos, block_size);
  1.1389 + 
  1.1390 +-	memcpy(lzma_header, src, LZMA_HEADER_SIZE);
  1.1391 +-	uncompressed_size = lzma_header[LZMA_PROPS_SIZE] |
  1.1392 +-		(lzma_header[LZMA_PROPS_SIZE + 1] << 8) |
  1.1393 +-		(lzma_header[LZMA_PROPS_SIZE + 2] << 16) |
  1.1394 +-		(lzma_header[LZMA_PROPS_SIZE + 3] << 24);
  1.1395 +-	memset(lzma_header + LZMA_PROPS_SIZE, 255, LZMA_UNCOMP_SIZE);
  1.1396 ++	*error = res;
  1.1397 ++	return res == LZMA_OK && size == (int) src_pos ? (int) dest_pos : -1;
  1.1398 ++}
  1.1399 + 
  1.1400 +-	strm.next_out = dest;
  1.1401 +-	strm.avail_out = block_size;
  1.1402 +-	strm.next_in = lzma_header;
  1.1403 +-	strm.avail_in = LZMA_HEADER_SIZE;
  1.1404 + 
  1.1405 +-	res = lzma_code(&strm, LZMA_RUN);
  1.1406 ++struct compressor xz_comp_ops = {
  1.1407 ++	.init = xz_init,
  1.1408 ++	.compress = xz_compress,
  1.1409 ++	.uncompress = xz_uncompress,
  1.1410 ++	.options = xz_options,
  1.1411 ++	.usage = xz_usage,
  1.1412 ++	.id = XZ_COMPRESSION,
  1.1413 ++	.name = "xz",
  1.1414 ++	.supported = 1
  1.1415 ++};
  1.1416 + 
  1.1417 +-	if(res != LZMA_OK || strm.avail_in != 0) {
  1.1418 +-		lzma_end(&strm);
  1.1419 +-		goto failed;
  1.1420 +-	}
  1.1421 +-
  1.1422 +-	strm.next_in = src + LZMA_HEADER_SIZE;
  1.1423 +-	strm.avail_in = size - LZMA_HEADER_SIZE;
  1.1424 +-
  1.1425 +-	res = lzma_code(&strm, LZMA_FINISH);
  1.1426 +-	lzma_end(&strm);
  1.1427 +-
  1.1428 +-	if(res == LZMA_STREAM_END || (res == LZMA_OK &&
  1.1429 +-		strm.total_out >= uncompressed_size && strm.avail_in == 0))
  1.1430 +-		return uncompressed_size;
  1.1431 +-
  1.1432 +-failed:
  1.1433 +-	*error = res;
  1.1434 +-	return -1;
  1.1435 +-}