fix error in mksquashfs4 when data can't be compressed
[openwrt.git] / tools / squashfs4 / patches / 110-lzma.patch
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 @@
371 +/*
372 + * Copyright (c) 2009  Felix Fietkau <nbd@openwrt.org>
373 + *
374 + * This program is free software; you can redistribute it and/or
375 + * modify it under the terms of the GNU General Public License
376 + * as published by the Free Software Foundation; either version 2,
377 + * or (at your option) any later version.
378 + *
379 + * This program is distributed in the hope that it will be useful,
380 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
381 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
382 + * GNU General Public License for more details.
383 + *
384 + * You should have received a copy of the GNU General Public License
385 + * along with this program; if not, write to the Free Software
386 + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
387 + *
388 + * uncompress.c
389 + */
390 +
391 +
392 +
393 +#ifdef USE_LZMA
394 +#include <LzmaLib.h>
395 +#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)
405 +{
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;
417 +                       break;
418 +               case SZ_ERROR_MEM:
419 +                       res = Z_MEM_ERROR;
420 +                       break;
421 +               }
422 +       } else
423 +#endif
424 +       res = uncompress(dest, dest_len, src, src_len);
425 +       return res;
426 +}
427 +
428 +
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 @@
434 +/*
435 + * Copyright (c) 2009  Felix Fietkau <nbd@openwrt.org>
436 + *
437 + * This program is free software; you can redistribute it and/or
438 + * modify it under the terms of the GNU General Public License
439 + * as published by the Free Software Foundation; either version 2,
440 + * or (at your option) any later version.
441 + *
442 + * This program is distributed in the hope that it will be useful,
443 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
444 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
445 + * GNU General Public License for more details.
446 + *
447 + * You should have received a copy of the GNU General Public License
448 + * along with this program; if not, write to the Free Software
449 + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
450 + *
451 + * uncompress.h
452 + */
453 +
454 +#ifdef USE_LZMA
455 +#include <LzmaLib.h>
456 +#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 +