1a86e058577331cab35f1efb7630abc708e173e0
[openwrt/svn-archive/archive.git] / tools / squashfs4 / patches / 110-lzma.patch
1 diff -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 @@
5 +/*
6 + *
7 + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
8 + * Phillip Lougher <phillip@lougher.demon.co.uk>
9 + *
10 + * This program is free software; you can redistribute it and/or
11 + * modify it under the terms of the GNU General Public License
12 + * as published by the Free Software Foundation; either version 2,
13 + * or (at your option) any later version.
14 + *
15 + * This program is distributed in the hope that it will be useful,
16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 + * GNU General Public License for more details.
19 + *
20 + * You should have received a copy of the GNU General Public License
21 + * along with this program; if not, write to the Free Software
22 + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 + *
24 + * compressor.c
25 + */
26 +
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 },
43 +#endif
44 + { NULL, NULL , 0, "unknown", 0}
45 +};
46 +
47 +
48 +struct compressor *lookup_compressor(char *name)
49 +{
50 + int i;
51 +
52 + for(i = 0; compressor[i].id; i++)
53 + if(strcmp(compressor[i].name, name) == 0)
54 + break;
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)
66 + break;
67 +
68 + return &compressor[i];
69 +}
70 +
71 +
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 +}
83 diff -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 @@
87 +/*
88 + *
89 + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
90 + * Phillip Lougher <phillip@lougher.demon.co.uk>
91 + *
92 + * This program is free software; you can redistribute it and/or
93 + * modify it under the terms of the GNU General Public License
94 + * as published by the Free Software Foundation; either version 2,
95 + * or (at your option) any later version.
96 + *
97 + * This program is distributed in the hope that it will be useful,
98 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
99 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
100 + * GNU General Public License for more details.
101 + *
102 + * You should have received a copy of the GNU General Public License
103 + * along with this program; if not, write to the Free Software
104 + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
105 + *
106 + * compressor.h
107 + */
108 +
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 *);
120 diff -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 +}
204 diff -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 +
229 +#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 +}
301 diff -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)
397 diff -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;
609 +#endif
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" :
1356 diff -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
1691 diff -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();
1713 diff -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);
1873 diff -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 }
1901 diff -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 {
1928 diff -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)*/;\
1947 diff -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;
1958 diff -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)
1970 diff -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)
1982 diff -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,7 @@
1986 #include "squashfs_swap.h"
1987 #include "squashfs_compat.h"
1988 #include "read_fs.h"
1989 +#include "compressor.h"
1990
1991 struct cache *fragment_cache, *data_cache;
1992 struct queue *to_reader, *to_deflate, *to_writer, *from_writer;
1993 @@ -36,6 +39,7 @@
1994
1995 struct super_block sBlk;
1996 squashfs_operations s_ops;
1997 +struct compressor *comp;
1998
1999 int bytes = 0, swap, file_count = 0, dir_count = 0, sym_count = 0,
2000 dev_count = 0, fifo_count = 0;
2001 @@ -590,31 +594,23 @@
2002 offset = 3;
2003 if(SQUASHFS_COMPRESSED(c_byte)) {
2004 char buffer[SQUASHFS_METADATA_SIZE];
2005 - int res;
2006 - unsigned long bytes = SQUASHFS_METADATA_SIZE;
2007 + int error, res;
2008
2009 c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
2010 if(read_bytes(start + offset, c_byte, buffer) == FALSE)
2011 goto failed;
2012
2013 - res = uncompress((unsigned char *) block, &bytes,
2014 - (const unsigned char *) buffer, c_byte);
2015 + res = comp->uncompress(block, buffer, c_byte,
2016 + SQUASHFS_METADATA_SIZE, &error);
2017
2018 - if(res != Z_OK) {
2019 - if(res == Z_MEM_ERROR)
2020 - ERROR("zlib::uncompress failed, not enough "
2021 - "memory\n");
2022 - else if(res == Z_BUF_ERROR)
2023 - ERROR("zlib::uncompress failed, not enough "
2024 - "room in output buffer\n");
2025 - else
2026 - ERROR("zlib::uncompress failed, unknown error "
2027 - "%d\n", res);
2028 + if(res == -1) {
2029 + ERROR("%s uncompress failed with error code %d\n",
2030 + comp->name, error);
2031 goto failed;
2032 }
2033 if(next)
2034 *next = start + offset + c_byte;
2035 - return bytes;
2036 + return res;
2037 } else {
2038 c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
2039 if(read_bytes(start + offset, c_byte, block) == FALSE)
2040 @@ -632,36 +628,26 @@
2041
2042 int read_data_block(long long start, unsigned int size, char *block)
2043 {
2044 - int res;
2045 - unsigned long bytes = block_size;
2046 + int error, res;
2047 int c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(size);
2048
2049 TRACE("read_data_block: block @0x%llx, %d %s bytes\n", start,
2050 - SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte),
2051 - SQUASHFS_COMPRESSED_BLOCK(c_byte) ? "compressed" :
2052 + c_byte, SQUASHFS_COMPRESSED_BLOCK(size) ? "compressed" :
2053 "uncompressed");
2054
2055 if(SQUASHFS_COMPRESSED_BLOCK(size)) {
2056 if(read_bytes(start, c_byte, data) == FALSE)
2057 goto failed;
2058
2059 - res = uncompress((unsigned char *) block, &bytes,
2060 - (const unsigned char *) data, c_byte);
2061 + res = comp->uncompress(block, data, c_byte, block_size, &error);
2062
2063 - if(res != Z_OK) {
2064 - if(res == Z_MEM_ERROR)
2065 - ERROR("zlib::uncompress failed, not enough "
2066 - "memory\n");
2067 - else if(res == Z_BUF_ERROR)
2068 - ERROR("zlib::uncompress failed, not enough "
2069 - "room in output buffer\n");
2070 - else
2071 - ERROR("zlib::uncompress failed, unknown error "
2072 - "%d\n", res);
2073 + if(res == -1) {
2074 + ERROR("%s uncompress failed with error code %d\n",
2075 + comp->name, error);
2076 goto failed;
2077 }
2078
2079 - return bytes;
2080 + return res;
2081 } else {
2082 if(read_bytes(start, c_byte, block) == FALSE)
2083 goto failed;
2084 @@ -671,7 +657,7 @@
2085
2086 failed:
2087 ERROR("read_data_block: failed to read block @0x%llx, size %d\n", start,
2088 - size);
2089 + c_byte);
2090 return FALSE;
2091 }
2092
2093 @@ -1383,6 +1369,11 @@
2094 #endif
2095 printf("Creation or last append time %s", mkfs_str ? mkfs_str :
2096 "failed to get time\n");
2097 + printf("Filesystem size %.2f Kbytes (%.2f Mbytes)\n",
2098 + sBlk.bytes_used / 1024.0, sBlk.bytes_used / (1024.0 * 1024.0));
2099 + if(sBlk.s_major == 4)
2100 + printf("Compression %s\n", comp->name);
2101 + printf("Block size %d\n", sBlk.block_size);
2102 printf("Filesystem is %sexportable via NFS\n",
2103 SQUASHFS_EXPORTABLE(sBlk.flags) ? "" : "not ");
2104
2105 @@ -1409,9 +1400,6 @@
2106 SQUASHFS_DUPLICATES(sBlk.flags) ? "" : "not ");
2107 else
2108 printf("Duplicates are removed\n");
2109 - printf("Filesystem size %.2f Kbytes (%.2f Mbytes)\n",
2110 - sBlk.bytes_used / 1024.0, sBlk.bytes_used / (1024.0 * 1024.0));
2111 - printf("Block size %d\n", sBlk.block_size);
2112 if(sBlk.s_major > 1)
2113 printf("Number of fragments %d\n", sBlk.fragments);
2114 printf("Number of inodes %d\n", sBlk.inodes);
2115 @@ -1459,6 +1447,18 @@
2116 s_ops.read_inode = read_inode_4;
2117 s_ops.read_uids_guids = read_uids_guids_4;
2118 memcpy(&sBlk, &sBlk_4, sizeof(sBlk_4));
2119 +
2120 + /*
2121 + * Check the compression type
2122 + */
2123 + comp = lookup_compressor_id(sBlk.compression);
2124 + if(!comp->supported) {
2125 + ERROR("Filesystem uses %s compression, this is "
2126 + "unsupported by this version\n", comp->name);
2127 + ERROR("Decompressors available:\n");
2128 + display_compressors("", "");
2129 + goto failed_mount;
2130 + }
2131 return TRUE;
2132 }
2133
2134 @@ -1548,6 +1548,11 @@
2135 goto failed_mount;
2136 }
2137
2138 + /*
2139 + * 1.x, 2.x and 3.x filesystems use gzip compression. Gzip is always
2140 + * suppported.
2141 + */
2142 + comp = lookup_compressor("gzip");
2143 return TRUE;
2144
2145 failed_mount:
2146 @@ -1707,32 +1712,24 @@
2147
2148 while(1) {
2149 struct cache_entry *entry = queue_get(to_deflate);
2150 - int res;
2151 - unsigned long bytes = block_size;
2152 + int error, res;
2153
2154 - res = uncompress((unsigned char *) tmp, &bytes,
2155 - (const unsigned char *) entry->data,
2156 - SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size));
2157 -
2158 - if(res != Z_OK) {
2159 - if(res == Z_MEM_ERROR)
2160 - ERROR("zlib::uncompress failed, not enough"
2161 - "memory\n");
2162 - else if(res == Z_BUF_ERROR)
2163 - ERROR("zlib::uncompress failed, not enough "
2164 - "room in output buffer\n");
2165 - else
2166 - ERROR("zlib::uncompress failed, unknown error "
2167 - "%d\n", res);
2168 - } else
2169 - memcpy(entry->data, tmp, bytes);
2170 + res = comp->uncompress(tmp, entry->data,
2171 + SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size), block_size,
2172 + &error);
2173 +
2174 + if(res == -1)
2175 + ERROR("%s uncompress failed with error code %d\n",
2176 + comp->name, error);
2177 + else
2178 + memcpy(entry->data, tmp, res);
2179
2180 /*
2181 * block has been either successfully decompressed, or an error
2182 * occurred, clear pending flag, set error appropriately and
2183 * wake up any threads waiting on this block
2184 */
2185 - cache_block_ready(entry, res != Z_OK);
2186 + cache_block_ready(entry, res == -1);
2187 }
2188 }
2189
2190 @@ -1913,7 +1910,7 @@
2191
2192
2193 #define VERSION() \
2194 - printf("unsquashfs version 4.0 (2009/04/05)\n");\
2195 + printf("unsquashfs version 4.1-CVS (2009/08/30)\n");\
2196 printf("copyright (C) 2009 Phillip Lougher <phillip@lougher.demon.co.uk>"\
2197 "\n\n");\
2198 printf("This program is free software; you can redistribute it and/or\n");\
2199 @@ -1938,7 +1935,6 @@
2200 int fragment_buffer_size = FRAGMENT_BUFFER_DEFAULT;
2201 int data_buffer_size = DATA_BUFFER_DEFAULT;
2202 char *b;
2203 - struct winsize winsize;
2204
2205 pthread_mutex_init(&screen_mutex, NULL);
2206 root_process = geteuid() == 0;
2207 @@ -2087,6 +2083,8 @@
2208 "regular expressions\n");
2209 ERROR("\t\t\t\trather than use the default shell "
2210 "wildcard\n\t\t\t\texpansion (globbing)\n");
2211 + ERROR("\nDecompressors available:\n");
2212 + display_compressors("", "");
2213 }
2214 exit(1);
2215 }
2216 diff -Nur squashfs4.0/squashfs-tools/unsquashfs.h squashfs4.0-lzma-snapshot/squashfs-tools/unsquashfs.h
2217 --- squashfs4.0/squashfs-tools/unsquashfs.h 2009-03-29 04:29:02.000000000 +0200
2218 +++ squashfs4.0-lzma-snapshot/squashfs-tools/unsquashfs.h 2009-10-20 06:03:39.000000000 +0200
2219 @@ -31,7 +31,6 @@
2220 #include <fcntl.h>
2221 #include <errno.h>
2222 #include <string.h>
2223 -#include <zlib.h>
2224 #include <sys/mman.h>
2225 #include <utime.h>
2226 #include <pwd.h>