Changeset 18268


Ignore:
Timestamp:
2009-11-02T10:52:54+01:00 (7 years ago)
Author:
kaloz
Message:

sync mksquashfs4 with the CVS code to generate LZMA images

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/squashfs4/patches/110-lzma.patch

    r17585 r18268  
    1 Index: squashfs4.0/squashfs-tools/mksquashfs.c 
    2 =================================================================== 
    3 --- squashfs4.0.orig/squashfs-tools/mksquashfs.c        2009-04-05 23:22:48.000000000 +0200 
    4 +++ squashfs4.0/squashfs-tools/mksquashfs.c     2009-09-14 17:21:46.210480446 +0200 
    5 @@ -64,6 +64,18 @@ 
    6  #include "global.h" 
    7  #include "sort.h" 
    8  #include "pseudo.h" 
    9 +#include "uncompress.h" 
    10 + 
    11 +#ifdef USE_LZMA 
    12 +#include <LzmaEnc.h> 
    13 +#include <LzmaDec.h> 
    14 +#define LZMA_DEFAULT_LEVEL     5 
    15 +#define LZMA_DEFAULT_DICT      0 
    16 +#define LZMA_DEFAULT_LC        1 
    17 +#define LZMA_DEFAULT_LP        2 
    18 +#define LZMA_DEFAULT_PB 2 
    19 +#define LZMA_DEFAULT_FB 32 
    20 +#endif 
    21   
    22  #ifdef SQUASHFS_TRACE 
    23  #define TRACE(s, args...)      do { \ 
    24 @@ -830,6 +842,19 @@ 
    25         rotate = (rotate + 1) % 4; 
    26  } 
    27   
    28 +#ifdef USE_LZMA 
    29 +static void *lzma_malloc(void *p, size_t size) 
    30 +{ 
    31 +       (void)p; 
    32 +       return malloc(size); 
    33 +} 
    34 +static void lzma_free(void *p, void *addr) 
    35 +{ 
    36 +       (void)p; 
    37 +       free(addr); 
    38 +} 
    39 +static ISzAlloc lzma_alloc = { lzma_malloc, lzma_free }; 
    40 +#endif 
    41   
    42  unsigned int mangle2(z_stream **strm, char *d, char *s, int size, 
    43         int block_size, int uncompressed, int data_block) 
    44 @@ -841,6 +866,50 @@ 
    45         if(uncompressed) 
    46                 goto notcompressed; 
    47   
    48 +#ifdef USE_LZMA 
    49 +       if (compression == LZMA_COMPRESSION) { 
    50 +               size_t outsize = block_size - LZMA_PROPS_SIZE; 
    51 +               size_t propsize = LZMA_PROPS_SIZE; 
    52 +               CLzmaEncProps props; 
    53 + 
    54 +               LzmaEncProps_Init(&props); 
    55 +               props.level = LZMA_DEFAULT_LEVEL; 
    56 +               props.dictSize = LZMA_DEFAULT_DICT; 
    57 +               props.lc = LZMA_DEFAULT_LC; 
    58 +               props.lp = LZMA_DEFAULT_LP; 
    59 +               props.pb = LZMA_DEFAULT_PB; 
    60 +               props.fb = LZMA_DEFAULT_FB; 
    61 +               props.numThreads = 1; 
    62 + 
    63 +               res = LzmaEncode((unsigned char *) d + LZMA_PROPS_SIZE, &outsize, 
    64 +                       (unsigned char *) s, size, 
    65 +                       &props, (unsigned char *) d, &propsize, 
    66 +                       1, NULL, &lzma_alloc, &lzma_alloc); 
    67 +               switch(res) { 
    68 +               case SZ_OK: 
    69 +                       outsize += LZMA_PROPS_SIZE; 
    70 +                       break; 
    71 +               case SZ_ERROR_DATA: 
    72 +                       BAD_ERROR("lzma::compress failed, data error\n"); 
    73 +                       break; 
    74 +               case SZ_ERROR_MEM: 
    75 +                       BAD_ERROR("lzma::compress failed, memory allocation error\n"); 
    76 +                       break; 
    77 +               case SZ_ERROR_PARAM: 
    78 +                       BAD_ERROR("lzma::compress failed, invalid parameters\n"); 
    79 +                       break; 
    80 +               case SZ_ERROR_OUTPUT_EOF: 
    81 +                       goto notcompressed; 
    82 +               /* should not happen */ 
    83 +               default: 
    84 +                       BAD_ERROR("lzma::compress failed, unknown error (%d)\n", res); 
    85 +                       break; 
    86 +               } 
    87 + 
    88 +               return outsize; 
    89 +       } 
    90 +#endif 
    91 + 
    92         if(stream == NULL) { 
    93                 if((stream = *strm = malloc(sizeof(z_stream))) == NULL) 
    94                         BAD_ERROR("mangle::compress failed, not enough " 
    95 @@ -1669,17 +1738,17 @@ 
    96                 else 
    97                         data = read_from_disk(start_block, size); 
    98   
    99 -               res = uncompress((unsigned char *) buffer->data, &bytes, 
    100 +               res = uncompress_wrapper((unsigned char *) buffer->data, &bytes, 
    101                         (const unsigned char *) data, size); 
    102                 if(res != Z_OK) { 
    103                         if(res == Z_MEM_ERROR) 
    104 -                               BAD_ERROR("zlib::uncompress failed, not enough " 
    105 +                               BAD_ERROR("uncompress failed, not enough " 
    106                                         "memory\n"); 
    107                         else if(res == Z_BUF_ERROR) 
    108 -                               BAD_ERROR("zlib::uncompress failed, not enough " 
    109 +                               BAD_ERROR("uncompress failed, not enough " 
    110                                         "room in output buffer\n"); 
    111                         else 
    112 -                               BAD_ERROR("zlib::uncompress failed," 
    113 +                               BAD_ERROR("uncompress failed," 
    114                                         "  unknown error %d\n", res); 
    115                 } 
    116         } else if(compressed_buffer) 
    117 @@ -4282,6 +4351,10 @@ 
    118                                         argv[0]); 
    119                                 exit(1); 
    120                         } 
    121 +#ifdef USE_LZMA 
    122 +               } else if(strcmp(argv[i], "-lzma") == 0) { 
    123 +                       compression = LZMA_COMPRESSION; 
    124 +#endif 
    125                 } else if(strcmp(argv[i], "-ef") == 0) { 
    126                         if(++i == argc) { 
    127                                 ERROR("%s: -ef missing filename\n", argv[0]); 
    128 @@ -4410,6 +4483,9 @@ 
    129                         ERROR("-b <block_size>\t\tset data block to " 
    130                                 "<block_size>.  Default %d bytes\n", 
    131                                 SQUASHFS_FILE_SIZE); 
    132 +#ifdef USE_LZMA 
    133 +                       ERROR("-lzma Enable LZMA compression\n"); 
    134 +#endif 
    135                         ERROR("-processors <number>\tUse <number> processors." 
    136                                 "  By default will use number of\n"); 
    137                         ERROR("\t\t\tprocessors available\n"); 
    138 @@ -4804,7 +4880,7 @@ 
    139         sBlk.bytes_used = bytes; 
    140   
    141         /* Only compression supported */ 
    142 -       sBlk.compression = ZLIB_COMPRESSION; 
    143 +       sBlk.compression = compression; 
    144   
    145         /* Xattrs are not currently supported */ 
    146         sBlk.xattr_table_start = SQUASHFS_INVALID_BLK; 
    147 Index: squashfs4.0/squashfs-tools/squashfs_fs.h 
    148 =================================================================== 
    149 --- squashfs4.0.orig/squashfs-tools/squashfs_fs.h       2009-03-18 03:50:20.000000000 +0100 
    150 +++ squashfs4.0/squashfs-tools/squashfs_fs.h    2009-09-14 17:20:36.310480350 +0200 
    151 @@ -229,6 +229,7 @@ 
    152  typedef long long              squashfs_inode_t; 
    153   
    154  #define ZLIB_COMPRESSION       1 
    155 +#define LZMA_COMPRESSION       2 
    156   
    157  struct squashfs_super_block { 
    158         unsigned int            s_magic; 
    159 Index: squashfs4.0/squashfs-tools/Makefile 
    160 =================================================================== 
    161 --- squashfs4.0.orig/squashfs-tools/Makefile    2009-04-05 04:03:36.000000000 +0200 
    162 +++ squashfs4.0/squashfs-tools/Makefile 2009-09-14 17:20:36.310480350 +0200 
    163 @@ -4,14 +4,20 @@ 
    164   
    165  CFLAGS := -I$(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE -O2 
    166   
    167 +ifdef USE_LZMA 
    168 +  LZMA_CFLAGS = -DUSE_LZMA 
    169 +  LZMA_LIB = -llzma 
    170 +  CFLAGS += $(LZMA_CFLAGS) 
    171 +endif 
    172 + 
    173  all: mksquashfs unsquashfs 
    174   
    175 -mksquashfs: mksquashfs.o read_fs.o sort.o swap.o pseudo.o 
    176 -       $(CC) mksquashfs.o read_fs.o sort.o swap.o pseudo.o -lz -lpthread -lm -o $@ 
    177 +mksquashfs: mksquashfs.o read_fs.o sort.o swap.o pseudo.o uncompress.o 
    178 +       $(CC) mksquashfs.o read_fs.o sort.o swap.o pseudo.o uncompress.o -lz -lpthread -lm $(LZMA_LIB) -o $@ 
    179   
    180 -mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h squashfs_swap.h Makefile 
    181 +mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h squashfs_swap.h uncompress.h Makefile 
    182   
    183 -read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h squashfs_swap.h Makefile 
    184 +read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h squashfs_swap.h uncompress.h Makefile 
    185   
    186  sort.o: sort.c squashfs_fs.h global.h sort.h Makefile 
    187   
    188 @@ -19,18 +25,20 @@ 
    189   
    190  pseudo.o: pseudo.c pseudo.h Makefile 
    191   
    192 -unsquashfs: unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o 
    193 -       $(CC) unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o -lz -lpthread -lm -o $@ 
    194 +uncompress.o: uncompress.c uncompress.h 
    195 + 
    196 +unsquashfs: unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o uncompress.o 
    197 +       $(CC) unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o uncompress.o -lz -lpthread -lm $(LZMA_LIB) -o $@ 
    198   
    199 -unsquashfs.o: unsquashfs.h unsquashfs.c squashfs_fs.h squashfs_swap.h squashfs_compat.h global.h Makefile 
    200 +unsquashfs.o: unsquashfs.h unsquashfs.c squashfs_fs.h squashfs_swap.h squashfs_compat.h global.h uncompress.h Makefile 
    201   
    202 -unsquash-1.o: unsquashfs.h unsquash-1.c squashfs_fs.h squashfs_compat.h global.h Makefile 
    203 +unsquash-1.o: unsquashfs.h unsquash-1.c squashfs_fs.h squashfs_compat.h global.h uncompress.h Makefile 
    204   
    205 -unsquash-2.o: unsquashfs.h unsquash-2.c unsquashfs.h squashfs_fs.h squashfs_compat.h global.h Makefile 
    206 +unsquash-2.o: unsquashfs.h unsquash-2.c unsquashfs.h squashfs_fs.h squashfs_compat.h global.h uncompress.h Makefile 
    207   
    208 -unsquash-3.o: unsquashfs.h unsquash-3.c squashfs_fs.h squashfs_compat.h global.h Makefile 
    209 +unsquash-3.o: unsquashfs.h unsquash-3.c squashfs_fs.h squashfs_compat.h global.h uncompress.h Makefile 
    210   
    211 -unsquash-4.o: unsquashfs.h unsquash-4.c squashfs_fs.h squashfs_swap.h global.h Makefile 
    212 +unsquash-4.o: unsquashfs.h unsquash-4.c squashfs_fs.h squashfs_swap.h global.h uncompress.h Makefile 
    213   
    214  clean: 
    215         -rm -f *.o mksquashfs unsquashfs 
    216 Index: squashfs4.0/squashfs-tools/read_fs.c 
    217 =================================================================== 
    218 --- squashfs4.0.orig/squashfs-tools/read_fs.c   2009-03-31 06:23:14.000000000 +0200 
    219 +++ squashfs4.0/squashfs-tools/read_fs.c        2009-09-14 17:20:36.310480350 +0200 
    220 @@ -51,6 +51,7 @@ 
    221  #include "squashfs_swap.h" 
    222  #include "read_fs.h" 
    223  #include "global.h" 
    224 +#include "uncompress.h" 
    225   
    226  #include <stdlib.h> 
    227   
    228 @@ -83,17 +84,17 @@ 
    229                 c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); 
    230                 read_destination(fd, start + offset, c_byte, buffer); 
    231   
    232 -               res = uncompress(block, &bytes, (const unsigned char *) buffer, 
    233 -                       c_byte); 
    234 +               res = uncompress_wrapper(block, &bytes, 
    235 +                       (const unsigned char *) buffer, c_byte); 
    236                 if(res != Z_OK) { 
    237                         if(res == Z_MEM_ERROR) 
    238 -                               ERROR("zlib::uncompress failed, not enough " 
    239 +                               ERROR("uncompress failed, not enough " 
    240                                         "memory\n"); 
    241                         else if(res == Z_BUF_ERROR) 
    242 -                               ERROR("zlib::uncompress failed, not enough " 
    243 +                               ERROR("uncompress failed, not enough " 
    244                                         "room in output buffer\n"); 
    245                         else 
    246 -                               ERROR("zlib::uncompress failed, unknown error " 
    247 +                               ERROR("uncompress failed, unknown error " 
    248                                         "%d\n", res); 
    249                         return 0; 
    250                 } 
    251 Index: squashfs4.0/squashfs-tools/unsquashfs.c 
    252 =================================================================== 
    253 --- squashfs4.0.orig/squashfs-tools/unsquashfs.c        2009-04-05 23:23:06.000000000 +0200 
    254 +++ squashfs4.0/squashfs-tools/unsquashfs.c     2009-09-14 17:20:36.310480350 +0200 
    255 @@ -24,6 +24,7 @@ 
    256  #include "unsquashfs.h" 
    257  #include "squashfs_swap.h" 
    258  #include "squashfs_compat.h" 
    259 +#include "uncompress.h" 
    260  #include "read_fs.h" 
    261   
    262  struct cache *fragment_cache, *data_cache; 
    263 @@ -597,18 +598,17 @@ 
    264                 if(read_bytes(start + offset, c_byte, buffer) == FALSE) 
    265                         goto failed; 
    266   
    267 -               res = uncompress((unsigned char *) block, &bytes, 
    268 +               res = uncompress_wrapper((unsigned char *) block, &bytes, 
    269                         (const unsigned char *) buffer, c_byte); 
    270 - 
    271                 if(res != Z_OK) { 
    272                         if(res == Z_MEM_ERROR) 
    273 -                               ERROR("zlib::uncompress failed, not enough " 
    274 +                               ERROR("uncompress failed, not enough " 
    275                                         "memory\n"); 
    276                         else if(res == Z_BUF_ERROR) 
    277 -                               ERROR("zlib::uncompress failed, not enough " 
    278 +                               ERROR("uncompress failed, not enough " 
    279                                         "room in output buffer\n"); 
    280                         else 
    281 -                               ERROR("zlib::uncompress failed, unknown error " 
    282 +                               ERROR("uncompress failed, unknown error " 
    283                                         "%d\n", res); 
    284                         goto failed; 
    285                 } 
    286 @@ -645,18 +645,17 @@ 
    287                 if(read_bytes(start, c_byte, data) == FALSE) 
    288                         goto failed; 
    289   
    290 -               res = uncompress((unsigned char *) block, &bytes, 
    291 +               res = uncompress_wrapper((unsigned char *) block, &bytes, 
    292                         (const unsigned char *) data, c_byte); 
    293 - 
    294                 if(res != Z_OK) { 
    295                         if(res == Z_MEM_ERROR) 
    296 -                               ERROR("zlib::uncompress failed, not enough " 
    297 +                               ERROR("uncompress failed, not enough " 
    298                                         "memory\n"); 
    299                         else if(res == Z_BUF_ERROR) 
    300 -                               ERROR("zlib::uncompress failed, not enough " 
    301 +                               ERROR("uncompress failed, not enough " 
    302                                         "room in output buffer\n"); 
    303                         else 
    304 -                               ERROR("zlib::uncompress failed, unknown error " 
    305 +                               ERROR("uncompress failed, unknown error " 
    306                                         "%d\n", res); 
    307                         goto failed; 
    308                 } 
    309 @@ -1459,7 +1458,7 @@ 
    310                 s_ops.read_inode = read_inode_4; 
    311                 s_ops.read_uids_guids = read_uids_guids_4; 
    312                 memcpy(&sBlk, &sBlk_4, sizeof(sBlk_4)); 
    313 -               return TRUE; 
    314 +               goto done; 
    315         } 
    316   
    317         /* 
    318 @@ -1548,6 +1547,9 @@ 
    319                 goto failed_mount; 
    320         } 
    321   
    322 +done: 
    323 +       compression = sBlk.compression; 
    324 + 
    325         return TRUE; 
    326   
    327  failed_mount: 
    328 @@ -1710,19 +1712,19 @@ 
    329                 int res; 
    330                 unsigned long bytes = block_size; 
    331   
    332 -               res = uncompress((unsigned char *) tmp, &bytes, 
    333 +               res = uncompress_wrapper((unsigned char *) tmp, &bytes, 
    334                         (const unsigned char *) entry->data, 
    335                         SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size)); 
    336   
    337                 if(res != Z_OK) { 
    338                         if(res == Z_MEM_ERROR) 
    339 -                               ERROR("zlib::uncompress failed, not enough" 
    340 +                               ERROR("uncompress failed, not enough" 
    341                                         "memory\n"); 
    342                         else if(res == Z_BUF_ERROR) 
    343 -                               ERROR("zlib::uncompress failed, not enough " 
    344 +                               ERROR("uncompress failed, not enough " 
    345                                         "room in output buffer\n"); 
    346                         else 
    347 -                               ERROR("zlib::uncompress failed, unknown error " 
    348 +                               ERROR("uncompress failed, unknown error " 
    349                                         "%d\n", res); 
    350                 } else 
    351                         memcpy(entry->data, tmp, bytes); 
    352 Index: squashfs4.0/squashfs-tools/mksquashfs.h 
    353 =================================================================== 
    354 --- squashfs4.0.orig/squashfs-tools/mksquashfs.h        2009-02-19 19:31:08.000000000 +0100 
    355 +++ squashfs4.0/squashfs-tools/mksquashfs.h     2009-09-14 17:20:36.310480350 +0200 
    356 @@ -41,4 +41,9 @@ 
    357  #define SQUASHFS_SWAP_LONG_LONGS(s, d, n) \ 
    358                                         memcpy(d, s, n * sizeof(long long)) 
    359  #endif 
    360 + 
    361 +extern int uncompress_wrapper(unsigned char *dest, unsigned long *dest_len, 
    362 +    const unsigned char *src, unsigned long src_len); 
    363 + 
    364 + 
    365  #endif 
    366 Index: squashfs4.0/squashfs-tools/uncompress.c 
    367 =================================================================== 
    368 --- /dev/null   1970-01-01 00:00:00.000000000 +0000 
    369 +++ squashfs4.0/squashfs-tools/uncompress.c     2009-09-14 17:20:36.310480350 +0200 
    370 @@ -0,0 +1,58 @@ 
     1diff -Nur squashfs4.0/squashfs-tools/compressor.c squashfs4.0-lzma-snapshot/squashfs-tools/compressor.c 
     2--- squashfs4.0/squashfs-tools/compressor.c     1970-01-01 01:00:00.000000000 +0100 
     3+++ squashfs4.0-lzma-snapshot/squashfs-tools/compressor.c       2009-10-20 06:03:37.000000000 +0200 
     4@@ -0,0 +1,78 @@ 
    3715+/* 
    372 + * Copyright (c) 2009  Felix Fietkau <nbd@openwrt.org> 
     6+ * 
     7+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 
     8+ * Phillip Lougher <phillip@lougher.demon.co.uk> 
    3739+ * 
    37410+ * This program is free software; you can redistribute it and/or 
     
    38622+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
    38723+ * 
    388 + * uncompress.c 
     24+ * compressor.c 
    38925+ */ 
    39026+ 
    391 + 
    392 + 
    393 +#ifdef USE_LZMA 
    394 +#include <LzmaLib.h> 
     27+#include <stdio.h> 
     28+#include <string.h> 
     29+#include "compressor.h" 
     30+#include "squashfs_fs.h" 
     31+ 
     32+extern int gzip_compress(void **, char *, char *, int, int, int *); 
     33+extern int gzip_uncompress(char *, char *, int, int, int *); 
     34+extern int lzma_compress(void **, char *, char *, int, int, int *); 
     35+extern int lzma_uncompress(char *, char *, int, int, int *); 
     36+ 
     37+struct compressor compressor[] = { 
     38+       { gzip_compress, gzip_uncompress, ZLIB_COMPRESSION, "gzip", 1 }, 
     39+#ifdef LZMA_SUPPORT 
     40+       { lzma_compress, lzma_uncompress, LZMA_COMPRESSION, "lzma", 1 }, 
     41+#else 
     42+       { NULL, NULL, LZMA_COMPRESSION, "lzma", 0 }, 
    39543+#endif 
    396 +#include <zlib.h> 
    397 +#include "squashfs_fs.h" 
    398 + 
    399 +/* compression algorithm */ 
    400 +int compression = ZLIB_COMPRESSION; 
    401 + 
    402 + 
    403 +int uncompress_wrapper(unsigned char *dest, unsigned long *dest_len, 
    404 +       const unsigned char *src, unsigned long src_len) 
     44+       { NULL, NULL , 0, "unknown", 0} 
     45+}; 
     46+ 
     47+ 
     48+struct compressor *lookup_compressor(char *name) 
    40549+{ 
    406 +       int res; 
    407 + 
    408 +#ifdef USE_LZMA 
    409 +       if (compression == LZMA_COMPRESSION) { 
    410 +               size_t slen = src_len - LZMA_PROPS_SIZE; 
    411 +               res = LzmaUncompress((unsigned char *)dest, dest_len, 
    412 +                       (const unsigned char *) src + LZMA_PROPS_SIZE, &slen, 
    413 +                       (const unsigned char *) src, LZMA_PROPS_SIZE); 
    414 +               switch(res) { 
    415 +               case SZ_OK: 
    416 +                       res = Z_OK; 
     50+       int i; 
     51+ 
     52+       for(i = 0; compressor[i].id; i++) 
     53+               if(strcmp(compressor[i].name, name) == 0) 
    41754+                       break; 
    418 +               case SZ_ERROR_MEM: 
    419 +                       res = Z_MEM_ERROR; 
     55+ 
     56+       return &compressor[i]; 
     57+} 
     58+ 
     59+ 
     60+struct compressor *lookup_compressor_id(int id) 
     61+{ 
     62+       int i; 
     63+ 
     64+       for(i = 0; compressor[i].id; i++) 
     65+               if(id == compressor[i].id) 
    42066+                       break; 
    421 +               } 
    422 +       } else 
    423 +#endif 
    424 +       res = uncompress(dest, dest_len, src, src_len); 
    425 +       return res; 
     67+ 
     68+       return &compressor[i]; 
    42669+} 
    42770+ 
    42871+ 
    429 Index: squashfs4.0/squashfs-tools/uncompress.h 
    430 =================================================================== 
    431 --- /dev/null   1970-01-01 00:00:00.000000000 +0000 
    432 +++ squashfs4.0/squashfs-tools/uncompress.h     2009-09-14 17:20:36.310480350 +0200 
    433 @@ -0,0 +1,29 @@ 
     72+void display_compressors(char *indent, char *def_comp) 
     73+{ 
     74+       int i; 
     75+ 
     76+       for(i = 0; compressor[i].id; i++) 
     77+               if(compressor[i].supported) 
     78+                       fprintf(stderr, "%s\t%s%s\n", indent, 
     79+                               compressor[i].name, 
     80+                               strcmp(compressor[i].name, def_comp) == 0 ? 
     81+                               " (default)" : ""); 
     82+} 
     83diff -Nur squashfs4.0/squashfs-tools/compressor.h squashfs4.0-lzma-snapshot/squashfs-tools/compressor.h 
     84--- squashfs4.0/squashfs-tools/compressor.h     1970-01-01 01:00:00.000000000 +0100 
     85+++ squashfs4.0-lzma-snapshot/squashfs-tools/compressor.h       2009-10-20 06:03:37.000000000 +0200 
     86@@ -0,0 +1,33 @@ 
    43487+/* 
    435 + * Copyright (c) 2009  Felix Fietkau <nbd@openwrt.org> 
     88+ * 
     89+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 
     90+ * Phillip Lougher <phillip@lougher.demon.co.uk> 
    43691+ * 
    43792+ * This program is free software; you can redistribute it and/or 
     
    449104+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
    450105+ * 
    451 + * uncompress.h 
     106+ * compressor.h 
    452107+ */ 
    453108+ 
    454 +#ifdef USE_LZMA 
     109+struct compressor { 
     110+       int (*compress)(void **, char *, char *, int, int, int *); 
     111+       int (*uncompress)(char *, char *, int, int, int *); 
     112+       int id; 
     113+       char *name; 
     114+       int supported; 
     115+}; 
     116+ 
     117+extern struct compressor *lookup_compressor(char *); 
     118+extern struct compressor *lookup_compressor_id(int); 
     119+extern void display_compressors(char *, char *); 
     120diff -Nur squashfs4.0/squashfs-tools/gzip_wrapper.c squashfs4.0-lzma-snapshot/squashfs-tools/gzip_wrapper.c 
     121--- squashfs4.0/squashfs-tools/gzip_wrapper.c   1970-01-01 01:00:00.000000000 +0100 
     122+++ squashfs4.0-lzma-snapshot/squashfs-tools/gzip_wrapper.c     2009-10-20 06:03:37.000000000 +0200 
     123@@ -0,0 +1,80 @@ 
     124+/* 
     125+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 
     126+ * Phillip Lougher <phillip@lougher.demon.co.uk> 
     127+ * 
     128+ * This program is free software; you can redistribute it and/or 
     129+ * modify it under the terms of the GNU General Public License 
     130+ * as published by the Free Software Foundation; either version 2, 
     131+ * or (at your option) any later version. 
     132+ * 
     133+ * This program is distributed in the hope that it will be useful, 
     134+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 
     135+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     136+ * GNU General Public License for more details. 
     137+ * 
     138+ * You should have received a copy of the GNU General Public License 
     139+ * along with this program; if not, write to the Free Software 
     140+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
     141+ * 
     142+ * gzip_wrapper.c 
     143+ */ 
     144+ 
     145+#include <stdlib.h> 
     146+#include <zlib.h> 
     147+ 
     148+int gzip_compress(void **strm, char *d, char *s, int size, int block_size, 
     149+               int *error) 
     150+{ 
     151+       int res = 0; 
     152+       z_stream *stream = *strm; 
     153+ 
     154+       if(stream == NULL) { 
     155+               if((stream = *strm = malloc(sizeof(z_stream))) == NULL) 
     156+                       goto failed; 
     157+ 
     158+               stream->zalloc = Z_NULL; 
     159+               stream->zfree = Z_NULL; 
     160+               stream->opaque = 0; 
     161+ 
     162+               if((res = deflateInit(stream, 9)) != Z_OK) 
     163+                       goto failed; 
     164+       } else if((res = deflateReset(stream)) != Z_OK) 
     165+               goto failed; 
     166+ 
     167+       stream->next_in = (unsigned char *) s; 
     168+       stream->avail_in = size; 
     169+       stream->next_out = (unsigned char *) d; 
     170+       stream->avail_out = block_size; 
     171+ 
     172+       res = deflate(stream, Z_FINISH); 
     173+       if(res == Z_STREAM_END) 
     174+               /* 
     175+                * Success, return the compressed size. 
     176+                */ 
     177+               return (int) stream->total_out; 
     178+       if(res == Z_OK) 
     179+               /* 
     180+                * Output buffer overflow.  Return out of buffer space 
     181+                */ 
     182+               return 0; 
     183+failed: 
     184+       /* 
     185+        * All other errors return failure, with the compressor 
     186+        * specific error code in *error 
     187+        */ 
     188+       *error = res; 
     189+       return -1; 
     190+} 
     191+ 
     192+ 
     193+int gzip_uncompress(char *d, char *s, int size, int block_size, int *error) 
     194+{ 
     195+       int res; 
     196+       unsigned long bytes = block_size; 
     197+ 
     198+       res = uncompress((unsigned char *) d, &bytes, 
     199+               (const unsigned char *) s, size); 
     200+ 
     201+       *error = res; 
     202+       return res == Z_OK ? (int) bytes : -1; 
     203+} 
     204diff -Nur squashfs4.0/squashfs-tools/lzma_wrapper.c squashfs4.0-lzma-snapshot/squashfs-tools/lzma_wrapper.c 
     205--- squashfs4.0/squashfs-tools/lzma_wrapper.c   1970-01-01 01:00:00.000000000 +0100 
     206+++ squashfs4.0-lzma-snapshot/squashfs-tools/lzma_wrapper.c     2009-10-14 05:32:57.000000000 +0200 
     207@@ -0,0 +1,93 @@ 
     208+/* 
     209+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 
     210+ * Phillip Lougher <phillip@lougher.demon.co.uk> 
     211+ * 
     212+ * This program is free software; you can redistribute it and/or 
     213+ * modify it under the terms of the GNU General Public License 
     214+ * as published by the Free Software Foundation; either version 2, 
     215+ * or (at your option) any later version. 
     216+ * 
     217+ * This program is distributed in the hope that it will be useful, 
     218+ * but WITHOUT ANY WARRANTY; without even the implied warranty of 
     219+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     220+ * GNU General Public License for more details. 
     221+ * 
     222+ * You should have received a copy of the GNU General Public License 
     223+ * along with this program; if not, write to the Free Software 
     224+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
     225+ * 
     226+ * lzma_wrapper.c 
     227+ */ 
     228+ 
    455229+#include <LzmaLib.h> 
     230+ 
     231+#define LZMA_HEADER_SIZE       (LZMA_PROPS_SIZE + 8) 
     232+ 
     233+int lzma_compress(void **strm, char *dest, char *src,  int size,int block_size, 
     234+               int *error) 
     235+{ 
     236+       unsigned char *d = (unsigned char *) dest, *s = (unsigned char *) src; 
     237+       size_t props_size = LZMA_PROPS_SIZE, 
     238+               outlen = block_size - LZMA_HEADER_SIZE; 
     239+       int res; 
     240+ 
     241+       res = LzmaCompress(d + LZMA_HEADER_SIZE, &outlen, s, size, d, 
     242+               &props_size, 5, block_size, 3, 0, 2, 32, 1); 
     243+        
     244+       if(res == SZ_ERROR_OUTPUT_EOF) { 
     245+               /* 
     246+                * Output buffer overflow.  Return out of buffer space error 
     247+                */ 
     248+               return 0; 
     249+       } 
     250+ 
     251+       if(res != SZ_OK) { 
     252+               /* 
     253+                * All other errors return failure, with the compressor 
     254+                * specific error code in *error 
     255+                */ 
     256+               *error = res; 
     257+               return -1; 
     258+       } 
     259+ 
     260+       /* 
     261+        * Fill in the 8 byte little endian uncompressed size field in the 
     262+        * LZMA header.  8 bytes is excessively large for squashfs but 
     263+        * this is the standard LZMA header and which is expected by the kernel 
     264+        * code 
     265+        */ 
     266+       d[LZMA_PROPS_SIZE] = size & 255; 
     267+       d[LZMA_PROPS_SIZE + 1] = (size >> 8) & 255; 
     268+       d[LZMA_PROPS_SIZE + 2] = (size >> 16) & 255; 
     269+       d[LZMA_PROPS_SIZE + 3] = (size >> 24) & 255; 
     270+       d[LZMA_PROPS_SIZE + 4] = 0; 
     271+       d[LZMA_PROPS_SIZE + 5] = 0; 
     272+       d[LZMA_PROPS_SIZE + 6] = 0; 
     273+       d[LZMA_PROPS_SIZE + 7] = 0; 
     274+ 
     275+       /* 
     276+        * Success, return the compressed size.  Outlen returned by the LZMA 
     277+        * compressor does not include the LZMA header space 
     278+        */ 
     279+       return outlen + LZMA_HEADER_SIZE; 
     280+} 
     281+ 
     282+ 
     283+int lzma_uncompress(char *dest, char *src, int size, int block_size, 
     284+       int *error) 
     285+{ 
     286+       unsigned char *d = (unsigned char *) dest, *s = (unsigned char *) src; 
     287+       size_t outlen, inlen = size - LZMA_HEADER_SIZE; 
     288+       int res; 
     289+ 
     290+       outlen = s[LZMA_PROPS_SIZE] | 
     291+               (s[LZMA_PROPS_SIZE + 1] << 8) | 
     292+               (s[LZMA_PROPS_SIZE + 2] << 16) | 
     293+               (s[LZMA_PROPS_SIZE + 3] << 24); 
     294+ 
     295+       res = LzmaUncompress(d, &outlen, s + LZMA_HEADER_SIZE, &inlen, 
     296+               s, LZMA_PROPS_SIZE); 
     297+        
     298+       *error = res; 
     299+       return res == SZ_OK ? outlen : -1; 
     300+} 
     301diff -Nur squashfs4.0/squashfs-tools/Makefile squashfs4.0-lzma-snapshot/squashfs-tools/Makefile 
     302--- squashfs4.0/squashfs-tools/Makefile 2009-04-05 04:03:36.000000000 +0200 
     303+++ squashfs4.0-lzma-snapshot/squashfs-tools/Makefile   2009-10-22 06:17:12.000000000 +0200 
     304@@ -1,40 +1,76 @@ 
     305+# 
     306+# Building LZMA support 
     307+# Download LZMA sdk (4.65 used in development, other versions may work), 
     308+# set LZMA_DIR to unpacked source, and uncomment next line 
     309+LZMA_SUPPORT = 1 
     310+LZMA_DIR = ../../lzma-4.65 
     311+ 
     312+#Compression default. 
     313+COMP_DEFAULT = gzip 
     314+ 
     315+INCLUDEDIR = -I. 
     316 INSTALL_DIR = /usr/local/bin 
     317  
     318-INCLUDEDIR = . 
     319+MKSQUASHFS_OBJS = mksquashfs.o read_fs.o sort.o swap.o pseudo.o compressor.o \ 
     320+       gzip_wrapper.o 
     321+ 
     322+UNSQUASHFS_OBJS = unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o \ 
     323+       unsquash-4.o swap.o compressor.o gzip_wrapper.o 
     324  
     325-CFLAGS := -I$(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE -O2 
     326+CFLAGS = $(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ 
     327+       -D_GNU_SOURCE -DCOMP_DEFAULT=\"$(COMP_DEFAULT)\" -O2 -Wall 
     328  
     329+ifdef LZMA_SUPPORT 
     330+LZMA_OBJS = $(LZMA_DIR)/C/Alloc.o $(LZMA_DIR)/C/LzFind.o \ 
     331+       $(LZMA_DIR)/C/LzmaDec.o $(LZMA_DIR)/C/LzmaEnc.o $(LZMA_DIR)/C/LzmaLib.o 
     332+INCLUDEDIR += -I$(LZMA_DIR)/C 
     333+CFLAGS += -DLZMA_SUPPORT 
     334+MKSQUASHFS_OBJS += lzma_wrapper.o $(LZMA_OBJS) 
     335+UNSQUASHFS_OBJS += lzma_wrapper.o $(LZMA_OBJS) 
     336+endif 
     337+ 
     338+.PHONY: all 
     339 all: mksquashfs unsquashfs 
     340  
     341-mksquashfs: mksquashfs.o read_fs.o sort.o swap.o pseudo.o 
     342-       $(CC) mksquashfs.o read_fs.o sort.o swap.o pseudo.o -lz -lpthread -lm -o $@ 
     343+mksquashfs: $(MKSQUASHFS_OBJS) 
     344+       $(CC) $(MKSQUASHFS_OBJS) -lz -lpthread -lm -o $@ 
     345+ 
     346+mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h \ 
     347+       squashfs_swap.h 
     348  
     349-mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h squashfs_swap.h Makefile 
     350+read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h squashfs_swap.h 
     351  
     352-read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h squashfs_swap.h Makefile 
     353+sort.o: sort.c squashfs_fs.h global.h sort.h 
     354  
     355-sort.o: sort.c squashfs_fs.h global.h sort.h Makefile 
     356+swap.o: swap.c 
     357  
     358-swap.o: swap.c Makefile 
     359+pseudo.o: pseudo.c pseudo.h 
     360  
     361-pseudo.o: pseudo.c pseudo.h Makefile 
     362+compressor.o: compressor.c compressor.h 
     363  
     364-unsquashfs: unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o 
     365-       $(CC) unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o -lz -lpthread -lm -o $@ 
     366+unsquashfs: $(UNSQUASHFS_OBJS) 
     367+       $(CC) $(UNSQUASHFS_OBJS) -lz -lpthread -lm -o $@ 
     368  
     369-unsquashfs.o: unsquashfs.h unsquashfs.c squashfs_fs.h squashfs_swap.h squashfs_compat.h global.h Makefile 
     370+unsquashfs.o: unsquashfs.h unsquashfs.c squashfs_fs.h squashfs_swap.h \ 
     371+       squashfs_compat.h global.h 
     372  
     373-unsquash-1.o: unsquashfs.h unsquash-1.c squashfs_fs.h squashfs_compat.h global.h Makefile 
     374+unsquash-1.o: unsquashfs.h unsquash-1.c squashfs_fs.h squashfs_compat.h \ 
     375+       global.h 
     376  
     377-unsquash-2.o: unsquashfs.h unsquash-2.c unsquashfs.h squashfs_fs.h squashfs_compat.h global.h Makefile 
     378+unsquash-2.o: unsquashfs.h unsquash-2.c unsquashfs.h squashfs_fs.h \ 
     379+       squashfs_compat.h global.h 
     380  
     381-unsquash-3.o: unsquashfs.h unsquash-3.c squashfs_fs.h squashfs_compat.h global.h Makefile 
     382+unsquash-3.o: unsquashfs.h unsquash-3.c squashfs_fs.h squashfs_compat.h \ 
     383+       global.h 
     384  
     385-unsquash-4.o: unsquashfs.h unsquash-4.c squashfs_fs.h squashfs_swap.h global.h Makefile 
     386+unsquash-4.o: unsquashfs.h unsquash-4.c squashfs_fs.h squashfs_swap.h \ 
     387+       global.h 
     388  
     389+.PHONY: clean 
     390 clean: 
     391        -rm -f *.o mksquashfs unsquashfs 
     392  
     393+.PHONY: install 
     394 install: mksquashfs unsquashfs 
     395        mkdir -p $(INSTALL_DIR) 
     396        cp mksquashfs $(INSTALL_DIR) 
     397diff -Nur squashfs4.0/squashfs-tools/mksquashfs.c squashfs4.0-lzma-snapshot/squashfs-tools/mksquashfs.c 
     398--- squashfs4.0/squashfs-tools/mksquashfs.c     2009-04-05 23:22:48.000000000 +0200 
     399+++ squashfs4.0-lzma-snapshot/squashfs-tools/mksquashfs.c       2009-10-20 06:03:38.000000000 +0200 
     400@@ -36,7 +36,6 @@ 
     401 #include <errno.h> 
     402 #include <dirent.h> 
     403 #include <string.h> 
     404-#include <zlib.h> 
     405 #include <stdlib.h> 
     406 #include <signal.h> 
     407 #include <setjmp.h> 
     408@@ -47,6 +46,7 @@ 
     409 #include <math.h> 
     410 #include <regex.h> 
     411 #include <fnmatch.h> 
     412+#include <sys/wait.h> 
     413  
     414 #ifndef linux 
     415 #define __BYTE_ORDER BYTE_ORDER 
     416@@ -64,6 +64,7 @@ 
     417 #include "global.h" 
     418 #include "sort.h" 
     419 #include "pseudo.h" 
     420+#include "compressor.h" 
     421  
     422 #ifdef SQUASHFS_TRACE 
     423 #define TRACE(s, args...)      do { \ 
     424@@ -245,10 +246,8 @@ 
     425 /* list of root directory entries read from original filesystem */ 
     426 int old_root_entries = 0; 
     427 struct old_root_entry_info { 
     428-       char                    name[SQUASHFS_NAME_LEN + 1]; 
     429-       squashfs_inode          inode; 
     430-       int                     type; 
     431-       int                     inode_number; 
     432+       char                    *name; 
     433+       struct inode_info       inode; 
     434 }; 
     435 struct old_root_entry_info *old_root_entry; 
     436  
     437@@ -371,10 +370,15 @@ 
     438 int reader_buffer_size; 
     439 int fragment_buffer_size; 
     440  
     441+/* compression operations structure */ 
     442+static struct compressor *comp; 
     443+char *comp_name = COMP_DEFAULT; 
     444+ 
     445 char *read_from_disk(long long start, unsigned int avail_bytes); 
     446 void add_old_root_entry(char *name, squashfs_inode inode, int inode_number, 
     447        int type); 
     448-extern int read_super(int fd, squashfs_super_block *sBlk, char *source); 
     449+extern struct compressor  *read_super(int fd, squashfs_super_block *sBlk, 
     450+       char *source); 
     451 extern long long read_filesystem(char *root_name, int fd, 
     452        squashfs_super_block *sBlk, char **cinode_table, char **data_cache, 
     453        char **cdirectory_table, char **directory_data_cache, 
     454@@ -831,83 +835,32 @@ 
     455 } 
     456  
     457  
     458-unsigned int mangle2(z_stream **strm, char *d, char *s, int size, 
     459+int mangle2(void **strm, char *d, char *s, int size, 
     460        int block_size, int uncompressed, int data_block) 
     461 { 
     462-       unsigned long c_byte; 
     463-       unsigned int res; 
     464-       z_stream *stream = *strm; 
     465- 
     466-       if(uncompressed) 
     467-               goto notcompressed; 
     468- 
     469-       if(stream == NULL) { 
     470-               if((stream = *strm = malloc(sizeof(z_stream))) == NULL) 
     471-                       BAD_ERROR("mangle::compress failed, not enough " 
     472-                               "memory\n"); 
     473- 
     474-               stream->zalloc = Z_NULL; 
     475-               stream->zfree = Z_NULL; 
     476-               stream->opaque = 0; 
     477- 
     478-               if((res = deflateInit(stream, 9)) != Z_OK) { 
     479-                       if(res == Z_MEM_ERROR) 
     480-                               BAD_ERROR("zlib::compress failed, not enough " 
     481-                                       "memory\n"); 
     482-                       else if(res == Z_STREAM_ERROR) 
     483-                               BAD_ERROR("zlib::compress failed, not a valid " 
     484-                                       "compression level\n"); 
     485-                       else if(res == Z_VERSION_ERROR) 
     486-                               BAD_ERROR("zlib::compress failed, incorrect " 
     487-                                       "zlib version\n"); 
     488-                       else 
     489-                               BAD_ERROR("zlib::compress failed, unknown " 
     490-                                       "error %d\n", res); 
     491-               } 
     492-       } else if((res = deflateReset(stream)) != Z_OK) { 
     493-               if(res == Z_STREAM_ERROR) 
     494-                       BAD_ERROR("zlib::compress failed, stream state " 
     495-                               "inconsistent\n"); 
     496-               else 
     497-                       BAD_ERROR("zlib::compress failed, unknown error %d\n", 
     498-                               res); 
     499-       } 
     500+       int error, c_byte = 0; 
     501  
     502-       stream->next_in = (unsigned char *) s; 
     503-       stream->avail_in = size; 
     504-       stream->next_out = (unsigned char *) d; 
     505-       stream->avail_out = block_size; 
     506- 
     507-       res = deflate(stream, Z_FINISH); 
     508-       if(res != Z_STREAM_END && res != Z_OK) { 
     509-               if(res == Z_STREAM_ERROR) 
     510-                       BAD_ERROR("zlib::compress failed, stream state " 
     511-                               "inconsistent\n"); 
     512-               else if(res == Z_BUF_ERROR) 
     513-                       BAD_ERROR("zlib::compress failed, no progress possible" 
     514-                               "\n"); 
     515-               else 
     516-                       BAD_ERROR("zlib::compress failed, unknown error %d\n", 
     517-                               res); 
     518+       if(!uncompressed) { 
     519+               c_byte = comp->compress(strm, d, s, size, block_size, &error); 
     520+               if(c_byte == -1) 
     521+                       BAD_ERROR("mangle2:: %s compress failed with error " 
     522+                               "code %d\n", comp->name, error); 
     523        } 
     524  
     525-       c_byte = stream->total_out; 
     526- 
     527-       if(res != Z_STREAM_END || c_byte >= size) { 
     528-notcompressed: 
     529+       if(c_byte == 0 || c_byte >= size) { 
     530                memcpy(d, s, size); 
     531                return size | (data_block ? SQUASHFS_COMPRESSED_BIT_BLOCK : 
     532                        SQUASHFS_COMPRESSED_BIT); 
     533        } 
     534  
     535-       return (unsigned int) c_byte; 
     536+       return c_byte; 
     537 } 
     538  
     539  
     540-unsigned int mangle(char *d, char *s, int size, int block_size, 
     541+int mangle(char *d, char *s, int size, int block_size, 
     542        int uncompressed, int data_block) 
     543 { 
     544-       static z_stream *stream = NULL; 
     545+       static void *stream = NULL; 
     546  
     547        return mangle2(&stream, d, s, size, block_size, uncompressed, 
     548                data_block); 
     549@@ -1660,8 +1613,7 @@ 
     550        pthread_mutex_unlock(&fragment_mutex); 
     551  
     552        if(SQUASHFS_COMPRESSED_BLOCK(disk_fragment->size)) { 
     553-               int res; 
     554-               unsigned long bytes = block_size; 
     555+               int error, res; 
     556                char *data; 
     557  
     558                if(compressed_buffer) 
     559@@ -1669,19 +1621,11 @@ 
     560                else 
     561                        data = read_from_disk(start_block, size); 
     562  
     563-               res = uncompress((unsigned char *) buffer->data, &bytes, 
     564-                       (const unsigned char *) data, size); 
     565-               if(res != Z_OK) { 
     566-                       if(res == Z_MEM_ERROR) 
     567-                               BAD_ERROR("zlib::uncompress failed, not enough " 
     568-                                       "memory\n"); 
     569-                       else if(res == Z_BUF_ERROR) 
     570-                               BAD_ERROR("zlib::uncompress failed, not enough " 
     571-                                       "room in output buffer\n"); 
     572-                       else 
     573-                               BAD_ERROR("zlib::uncompress failed," 
     574-                                       "  unknown error %d\n", res); 
     575-               } 
     576+               res = comp->uncompress(buffer->data, data, size, block_size, 
     577+                       &error); 
     578+               if(res == -1) 
     579+                       BAD_ERROR("%s uncompress failed with error code %d\n", 
     580+                               comp->name, error); 
     581        } else if(compressed_buffer) 
     582                memcpy(buffer->data, compressed_buffer->data, size); 
     583        else 
     584@@ -1733,9 +1677,7 @@ 
     585                entry->buffer->block = bytes; 
     586                bytes += compressed_size; 
     587                fragments_outstanding --; 
     588-               pthread_mutex_unlock(&fragment_mutex); 
     589                queue_put(to_writer, entry->buffer); 
     590-               pthread_mutex_lock(&fragment_mutex); 
     591                TRACE("fragment_locked writing fragment %d, compressed size %d" 
     592                        "\n", entry->fragment, compressed_size); 
     593                free(entry); 
     594@@ -1758,6 +1700,8 @@ 
     595        pthread_mutex_lock(&fragment_mutex); 
     596        insert_fragment_list(&frag_locked_list, entry); 
     597        pthread_mutex_unlock(&fragment_mutex); 
     598+ 
     599+       return TRUE; 
     600 } 
     601  
     602  
     603@@ -1824,7 +1768,9 @@ 
     604        unsigned short c_byte; 
     605        char cbuffer[(SQUASHFS_METADATA_SIZE << 2) + 2]; 
     606         
     607+#ifdef SQUASHFS_TRACE 
     608        long long obytes = bytes; 
    456609+#endif 
    457 + 
    458 +extern int compression; 
    459 +extern int uncompress_wrapper(unsigned char *dest, unsigned long *dest_len, 
    460 +    const unsigned char *src, unsigned long src_len); 
    461 + 
    462 + 
     610  
     611        for(i = 0; i < meta_blocks; i++) { 
     612                int avail_bytes = length > SQUASHFS_METADATA_SIZE ? 
     613@@ -2170,11 +2116,85 @@ 
     614 } 
     615  
     616  
     617+static int seq = 0; 
     618+void reader_read_process(struct dir_ent *dir_ent) 
     619+{ 
     620+       struct file_buffer *prev_buffer = NULL, *file_buffer; 
     621+       int status, res, byte, count = 0; 
     622+       int file = get_pseudo_file(dir_ent->inode->pseudo_id)->fd; 
     623+       int child = get_pseudo_file(dir_ent->inode->pseudo_id)->child; 
     624+       long long bytes = 0; 
     625+ 
     626+       while(1) { 
     627+               file_buffer = cache_get(reader_buffer, 0, 0); 
     628+               file_buffer->sequence = seq ++; 
     629+ 
     630+               byte = read_bytes(file, file_buffer->data, block_size); 
     631+               if(byte == -1) 
     632+                       goto read_err; 
     633+ 
     634+               file_buffer->size = byte; 
     635+               file_buffer->file_size = -1; 
     636+               file_buffer->block = count ++; 
     637+               file_buffer->error = FALSE; 
     638+               file_buffer->fragment = FALSE; 
     639+               bytes += byte; 
     640+ 
     641+               if(byte == 0) 
     642+                       break; 
     643+ 
     644+               /* 
     645+                * Update estimated_uncompressed block count.  This is done 
     646+                * on every block rather than waiting for all blocks to be 
     647+                * read incase write_file_process() is running in parallel 
     648+                * with this.  Otherwise cur uncompressed block count may 
     649+                * get ahead of the total uncompressed block count. 
     650+                */  
     651+               estimated_uncompressed ++; 
     652+ 
     653+               if(prev_buffer) 
     654+                       queue_put(from_reader, prev_buffer); 
     655+               prev_buffer = file_buffer; 
     656+       } 
     657+ 
     658+       /* 
     659+        * Update inode file size now that the size of the dynamic pseudo file 
     660+        * is known.  This is needed for the -info option. 
     661+        */ 
     662+       dir_ent->inode->buf.st_size = bytes; 
     663+ 
     664+       res = waitpid(child, &status, 0); 
     665+       if(res == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) 
     666+               goto read_err; 
     667+ 
     668+       if(prev_buffer == NULL) 
     669+               prev_buffer = file_buffer; 
     670+       else { 
     671+               cache_block_put(file_buffer); 
     672+               seq --; 
     673+       } 
     674+       prev_buffer->file_size = bytes; 
     675+       prev_buffer->fragment = !no_fragments && 
     676+               (count == 2 || always_use_fragments) && (byte < block_size); 
     677+       queue_put(from_reader, prev_buffer); 
     678+ 
     679+       return; 
     680+ 
     681+read_err: 
     682+       if(prev_buffer) { 
     683+               cache_block_put(file_buffer); 
     684+               seq --; 
     685+               file_buffer = prev_buffer; 
     686+       } 
     687+       file_buffer->error = TRUE; 
     688+       queue_put(from_deflate, file_buffer); 
     689+} 
     690+ 
     691+ 
     692 void reader_read_file(struct dir_ent *dir_ent) 
     693 { 
     694        struct stat *buf = &dir_ent->inode->buf, buf2; 
     695        struct file_buffer *file_buffer; 
     696-       static int index = 0; 
     697        int blocks, byte, count, expected, file, frag_block; 
     698        long long bytes, read_size; 
     699  
     700@@ -2202,7 +2222,7 @@ 
     701                if(file_buffer) 
     702                        queue_put(from_reader, file_buffer); 
     703                file_buffer = cache_get(reader_buffer, 0, 0); 
     704-               file_buffer->sequence = index ++; 
     705+               file_buffer->sequence = seq ++; 
     706  
     707                byte = file_buffer->size = read_bytes(file, file_buffer->data, 
     708                        block_size); 
     709@@ -2238,7 +2258,7 @@ 
     710  
     711 read_err: 
     712        file_buffer = cache_get(reader_buffer, 0, 0); 
     713-       file_buffer->sequence = index ++; 
     714+       file_buffer->sequence = seq ++; 
     715 read_err2: 
     716        file_buffer->error = TRUE; 
     717        queue_put(from_deflate, file_buffer); 
     718@@ -2262,9 +2282,14 @@ 
     719        for(i = 0; i < dir->count; i++) { 
     720                struct dir_ent *dir_ent = dir->list[i]; 
     721                struct stat *buf = &dir_ent->inode->buf; 
     722-               if(dir_ent->data) 
     723+               if(dir_ent->inode->root_entry) 
     724                        continue; 
     725  
     726+               if(dir_ent->inode->pseudo_file) { 
     727+                       reader_read_process(dir_ent); 
     728+                       continue; 
     729+               } 
     730+ 
     731                switch(buf->st_mode & S_IFMT) { 
     732                        case S_IFREG: 
     733                                reader_read_file(dir_ent); 
     734@@ -2365,7 +2390,7 @@ 
     735  
     736 void *deflator(void *arg) 
     737 { 
     738-       z_stream *stream = NULL; 
     739+       void *stream = NULL; 
     740        int oldstate; 
     741  
     742        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); 
     743@@ -2402,7 +2427,7 @@ 
     744  
     745 void *frag_deflator(void *arg) 
     746 { 
     747-       z_stream *stream = NULL; 
     748+       void *stream = NULL; 
     749        int oldstate; 
     750  
     751        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); 
     752@@ -2426,8 +2451,8 @@ 
     753                        write_buffer->block = bytes; 
     754                        bytes += compressed_size; 
     755                        fragments_outstanding --; 
     756-                       pthread_mutex_unlock(&fragment_mutex); 
     757                        queue_put(to_writer, write_buffer); 
     758+                       pthread_mutex_unlock(&fragment_mutex); 
     759                        TRACE("Writing fragment %lld, uncompressed size %d, " 
     760                                "compressed size %d\n", file_buffer->block, 
     761                                file_buffer->size, compressed_size); 
     762@@ -2674,6 +2699,98 @@ 
     763 } 
     764  
     765  
     766+int write_file_process(squashfs_inode *inode, struct dir_ent *dir_ent, 
     767+       struct file_buffer *read_buffer, int *duplicate_file) 
     768+{ 
     769+       long long read_size, file_bytes, start; 
     770+       struct fragment *fragment; 
     771+       unsigned int *block_list = NULL; 
     772+       int block = 0, status; 
     773+       long long sparse = 0; 
     774+       struct file_buffer *fragment_buffer = NULL; 
     775+ 
     776+       *duplicate_file = FALSE; 
     777+ 
     778+       lock_fragments(); 
     779+ 
     780+       file_bytes = 0; 
     781+       start = bytes; 
     782+       while (1) { 
     783+               read_size = read_buffer->file_size; 
     784+               if(read_buffer->fragment && read_buffer->c_byte) 
     785+                       fragment_buffer = read_buffer; 
     786+               else { 
     787+                       block_list = realloc(block_list, (block + 1) * 
     788+                               sizeof(unsigned int)); 
     789+                       if(block_list == NULL) 
     790+                               BAD_ERROR("Out of memory allocating block_list" 
     791+                                       "\n"); 
     792+                       block_list[block ++] = read_buffer->c_byte; 
     793+                       if(read_buffer->c_byte) { 
     794+                               read_buffer->block = bytes; 
     795+                               bytes += read_buffer->size; 
     796+                               cache_rehash(read_buffer, read_buffer->block); 
     797+                               file_bytes += read_buffer->size; 
     798+                               queue_put(to_writer, read_buffer); 
     799+                       } else { 
     800+                               sparse += read_buffer->size; 
     801+                               cache_block_put(read_buffer); 
     802+                       } 
     803+               } 
     804+               inc_progress_bar(); 
     805+ 
     806+               if(read_size != -1) 
     807+                       break; 
     808+ 
     809+               read_buffer = get_file_buffer(from_deflate); 
     810+               if(read_buffer->error) 
     811+                       goto read_err; 
     812+       } 
     813+ 
     814+       unlock_fragments(); 
     815+       fragment = get_and_fill_fragment(fragment_buffer); 
     816+       cache_block_put(fragment_buffer); 
     817+ 
     818+       if(duplicate_checking) 
     819+               add_non_dup(read_size, file_bytes, block_list, start, fragment, 
     820+                       0, 0, FALSE); 
     821+       file_count ++; 
     822+       total_bytes += read_size; 
     823+ 
     824+       if(read_size < (1LL << 32) && start < (1LL << 32) && sparse == 0) 
     825+               create_inode(inode, dir_ent, SQUASHFS_FILE_TYPE, read_size, 
     826+                       start, block, block_list, fragment, NULL, 0); 
     827+       else 
     828+               create_inode(inode, dir_ent, SQUASHFS_LREG_TYPE, read_size, 
     829+                       start, block, block_list, fragment, NULL, sparse); 
     830+ 
     831+       if(duplicate_checking == FALSE) 
     832+               free(block_list); 
     833+ 
     834+       return 0; 
     835+ 
     836+read_err: 
     837+       cur_uncompressed -= block; 
     838+       status = read_buffer->error; 
     839+       bytes = start; 
     840+       if(!block_device) { 
     841+               int res; 
     842+ 
     843+               queue_put(to_writer, NULL); 
     844+               if(queue_get(from_writer) != 0) 
     845+                       EXIT_MKSQUASHFS(); 
     846+               res = ftruncate(fd, bytes); 
     847+               if(res != 0) 
     848+                       BAD_ERROR("Failed to truncate dest file because %s\n", 
     849+                               strerror(errno)); 
     850+       } 
     851+       unlock_fragments(); 
     852+       free(block_list); 
     853+       cache_block_put(read_buffer); 
     854+       return status; 
     855+} 
     856+ 
     857+ 
     858 int write_file_blocks(squashfs_inode *inode, struct dir_ent *dir_ent, 
     859        long long read_size, struct file_buffer *read_buffer, 
     860        int *duplicate_file) 
     861@@ -2941,7 +3058,10 @@ 
     862         
     863        read_size = read_buffer->file_size; 
     864  
     865-       if(read_size == 0) { 
     866+       if(read_size == -1) 
     867+               status = write_file_process(inode, dir_ent, read_buffer, 
     868+                       duplicate_file); 
     869+       else if(read_size == 0) { 
     870                write_file_empty(inode, dir_ent, duplicate_file); 
     871                cache_block_put(read_buffer); 
     872        } else if(read_buffer->fragment && read_buffer->c_byte) 
     873@@ -3036,6 +3156,8 @@ 
     874  
     875        memcpy(&inode->buf, buf, sizeof(struct stat)); 
     876        inode->read = FALSE; 
     877+       inode->root_entry = FALSE; 
     878+       inode->pseudo_file = FALSE; 
     879        inode->inode = SQUASHFS_INVALID_BLK; 
     880        inode->nlink = 1; 
     881  
     882@@ -3056,7 +3178,7 @@ 
     883  
     884  
     885 inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir, 
     886-       struct inode_info *inode_info, void *data, struct dir_info *dir) 
     887+       struct inode_info *inode_info, struct dir_info *dir) 
     888 { 
     889        if((dir->count % DIR_ENTRIES) == 0) { 
     890                dir->list = realloc(dir->list, (dir->count + DIR_ENTRIES) * 
     891@@ -3075,8 +3197,7 @@ 
     892                NULL; 
     893        dir->list[dir->count]->inode = inode_info; 
     894        dir->list[dir->count]->dir = sub_dir; 
     895-       dir->list[dir->count]->our_dir = dir; 
     896-       dir->list[dir->count++]->data = data; 
     897+       dir->list[dir->count++]->our_dir = dir; 
     898        dir->byte_count += strlen(name) + sizeof(squashfs_dir_entry); 
     899 } 
     900  
     901@@ -3128,10 +3249,10 @@ 
     902  
     903        if(dir->count < old_root_entries) 
     904                for(i = 0; i < old_root_entries; i++) { 
     905-                       if(old_root_entry[i].type == SQUASHFS_DIR_TYPE) 
     906+                       if(old_root_entry[i].inode.type == SQUASHFS_DIR_TYPE) 
     907                                dir->directory_count ++; 
     908-                       add_dir_entry(old_root_entry[i].name, "", NULL, NULL, 
     909-                               &old_root_entry[i], dir); 
     910+                       add_dir_entry(old_root_entry[i].name, "", NULL, 
     911+                               &old_root_entry[i].inode, dir); 
     912                } 
     913  
     914        while(index < source) { 
     915@@ -3167,10 +3288,10 @@ 
     916  
     917        if(dir->count < old_root_entries) 
     918                for(i = 0; i < old_root_entries; i++) { 
     919-                       if(old_root_entry[i].type == SQUASHFS_DIR_TYPE) 
     920+                       if(old_root_entry[i].inode.type == SQUASHFS_DIR_TYPE) 
     921                                dir->directory_count ++; 
     922-                       add_dir_entry(old_root_entry[i].name, "", NULL, NULL, 
     923-                               &old_root_entry[i], dir); 
     924+                       add_dir_entry(old_root_entry[i].name, "", NULL, 
     925+                               &old_root_entry[i].inode, dir); 
     926                } 
     927  
     928        if((d_name = readdir(dir->linuxdir)) != NULL) { 
     929@@ -3215,7 +3336,7 @@ 
     930        int current_count; 
     931  
     932        while((current_count = dir_info->current_count++) < dir_info->count) 
     933-               if(dir_info->list[current_count]->data) 
     934+               if(dir_info->list[current_count]->inode->root_entry) 
     935                        continue; 
     936                else  
     937                        return dir_info->list[current_count]; 
     938@@ -3240,11 +3361,11 @@ 
     939        int current_count; 
     940  
     941        while((current_count = dir_info->current_count++) < dir_info->count) 
     942-               if(dir_info->list[current_count]->data) 
     943-                       add_dir(dir_info->list[current_count]->data->inode, 
     944-                               dir_info->list[current_count]->data->inode_number, 
     945+               if(dir_info->list[current_count]->inode->root_entry) 
     946+                       add_dir(dir_info->list[current_count]->inode->inode, 
     947+                               dir_info->list[current_count]->inode->inode_number, 
     948                                dir_info->list[current_count]->name, 
     949-                               dir_info->list[current_count]->data->type, dir); 
     950+                               dir_info->list[current_count]->inode->type, dir); 
     951                else  
     952                        return dir_info->list[current_count]; 
     953        return NULL;     
     954@@ -3313,7 +3434,6 @@ 
     955        dir_ent->name = dir_ent->pathname = strdup(pathname); 
     956        dir_ent->dir = dir_info; 
     957        dir_ent->our_dir = NULL; 
     958-       dir_ent->data = NULL; 
     959        dir_info->dir_ent = dir_ent; 
     960  
     961        if(sorted) 
     962@@ -3383,7 +3503,7 @@ 
     963                        sub_dir = NULL; 
     964  
     965                add_dir_entry(dir_name, filename, sub_dir, lookup_inode(&buf), 
     966-                       NULL, dir); 
     967+                       dir); 
     968        } 
     969  
     970        scan1_freedir(dir); 
     971@@ -3399,7 +3519,7 @@ 
     972        struct dir_ent *dir_ent; 
     973        struct pseudo_entry *pseudo_ent; 
     974        struct stat buf; 
     975-       static pseudo_ino = 1; 
     976+       static int pseudo_ino = 1; 
     977         
     978        if(dir == NULL && (dir = scan1_opendir("")) == NULL) 
     979                return NULL; 
     980@@ -3415,6 +3535,29 @@ 
     981  
     982        while((pseudo_ent = pseudo_readdir(pseudo)) != NULL) { 
     983                dir_ent = scan2_lookup(dir, pseudo_ent->name); 
     984+               if(pseudo_ent->dev->type == 's') { 
     985+                       struct stat *buf; 
     986+                       if(dir_ent == NULL) { 
     987+                               ERROR("Pseudo set file \"%s\" does not exist " 
     988+                                       "in source filesystem.  Ignoring\n", 
     989+                                       pseudo_ent->pathname); 
     990+                               continue; 
     991+                       } 
     992+                       if(dir_ent->inode->root_entry) { 
     993+                               ERROR("Pseudo set file \"%s\" is a pre-existing" 
     994+                                       " file in the filesystem being appended" 
     995+                                       "  to.  It cannot be modified. " 
     996+                                       "Ignoring!\n", pseudo_ent->pathname); 
     997+                               continue; 
     998+                       } 
     999+                       buf = &dir_ent->inode->buf; 
     1000+                       buf->st_mode = (buf->st_mode & S_IFMT) | 
     1001+                               pseudo_ent->dev->mode; 
     1002+                       buf->st_uid = pseudo_ent->dev->uid; 
     1003+                       buf->st_gid = pseudo_ent->dev->gid; 
     1004+                       continue; 
     1005+               } 
     1006+ 
     1007                if(dir_ent) { 
     1008                        ERROR("Pseudo file \"%s\" exists in source filesystem " 
     1009                                "\"%s\"\n", pseudo_ent->pathname, 
     1010@@ -3444,8 +3587,29 @@ 
     1011                buf.st_mtime = time(NULL); 
     1012                buf.st_ino = pseudo_ino ++; 
     1013  
     1014-               add_dir_entry(pseudo_ent->name, pseudo_ent->pathname, sub_dir, 
     1015-                       lookup_inode(&buf), NULL, dir); 
     1016+               if(pseudo_ent->dev->type == 'f') { 
     1017+#ifdef USE_TMP_FILE 
     1018+                       struct stat buf2; 
     1019+                       int res = stat(pseudo_ent->dev->filename, &buf2); 
     1020+                       if(res == -1) { 
     1021+                               ERROR("Stat on pseudo file \"%s\" failed, " 
     1022+                                       "skipping...", pseudo_ent->pathname); 
     1023+                               continue; 
     1024+                       } 
     1025+                       buf.st_size = buf2.st_size; 
     1026+                       add_dir_entry(pseudo_ent->name, 
     1027+                               pseudo_ent->dev->filename, sub_dir, 
     1028+                               lookup_inode(&buf), dir); 
     1029+#else 
     1030+                       struct inode_info *inode = lookup_inode(&buf); 
     1031+                       inode->pseudo_id = pseudo_ent->dev->pseudo_id; 
     1032+                       inode->pseudo_file = TRUE;               
     1033+                       add_dir_entry(pseudo_ent->name, pseudo_ent->pathname, 
     1034+                               sub_dir, inode, dir); 
     1035+#endif 
     1036+               } else 
     1037+                       add_dir_entry(pseudo_ent->name, pseudo_ent->pathname, 
     1038+                               sub_dir, lookup_inode(&buf), dir); 
     1039        } 
     1040  
     1041        scan2_freedir(dir); 
     1042@@ -3482,8 +3646,9 @@ 
     1043                                                &duplicate_file); 
     1044                                        INFO("file %s, uncompressed size %lld " 
     1045                                                "bytes %s\n", filename, 
     1046-                                               buf->st_size, duplicate_file ? 
     1047-                                               "DUPLICATE" : ""); 
     1048+                                               (long long) buf->st_size, 
     1049+                                               duplicate_file ?  "DUPLICATE" : 
     1050+                                                ""); 
     1051                                        break; 
     1052  
     1053                                case S_IFDIR: 
     1054@@ -3557,6 +3722,7 @@ 
     1055                                                INFO("file %s, uncompressed " 
     1056                                                        "size %lld bytes LINK" 
     1057                                                        "\n", filename, 
     1058+                                                       (long long) 
     1059                                                        buf->st_size); 
     1060                                        break; 
     1061                                case SQUASHFS_SYMLINK_TYPE: 
     1062@@ -3667,10 +3833,11 @@ 
     1063                BAD_ERROR("Out of memory in old root directory entries " 
     1064                        "reallocation\n"); 
     1065  
     1066-       strcpy(old_root_entry[old_root_entries].name, name); 
     1067-       old_root_entry[old_root_entries].inode = inode; 
     1068-       old_root_entry[old_root_entries].inode_number = inode_number; 
     1069-       old_root_entry[old_root_entries++].type = type; 
     1070+       old_root_entry[old_root_entries].name = strdup(name); 
     1071+       old_root_entry[old_root_entries].inode.inode = inode; 
     1072+       old_root_entry[old_root_entries].inode.inode_number = inode_number; 
     1073+       old_root_entry[old_root_entries].inode.type = type; 
     1074+       old_root_entry[old_root_entries++].inode.root_entry = TRUE; 
     1075 } 
     1076  
     1077  
     1078@@ -4137,7 +4304,7 @@ 
     1079  
     1080  
     1081 #define VERSION() \ 
     1082-       printf("mksquashfs version 4.0 (2009/04/05)\n");\ 
     1083+       printf("mksquashfs version 4.1-CVS (2009/09/20)\n");\ 
     1084        printf("copyright (C) 2009 Phillip Lougher <phillip@lougher.demon.co.uk>\n\n"); \ 
     1085        printf("This program is free software; you can redistribute it and/or\n");\ 
     1086        printf("modify it under the terms of the GNU General Public License\n");\ 
     1087@@ -4172,26 +4339,28 @@ 
     1088        source_path = argv + 1; 
     1089        source = i - 2; 
     1090        for(; i < argc; i++) { 
     1091-               if(strcmp(argv[i], "-pf") == 0) { 
     1092+               if(strcmp(argv[i], "-comp") == 0) { 
     1093                        if(++i == argc) { 
     1094-                               ERROR("%s: -pf missing filename\n", argv[0]); 
     1095+                               ERROR("%s: -comp missing compression type\n", 
     1096+                                       argv[0]); 
     1097                                exit(1); 
     1098                        } 
     1099-                       if(read_pseudo_file(&pseudo, argv[i]) == FALSE) { 
     1100-                               ERROR("Failed to parse pseudo file \"%s\"\n", 
     1101-                                       argv[i]); 
     1102+                       comp_name = argv[i]; 
     1103+               } else if(strcmp(argv[i], "-pf") == 0) { 
     1104+                       if(++i == argc) { 
     1105+                               ERROR("%s: -pf missing filename\n", argv[0]); 
     1106                                exit(1); 
     1107                        } 
     1108+                       if(read_pseudo_file(&pseudo, argv[i]) == FALSE) 
     1109+                               exit(1); 
     1110                } else if(strcmp(argv[i], "-p") == 0) { 
     1111                        if(++i == argc) { 
     1112                                ERROR("%s: -p missing pseudo file definition\n", 
     1113                                        argv[0]); 
     1114                                exit(1); 
     1115                        } 
     1116-                       if(read_pseudo_def(&pseudo, argv[i]) == FALSE) { 
     1117-                               ERROR("Failed to parse pseudo definition\n"); 
     1118+                       if(read_pseudo_def(&pseudo, argv[i]) == FALSE) 
     1119                                exit(1); 
     1120-                       } 
     1121                } else if(strcmp(argv[i], "-recover") == 0) { 
     1122                        if(++i == argc) { 
     1123                                ERROR("%s: -recover missing recovery file\n", 
     1124@@ -4394,34 +4563,16 @@ 
     1125 printOptions: 
     1126                        ERROR("SYNTAX:%s source1 source2 ...  dest [options] " 
     1127                                "[-e list of exclude\ndirs/files]\n", argv[0]); 
     1128-                       ERROR("\nOptions are\n"); 
     1129-                       ERROR("-version\t\tprint version, licence and " 
     1130-                               "copyright message\n"); 
     1131-                       ERROR("-recover <name>\t\trecover filesystem data " 
     1132-                               "using recovery file <name>\n"); 
     1133-                       ERROR("-no-recovery\t\tdon't generate a recovery " 
     1134-                               "file\n"); 
     1135-                       ERROR("-info\t\t\tprint files written to filesystem\n"); 
     1136-                       ERROR("-no-exports\t\tdon't make the filesystem " 
     1137-                               "exportable via NFS\n"); 
     1138-                       ERROR("-no-progress\t\tdon't display the progress " 
     1139-                               "bar\n"); 
     1140-                       ERROR("-no-sparse\t\tdon't detect sparse files\n"); 
     1141+                       ERROR("\nFilesystem build options:\n"); 
     1142+                       ERROR("-comp <comp>\t\tselect <comp> compression\n"); 
     1143+                       ERROR("\t\t\tCompressors available:\n"); 
     1144+                       display_compressors("\t\t\t", COMP_DEFAULT); 
     1145                        ERROR("-b <block_size>\t\tset data block to " 
     1146                                "<block_size>.  Default %d bytes\n", 
     1147                                SQUASHFS_FILE_SIZE); 
     1148-                       ERROR("-processors <number>\tUse <number> processors." 
     1149-                               "  By default will use number of\n"); 
     1150-                       ERROR("\t\t\tprocessors available\n"); 
     1151-                       ERROR("-read-queue <size>\tSet input queue to <size> " 
     1152-                               "Mbytes.  Default %d Mbytes\n", 
     1153-                               READER_BUFFER_DEFAULT); 
     1154-                       ERROR("-write-queue <size>\tSet output queue to <size> " 
     1155-                               "Mbytes.  Default %d Mbytes\n", 
     1156-                               WRITER_BUFFER_DEFAULT); 
     1157-                       ERROR("-fragment-queue <size>\tSet fagment queue to " 
     1158-                               "<size> Mbytes.  Default %d Mbytes\n", 
     1159-                               FRAGMENT_BUFFER_DEFAULT); 
     1160+                       ERROR("-no-exports\t\tdon't make the filesystem " 
     1161+                               "exportable via NFS\n"); 
     1162+                       ERROR("-no-sparse\t\tdon't detect sparse files\n"); 
     1163                        ERROR("-noI\t\t\tdo not compress inode table\n"); 
     1164                        ERROR("-noD\t\t\tdo not compress data blocks\n"); 
     1165                        ERROR("-noF\t\t\tdo not compress fragment blocks\n"); 
     1166@@ -4430,13 +4581,34 @@ 
     1167                                "files larger than block size\n"); 
     1168                        ERROR("-no-duplicates\t\tdo not perform duplicate " 
     1169                                "checking\n"); 
     1170-                       ERROR("-noappend\t\tdo not append to existing " 
     1171-                               "filesystem\n"); 
     1172+                       ERROR("-all-root\t\tmake all files owned by root\n"); 
     1173+                       ERROR("-force-uid uid\t\tset all file uids to uid\n"); 
     1174+                       ERROR("-force-gid gid\t\tset all file gids to gid\n"); 
     1175+                       ERROR("-nopad\t\t\tdo not pad filesystem to a multiple " 
     1176+                               "of 4K\n"); 
     1177                        ERROR("-keep-as-directory\tif one source directory is " 
     1178                                "specified, create a root\n"); 
     1179                        ERROR("\t\t\tdirectory containing that directory, " 
     1180                                "rather than the\n"); 
     1181                        ERROR("\t\t\tcontents of the directory\n"); 
     1182+                       ERROR("\nFilesystem filter options:\n"); 
     1183+                       ERROR("-p <pseudo-definition>\tAdd pseudo file definition\n"); 
     1184+                       ERROR("-pf <pseudo-file>\tAdd list of pseudo file definitions\n"); 
     1185+                       ERROR("-sort <sort_file>\tsort files according to " 
     1186+                               "priorities in <sort_file>.  One\n"); 
     1187+                       ERROR("\t\t\tfile or dir with priority per line.  " 
     1188+                               "Priority -32768 to\n"); 
     1189+                       ERROR("\t\t\t32767, default priority 0\n"); 
     1190+                       ERROR("-ef <exclude_file>\tlist of exclude dirs/files." 
     1191+                               "  One per line\n"); 
     1192+                       ERROR("-wildcards\t\tAllow extended shell wildcards " 
     1193+                               "(globbing) to be used in\n\t\t\texclude " 
     1194+                               "dirs/files\n"); 
     1195+                       ERROR("-regex\t\t\tAllow POSIX regular expressions to " 
     1196+                               "be used in exclude\n\t\t\tdirs/files\n"); 
     1197+                       ERROR("\nFilesystem append options:\n"); 
     1198+                       ERROR("-noappend\t\tdo not append to existing " 
     1199+                               "filesystem\n"); 
     1200                        ERROR("-root-becomes <name>\twhen appending source " 
     1201                                "files/directories, make the\n"); 
     1202                        ERROR("\t\t\toriginal root become a subdirectory in " 
     1203@@ -4444,11 +4616,29 @@ 
     1204                        ERROR("\t\t\tcalled <name>, rather than adding the new " 
     1205                                "source items\n"); 
     1206                        ERROR("\t\t\tto the original root\n"); 
     1207-                       ERROR("-all-root\t\tmake all files owned by root\n"); 
     1208-                       ERROR("-force-uid uid\t\tset all file uids to uid\n"); 
     1209-                       ERROR("-force-gid gid\t\tset all file gids to gid\n"); 
     1210-                       ERROR("-nopad\t\t\tdo not pad filesystem to a multiple " 
     1211-                               "of 4K\n"); 
     1212+                       ERROR("\nMksquashfs runtime options:\n"); 
     1213+                       ERROR("-version\t\tprint version, licence and " 
     1214+                               "copyright message\n"); 
     1215+                       ERROR("-recover <name>\t\trecover filesystem data " 
     1216+                               "using recovery file <name>\n"); 
     1217+                       ERROR("-no-recovery\t\tdon't generate a recovery " 
     1218+                               "file\n"); 
     1219+                       ERROR("-info\t\t\tprint files written to filesystem\n"); 
     1220+                       ERROR("-no-progress\t\tdon't display the progress " 
     1221+                               "bar\n"); 
     1222+                       ERROR("-processors <number>\tUse <number> processors." 
     1223+                               "  By default will use number of\n"); 
     1224+                       ERROR("\t\t\tprocessors available\n"); 
     1225+                       ERROR("-read-queue <size>\tSet input queue to <size> " 
     1226+                               "Mbytes.  Default %d Mbytes\n", 
     1227+                               READER_BUFFER_DEFAULT); 
     1228+                       ERROR("-write-queue <size>\tSet output queue to <size> " 
     1229+                               "Mbytes.  Default %d Mbytes\n", 
     1230+                               WRITER_BUFFER_DEFAULT); 
     1231+                       ERROR("-fragment-queue <size>\tSet fagment queue to " 
     1232+                               "<size> Mbytes.  Default %d Mbytes\n", 
     1233+                               FRAGMENT_BUFFER_DEFAULT); 
     1234+                       ERROR("\nMiscellaneous options:\n"); 
     1235                        ERROR("-root-owned\t\talternative name for -all-root" 
     1236                                "\n"); 
     1237                        ERROR("-noInodeCompression\talternative name for -noI" 
     1238@@ -4457,20 +4647,6 @@ 
     1239                                "\n"); 
     1240                        ERROR("-noFragmentCompression\talternative name for " 
     1241                                "-noF\n"); 
     1242-                       ERROR("-sort <sort_file>\tsort files according to " 
     1243-                               "priorities in <sort_file>.  One\n"); 
     1244-                       ERROR("\t\t\tfile or dir with priority per line.  " 
     1245-                               "Priority -32768 to\n"); 
     1246-                       ERROR("\t\t\t32767, default priority 0\n"); 
     1247-                       ERROR("-ef <exclude_file>\tlist of exclude dirs/files." 
     1248-                               "  One per line\n"); 
     1249-                       ERROR("-wildcards\t\tAllow extended shell wildcards " 
     1250-                               "(globbing) to be used in\n\t\t\texclude " 
     1251-                               "dirs/files\n"); 
     1252-                       ERROR("-regex\t\t\tAllow POSIX regular expressions to " 
     1253-                               "be used in exclude\n\t\t\tdirs/files\n"); 
     1254-                       ERROR("-p <pseudo-definition>\tAdd pseudo file definition\n"); 
     1255-                       ERROR("-pf <pseudo-file>\tAdd list of pseudo file definitions\n"); 
     1256                        exit(1); 
     1257                } 
     1258        } 
     1259@@ -4548,11 +4724,10 @@ 
     1260                        fclose(fd); 
     1261                } else if(strcmp(argv[i], "-e") == 0) 
     1262                        break; 
     1263-               else if(strcmp(argv[i], "-b") == 0 || 
     1264-                               strcmp(argv[i], "-root-becomes") == 0 || 
     1265+               else if(strcmp(argv[i], "-root-becomes") == 0 || 
     1266                                strcmp(argv[i], "-sort") == 0 || 
     1267                                strcmp(argv[i], "-pf") == 0 || 
     1268-                               strcmp(argv[i], "-p") == 0) 
     1269+                               strcmp(argv[i], "-comp") == 0) 
     1270                        i++; 
     1271  
     1272        if(i != argc) { 
     1273@@ -4574,11 +4749,10 @@ 
     1274                        sorted ++; 
     1275                } else if(strcmp(argv[i], "-e") == 0) 
     1276                        break; 
     1277-               else if(strcmp(argv[i], "-b") == 0 || 
     1278-                               strcmp(argv[i], "-root-becomes") == 0 || 
     1279+               else if(strcmp(argv[i], "-root-becomes") == 0 || 
     1280                                strcmp(argv[i], "-ef") == 0 || 
     1281                                strcmp(argv[i], "-pf") == 0 || 
     1282-                               strcmp(argv[i], "-p") == 0) 
     1283+                               strcmp(argv[i], "-comp") == 0) 
     1284                        i++; 
     1285  
     1286 #ifdef SQUASHFS_TRACE 
     1287@@ -4586,7 +4760,8 @@ 
     1288 #endif 
     1289  
     1290        if(!delete) { 
     1291-               if(read_super(fd, &sBlk, argv[source + 1]) == 0) { 
     1292+               comp = read_super(fd, &sBlk, argv[source + 1]); 
     1293+               if(comp == NULL) { 
     1294                        ERROR("Failed to read existing filesystem - will not " 
     1295                                "overwrite - ABORTING!\n"); 
     1296                        ERROR("To force Mksquashfs to write to this block " 
     1297@@ -4603,6 +4778,15 @@ 
     1298                always_use_fragments = SQUASHFS_ALWAYS_FRAGMENTS(sBlk.flags); 
     1299                duplicate_checking = SQUASHFS_DUPLICATES(sBlk.flags); 
     1300                exportable = SQUASHFS_EXPORTABLE(sBlk.flags); 
     1301+       } else { 
     1302+               comp = lookup_compressor(comp_name); 
     1303+               if(!comp->supported) { 
     1304+                       ERROR("FATAL_ERROR: Compressor \"%s\" is not " 
     1305+                               "supported!\n", comp_name); 
     1306+                       ERROR("Compressors available:\n"); 
     1307+                       display_compressors("", COMP_DEFAULT); 
     1308+                       EXIT_MKSQUASHFS(); 
     1309+               } 
     1310        } 
     1311  
     1312        initialise_threads(); 
     1313@@ -4648,8 +4832,8 @@ 
     1314                        "size %d\n", SQUASHFS_MAJOR, s_minor, argv[source + 1], 
     1315                        block_size); 
     1316                printf("All -b, -noI, -noD, -noF, no-duplicates, no-fragments, " 
     1317-                       "-always-use-fragments and -exportable options ignored" 
     1318-                       "\n"); 
     1319+                       "-always-use-fragments,\n-exportable and -comp options " 
     1320+                       "ignored\n"); 
     1321                printf("\nIf appending is not wanted, please re-run with " 
     1322                        "-noappend specified!\n\n"); 
     1323  
     1324@@ -4803,8 +4987,7 @@ 
     1325  
     1326        sBlk.bytes_used = bytes; 
     1327  
     1328-       /* Only compression supported */ 
     1329-       sBlk.compression = ZLIB_COMPRESSION; 
     1330+       sBlk.compression = comp->id; 
     1331  
     1332        /* Xattrs are not currently supported */ 
     1333        sBlk.xattr_table_start = SQUASHFS_INVALID_BLK; 
     1334@@ -4820,6 +5003,8 @@ 
     1335  
     1336        close(fd); 
     1337  
     1338+       delete_pseudo_files(); 
     1339+ 
     1340        if(recovery_file[0] != '\0') 
     1341                unlink(recovery_file); 
     1342  
     1343@@ -4827,9 +5012,9 @@ 
     1344                * sizeof(unsigned short) + guid_count * sizeof(unsigned short) + 
     1345                sizeof(squashfs_super_block); 
     1346  
     1347-       printf("\n%sSquashfs %d.%d filesystem, data block size %d\n", 
     1348-               exportable ? "Exportable " : "", SQUASHFS_MAJOR, SQUASHFS_MINOR, 
     1349-               block_size); 
     1350+       printf("\n%sSquashfs %d.%d filesystem, %s compressed, data block size" 
     1351+               " %d\n", exportable ? "Exportable " : "", SQUASHFS_MAJOR, 
     1352+               SQUASHFS_MINOR, comp->name, block_size); 
     1353        printf("\t%s data, %s metadata, %s fragments\n", 
     1354                noD ? "uncompressed" : "compressed", noI ?  "uncompressed" : 
     1355                "compressed", no_fragments ? "no" : noF ? "uncompressed" : 
     1356diff -Nur squashfs4.0/squashfs-tools/pseudo.c squashfs4.0-lzma-snapshot/squashfs-tools/pseudo.c 
     1357--- squashfs4.0/squashfs-tools/pseudo.c 2009-04-05 04:01:58.000000000 +0200 
     1358+++ squashfs4.0-lzma-snapshot/squashfs-tools/pseudo.c   2009-10-20 06:03:38.000000000 +0200 
     1359@@ -30,6 +30,7 @@ 
     1360 #include <string.h> 
     1361 #include <stdlib.h> 
     1362 #include <sys/types.h> 
     1363+#include <sys/wait.h> 
     1364  
     1365 #include "pseudo.h" 
     1366  
     1367@@ -55,6 +56,9 @@ 
     1368 #define TRUE 1 
     1369 #define FALSE 0 
     1370  
     1371+struct pseudo_dev **pseudo_file = NULL; 
     1372+int pseudo_count = 0; 
     1373+ 
     1374 static void dump_pseudo(struct pseudo *pseudo, char *string) 
     1375 { 
     1376        int i; 
     1377@@ -99,7 +103,7 @@ 
     1378        char *target, char *alltarget) 
     1379 { 
     1380        char targname[1024]; 
     1381-       int i, error; 
     1382+       int i; 
     1383  
     1384        target = get_component(target, targname); 
     1385  
     1386@@ -128,12 +132,8 @@ 
     1387                if(target[0] == '\0') { 
     1388                        /* at leaf pathname component */ 
     1389                        pseudo->name[i].pseudo = NULL; 
     1390-                       pseudo->name[i].dev = malloc(sizeof(struct pseudo_dev)); 
     1391-                       if(pseudo->name[i].dev == NULL) 
     1392-                               BAD_ERROR("failed to allocate pseudo file\n"); 
     1393                        pseudo->name[i].pathname = strdup(alltarget); 
     1394-                       memcpy(pseudo->name[i].dev, pseudo_dev, 
     1395-                               sizeof(struct pseudo_dev)); 
     1396+                       pseudo->name[i].dev = pseudo_dev; 
     1397                } else { 
     1398                        /* recurse adding child components */ 
     1399                        pseudo->name[i].dev = NULL; 
     1400@@ -169,15 +169,9 @@ 
     1401                        if(target[0] == '\0') { 
     1402                                if(pseudo->name[i].dev == NULL && 
     1403                                                pseudo_dev->type == 'd') { 
     1404-                                       pseudo->name[i].dev = 
     1405-                                               malloc(sizeof(struct pseudo_dev)); 
     1406-                                       if(pseudo->name[i].dev == NULL) 
     1407-                                               BAD_ERROR("failed to allocate " 
     1408-                                                       "pseudo file\n"); 
     1409                                        pseudo->name[i].pathname = 
     1410                                                strdup(alltarget); 
     1411-                                       memcpy(pseudo->name[i].dev, pseudo_dev, 
     1412-                                               sizeof(struct pseudo_dev)); 
     1413+                                       pseudo->name[i].dev = pseudo_dev; 
     1414                                } else 
     1415                                        ERROR("%s already exists as a " 
     1416                                                "directory.  Ignoring %s!\n", 
     1417@@ -229,16 +223,113 @@ 
     1418 } 
     1419  
     1420  
     1421+int exec_file(char *command, struct pseudo_dev *dev) 
     1422+{ 
     1423+       int child, res; 
     1424+       static pid_t pid = -1; 
     1425+       int pipefd[2]; 
     1426+#ifdef USE_TMP_FILE 
     1427+       char filename[1024]; 
     1428+       int status; 
     1429+       static int number = 0; 
     1430+#endif 
     1431+ 
     1432+       if(pid == -1) 
     1433+               pid = getpid(); 
     1434+ 
     1435+#ifdef USE_TMP_FILE 
     1436+       sprintf(filename, "/tmp/squashfs_pseudo_%d_%d", pid, number ++); 
     1437+       pipefd[1] = open(filename, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU); 
     1438+       if(pipefd[1] == -1) { 
     1439+               printf("open failed\n"); 
     1440+               return -1; 
     1441+       } 
     1442+#else 
     1443+       res = pipe(pipefd); 
     1444+       if(res == -1) { 
     1445+               printf("pipe failed\n"); 
     1446+               return -1; 
     1447+       } 
     1448+#endif 
     1449+ 
     1450+       child = fork(); 
     1451+       if(child == -1) { 
     1452+               printf("fork failed\n"); 
     1453+               goto failed; 
     1454+       } 
     1455+ 
     1456+       if(child == 0) { 
     1457+               close(STDOUT_FILENO); 
     1458+               res = dup(pipefd[1]); 
     1459+               if(res == -1) { 
     1460+                       printf("dup failed\n"); 
     1461+                       exit(EXIT_FAILURE); 
     1462+               } 
     1463+               execl("/bin/sh", "sh", "-c", command, (char *) NULL); 
     1464+               printf("execl failed\n"); 
     1465+               exit(EXIT_FAILURE); 
     1466+       } 
     1467+ 
     1468+#ifdef USE_TMP_FILE 
     1469+       res = waitpid(child, &status, 0); 
     1470+       close(pipefd[1]); 
     1471+       if(res != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0) { 
     1472+               dev->filename = strdup(filename); 
     1473+               return 0; 
     1474+       } 
     1475+failed: 
     1476+       unlink(filename); 
     1477+       return -1; 
     1478+#else 
     1479+       close(pipefd[1]); 
     1480+       dev->fd = pipefd[0]; 
     1481+       dev->child = child; 
     1482+       return 0; 
     1483+failed: 
     1484+       return -1; 
     1485+#endif 
     1486+} 
     1487+ 
     1488+ 
     1489+void add_pseudo_file(struct pseudo_dev *dev) 
     1490+{ 
     1491+       pseudo_file = realloc(pseudo_file, (pseudo_count + 1) * 
     1492+               sizeof(struct pseudo_dev *)); 
     1493+       if(pseudo_file == NULL) 
     1494+               BAD_ERROR("Failed to realloc pseudo_file\n"); 
     1495+ 
     1496+       dev->pseudo_id = pseudo_count; 
     1497+       pseudo_file[pseudo_count ++] = dev; 
     1498+} 
     1499+ 
     1500+ 
     1501+void delete_pseudo_files() 
     1502+{ 
     1503+#ifdef USE_TMP_FILE 
     1504+       int i; 
     1505+ 
     1506+       for(i = 0; i < pseudo_count; i++) 
     1507+               unlink(pseudo_file[i]->filename); 
     1508+#endif 
     1509+} 
     1510+ 
     1511+ 
     1512+struct pseudo_dev *get_pseudo_file(int pseudo_id) 
     1513+{ 
     1514+       return pseudo_file[pseudo_id]; 
     1515+} 
     1516+ 
     1517+ 
     1518 int read_pseudo_def(struct pseudo **pseudo, char *def) 
     1519 { 
     1520-       int n; 
     1521+       int n, bytes; 
     1522        unsigned int major = 0, minor = 0, mode; 
     1523        char filename[2048], type, suid[100], sgid[100], *ptr; 
     1524        long long uid, gid; 
     1525-       struct pseudo_dev dev; 
     1526+       struct pseudo_dev *dev; 
     1527  
     1528-       n = sscanf(def, "%s %c %o %s %s %u %u", filename, &type, &mode, suid, sgid, 
     1529-                       &major, &minor); 
     1530+       n = sscanf(def, "%s %c %o %s %s %n", filename, &type, &mode, suid, 
     1531+                       sgid, &bytes); 
     1532  
     1533        if(n < 5) { 
     1534                ERROR("Not enough or invalid arguments in pseudo file " 
     1535@@ -249,7 +340,9 @@ 
     1536        switch(type) { 
     1537        case 'b': 
     1538        case 'c': 
     1539-               if(n < 7) { 
     1540+               n = sscanf(def + bytes,  "%u %u", &major, &minor); 
     1541+ 
     1542+               if(n < 2) { 
     1543                        ERROR("Not enough or invalid arguments in pseudo file " 
     1544                                "definition\n"); 
     1545                        goto error; 
     1546@@ -265,47 +358,15 @@ 
     1547                        goto error; 
     1548                } 
     1549  
     1550-               /* fall through */ 
     1551-       case 'd': 
     1552-               if(mode > 0777) { 
     1553-                       ERROR("Mode %o out of range\n", mode); 
     1554+       case 'f': 
     1555+               if(def[bytes] == '\0') { 
     1556+                       ERROR("Not enough arguments in pseudo file " 
     1557+                               "definition\n"); 
     1558                        goto error; 
     1559-               } 
     1560- 
     1561-               uid = strtoll(suid, &ptr, 10); 
     1562-               if(*ptr == '\0') { 
     1563-                       if(uid < 0 || uid > ((1LL << 32) - 1)) { 
     1564-                               ERROR("Uid %s out of range\n", suid); 
     1565-                               goto error; 
     1566-                       } 
     1567-               } else { 
     1568-                       struct passwd *pwuid = getpwnam(suid); 
     1569-                       if(pwuid) 
     1570-                               uid = pwuid->pw_uid; 
     1571-                       else { 
     1572-                               ERROR("Uid %s invalid uid or unknown user\n", 
     1573-                                       suid); 
     1574-                               goto error; 
     1575-                       } 
     1576-               } 
     1577-                
     1578-               gid = strtoll(sgid, &ptr, 10); 
     1579-               if(*ptr == '\0') { 
     1580-                       if(gid < 0 || gid > ((1LL << 32) - 1)) { 
     1581-                               ERROR("Gid %s out of range\n", sgid); 
     1582-                               goto error; 
     1583-                       } 
     1584-               } else { 
     1585-                       struct group *grgid = getgrnam(sgid); 
     1586-                       if(grgid) 
     1587-                               gid = grgid->gr_gid; 
     1588-                       else { 
     1589-                               ERROR("Gid %s invalid uid or unknown user\n", 
     1590-                                       sgid); 
     1591-                               goto error; 
     1592-                       } 
     1593-               } 
     1594- 
     1595+               }        
     1596+               break; 
     1597+       case 'd': 
     1598+       case 'm': 
     1599                break; 
     1600        default: 
     1601                ERROR("Unsupported type %c\n", type); 
     1602@@ -313,6 +374,43 @@ 
     1603        } 
     1604  
     1605  
     1606+       if(mode > 0777) { 
     1607+               ERROR("Mode %o out of range\n", mode); 
     1608+               goto error; 
     1609+       } 
     1610+ 
     1611+       uid = strtoll(suid, &ptr, 10); 
     1612+       if(*ptr == '\0') { 
     1613+               if(uid < 0 || uid > ((1LL << 32) - 1)) { 
     1614+                       ERROR("Uid %s out of range\n", suid); 
     1615+                       goto error; 
     1616+               } 
     1617+       } else { 
     1618+               struct passwd *pwuid = getpwnam(suid); 
     1619+               if(pwuid) 
     1620+                       uid = pwuid->pw_uid; 
     1621+               else { 
     1622+                       ERROR("Uid %s invalid uid or unknown user\n", suid); 
     1623+                       goto error; 
     1624+               } 
     1625+       } 
     1626+                
     1627+       gid = strtoll(sgid, &ptr, 10); 
     1628+       if(*ptr == '\0') { 
     1629+               if(gid < 0 || gid > ((1LL << 32) - 1)) { 
     1630+                       ERROR("Gid %s out of range\n", sgid); 
     1631+                       goto error; 
     1632+               } 
     1633+       } else { 
     1634+               struct group *grgid = getgrnam(sgid); 
     1635+               if(grgid) 
     1636+                       gid = grgid->gr_gid; 
     1637+               else { 
     1638+                       ERROR("Gid %s invalid uid or unknown user\n", sgid); 
     1639+                       goto error; 
     1640+               } 
     1641+       } 
     1642+ 
     1643        switch(type) { 
     1644        case 'b': 
     1645                mode |= S_IFBLK; 
     1646@@ -323,16 +421,37 @@ 
     1647        case 'd': 
     1648                mode |= S_IFDIR; 
     1649                break; 
     1650+       case 'f': 
     1651+               mode |= S_IFREG; 
     1652+               break; 
     1653        } 
     1654  
     1655-       dev.type = type; 
     1656-       dev.mode = mode; 
     1657-       dev.uid = uid; 
     1658-       dev.gid = gid; 
     1659-       dev.major = major; 
     1660-       dev.minor = minor; 
     1661+       dev = malloc(sizeof(struct pseudo_dev)); 
     1662+       if(dev == NULL) 
     1663+               BAD_ERROR("Failed to create pseudo_dev\n"); 
     1664+ 
     1665+       dev->type = type; 
     1666+       dev->mode = mode; 
     1667+       dev->uid = uid; 
     1668+       dev->gid = gid; 
     1669+       dev->major = major; 
     1670+       dev->minor = minor; 
     1671+ 
     1672+       if(type == 'f') { 
     1673+               int res; 
     1674+ 
     1675+               printf("Executing dynamic pseudo file\n"); 
     1676+               printf("\t\"%s\"\n", def); 
     1677+               res = exec_file(def + bytes, dev); 
     1678+               if(res == -1) { 
     1679+                       ERROR("Failed to execute dynamic pseudo file definition" 
     1680+                               " \"%s\"\n", def); 
     1681+                       return FALSE; 
     1682+               } 
     1683+               add_pseudo_file(dev); 
     1684+       } 
     1685  
     1686-       *pseudo = add_pseudo(*pseudo, &dev, filename, filename); 
     1687+       *pseudo = add_pseudo(*pseudo, dev, filename, filename); 
     1688  
     1689        return TRUE; 
     1690  
     1691diff -Nur squashfs4.0/squashfs-tools/pseudo.h squashfs4.0-lzma-snapshot/squashfs-tools/pseudo.h 
     1692--- squashfs4.0/squashfs-tools/pseudo.h 2009-04-04 03:44:24.000000000 +0200 
     1693+++ squashfs4.0-lzma-snapshot/squashfs-tools/pseudo.h   2009-10-20 06:03:38.000000000 +0200 
     1694@@ -27,6 +27,12 @@ 
     1695        unsigned int    gid; 
     1696        unsigned int    major; 
     1697        unsigned int    minor; 
     1698+       int             pseudo_id; 
     1699+       int             fd; 
     1700+       int             child; 
     1701+#ifdef USE_TMP_FILE 
     1702+       char            *filename; 
     1703+#endif 
     1704 }; 
     1705  
     1706 struct pseudo_entry { 
     1707@@ -46,3 +52,5 @@ 
     1708 extern int read_pseudo_file(struct pseudo **, char *); 
     1709 extern struct pseudo *pseudo_subdir(char *, struct pseudo *); 
     1710 extern struct pseudo_entry *pseudo_readdir(struct pseudo *); 
     1711+extern struct pseudo_dev *get_pseudo_file(int); 
     1712+extern void delete_pseudo_files(); 
     1713diff -Nur squashfs4.0/squashfs-tools/read_fs.c squashfs4.0-lzma-snapshot/squashfs-tools/read_fs.c 
     1714--- squashfs4.0/squashfs-tools/read_fs.c        2009-03-31 06:23:14.000000000 +0200 
     1715+++ squashfs4.0-lzma-snapshot/squashfs-tools/read_fs.c  2009-10-20 06:03:38.000000000 +0200 
     1716@@ -36,7 +36,6 @@ 
     1717 #include <fcntl.h> 
     1718 #include <errno.h> 
     1719 #include <string.h> 
     1720-#include <zlib.h> 
     1721 #include <sys/mman.h> 
     1722  
     1723 #ifndef linux 
     1724@@ -51,6 +50,7 @@ 
     1725 #include "squashfs_swap.h" 
     1726 #include "read_fs.h" 
     1727 #include "global.h" 
     1728+#include "compressor.h" 
     1729  
     1730 #include <stdlib.h> 
     1731  
     1732@@ -66,7 +66,9 @@ 
     1733                                                fprintf(stderr, s, ## args); \ 
     1734                                        } while(0) 
     1735  
     1736-int read_block(int fd, long long start, long long *next, unsigned char *block, 
     1737+static struct compressor *comp; 
     1738+ 
     1739+int read_block(int fd, long long start, long long *next, void *block, 
     1740        squashfs_super_block *sBlk) 
     1741 { 
     1742        unsigned short c_byte; 
     1743@@ -77,32 +79,24 @@ 
     1744  
     1745        if(SQUASHFS_COMPRESSED(c_byte)) { 
     1746                char buffer[SQUASHFS_METADATA_SIZE]; 
     1747-               int res; 
     1748-               unsigned long bytes = SQUASHFS_METADATA_SIZE; 
     1749+               int error, res; 
     1750  
     1751                c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); 
     1752                read_destination(fd, start + offset, c_byte, buffer); 
     1753  
     1754-               res = uncompress(block, &bytes, (const unsigned char *) buffer, 
     1755-                       c_byte); 
     1756-               if(res != Z_OK) { 
     1757-                       if(res == Z_MEM_ERROR) 
     1758-                               ERROR("zlib::uncompress failed, not enough " 
     1759-                                       "memory\n"); 
     1760-                       else if(res == Z_BUF_ERROR) 
     1761-                               ERROR("zlib::uncompress failed, not enough " 
     1762-                                       "room in output buffer\n"); 
     1763-                       else 
     1764-                               ERROR("zlib::uncompress failed, unknown error " 
     1765-                                       "%d\n", res); 
     1766+               res = comp->uncompress(block, buffer, c_byte, 
     1767+                       SQUASHFS_METADATA_SIZE, &error); 
     1768+               if(res == -1) { 
     1769+                       ERROR("%s uncompress failed with error code %d\n", 
     1770+                               comp->name, error); 
     1771                        return 0; 
     1772                } 
     1773                if(next) 
     1774                        *next = start + offset + c_byte; 
     1775-               return bytes; 
     1776+               return res; 
     1777        } else { 
     1778                c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); 
     1779-               read_destination(fd, start + offset, c_byte, (char *) block); 
     1780+               read_destination(fd, start + offset, c_byte, block); 
     1781                if(next) 
     1782                        *next = start + offset + c_byte; 
     1783                return c_byte; 
     1784@@ -356,7 +350,7 @@ 
     1785 } 
     1786  
     1787  
     1788-int read_super(int fd, squashfs_super_block *sBlk, char *source) 
     1789+struct compressor *read_super(int fd, squashfs_super_block *sBlk, char *source) 
     1790 { 
     1791        read_destination(fd, SQUASHFS_START, sizeof(squashfs_super_block), 
     1792                (char *) sBlk); 
     1793@@ -388,8 +382,18 @@ 
     1794                goto failed_mount; 
     1795        } 
     1796  
     1797+       /* Check the compression type */ 
     1798+       comp = lookup_compressor_id(sBlk->compression); 
     1799+       if(!comp->supported) { 
     1800+               ERROR("Filesystem on %s uses %s compression, this is" 
     1801+                       "unsupported by this version\n", source, comp->name); 
     1802+               display_compressors("", ""); 
     1803+               goto failed_mount; 
     1804+       } 
     1805+ 
     1806        printf("Found a valid %sSQUASHFS superblock on %s.\n", 
     1807                SQUASHFS_EXPORTABLE(sBlk->flags) ? "exportable " : "", source); 
     1808+       printf("\tCompression used %s\n", comp->name); 
     1809        printf("\tInodes are %scompressed\n", 
     1810                SQUASHFS_UNCOMPRESSED_INODES(sBlk->flags) ? "un" : ""); 
     1811        printf("\tData is %scompressed\n", 
     1812@@ -417,10 +421,10 @@ 
     1813        TRACE("sBlk->lookup_table_start %llx\n", sBlk->lookup_table_start); 
     1814        printf("\n"); 
     1815  
     1816-       return TRUE; 
     1817+       return comp; 
     1818  
     1819 failed_mount: 
     1820-       return FALSE; 
     1821+       return NULL; 
     1822 } 
     1823  
     1824  
     1825@@ -514,12 +518,17 @@ 
     1826        SQUASHFS_INSWAP_ID_BLOCKS(index, indexes); 
     1827  
     1828        for(i = 0; i < indexes; i++) { 
     1829-               int length; 
     1830-               length = read_block(fd, index[i], NULL, 
     1831+               int length = read_block(fd, index[i], NULL, 
     1832                        ((unsigned char *) id_table) + 
     1833                        (i * SQUASHFS_METADATA_SIZE), sBlk); 
     1834                TRACE("Read id table block %d, from 0x%llx, length %d\n", i, 
     1835                        index[i], length); 
     1836+               if(length == 0) { 
     1837+                       ERROR("Failed to read id table block %d, from 0x%llx, " 
     1838+                               "length %d\n", i, index[i], length); 
     1839+                       free(id_table); 
     1840+                       return NULL; 
     1841+               } 
     1842        } 
     1843  
     1844        SQUASHFS_INSWAP_INTS(id_table, sBlk->no_ids); 
     1845@@ -563,6 +572,13 @@ 
     1846                        (i * SQUASHFS_METADATA_SIZE), sBlk); 
     1847                TRACE("Read fragment table block %d, from 0x%llx, length %d\n", 
     1848                        i, fragment_table_index[i], length); 
     1849+               if(length == 0) { 
     1850+                       ERROR("Failed to read fragment table block %d, from " 
     1851+                               "0x%llx, length %d\n", i, 
     1852+                               fragment_table_index[i], length); 
     1853+                       free(*fragment_table); 
     1854+                       return 0; 
     1855+               } 
     1856        } 
     1857  
     1858        for(i = 0; i < sBlk->fragments; i++) 
     1859@@ -599,6 +615,13 @@ 
     1860                        (i * SQUASHFS_METADATA_SIZE), sBlk); 
     1861                TRACE("Read inode lookup table block %d, from 0x%llx, length " 
     1862                        "%d\n", i, index[i], length); 
     1863+               if(length == 0) { 
     1864+                       ERROR("Failed to read inode lookup table block %d, " 
     1865+                               "from 0x%llx, length %d\n", i, index[i], 
     1866+                               length); 
     1867+                       free(*inode_lookup_table); 
     1868+                       return 0; 
     1869+               } 
     1870        } 
     1871  
     1872        SQUASHFS_INSWAP_LONG_LONGS(*inode_lookup_table, sBlk->inodes); 
     1873diff -Nur squashfs4.0/squashfs-tools/sort.c squashfs4.0-lzma-snapshot/squashfs-tools/sort.c 
     1874--- squashfs4.0/squashfs-tools/sort.c   2009-03-31 06:25:53.000000000 +0200 
     1875+++ squashfs4.0-lzma-snapshot/squashfs-tools/sort.c     2009-10-20 06:03:38.000000000 +0200 
     1876@@ -198,7 +198,7 @@ 
     1877        while(dir->current_count < dir->count) { 
     1878                struct dir_ent *dir_ent = dir->list[dir->current_count++]; 
     1879                struct stat *buf = &dir_ent->inode->buf; 
     1880-               if(dir_ent->data) 
     1881+               if(dir_ent->inode->root_entry) 
     1882                        continue; 
     1883  
     1884                switch(buf->st_mode & S_IFMT) { 
     1885@@ -254,6 +254,7 @@ 
     1886                                write_file(&inode, entry->dir, &duplicate_file); 
     1887                                INFO("file %s, uncompressed size %lld bytes %s" 
     1888                                        "\n", entry->dir->pathname, 
     1889+                                       (long long) 
     1890                                        entry->dir->inode->buf.st_size, 
     1891                                        duplicate_file ? "DUPLICATE" : ""); 
     1892                                entry->dir->inode->inode = inode; 
     1893@@ -261,6 +262,7 @@ 
     1894                        } else 
     1895                                INFO("file %s, uncompressed size %lld bytes " 
     1896                                        "LINK\n", entry->dir->pathname, 
     1897+                                       (long long) 
     1898                                        entry->dir->inode->buf.st_size); 
     1899                } 
     1900 } 
     1901diff -Nur squashfs4.0/squashfs-tools/sort.h squashfs4.0-lzma-snapshot/squashfs-tools/sort.h 
     1902--- squashfs4.0/squashfs-tools/sort.h   2009-02-08 13:02:53.000000000 +0100 
     1903+++ squashfs4.0-lzma-snapshot/squashfs-tools/sort.h     2009-10-20 06:03:38.000000000 +0200 
     1904@@ -42,17 +42,19 @@ 
     1905        struct inode_info       *inode; 
     1906        struct dir_info         *dir; 
     1907        struct dir_info         *our_dir; 
     1908-       struct old_root_entry_info *data; 
     1909 }; 
     1910  
     1911 struct inode_info { 
     1912-       unsigned int            nlink; 
     1913        struct stat             buf; 
     1914+       struct inode_info       *next; 
     1915        squashfs_inode          inode; 
     1916-       unsigned int            type; 
     1917        unsigned int            inode_number; 
     1918+       unsigned int            nlink; 
     1919+       int                     pseudo_id; 
     1920+       char                    type; 
     1921        char                    read; 
     1922-       struct inode_info       *next; 
     1923+       char                    root_entry; 
     1924+       char                    pseudo_file; 
     1925 }; 
     1926  
     1927 struct priority_entry { 
     1928diff -Nur squashfs4.0/squashfs-tools/squashfs_compat.h squashfs4.0-lzma-snapshot/squashfs-tools/squashfs_compat.h 
     1929--- squashfs4.0/squashfs-tools/squashfs_compat.h        2009-03-16 05:27:27.000000000 +0100 
     1930+++ squashfs4.0-lzma-snapshot/squashfs-tools/squashfs_compat.h  2009-10-20 06:03:38.000000000 +0200 
     1931@@ -777,11 +777,10 @@ 
     1932 #endif 
     1933  
     1934 #define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\ 
     1935-       int bits;\ 
     1936-       int b_pos = pos % 8;\ 
     1937-       unsigned long long val = 0;\ 
     1938-       unsigned char *s = (unsigned char *)p + (pos / 8);\ 
     1939-       unsigned char *d = ((unsigned char *) &val) + 7;\ 
     1940+       b_pos = pos % 8;\ 
     1941+       val = 0;\ 
     1942+       s = (unsigned char *)p + (pos / 8);\ 
     1943+       d = ((unsigned char *) &val) + 7;\ 
     1944        for(bits = 0; bits < (tbits + b_pos); bits += 8) \ 
     1945                *d-- = *s++;\ 
     1946        value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\ 
     1947diff -Nur squashfs4.0/squashfs-tools/squashfs_fs.h squashfs4.0-lzma-snapshot/squashfs-tools/squashfs_fs.h 
     1948--- squashfs4.0/squashfs-tools/squashfs_fs.h    2009-03-18 03:50:20.000000000 +0100 
     1949+++ squashfs4.0-lzma-snapshot/squashfs-tools/squashfs_fs.h      2009-10-20 06:03:38.000000000 +0200 
     1950@@ -229,6 +229,7 @@ 
     1951 typedef long long              squashfs_inode_t; 
     1952  
     1953 #define ZLIB_COMPRESSION       1 
     1954+#define LZMA_COMPRESSION       2 
     1955  
     1956 struct squashfs_super_block { 
     1957        unsigned int            s_magic; 
     1958diff -Nur squashfs4.0/squashfs-tools/unsquash-3.c squashfs4.0-lzma-snapshot/squashfs-tools/unsquash-3.c 
     1959--- squashfs4.0/squashfs-tools/unsquash-3.c     2009-03-31 06:35:10.000000000 +0200 
     1960+++ squashfs4.0-lzma-snapshot/squashfs-tools/unsquash-3.c       2009-10-20 06:03:38.000000000 +0200 
     1961@@ -36,7 +36,7 @@ 
     1962                sBlk.fragment_table_start); 
     1963  
     1964        if(sBlk.fragments == 0) 
     1965-               return; 
     1966+               return TRUE; 
     1967  
     1968        if((fragment_table = malloc(sBlk.fragments * 
     1969                        sizeof(squashfs_fragment_entry_3))) == NULL) 
     1970diff -Nur squashfs4.0/squashfs-tools/unsquash-4.c squashfs4.0-lzma-snapshot/squashfs-tools/unsquash-4.c 
     1971--- squashfs4.0/squashfs-tools/unsquash-4.c     2009-03-31 06:38:31.000000000 +0200 
     1972+++ squashfs4.0-lzma-snapshot/squashfs-tools/unsquash-4.c       2009-10-20 06:03:38.000000000 +0200 
     1973@@ -38,7 +38,7 @@ 
     1974                sBlk.fragment_table_start); 
     1975  
     1976        if(sBlk.fragments == 0) 
     1977-               return; 
     1978+               return TRUE; 
     1979  
     1980        if((fragment_table = malloc(sBlk.fragments * 
     1981                        sizeof(squashfs_fragment_entry))) == NULL) 
     1982diff -Nur squashfs4.0/squashfs-tools/unsquashfs.c squashfs4.0-lzma-snapshot/squashfs-tools/unsquashfs.c 
     1983--- squashfs4.0/squashfs-tools/unsquashfs.c     2009-04-05 23:23:06.000000000 +0200 
     1984+++ squashfs4.0-lzma-snapshot/squashfs-tools/unsquashfs.c       2009-10-20 06:03:39.000000000 +0200 
     1985@@ -25,6 +25,9 @@ 
     1986 #include "squashfs_swap.h" 
     1987 #include "squashfs_compat.h" 
     1988 #include "read_fs.h" 
     1989+#include "compressor.h" 
     1990+ 
     1991+#include <sys/sysinfo.h> 
     1992  
     1993 struct cache *fragment_cache, *data_cache; 
     1994 struct queue *to_reader, *to_deflate, *to_writer, *from_writer; 
     1995@@ -36,6 +39,7 @@ 
     1996  
     1997 struct super_block sBlk; 
     1998 squashfs_operations s_ops; 
     1999+struct compressor *comp; 
     2000  
     2001 int bytes = 0, swap, file_count = 0, dir_count = 0, sym_count = 0, 
     2002        dev_count = 0, fifo_count = 0; 
     2003@@ -590,31 +594,23 @@ 
     2004                offset = 3; 
     2005        if(SQUASHFS_COMPRESSED(c_byte)) { 
     2006                char buffer[SQUASHFS_METADATA_SIZE]; 
     2007-               int res; 
     2008-               unsigned long bytes = SQUASHFS_METADATA_SIZE; 
     2009+               int error, res; 
     2010  
     2011                c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); 
     2012                if(read_bytes(start + offset, c_byte, buffer) == FALSE) 
     2013                        goto failed; 
     2014  
     2015-               res = uncompress((unsigned char *) block, &bytes, 
     2016-                       (const unsigned char *) buffer, c_byte); 
     2017+               res = comp->uncompress(block, buffer, c_byte, 
     2018+                       SQUASHFS_METADATA_SIZE, &error); 
     2019  
     2020-               if(res != Z_OK) { 
     2021-                       if(res == Z_MEM_ERROR) 
     2022-                               ERROR("zlib::uncompress failed, not enough " 
     2023-                                       "memory\n"); 
     2024-                       else if(res == Z_BUF_ERROR) 
     2025-                               ERROR("zlib::uncompress failed, not enough " 
     2026-                                       "room in output buffer\n"); 
     2027-                       else 
     2028-                               ERROR("zlib::uncompress failed, unknown error " 
     2029-                                       "%d\n", res); 
     2030+               if(res == -1) { 
     2031+                       ERROR("%s uncompress failed with error code %d\n", 
     2032+                               comp->name, error); 
     2033                        goto failed; 
     2034                } 
     2035                if(next) 
     2036                        *next = start + offset + c_byte; 
     2037-               return bytes; 
     2038+               return res; 
     2039        } else { 
     2040                c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); 
     2041                if(read_bytes(start + offset, c_byte, block) == FALSE) 
     2042@@ -632,36 +628,26 @@ 
     2043  
     2044 int read_data_block(long long start, unsigned int size, char *block) 
     2045 { 
     2046-       int res; 
     2047-       unsigned long bytes = block_size; 
     2048+       int error, res; 
     2049        int c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(size); 
     2050  
     2051        TRACE("read_data_block: block @0x%llx, %d %s bytes\n", start, 
     2052-               SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte), 
     2053-               SQUASHFS_COMPRESSED_BLOCK(c_byte) ? "compressed" : 
     2054+               c_byte, SQUASHFS_COMPRESSED_BLOCK(size) ? "compressed" : 
     2055                "uncompressed"); 
     2056  
     2057        if(SQUASHFS_COMPRESSED_BLOCK(size)) { 
     2058                if(read_bytes(start, c_byte, data) == FALSE) 
     2059                        goto failed; 
     2060  
     2061-               res = uncompress((unsigned char *) block, &bytes, 
     2062-                       (const unsigned char *) data, c_byte); 
     2063+               res = comp->uncompress(block, data, c_byte, block_size, &error); 
     2064  
     2065-               if(res != Z_OK) { 
     2066-                       if(res == Z_MEM_ERROR) 
     2067-                               ERROR("zlib::uncompress failed, not enough " 
     2068-                                       "memory\n"); 
     2069-                       else if(res == Z_BUF_ERROR) 
     2070-                               ERROR("zlib::uncompress failed, not enough " 
     2071-                                       "room in output buffer\n"); 
     2072-                       else 
     2073-                               ERROR("zlib::uncompress failed, unknown error " 
     2074-                                       "%d\n", res); 
     2075+               if(res == -1) { 
     2076+                       ERROR("%s uncompress failed with error code %d\n", 
     2077+                               comp->name, error); 
     2078                        goto failed; 
     2079                } 
     2080  
     2081-               return bytes; 
     2082+               return res; 
     2083        } else { 
     2084                if(read_bytes(start, c_byte, block) == FALSE) 
     2085                        goto failed; 
     2086@@ -671,7 +657,7 @@ 
     2087  
     2088 failed: 
     2089        ERROR("read_data_block: failed to read block @0x%llx, size %d\n", start, 
     2090-               size); 
     2091+               c_byte); 
     2092        return FALSE; 
     2093 } 
     2094  
     2095@@ -1383,6 +1369,11 @@ 
     2096 #endif 
     2097        printf("Creation or last append time %s", mkfs_str ? mkfs_str : 
     2098                "failed to get time\n"); 
     2099+       printf("Filesystem size %.2f Kbytes (%.2f Mbytes)\n", 
     2100+               sBlk.bytes_used / 1024.0, sBlk.bytes_used / (1024.0 * 1024.0)); 
     2101+       if(sBlk.s_major == 4) 
     2102+               printf("Compression %s\n", comp->name); 
     2103+       printf("Block size %d\n", sBlk.block_size); 
     2104        printf("Filesystem is %sexportable via NFS\n", 
     2105                SQUASHFS_EXPORTABLE(sBlk.flags) ? "" : "not "); 
     2106  
     2107@@ -1409,9 +1400,6 @@ 
     2108                        SQUASHFS_DUPLICATES(sBlk.flags) ? "" : "not "); 
     2109        else 
     2110                printf("Duplicates are removed\n"); 
     2111-       printf("Filesystem size %.2f Kbytes (%.2f Mbytes)\n", 
     2112-               sBlk.bytes_used / 1024.0, sBlk.bytes_used / (1024.0 * 1024.0)); 
     2113-       printf("Block size %d\n", sBlk.block_size); 
     2114        if(sBlk.s_major > 1) 
     2115                printf("Number of fragments %d\n", sBlk.fragments); 
     2116        printf("Number of inodes %d\n", sBlk.inodes); 
     2117@@ -1459,6 +1447,18 @@ 
     2118                s_ops.read_inode = read_inode_4; 
     2119                s_ops.read_uids_guids = read_uids_guids_4; 
     2120                memcpy(&sBlk, &sBlk_4, sizeof(sBlk_4)); 
     2121+ 
     2122+               /* 
     2123+                * Check the compression type 
     2124+                */ 
     2125+               comp = lookup_compressor_id(sBlk.compression); 
     2126+               if(!comp->supported) { 
     2127+                       ERROR("Filesystem uses %s compression, this is " 
     2128+                               "unsupported by this version\n", comp->name); 
     2129+                       ERROR("Decompressors available:\n"); 
     2130+                       display_compressors("", ""); 
     2131+                       goto failed_mount; 
     2132+               } 
     2133                return TRUE; 
     2134        } 
     2135  
     2136@@ -1548,6 +1548,11 @@ 
     2137                goto failed_mount; 
     2138        } 
     2139  
     2140+       /* 
     2141+        * 1.x, 2.x and 3.x filesystems use gzip compression.  Gzip is always 
     2142+        * suppported. 
     2143+        */ 
     2144+       comp = lookup_compressor("gzip"); 
     2145        return TRUE; 
     2146  
     2147 failed_mount: 
     2148@@ -1707,32 +1712,24 @@ 
     2149  
     2150        while(1) { 
     2151                struct cache_entry *entry = queue_get(to_deflate); 
     2152-               int res; 
     2153-               unsigned long bytes = block_size; 
     2154+               int error, res; 
     2155  
     2156-               res = uncompress((unsigned char *) tmp, &bytes, 
     2157-                       (const unsigned char *) entry->data, 
     2158-                       SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size)); 
     2159- 
     2160-               if(res != Z_OK) { 
     2161-                       if(res == Z_MEM_ERROR) 
     2162-                               ERROR("zlib::uncompress failed, not enough" 
     2163-                                       "memory\n"); 
     2164-                       else if(res == Z_BUF_ERROR) 
     2165-                               ERROR("zlib::uncompress failed, not enough " 
     2166-                                       "room in output buffer\n"); 
     2167-                       else 
     2168-                               ERROR("zlib::uncompress failed, unknown error " 
     2169-                                       "%d\n", res); 
     2170-               } else 
     2171-                       memcpy(entry->data, tmp, bytes); 
     2172+               res = comp->uncompress(tmp, entry->data, 
     2173+                       SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size), block_size, 
     2174+                       &error); 
     2175+ 
     2176+               if(res == -1) 
     2177+                       ERROR("%s uncompress failed with error code %d\n", 
     2178+                               comp->name, error); 
     2179+               else 
     2180+                       memcpy(entry->data, tmp, res); 
     2181  
     2182                /* 
     2183                 * block has been either successfully decompressed, or an error 
     2184                 * occurred, clear pending flag, set error appropriately and 
     2185                 * wake up any threads waiting on this block 
     2186                 */  
     2187-               cache_block_ready(entry, res != Z_OK); 
     2188+               cache_block_ready(entry, res == -1); 
     2189        } 
     2190 } 
     2191  
     2192@@ -1913,7 +1910,7 @@ 
     2193  
     2194  
     2195 #define VERSION() \ 
     2196-       printf("unsquashfs version 4.0 (2009/04/05)\n");\ 
     2197+       printf("unsquashfs version 4.1-CVS (2009/08/30)\n");\ 
     2198        printf("copyright (C) 2009 Phillip Lougher <phillip@lougher.demon.co.uk>"\ 
     2199                "\n\n");\ 
     2200        printf("This program is free software; you can redistribute it and/or\n");\ 
     2201@@ -1938,7 +1935,6 @@ 
     2202        int fragment_buffer_size = FRAGMENT_BUFFER_DEFAULT; 
     2203        int data_buffer_size = DATA_BUFFER_DEFAULT; 
     2204        char *b; 
     2205-       struct winsize winsize; 
     2206  
     2207        pthread_mutex_init(&screen_mutex, NULL); 
     2208        root_process = geteuid() == 0; 
     2209@@ -2087,6 +2083,8 @@ 
     2210                                "regular expressions\n"); 
     2211                        ERROR("\t\t\t\trather than use the default shell " 
     2212                                "wildcard\n\t\t\t\texpansion (globbing)\n"); 
     2213+                       ERROR("\nDecompressors available:\n"); 
     2214+                       display_compressors("", ""); 
     2215                } 
     2216                exit(1); 
     2217        } 
     2218diff -Nur squashfs4.0/squashfs-tools/unsquashfs.h squashfs4.0-lzma-snapshot/squashfs-tools/unsquashfs.h 
     2219--- squashfs4.0/squashfs-tools/unsquashfs.h     2009-03-29 04:29:02.000000000 +0200 
     2220+++ squashfs4.0-lzma-snapshot/squashfs-tools/unsquashfs.h       2009-10-20 06:03:39.000000000 +0200 
     2221@@ -31,7 +31,6 @@ 
     2222 #include <fcntl.h> 
     2223 #include <errno.h> 
     2224 #include <string.h> 
     2225-#include <zlib.h> 
     2226 #include <sys/mman.h> 
     2227 #include <utime.h> 
     2228 #include <pwd.h> 
Note: See TracChangeset for help on using the changeset viewer.