Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 207737 | Differences between
and this patch

Collapse All | Expand All

(-)squashfs-tools/compressor.c (+78 lines)
Line 0 Link Here
1
/*
2
 *
3
 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4
 * Phillip Lougher <phillip@lougher.demon.co.uk>
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2,
9
 * or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
 *
20
 * compressor.c
21
 */
22
23
#include <stdio.h>
24
#include <string.h>
25
#include "compressor.h"
26
#include "squashfs_fs.h"
27
28
extern int gzip_compress(void **, char *, char *, int, int, int *);
29
extern int gzip_uncompress(char *, char *, int, int, int *);
30
extern int lzma_compress(void **, char *, char *, int, int, int *);
31
extern int lzma_uncompress(char *, char *, int, int, int *);
32
33
struct compressor compressor[] = {
34
	{ gzip_compress, gzip_uncompress, ZLIB_COMPRESSION, "gzip", 1 },
35
#ifdef LZMA_SUPPORT
36
	{ lzma_compress, lzma_uncompress, LZMA_COMPRESSION, "lzma", 1 },
37
#else
38
	{ NULL, NULL, LZMA_COMPRESSION, "lzma", 0 },
39
#endif
40
	{ NULL, NULL , 0, "unknown", 0}
41
};
42
43
44
struct compressor *lookup_compressor(char *name)
45
{
46
	int i;
47
48
	for(i = 0; compressor[i].id; i++)
49
		if(strcmp(compressor[i].name, name) == 0)
50
			break;
51
52
	return &compressor[i];
53
}
54
55
56
struct compressor *lookup_compressor_id(int id)
57
{
58
	int i;
59
60
	for(i = 0; compressor[i].id; i++)
61
		if(id == compressor[i].id)
62
			break;
63
64
	return &compressor[i];
65
}
66
67
68
void display_compressors(char *indent, char *def_comp)
69
{
70
	int i;
71
72
	for(i = 0; compressor[i].id; i++)
73
		if(compressor[i].supported)
74
			fprintf(stderr, "%s\t%s%s\n", indent,
75
				compressor[i].name,
76
				strcmp(compressor[i].name, def_comp) == 0 ?
77
				" (default)" : "");
78
}
(-)squashfs-tools/compressor.h (+33 lines)
Line 0 Link Here
1
/*
2
 *
3
 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4
 * Phillip Lougher <phillip@lougher.demon.co.uk>
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2,
9
 * or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
 *
20
 * compressor.h
21
 */
22
23
struct compressor {
24
	int (*compress)(void **, char *, char *, int, int, int *);
25
	int (*uncompress)(char *, char *, int, int, int *);
26
	int id;
27
	char *name;
28
	int supported;
29
};
30
31
extern struct compressor *lookup_compressor(char *);
32
extern struct compressor *lookup_compressor_id(int);
33
extern void display_compressors(char *, char *);
(-)squashfs-tools/gzip_wrapper.c (+80 lines)
Line 0 Link Here
1
/*
2
 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
3
 * Phillip Lougher <phillip@lougher.demon.co.uk>
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2,
8
 * or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 *
19
 * gzip_wrapper.c
20
 */
21
22
#include <stdlib.h>
23
#include <zlib.h>
24
25
int gzip_compress(void **strm, char *d, char *s, int size, int block_size,
26
		int *error)
27
{
28
	int res = 0;
29
	z_stream *stream = *strm;
30
31
	if(stream == NULL) {
32
		if((stream = *strm = malloc(sizeof(z_stream))) == NULL)
33
			goto failed;
34
35
		stream->zalloc = Z_NULL;
36
		stream->zfree = Z_NULL;
37
		stream->opaque = 0;
38
39
		if((res = deflateInit(stream, 9)) != Z_OK)
40
			goto failed;
41
	} else if((res = deflateReset(stream)) != Z_OK)
42
		goto failed;
43
44
	stream->next_in = (unsigned char *) s;
45
	stream->avail_in = size;
46
	stream->next_out = (unsigned char *) d;
47
	stream->avail_out = block_size;
48
49
	res = deflate(stream, Z_FINISH);
50
	if(res == Z_STREAM_END)
51
		/*
52
		 * Success, return the compressed size.
53
		 */
54
		return (int) stream->total_out;
55
	if(res == Z_OK)
56
		/*
57
		 * Output buffer overflow.  Return out of buffer space
58
		 */
59
		return 0;
60
failed:
61
	/*
62
	 * All other errors return failure, with the compressor
63
	 * specific error code in *error
64
	 */
65
	*error = res;
66
	return -1;
67
}
68
69
70
int gzip_uncompress(char *d, char *s, int size, int block_size, int *error)
71
{
72
	int res;
73
	unsigned long bytes = block_size;
74
75
	res = uncompress((unsigned char *) d, &bytes,
76
		(const unsigned char *) s, size);
77
78
	*error = res;
79
	return res == Z_OK ? (int) bytes : -1;
80
}
(-)squashfs-tools/lzma_wrapper.c (+93 lines)
Line 0 Link Here
1
/*
2
 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
3
 * Phillip Lougher <phillip@lougher.demon.co.uk>
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2,
8
 * or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 *
19
 * lzma_wrapper.c
20
 */
21
22
#include <LzmaLib.h>
23
24
#define LZMA_HEADER_SIZE	(LZMA_PROPS_SIZE + 8)
25
26
int lzma_compress(void **strm, char *dest, char *src,  int size,int block_size,
27
		int *error)
28
{
29
	unsigned char *d = (unsigned char *) dest, *s = (unsigned char *) src;
30
	size_t props_size = LZMA_PROPS_SIZE,
31
		outlen = block_size - LZMA_HEADER_SIZE;
32
	int res;
33
34
	res = LzmaCompress(d + LZMA_HEADER_SIZE, &outlen, s, size, d,
35
		&props_size, 5, block_size, 3, 0, 2, 32, 1);
36
	
37
	if(res == SZ_ERROR_OUTPUT_EOF) {
38
		/*
39
		 * Output buffer overflow.  Return out of buffer space error
40
		 */
41
		return 0;
42
	}
43
44
	if(res != SZ_OK) {
45
		/*
46
		 * All other errors return failure, with the compressor
47
		 * specific error code in *error
48
		 */
49
		*error = res;
50
		return -1;
51
	}
52
53
	/*
54
	 * Fill in the 8 byte little endian uncompressed size field in the
55
	 * LZMA header.  8 bytes is excessively large for squashfs but
56
	 * this is the standard LZMA header and which is expected by the kernel
57
	 * code
58
	 */
59
	d[LZMA_PROPS_SIZE] = size & 255;
60
	d[LZMA_PROPS_SIZE + 1] = (size >> 8) & 255;
61
	d[LZMA_PROPS_SIZE + 2] = (size >> 16) & 255;
62
	d[LZMA_PROPS_SIZE + 3] = (size >> 24) & 255;
63
	d[LZMA_PROPS_SIZE + 4] = 0;
64
	d[LZMA_PROPS_SIZE + 5] = 0;
65
	d[LZMA_PROPS_SIZE + 6] = 0;
66
	d[LZMA_PROPS_SIZE + 7] = 0;
67
68
	/*
69
	 * Success, return the compressed size.  Outlen returned by the LZMA
70
	 * compressor does not include the LZMA header space
71
	 */
72
	return outlen + LZMA_HEADER_SIZE;
73
}
74
75
76
int lzma_uncompress(char *dest, char *src, int size, int block_size,
77
	int *error)
78
{
79
	unsigned char *d = (unsigned char *) dest, *s = (unsigned char *) src;
80
	size_t outlen, inlen = size - LZMA_HEADER_SIZE;
81
	int res;
82
83
	outlen = s[LZMA_PROPS_SIZE] |
84
		(s[LZMA_PROPS_SIZE + 1] << 8) |
85
		(s[LZMA_PROPS_SIZE + 2] << 16) |
86
		(s[LZMA_PROPS_SIZE + 3] << 24);
87
88
	res = LzmaUncompress(d, &outlen, s + LZMA_HEADER_SIZE, &inlen,
89
		s, LZMA_PROPS_SIZE);
90
	
91
	*error = res;
92
	return res == SZ_OK ? outlen : -1;
93
}
(-)squashfs-tools/Makefile (-16 / +52 lines)
Lines 1-40 Link Here
1
#
2
# Building LZMA support
3
# Download LZMA sdk (4.65 used in development, other versions may work),
4
# set LZMA_DIR to unpacked source, and uncomment next line
5
LZMA_SUPPORT = 1
6
LZMA_DIR = ../../
7
8
#Compression default.
9
COMP_DEFAULT = gzip
10
11
INCLUDEDIR = -I.
1
INSTALL_DIR = /usr/local/bin
12
INSTALL_DIR = /usr/local/bin
2
13
3
INCLUDEDIR = .
14
MKSQUASHFS_OBJS = mksquashfs.o read_fs.o sort.o swap.o pseudo.o compressor.o \
15
	gzip_wrapper.o
16
17
UNSQUASHFS_OBJS = unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o \
18
	unsquash-4.o swap.o compressor.o gzip_wrapper.o
4
19
5
CFLAGS := -I$(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE -O2
20
CFLAGS := $(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \
21
	-D_GNU_SOURCE -DCOMP_DEFAULT=\"$(COMP_DEFAULT)\" -O2 -Wall
6
22
23
ifdef LZMA_SUPPORT
24
LZMA_OBJS = $(LZMA_DIR)/C/Alloc.o $(LZMA_DIR)/C/LzFind.o \
25
	$(LZMA_DIR)/C/LzmaDec.o $(LZMA_DIR)/C/LzmaEnc.o $(LZMA_DIR)/C/LzmaLib.o
26
INCLUDEDIR += -I$(LZMA_DIR)/C
27
CFLAGS += -DLZMA_SUPPORT -I../../C
28
MKSQUASHFS_OBJS += lzma_wrapper.o $(LZMA_OBJS)
29
UNSQUASHFS_OBJS += lzma_wrapper.o $(LZMA_OBJS)
30
endif
31
32
.PHONY: all
7
all: mksquashfs unsquashfs
33
all: mksquashfs unsquashfs
8
34
9
mksquashfs: mksquashfs.o read_fs.o sort.o swap.o pseudo.o
35
mksquashfs: $(MKSQUASHFS_OBJS)
10
	$(CC) mksquashfs.o read_fs.o sort.o swap.o pseudo.o -lz -lpthread -lm -o $@
36
	$(CC) $(MKSQUASHFS_OBJS) -lz -lpthread -lm -o $@
37
38
mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h \
39
	squashfs_swap.h
11
40
12
mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h squashfs_swap.h Makefile
41
read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h squashfs_swap.h
13
42
14
read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h squashfs_swap.h Makefile
43
sort.o: sort.c squashfs_fs.h global.h sort.h
15
44
16
sort.o: sort.c squashfs_fs.h global.h sort.h Makefile
45
swap.o: swap.c
17
46
18
swap.o: swap.c Makefile
47
pseudo.o: pseudo.c pseudo.h
19
48
20
pseudo.o: pseudo.c pseudo.h Makefile
49
compressor.o: compressor.c compressor.h
21
50
22
unsquashfs: unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o
51
unsquashfs: $(UNSQUASHFS_OBJS)
23
	$(CC) unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o -lz -lpthread -lm -o $@
52
	$(CC) $(UNSQUASHFS_OBJS) -lz -lpthread -lm -o $@
24
53
25
unsquashfs.o: unsquashfs.h unsquashfs.c squashfs_fs.h squashfs_swap.h squashfs_compat.h global.h Makefile
54
unsquashfs.o: unsquashfs.h unsquashfs.c squashfs_fs.h squashfs_swap.h \
55
	squashfs_compat.h global.h
26
56
27
unsquash-1.o: unsquashfs.h unsquash-1.c squashfs_fs.h squashfs_compat.h global.h Makefile
57
unsquash-1.o: unsquashfs.h unsquash-1.c squashfs_fs.h squashfs_compat.h \
58
	global.h
28
59
29
unsquash-2.o: unsquashfs.h unsquash-2.c unsquashfs.h squashfs_fs.h squashfs_compat.h global.h Makefile
60
unsquash-2.o: unsquashfs.h unsquash-2.c unsquashfs.h squashfs_fs.h \
61
	squashfs_compat.h global.h
30
62
31
unsquash-3.o: unsquashfs.h unsquash-3.c squashfs_fs.h squashfs_compat.h global.h Makefile
63
unsquash-3.o: unsquashfs.h unsquash-3.c squashfs_fs.h squashfs_compat.h \
64
	global.h
32
65
33
unsquash-4.o: unsquashfs.h unsquash-4.c squashfs_fs.h squashfs_swap.h global.h Makefile
66
unsquash-4.o: unsquashfs.h unsquash-4.c squashfs_fs.h squashfs_swap.h \
67
	global.h
34
68
69
.PHONY: clean
35
clean:
70
clean:
36
	-rm -f *.o mksquashfs unsquashfs
71
	-rm -f *.o mksquashfs unsquashfs
37
72
73
.PHONY: install
38
install: mksquashfs unsquashfs
74
install: mksquashfs unsquashfs
39
	mkdir -p $(INSTALL_DIR)
75
	mkdir -p $(INSTALL_DIR)
40
	cp mksquashfs $(INSTALL_DIR)
76
	cp mksquashfs $(INSTALL_DIR)
(-)squashfs-tools/mksquashfs.c (-186 / +371 lines)
Lines 36-42 Link Here
36
#include <errno.h>
36
#include <errno.h>
37
#include <dirent.h>
37
#include <dirent.h>
38
#include <string.h>
38
#include <string.h>
39
#include <zlib.h>
40
#include <stdlib.h>
39
#include <stdlib.h>
41
#include <signal.h>
40
#include <signal.h>
42
#include <setjmp.h>
41
#include <setjmp.h>
Lines 47-52 Link Here
47
#include <math.h>
46
#include <math.h>
48
#include <regex.h>
47
#include <regex.h>
49
#include <fnmatch.h>
48
#include <fnmatch.h>
49
#include <sys/wait.h>
50
50
51
#ifndef linux
51
#ifndef linux
52
#define __BYTE_ORDER BYTE_ORDER
52
#define __BYTE_ORDER BYTE_ORDER
Lines 64-69 Link Here
64
#include "global.h"
64
#include "global.h"
65
#include "sort.h"
65
#include "sort.h"
66
#include "pseudo.h"
66
#include "pseudo.h"
67
#include "compressor.h"
67
68
68
#ifdef SQUASHFS_TRACE
69
#ifdef SQUASHFS_TRACE
69
#define TRACE(s, args...)	do { \
70
#define TRACE(s, args...)	do { \
Lines 245-254 char **source_path; Link Here
245
/* list of root directory entries read from original filesystem */
246
/* list of root directory entries read from original filesystem */
246
int old_root_entries = 0;
247
int old_root_entries = 0;
247
struct old_root_entry_info {
248
struct old_root_entry_info {
248
	char			name[SQUASHFS_NAME_LEN + 1];
249
	char			*name;
249
	squashfs_inode		inode;
250
	struct inode_info	inode;
250
	int			type;
251
	int			inode_number;
252
};
251
};
253
struct old_root_entry_info *old_root_entry;
252
struct old_root_entry_info *old_root_entry;
254
253
Lines 371-380 int writer_buffer_size; Link Here
371
int reader_buffer_size;
370
int reader_buffer_size;
372
int fragment_buffer_size;
371
int fragment_buffer_size;
373
372
373
/* compression operations structure */
374
static struct compressor *comp;
375
char *comp_name = COMP_DEFAULT;
376
374
char *read_from_disk(long long start, unsigned int avail_bytes);
377
char *read_from_disk(long long start, unsigned int avail_bytes);
375
void add_old_root_entry(char *name, squashfs_inode inode, int inode_number,
378
void add_old_root_entry(char *name, squashfs_inode inode, int inode_number,
376
	int type);
379
	int type);
377
extern int read_super(int fd, squashfs_super_block *sBlk, char *source);
380
extern struct compressor  *read_super(int fd, squashfs_super_block *sBlk,
381
	char *source);
378
extern long long read_filesystem(char *root_name, int fd,
382
extern long long read_filesystem(char *root_name, int fd,
379
	squashfs_super_block *sBlk, char **cinode_table, char **data_cache,
383
	squashfs_super_block *sBlk, char **cinode_table, char **data_cache,
380
	char **cdirectory_table, char **directory_data_cache,
384
	char **cdirectory_table, char **directory_data_cache,
Lines 831-913 void sigalrm_handler() Link Here
831
}
835
}
832
836
833
837
834
unsigned int mangle2(z_stream **strm, char *d, char *s, int size,
838
int mangle2(void **strm, char *d, char *s, int size,
835
	int block_size, int uncompressed, int data_block)
839
	int block_size, int uncompressed, int data_block)
836
{
840
{
837
	unsigned long c_byte;
841
	int error, c_byte = 0;
838
	unsigned int res;
839
	z_stream *stream = *strm;
840
841
	if(uncompressed)
842
		goto notcompressed;
843
844
	if(stream == NULL) {
845
		if((stream = *strm = malloc(sizeof(z_stream))) == NULL)
846
			BAD_ERROR("mangle::compress failed, not enough "
847
				"memory\n");
848
849
		stream->zalloc = Z_NULL;
850
		stream->zfree = Z_NULL;
851
		stream->opaque = 0;
852
853
		if((res = deflateInit(stream, 9)) != Z_OK) {
854
			if(res == Z_MEM_ERROR)
855
				BAD_ERROR("zlib::compress failed, not enough "
856
					"memory\n");
857
			else if(res == Z_STREAM_ERROR)
858
				BAD_ERROR("zlib::compress failed, not a valid "
859
					"compression level\n");
860
			else if(res == Z_VERSION_ERROR)
861
				BAD_ERROR("zlib::compress failed, incorrect "
862
					"zlib version\n");
863
			else
864
				BAD_ERROR("zlib::compress failed, unknown "
865
					"error %d\n", res);
866
		}
867
	} else if((res = deflateReset(stream)) != Z_OK) {
868
		if(res == Z_STREAM_ERROR)
869
			BAD_ERROR("zlib::compress failed, stream state "
870
				"inconsistent\n");
871
		else
872
			BAD_ERROR("zlib::compress failed, unknown error %d\n",
873
				res);
874
	}
875
842
876
	stream->next_in = (unsigned char *) s;
843
	if(!uncompressed) {
877
	stream->avail_in = size;
844
		c_byte = comp->compress(strm, d, s, size, block_size, &error);
878
	stream->next_out = (unsigned char *) d;
845
		if(c_byte == -1)
879
	stream->avail_out = block_size;
846
			BAD_ERROR("mangle2:: %s compress failed with error "
880
847
				"code %d\n", comp->name, error);
881
	res = deflate(stream, Z_FINISH);
882
	if(res != Z_STREAM_END && res != Z_OK) {
883
		if(res == Z_STREAM_ERROR)
884
			BAD_ERROR("zlib::compress failed, stream state "
885
				"inconsistent\n");
886
		else if(res == Z_BUF_ERROR)
887
			BAD_ERROR("zlib::compress failed, no progress possible"
888
				"\n");
889
		else
890
			BAD_ERROR("zlib::compress failed, unknown error %d\n",
891
				res);
892
	}
848
	}
893
849
894
	c_byte = stream->total_out;
850
	if(c_byte == 0 || c_byte >= size) {
895
896
	if(res != Z_STREAM_END || c_byte >= size) {
897
notcompressed:
898
		memcpy(d, s, size);
851
		memcpy(d, s, size);
899
		return size | (data_block ? SQUASHFS_COMPRESSED_BIT_BLOCK :
852
		return size | (data_block ? SQUASHFS_COMPRESSED_BIT_BLOCK :
900
			SQUASHFS_COMPRESSED_BIT);
853
			SQUASHFS_COMPRESSED_BIT);
901
	}
854
	}
902
855
903
	return (unsigned int) c_byte;
856
	return c_byte;
904
}
857
}
905
858
906
859
907
unsigned int mangle(char *d, char *s, int size, int block_size,
860
int mangle(char *d, char *s, int size, int block_size,
908
	int uncompressed, int data_block)
861
	int uncompressed, int data_block)
909
{
862
{
910
	static z_stream *stream = NULL;
863
	static void *stream = NULL;
911
864
912
	return mangle2(&stream, d, s, size, block_size, uncompressed,
865
	return mangle2(&stream, d, s, size, block_size, uncompressed,
913
		data_block);
866
		data_block);
Lines 1660-1667 struct file_buffer *get_fragment(struct Link Here
1660
	pthread_mutex_unlock(&fragment_mutex);
1613
	pthread_mutex_unlock(&fragment_mutex);
1661
1614
1662
	if(SQUASHFS_COMPRESSED_BLOCK(disk_fragment->size)) {
1615
	if(SQUASHFS_COMPRESSED_BLOCK(disk_fragment->size)) {
1663
		int res;
1616
		int error, res;
1664
		unsigned long bytes = block_size;
1665
		char *data;
1617
		char *data;
1666
1618
1667
		if(compressed_buffer)
1619
		if(compressed_buffer)
Lines 1669-1687 struct file_buffer *get_fragment(struct Link Here
1669
		else
1621
		else
1670
			data = read_from_disk(start_block, size);
1622
			data = read_from_disk(start_block, size);
1671
1623
1672
		res = uncompress((unsigned char *) buffer->data, &bytes,
1624
		res = comp->uncompress(buffer->data, data, size, block_size,
1673
			(const unsigned char *) data, size);
1625
			&error);
1674
		if(res != Z_OK) {
1626
		if(res == -1)
1675
			if(res == Z_MEM_ERROR)
1627
			BAD_ERROR("%s uncompress failed with error code %d\n",
1676
				BAD_ERROR("zlib::uncompress failed, not enough "
1628
				comp->name, error);
1677
					"memory\n");
1678
			else if(res == Z_BUF_ERROR)
1679
				BAD_ERROR("zlib::uncompress failed, not enough "
1680
					"room in output buffer\n");
1681
			else
1682
				BAD_ERROR("zlib::uncompress failed,"
1683
					"  unknown error %d\n", res);
1684
		}
1685
	} else if(compressed_buffer)
1629
	} else if(compressed_buffer)
1686
		memcpy(buffer->data, compressed_buffer->data, size);
1630
		memcpy(buffer->data, compressed_buffer->data, size);
1687
	else
1631
	else
Lines 1733-1741 void unlock_fragments() Link Here
1733
		entry->buffer->block = bytes;
1677
		entry->buffer->block = bytes;
1734
		bytes += compressed_size;
1678
		bytes += compressed_size;
1735
		fragments_outstanding --;
1679
		fragments_outstanding --;
1736
		pthread_mutex_unlock(&fragment_mutex);
1737
		queue_put(to_writer, entry->buffer);
1680
		queue_put(to_writer, entry->buffer);
1738
		pthread_mutex_lock(&fragment_mutex);
1739
		TRACE("fragment_locked writing fragment %d, compressed size %d"
1681
		TRACE("fragment_locked writing fragment %d, compressed size %d"
1740
			"\n", entry->fragment, compressed_size);
1682
			"\n", entry->fragment, compressed_size);
1741
		free(entry);
1683
		free(entry);
Lines 1758-1763 int add_pending_fragment(struct file_buf Link Here
1758
	pthread_mutex_lock(&fragment_mutex);
1700
	pthread_mutex_lock(&fragment_mutex);
1759
	insert_fragment_list(&frag_locked_list, entry);
1701
	insert_fragment_list(&frag_locked_list, entry);
1760
	pthread_mutex_unlock(&fragment_mutex);
1702
	pthread_mutex_unlock(&fragment_mutex);
1703
1704
	return TRUE;
1761
}
1705
}
1762
1706
1763
1707
Lines 1824-1830 long long generic_write_table(int length Link Here
1824
	unsigned short c_byte;
1768
	unsigned short c_byte;
1825
	char cbuffer[(SQUASHFS_METADATA_SIZE << 2) + 2];
1769
	char cbuffer[(SQUASHFS_METADATA_SIZE << 2) + 2];
1826
	
1770
	
1771
#ifdef SQUASHFS_TRACE
1827
	long long obytes = bytes;
1772
	long long obytes = bytes;
1773
#endif
1828
1774
1829
	for(i = 0; i < meta_blocks; i++) {
1775
	for(i = 0; i < meta_blocks; i++) {
1830
		int avail_bytes = length > SQUASHFS_METADATA_SIZE ?
1776
		int avail_bytes = length > SQUASHFS_METADATA_SIZE ?
Lines 2170-2180 struct file_info *duplicate(long long fi Link Here
2170
}
2116
}
2171
2117
2172
2118
2119
static int seq = 0;
2120
void reader_read_process(struct dir_ent *dir_ent)
2121
{
2122
	struct file_buffer *prev_buffer = NULL, *file_buffer;
2123
	int status, res, byte, count = 0;
2124
	int file = get_pseudo_file(dir_ent->inode->pseudo_id)->fd;
2125
	int child = get_pseudo_file(dir_ent->inode->pseudo_id)->child;
2126
	long long bytes = 0;
2127
2128
	while(1) {
2129
		file_buffer = cache_get(reader_buffer, 0, 0);
2130
		file_buffer->sequence = seq ++;
2131
2132
		byte = read_bytes(file, file_buffer->data, block_size);
2133
		if(byte == -1)
2134
			goto read_err;
2135
2136
		file_buffer->size = byte;
2137
		file_buffer->file_size = -1;
2138
		file_buffer->block = count ++;
2139
		file_buffer->error = FALSE;
2140
		file_buffer->fragment = FALSE;
2141
		bytes += byte;
2142
2143
		if(byte == 0)
2144
			break;
2145
2146
		/*
2147
		 * Update estimated_uncompressed block count.  This is done
2148
		 * on every block rather than waiting for all blocks to be
2149
		 * read incase write_file_process() is running in parallel
2150
		 * with this.  Otherwise cur uncompressed block count may
2151
		 * get ahead of the total uncompressed block count.
2152
		 */ 
2153
		estimated_uncompressed ++;
2154
2155
		if(prev_buffer)
2156
			queue_put(from_reader, prev_buffer);
2157
		prev_buffer = file_buffer;
2158
	}
2159
2160
	/*
2161
 	 * Update inode file size now that the size of the dynamic pseudo file
2162
	 * is known.  This is needed for the -info option.
2163
	 */
2164
	dir_ent->inode->buf.st_size = bytes;
2165
2166
	res = waitpid(child, &status, 0);
2167
	if(res == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0)
2168
		goto read_err;
2169
2170
	if(prev_buffer == NULL)
2171
		prev_buffer = file_buffer;
2172
	else {
2173
		cache_block_put(file_buffer);
2174
		seq --;
2175
	}
2176
	prev_buffer->file_size = bytes;
2177
	prev_buffer->fragment = !no_fragments &&
2178
		(count == 2 || always_use_fragments) && (byte < block_size);
2179
	queue_put(from_reader, prev_buffer);
2180
2181
	return;
2182
2183
read_err:
2184
	if(prev_buffer) {
2185
		cache_block_put(file_buffer);
2186
		seq --;
2187
		file_buffer = prev_buffer;
2188
	}
2189
	file_buffer->error = TRUE;
2190
	queue_put(from_deflate, file_buffer);
2191
}
2192
2193
2173
void reader_read_file(struct dir_ent *dir_ent)
2194
void reader_read_file(struct dir_ent *dir_ent)
2174
{
2195
{
2175
	struct stat *buf = &dir_ent->inode->buf, buf2;
2196
	struct stat *buf = &dir_ent->inode->buf, buf2;
2176
	struct file_buffer *file_buffer;
2197
	struct file_buffer *file_buffer;
2177
	static int index = 0;
2178
	int blocks, byte, count, expected, file, frag_block;
2198
	int blocks, byte, count, expected, file, frag_block;
2179
	long long bytes, read_size;
2199
	long long bytes, read_size;
2180
2200
Lines 2202-2208 again: Link Here
2202
		if(file_buffer)
2222
		if(file_buffer)
2203
			queue_put(from_reader, file_buffer);
2223
			queue_put(from_reader, file_buffer);
2204
		file_buffer = cache_get(reader_buffer, 0, 0);
2224
		file_buffer = cache_get(reader_buffer, 0, 0);
2205
		file_buffer->sequence = index ++;
2225
		file_buffer->sequence = seq ++;
2206
2226
2207
		byte = file_buffer->size = read_bytes(file, file_buffer->data,
2227
		byte = file_buffer->size = read_bytes(file, file_buffer->data,
2208
			block_size);
2228
			block_size);
Lines 2238-2244 again: Link Here
2238
2258
2239
read_err:
2259
read_err:
2240
	file_buffer = cache_get(reader_buffer, 0, 0);
2260
	file_buffer = cache_get(reader_buffer, 0, 0);
2241
	file_buffer->sequence = index ++;
2261
	file_buffer->sequence = seq ++;
2242
read_err2:
2262
read_err2:
2243
	file_buffer->error = TRUE;
2263
	file_buffer->error = TRUE;
2244
	queue_put(from_deflate, file_buffer);
2264
	queue_put(from_deflate, file_buffer);
Lines 2262-2270 void reader_scan(struct dir_info *dir) { Link Here
2262
	for(i = 0; i < dir->count; i++) {
2282
	for(i = 0; i < dir->count; i++) {
2263
		struct dir_ent *dir_ent = dir->list[i];
2283
		struct dir_ent *dir_ent = dir->list[i];
2264
		struct stat *buf = &dir_ent->inode->buf;
2284
		struct stat *buf = &dir_ent->inode->buf;
2265
		if(dir_ent->data)
2285
		if(dir_ent->inode->root_entry)
2266
			continue;
2286
			continue;
2267
2287
2288
		if(dir_ent->inode->pseudo_file) {
2289
			reader_read_process(dir_ent);
2290
			continue;
2291
		}
2292
2268
		switch(buf->st_mode & S_IFMT) {
2293
		switch(buf->st_mode & S_IFMT) {
2269
			case S_IFREG:
2294
			case S_IFREG:
2270
				reader_read_file(dir_ent);
2295
				reader_read_file(dir_ent);
Lines 2365-2371 int all_zero(struct file_buffer *file_bu Link Here
2365
2390
2366
void *deflator(void *arg)
2391
void *deflator(void *arg)
2367
{
2392
{
2368
	z_stream *stream = NULL;
2393
	void *stream = NULL;
2369
	int oldstate;
2394
	int oldstate;
2370
2395
2371
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
2396
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
Lines 2402-2408 void *deflator(void *arg) Link Here
2402
2427
2403
void *frag_deflator(void *arg)
2428
void *frag_deflator(void *arg)
2404
{
2429
{
2405
	z_stream *stream = NULL;
2430
	void *stream = NULL;
2406
	int oldstate;
2431
	int oldstate;
2407
2432
2408
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
2433
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
Lines 2426-2433 void *frag_deflator(void *arg) Link Here
2426
			write_buffer->block = bytes;
2451
			write_buffer->block = bytes;
2427
			bytes += compressed_size;
2452
			bytes += compressed_size;
2428
			fragments_outstanding --;
2453
			fragments_outstanding --;
2429
			pthread_mutex_unlock(&fragment_mutex);
2430
			queue_put(to_writer, write_buffer);
2454
			queue_put(to_writer, write_buffer);
2455
			pthread_mutex_unlock(&fragment_mutex);
2431
			TRACE("Writing fragment %lld, uncompressed size %d, "
2456
			TRACE("Writing fragment %lld, uncompressed size %d, "
2432
				"compressed size %d\n", file_buffer->block,
2457
				"compressed size %d\n", file_buffer->block,
2433
				file_buffer->size, compressed_size);
2458
				file_buffer->size, compressed_size);
Lines 2674-2679 void write_file_frag(squashfs_inode *ino Link Here
2674
}
2699
}
2675
2700
2676
2701
2702
int write_file_process(squashfs_inode *inode, struct dir_ent *dir_ent,
2703
	struct file_buffer *read_buffer, int *duplicate_file)
2704
{
2705
	long long read_size, file_bytes, start;
2706
	struct fragment *fragment;
2707
	unsigned int *block_list = NULL;
2708
	int block = 0, status;
2709
	long long sparse = 0;
2710
	struct file_buffer *fragment_buffer = NULL;
2711
2712
	*duplicate_file = FALSE;
2713
2714
	lock_fragments();
2715
2716
	file_bytes = 0;
2717
	start = bytes;
2718
	while (1) {
2719
		read_size = read_buffer->file_size;
2720
		if(read_buffer->fragment && read_buffer->c_byte)
2721
			fragment_buffer = read_buffer;
2722
		else {
2723
			block_list = realloc(block_list, (block + 1) *
2724
				sizeof(unsigned int));
2725
			if(block_list == NULL)
2726
				BAD_ERROR("Out of memory allocating block_list"
2727
					"\n");
2728
			block_list[block ++] = read_buffer->c_byte;
2729
			if(read_buffer->c_byte) {
2730
				read_buffer->block = bytes;
2731
				bytes += read_buffer->size;
2732
				cache_rehash(read_buffer, read_buffer->block);
2733
				file_bytes += read_buffer->size;
2734
				queue_put(to_writer, read_buffer);
2735
			} else {
2736
				sparse += read_buffer->size;
2737
				cache_block_put(read_buffer);
2738
			}
2739
		}
2740
		inc_progress_bar();
2741
2742
		if(read_size != -1)
2743
			break;
2744
2745
		read_buffer = get_file_buffer(from_deflate);
2746
		if(read_buffer->error)
2747
			goto read_err;
2748
	}
2749
2750
	unlock_fragments();
2751
	fragment = get_and_fill_fragment(fragment_buffer);
2752
	cache_block_put(fragment_buffer);
2753
2754
	if(duplicate_checking)
2755
		add_non_dup(read_size, file_bytes, block_list, start, fragment,
2756
			0, 0, FALSE);
2757
	file_count ++;
2758
	total_bytes += read_size;
2759
2760
	if(read_size < (1LL << 32) && start < (1LL << 32) && sparse == 0)
2761
		create_inode(inode, dir_ent, SQUASHFS_FILE_TYPE, read_size,
2762
			start, block, block_list, fragment, NULL, 0);
2763
	else
2764
		create_inode(inode, dir_ent, SQUASHFS_LREG_TYPE, read_size,
2765
			start, block, block_list, fragment, NULL, sparse);
2766
2767
	if(duplicate_checking == FALSE)
2768
		free(block_list);
2769
2770
	return 0;
2771
2772
read_err:
2773
	cur_uncompressed -= block;
2774
	status = read_buffer->error;
2775
	bytes = start;
2776
	if(!block_device) {
2777
		int res;
2778
2779
		queue_put(to_writer, NULL);
2780
		if(queue_get(from_writer) != 0)
2781
			EXIT_MKSQUASHFS();
2782
		res = ftruncate(fd, bytes);
2783
		if(res != 0)
2784
			BAD_ERROR("Failed to truncate dest file because %s\n",
2785
				strerror(errno));
2786
	}
2787
	unlock_fragments();
2788
	free(block_list);
2789
	cache_block_put(read_buffer);
2790
	return status;
2791
}
2792
2793
2677
int write_file_blocks(squashfs_inode *inode, struct dir_ent *dir_ent,
2794
int write_file_blocks(squashfs_inode *inode, struct dir_ent *dir_ent,
2678
	long long read_size, struct file_buffer *read_buffer,
2795
	long long read_size, struct file_buffer *read_buffer,
2679
	int *duplicate_file)
2796
	int *duplicate_file)
Lines 2941-2947 again: Link Here
2941
	
3058
	
2942
	read_size = read_buffer->file_size;
3059
	read_size = read_buffer->file_size;
2943
3060
2944
	if(read_size == 0) {
3061
	if(read_size == -1)
3062
		status = write_file_process(inode, dir_ent, read_buffer,
3063
			duplicate_file);
3064
	else if(read_size == 0) {
2945
		write_file_empty(inode, dir_ent, duplicate_file);
3065
		write_file_empty(inode, dir_ent, duplicate_file);
2946
		cache_block_put(read_buffer);
3066
		cache_block_put(read_buffer);
2947
	} else if(read_buffer->fragment && read_buffer->c_byte)
3067
	} else if(read_buffer->fragment && read_buffer->c_byte)
Lines 3036-3041 struct inode_info *lookup_inode(struct s Link Here
3036
3156
3037
	memcpy(&inode->buf, buf, sizeof(struct stat));
3157
	memcpy(&inode->buf, buf, sizeof(struct stat));
3038
	inode->read = FALSE;
3158
	inode->read = FALSE;
3159
	inode->root_entry = FALSE;
3160
	inode->pseudo_file = FALSE;
3039
	inode->inode = SQUASHFS_INVALID_BLK;
3161
	inode->inode = SQUASHFS_INVALID_BLK;
3040
	inode->nlink = 1;
3162
	inode->nlink = 1;
3041
3163
Lines 3056-3062 struct inode_info *lookup_inode(struct s Link Here
3056
3178
3057
3179
3058
inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir,
3180
inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir,
3059
	struct inode_info *inode_info, void *data, struct dir_info *dir)
3181
	struct inode_info *inode_info, struct dir_info *dir)
3060
{
3182
{
3061
	if((dir->count % DIR_ENTRIES) == 0) {
3183
	if((dir->count % DIR_ENTRIES) == 0) {
3062
		dir->list = realloc(dir->list, (dir->count + DIR_ENTRIES) *
3184
		dir->list = realloc(dir->list, (dir->count + DIR_ENTRIES) *
Lines 3075-3082 inline void add_dir_entry(char *name, ch Link Here
3075
		NULL;
3197
		NULL;
3076
	dir->list[dir->count]->inode = inode_info;
3198
	dir->list[dir->count]->inode = inode_info;
3077
	dir->list[dir->count]->dir = sub_dir;
3199
	dir->list[dir->count]->dir = sub_dir;
3078
	dir->list[dir->count]->our_dir = dir;
3200
	dir->list[dir->count++]->our_dir = dir;
3079
	dir->list[dir->count++]->data = data;
3080
	dir->byte_count += strlen(name) + sizeof(squashfs_dir_entry);
3201
	dir->byte_count += strlen(name) + sizeof(squashfs_dir_entry);
3081
}
3202
}
3082
3203
Lines 3128-3137 int scan1_encomp_readdir(char *pathname, Link Here
3128
3249
3129
	if(dir->count < old_root_entries)
3250
	if(dir->count < old_root_entries)
3130
		for(i = 0; i < old_root_entries; i++) {
3251
		for(i = 0; i < old_root_entries; i++) {
3131
			if(old_root_entry[i].type == SQUASHFS_DIR_TYPE)
3252
			if(old_root_entry[i].inode.type == SQUASHFS_DIR_TYPE)
3132
				dir->directory_count ++;
3253
				dir->directory_count ++;
3133
			add_dir_entry(old_root_entry[i].name, "", NULL, NULL,
3254
			add_dir_entry(old_root_entry[i].name, "", NULL,
3134
				&old_root_entry[i], dir);
3255
				&old_root_entry[i].inode, dir);
3135
		}
3256
		}
3136
3257
3137
	while(index < source) {
3258
	while(index < source) {
Lines 3167-3176 int scan1_single_readdir(char *pathname, Link Here
3167
3288
3168
	if(dir->count < old_root_entries)
3289
	if(dir->count < old_root_entries)
3169
		for(i = 0; i < old_root_entries; i++) {
3290
		for(i = 0; i < old_root_entries; i++) {
3170
			if(old_root_entry[i].type == SQUASHFS_DIR_TYPE)
3291
			if(old_root_entry[i].inode.type == SQUASHFS_DIR_TYPE)
3171
				dir->directory_count ++;
3292
				dir->directory_count ++;
3172
			add_dir_entry(old_root_entry[i].name, "", NULL, NULL,
3293
			add_dir_entry(old_root_entry[i].name, "", NULL,
3173
				&old_root_entry[i], dir);
3294
				&old_root_entry[i].inode, dir);
3174
		}
3295
		}
3175
3296
3176
	if((d_name = readdir(dir->linuxdir)) != NULL) {
3297
	if((d_name = readdir(dir->linuxdir)) != NULL) {
Lines 3215-3221 struct dir_ent *scan2_readdir(struct dir Link Here
3215
	int current_count;
3336
	int current_count;
3216
3337
3217
	while((current_count = dir_info->current_count++) < dir_info->count)
3338
	while((current_count = dir_info->current_count++) < dir_info->count)
3218
		if(dir_info->list[current_count]->data)
3339
		if(dir_info->list[current_count]->inode->root_entry)
3219
			continue;
3340
			continue;
3220
		else 
3341
		else 
3221
			return dir_info->list[current_count];
3342
			return dir_info->list[current_count];
Lines 3240-3250 struct dir_ent *scan3_readdir(struct dir Link Here
3240
	int current_count;
3361
	int current_count;
3241
3362
3242
	while((current_count = dir_info->current_count++) < dir_info->count)
3363
	while((current_count = dir_info->current_count++) < dir_info->count)
3243
		if(dir_info->list[current_count]->data)
3364
		if(dir_info->list[current_count]->inode->root_entry)
3244
			add_dir(dir_info->list[current_count]->data->inode,
3365
			add_dir(dir_info->list[current_count]->inode->inode,
3245
				dir_info->list[current_count]->data->inode_number,
3366
				dir_info->list[current_count]->inode->inode_number,
3246
				dir_info->list[current_count]->name,
3367
				dir_info->list[current_count]->name,
3247
				dir_info->list[current_count]->data->type, dir);
3368
				dir_info->list[current_count]->inode->type, dir);
3248
		else 
3369
		else 
3249
			return dir_info->list[current_count];
3370
			return dir_info->list[current_count];
3250
	return NULL;	
3371
	return NULL;	
Lines 3313-3319 void dir_scan(squashfs_inode *inode, cha Link Here
3313
	dir_ent->name = dir_ent->pathname = strdup(pathname);
3434
	dir_ent->name = dir_ent->pathname = strdup(pathname);
3314
	dir_ent->dir = dir_info;
3435
	dir_ent->dir = dir_info;
3315
	dir_ent->our_dir = NULL;
3436
	dir_ent->our_dir = NULL;
3316
	dir_ent->data = NULL;
3317
	dir_info->dir_ent = dir_ent;
3437
	dir_info->dir_ent = dir_ent;
3318
3438
3319
	if(sorted)
3439
	if(sorted)
Lines 3383-3389 struct dir_info *dir_scan1(char *pathnam Link Here
3383
			sub_dir = NULL;
3503
			sub_dir = NULL;
3384
3504
3385
		add_dir_entry(dir_name, filename, sub_dir, lookup_inode(&buf),
3505
		add_dir_entry(dir_name, filename, sub_dir, lookup_inode(&buf),
3386
			NULL, dir);
3506
			dir);
3387
	}
3507
	}
3388
3508
3389
	scan1_freedir(dir);
3509
	scan1_freedir(dir);
Lines 3399-3405 struct dir_info *dir_scan2(struct dir_in Link Here
3399
	struct dir_ent *dir_ent;
3519
	struct dir_ent *dir_ent;
3400
	struct pseudo_entry *pseudo_ent;
3520
	struct pseudo_entry *pseudo_ent;
3401
	struct stat buf;
3521
	struct stat buf;
3402
	static pseudo_ino = 1;
3522
	static int pseudo_ino = 1;
3403
	
3523
	
3404
	if(dir == NULL && (dir = scan1_opendir("")) == NULL)
3524
	if(dir == NULL && (dir = scan1_opendir("")) == NULL)
3405
		return NULL;
3525
		return NULL;
Lines 3415-3420 struct dir_info *dir_scan2(struct dir_in Link Here
3415
3535
3416
	while((pseudo_ent = pseudo_readdir(pseudo)) != NULL) {
3536
	while((pseudo_ent = pseudo_readdir(pseudo)) != NULL) {
3417
		dir_ent = scan2_lookup(dir, pseudo_ent->name);
3537
		dir_ent = scan2_lookup(dir, pseudo_ent->name);
3538
		if(pseudo_ent->dev->type == 's') {
3539
			struct stat *buf;
3540
			if(dir_ent == NULL) {
3541
				ERROR("Pseudo set file \"%s\" does not exist "
3542
					"in source filesystem.  Ignoring\n",
3543
					pseudo_ent->pathname);
3544
				continue;
3545
			}
3546
			if(dir_ent->inode->root_entry) {
3547
				ERROR("Pseudo set file \"%s\" is a pre-existing"
3548
					" file in the filesystem being appended"
3549
					"  to.  It cannot be modified. "
3550
					"Ignoring!\n", pseudo_ent->pathname);
3551
				continue;
3552
			}
3553
			buf = &dir_ent->inode->buf;
3554
			buf->st_mode = (buf->st_mode & S_IFMT) |
3555
				pseudo_ent->dev->mode;
3556
			buf->st_uid = pseudo_ent->dev->uid;
3557
			buf->st_gid = pseudo_ent->dev->gid;
3558
			continue;
3559
		}
3560
3418
		if(dir_ent) {
3561
		if(dir_ent) {
3419
			ERROR("Pseudo file \"%s\" exists in source filesystem "
3562
			ERROR("Pseudo file \"%s\" exists in source filesystem "
3420
				"\"%s\"\n", pseudo_ent->pathname,
3563
				"\"%s\"\n", pseudo_ent->pathname,
Lines 3444-3451 struct dir_info *dir_scan2(struct dir_in Link Here
3444
		buf.st_mtime = time(NULL);
3587
		buf.st_mtime = time(NULL);
3445
		buf.st_ino = pseudo_ino ++;
3588
		buf.st_ino = pseudo_ino ++;
3446
3589
3447
		add_dir_entry(pseudo_ent->name, pseudo_ent->pathname, sub_dir,
3590
		if(pseudo_ent->dev->type == 'f') {
3448
			lookup_inode(&buf), NULL, dir);
3591
#ifdef USE_TMP_FILE
3592
			struct stat buf2;
3593
			int res = stat(pseudo_ent->dev->filename, &buf2);
3594
			if(res == -1) {
3595
				ERROR("Stat on pseudo file \"%s\" failed, "
3596
					"skipping...", pseudo_ent->pathname);
3597
				continue;
3598
			}
3599
			buf.st_size = buf2.st_size;
3600
			add_dir_entry(pseudo_ent->name,
3601
				pseudo_ent->dev->filename, sub_dir,
3602
				lookup_inode(&buf), dir);
3603
#else
3604
			struct inode_info *inode = lookup_inode(&buf);
3605
			inode->pseudo_id = pseudo_ent->dev->pseudo_id;
3606
			inode->pseudo_file = TRUE;		
3607
			add_dir_entry(pseudo_ent->name, pseudo_ent->pathname,
3608
				sub_dir, inode, dir);
3609
#endif
3610
		} else
3611
			add_dir_entry(pseudo_ent->name, pseudo_ent->pathname,
3612
				sub_dir, lookup_inode(&buf), dir);
3449
	}
3613
	}
3450
3614
3451
	scan2_freedir(dir);
3615
	scan2_freedir(dir);
Lines 3482-3489 void dir_scan3(squashfs_inode *inode, st Link Here
3482
						&duplicate_file);
3646
						&duplicate_file);
3483
					INFO("file %s, uncompressed size %lld "
3647
					INFO("file %s, uncompressed size %lld "
3484
						"bytes %s\n", filename,
3648
						"bytes %s\n", filename,
3485
						buf->st_size, duplicate_file ?
3649
						(long long) buf->st_size,
3486
						"DUPLICATE" : "");
3650
						duplicate_file ?  "DUPLICATE" :
3651
						 "");
3487
					break;
3652
					break;
3488
3653
3489
				case S_IFDIR:
3654
				case S_IFDIR:
Lines 3557-3562 void dir_scan3(squashfs_inode *inode, st Link Here
3557
						INFO("file %s, uncompressed "
3722
						INFO("file %s, uncompressed "
3558
							"size %lld bytes LINK"
3723
							"size %lld bytes LINK"
3559
							"\n", filename,
3724
							"\n", filename,
3725
							(long long)
3560
							buf->st_size);
3726
							buf->st_size);
3561
					break;
3727
					break;
3562
				case SQUASHFS_SYMLINK_TYPE:
3728
				case SQUASHFS_SYMLINK_TYPE:
Lines 3667-3676 void add_old_root_entry(char *name, squa Link Here
3667
		BAD_ERROR("Out of memory in old root directory entries "
3833
		BAD_ERROR("Out of memory in old root directory entries "
3668
			"reallocation\n");
3834
			"reallocation\n");
3669
3835
3670
	strcpy(old_root_entry[old_root_entries].name, name);
3836
	old_root_entry[old_root_entries].name = strdup(name);
3671
	old_root_entry[old_root_entries].inode = inode;
3837
	old_root_entry[old_root_entries].inode.inode = inode;
3672
	old_root_entry[old_root_entries].inode_number = inode_number;
3838
	old_root_entry[old_root_entries].inode.inode_number = inode_number;
3673
	old_root_entry[old_root_entries++].type = type;
3839
	old_root_entry[old_root_entries].inode.type = type;
3840
	old_root_entry[old_root_entries++].inode.root_entry = TRUE;
3674
}
3841
}
3675
3842
3676
3843
Lines 4172-4197 int main(int argc, char *argv[]) Link Here
4172
	source_path = argv + 1;
4339
	source_path = argv + 1;
4173
	source = i - 2;
4340
	source = i - 2;
4174
	for(; i < argc; i++) {
4341
	for(; i < argc; i++) {
4175
		if(strcmp(argv[i], "-pf") == 0) {
4342
		if(strcmp(argv[i], "-comp") == 0) {
4176
			if(++i == argc) {
4343
			if(++i == argc) {
4177
				ERROR("%s: -pf missing filename\n", argv[0]);
4344
				ERROR("%s: -comp missing compression type\n",
4345
					argv[0]);
4178
				exit(1);
4346
				exit(1);
4179
			}
4347
			}
4180
			if(read_pseudo_file(&pseudo, argv[i]) == FALSE) {
4348
			comp_name = argv[i];
4181
				ERROR("Failed to parse pseudo file \"%s\"\n",
4349
		} else if(strcmp(argv[i], "-pf") == 0) {
4182
					argv[i]);
4350
			if(++i == argc) {
4351
				ERROR("%s: -pf missing filename\n", argv[0]);
4183
				exit(1);
4352
				exit(1);
4184
			}
4353
			}
4354
			if(read_pseudo_file(&pseudo, argv[i]) == FALSE)
4355
				exit(1);
4185
		} else if(strcmp(argv[i], "-p") == 0) {
4356
		} else if(strcmp(argv[i], "-p") == 0) {
4186
			if(++i == argc) {
4357
			if(++i == argc) {
4187
				ERROR("%s: -p missing pseudo file definition\n",
4358
				ERROR("%s: -p missing pseudo file definition\n",
4188
					argv[0]);
4359
					argv[0]);
4189
				exit(1);
4360
				exit(1);
4190
			}
4361
			}
4191
			if(read_pseudo_def(&pseudo, argv[i]) == FALSE) {
4362
			if(read_pseudo_def(&pseudo, argv[i]) == FALSE)
4192
				ERROR("Failed to parse pseudo definition\n");
4193
				exit(1);
4363
				exit(1);
4194
			}
4195
		} else if(strcmp(argv[i], "-recover") == 0) {
4364
		} else if(strcmp(argv[i], "-recover") == 0) {
4196
			if(++i == argc) {
4365
			if(++i == argc) {
4197
				ERROR("%s: -recover missing recovery file\n",
4366
				ERROR("%s: -recover missing recovery file\n",
Lines 4394-4427 int main(int argc, char *argv[]) Link Here
4394
printOptions:
4563
printOptions:
4395
			ERROR("SYNTAX:%s source1 source2 ...  dest [options] "
4564
			ERROR("SYNTAX:%s source1 source2 ...  dest [options] "
4396
				"[-e list of exclude\ndirs/files]\n", argv[0]);
4565
				"[-e list of exclude\ndirs/files]\n", argv[0]);
4397
			ERROR("\nOptions are\n");
4566
			ERROR("\nFilesystem build options:\n");
4398
			ERROR("-version\t\tprint version, licence and "
4567
			ERROR("-comp <comp>\t\tselect <comp> compression\n");
4399
				"copyright message\n");
4568
			ERROR("\t\t\tCompressors available:\n");
4400
			ERROR("-recover <name>\t\trecover filesystem data "
4569
			display_compressors("\t\t\t", COMP_DEFAULT);
4401
				"using recovery file <name>\n");
4402
			ERROR("-no-recovery\t\tdon't generate a recovery "
4403
				"file\n");
4404
			ERROR("-info\t\t\tprint files written to filesystem\n");
4405
			ERROR("-no-exports\t\tdon't make the filesystem "
4406
				"exportable via NFS\n");
4407
			ERROR("-no-progress\t\tdon't display the progress "
4408
				"bar\n");
4409
			ERROR("-no-sparse\t\tdon't detect sparse files\n");
4410
			ERROR("-b <block_size>\t\tset data block to "
4570
			ERROR("-b <block_size>\t\tset data block to "
4411
				"<block_size>.  Default %d bytes\n",
4571
				"<block_size>.  Default %d bytes\n",
4412
				SQUASHFS_FILE_SIZE);
4572
				SQUASHFS_FILE_SIZE);
4413
			ERROR("-processors <number>\tUse <number> processors."
4573
			ERROR("-no-exports\t\tdon't make the filesystem "
4414
				"  By default will use number of\n");
4574
				"exportable via NFS\n");
4415
			ERROR("\t\t\tprocessors available\n");
4575
			ERROR("-no-sparse\t\tdon't detect sparse files\n");
4416
			ERROR("-read-queue <size>\tSet input queue to <size> "
4417
				"Mbytes.  Default %d Mbytes\n",
4418
				READER_BUFFER_DEFAULT);
4419
			ERROR("-write-queue <size>\tSet output queue to <size> "
4420
				"Mbytes.  Default %d Mbytes\n",
4421
				WRITER_BUFFER_DEFAULT);
4422
			ERROR("-fragment-queue <size>\tSet fagment queue to "
4423
				"<size> Mbytes.  Default %d Mbytes\n",
4424
				FRAGMENT_BUFFER_DEFAULT);
4425
			ERROR("-noI\t\t\tdo not compress inode table\n");
4576
			ERROR("-noI\t\t\tdo not compress inode table\n");
4426
			ERROR("-noD\t\t\tdo not compress data blocks\n");
4577
			ERROR("-noD\t\t\tdo not compress data blocks\n");
4427
			ERROR("-noF\t\t\tdo not compress fragment blocks\n");
4578
			ERROR("-noF\t\t\tdo not compress fragment blocks\n");
Lines 4430-4442 printOptions: Link Here
4430
				"files larger than block size\n");
4581
				"files larger than block size\n");
4431
			ERROR("-no-duplicates\t\tdo not perform duplicate "
4582
			ERROR("-no-duplicates\t\tdo not perform duplicate "
4432
				"checking\n");
4583
				"checking\n");
4433
			ERROR("-noappend\t\tdo not append to existing "
4584
			ERROR("-all-root\t\tmake all files owned by root\n");
4434
				"filesystem\n");
4585
			ERROR("-force-uid uid\t\tset all file uids to uid\n");
4586
			ERROR("-force-gid gid\t\tset all file gids to gid\n");
4587
			ERROR("-nopad\t\t\tdo not pad filesystem to a multiple "
4588
				"of 4K\n");
4435
			ERROR("-keep-as-directory\tif one source directory is "
4589
			ERROR("-keep-as-directory\tif one source directory is "
4436
				"specified, create a root\n");
4590
				"specified, create a root\n");
4437
			ERROR("\t\t\tdirectory containing that directory, "
4591
			ERROR("\t\t\tdirectory containing that directory, "
4438
				"rather than the\n");
4592
				"rather than the\n");
4439
			ERROR("\t\t\tcontents of the directory\n");
4593
			ERROR("\t\t\tcontents of the directory\n");
4594
			ERROR("\nFilesystem filter options:\n");
4595
			ERROR("-p <pseudo-definition>\tAdd pseudo file definition\n");
4596
			ERROR("-pf <pseudo-file>\tAdd list of pseudo file definitions\n");
4597
			ERROR("-sort <sort_file>\tsort files according to "
4598
				"priorities in <sort_file>.  One\n");
4599
			ERROR("\t\t\tfile or dir with priority per line.  "
4600
				"Priority -32768 to\n");
4601
			ERROR("\t\t\t32767, default priority 0\n");
4602
			ERROR("-ef <exclude_file>\tlist of exclude dirs/files."
4603
				"  One per line\n");
4604
			ERROR("-wildcards\t\tAllow extended shell wildcards "
4605
				"(globbing) to be used in\n\t\t\texclude "
4606
				"dirs/files\n");
4607
			ERROR("-regex\t\t\tAllow POSIX regular expressions to "
4608
				"be used in exclude\n\t\t\tdirs/files\n");
4609
			ERROR("\nFilesystem append options:\n");
4610
			ERROR("-noappend\t\tdo not append to existing "
4611
				"filesystem\n");
4440
			ERROR("-root-becomes <name>\twhen appending source "
4612
			ERROR("-root-becomes <name>\twhen appending source "
4441
				"files/directories, make the\n");
4613
				"files/directories, make the\n");
4442
			ERROR("\t\t\toriginal root become a subdirectory in "
4614
			ERROR("\t\t\toriginal root become a subdirectory in "
Lines 4444-4454 printOptions: Link Here
4444
			ERROR("\t\t\tcalled <name>, rather than adding the new "
4616
			ERROR("\t\t\tcalled <name>, rather than adding the new "
4445
				"source items\n");
4617
				"source items\n");
4446
			ERROR("\t\t\tto the original root\n");
4618
			ERROR("\t\t\tto the original root\n");
4447
			ERROR("-all-root\t\tmake all files owned by root\n");
4619
			ERROR("\nMksquashfs runtime options:\n");
4448
			ERROR("-force-uid uid\t\tset all file uids to uid\n");
4620
			ERROR("-version\t\tprint version, licence and "
4449
			ERROR("-force-gid gid\t\tset all file gids to gid\n");
4621
				"copyright message\n");
4450
			ERROR("-nopad\t\t\tdo not pad filesystem to a multiple "
4622
			ERROR("-recover <name>\t\trecover filesystem data "
4451
				"of 4K\n");
4623
				"using recovery file <name>\n");
4624
			ERROR("-no-recovery\t\tdon't generate a recovery "
4625
				"file\n");
4626
			ERROR("-info\t\t\tprint files written to filesystem\n");
4627
			ERROR("-no-progress\t\tdon't display the progress "
4628
				"bar\n");
4629
			ERROR("-processors <number>\tUse <number> processors."
4630
				"  By default will use number of\n");
4631
			ERROR("\t\t\tprocessors available\n");
4632
			ERROR("-read-queue <size>\tSet input queue to <size> "
4633
				"Mbytes.  Default %d Mbytes\n",
4634
				READER_BUFFER_DEFAULT);
4635
			ERROR("-write-queue <size>\tSet output queue to <size> "
4636
				"Mbytes.  Default %d Mbytes\n",
4637
				WRITER_BUFFER_DEFAULT);
4638
			ERROR("-fragment-queue <size>\tSet fagment queue to "
4639
				"<size> Mbytes.  Default %d Mbytes\n",
4640
				FRAGMENT_BUFFER_DEFAULT);
4641
			ERROR("\nMiscellaneous options:\n");
4452
			ERROR("-root-owned\t\talternative name for -all-root"
4642
			ERROR("-root-owned\t\talternative name for -all-root"
4453
				"\n");
4643
				"\n");
4454
			ERROR("-noInodeCompression\talternative name for -noI"
4644
			ERROR("-noInodeCompression\talternative name for -noI"
Lines 4457-4476 printOptions: Link Here
4457
				"\n");
4647
				"\n");
4458
			ERROR("-noFragmentCompression\talternative name for "
4648
			ERROR("-noFragmentCompression\talternative name for "
4459
				"-noF\n");
4649
				"-noF\n");
4460
			ERROR("-sort <sort_file>\tsort files according to "
4461
				"priorities in <sort_file>.  One\n");
4462
			ERROR("\t\t\tfile or dir with priority per line.  "
4463
				"Priority -32768 to\n");
4464
			ERROR("\t\t\t32767, default priority 0\n");
4465
			ERROR("-ef <exclude_file>\tlist of exclude dirs/files."
4466
				"  One per line\n");
4467
			ERROR("-wildcards\t\tAllow extended shell wildcards "
4468
				"(globbing) to be used in\n\t\t\texclude "
4469
				"dirs/files\n");
4470
			ERROR("-regex\t\t\tAllow POSIX regular expressions to "
4471
				"be used in exclude\n\t\t\tdirs/files\n");
4472
			ERROR("-p <pseudo-definition>\tAdd pseudo file definition\n");
4473
			ERROR("-pf <pseudo-file>\tAdd list of pseudo file definitions\n");
4474
			exit(1);
4650
			exit(1);
4475
		}
4651
		}
4476
	}
4652
	}
Lines 4548-4558 printOptions: Link Here
4548
			fclose(fd);
4724
			fclose(fd);
4549
		} else if(strcmp(argv[i], "-e") == 0)
4725
		} else if(strcmp(argv[i], "-e") == 0)
4550
			break;
4726
			break;
4551
		else if(strcmp(argv[i], "-b") == 0 ||
4727
		else if(strcmp(argv[i], "-root-becomes") == 0 ||
4552
				strcmp(argv[i], "-root-becomes") == 0 ||
4553
				strcmp(argv[i], "-sort") == 0 ||
4728
				strcmp(argv[i], "-sort") == 0 ||
4554
				strcmp(argv[i], "-pf") == 0 ||
4729
				strcmp(argv[i], "-pf") == 0 ||
4555
				strcmp(argv[i], "-p") == 0)
4730
				strcmp(argv[i], "-comp") == 0)
4556
			i++;
4731
			i++;
4557
4732
4558
	if(i != argc) {
4733
	if(i != argc) {
Lines 4574-4584 printOptions: Link Here
4574
			sorted ++;
4749
			sorted ++;
4575
		} else if(strcmp(argv[i], "-e") == 0)
4750
		} else if(strcmp(argv[i], "-e") == 0)
4576
			break;
4751
			break;
4577
		else if(strcmp(argv[i], "-b") == 0 ||
4752
		else if(strcmp(argv[i], "-root-becomes") == 0 ||
4578
				strcmp(argv[i], "-root-becomes") == 0 ||
4579
				strcmp(argv[i], "-ef") == 0 ||
4753
				strcmp(argv[i], "-ef") == 0 ||
4580
				strcmp(argv[i], "-pf") == 0 ||
4754
				strcmp(argv[i], "-pf") == 0 ||
4581
				strcmp(argv[i], "-p") == 0)
4755
				strcmp(argv[i], "-comp") == 0)
4582
			i++;
4756
			i++;
4583
4757
4584
#ifdef SQUASHFS_TRACE
4758
#ifdef SQUASHFS_TRACE
Lines 4586-4592 printOptions: Link Here
4586
#endif
4760
#endif
4587
4761
4588
	if(!delete) {
4762
	if(!delete) {
4589
	        if(read_super(fd, &sBlk, argv[source + 1]) == 0) {
4763
	        comp = read_super(fd, &sBlk, argv[source + 1]);
4764
	        if(comp == NULL) {
4590
			ERROR("Failed to read existing filesystem - will not "
4765
			ERROR("Failed to read existing filesystem - will not "
4591
				"overwrite - ABORTING!\n");
4766
				"overwrite - ABORTING!\n");
4592
			ERROR("To force Mksquashfs to write to this block "
4767
			ERROR("To force Mksquashfs to write to this block "
Lines 4603-4608 printOptions: Link Here
4603
		always_use_fragments = SQUASHFS_ALWAYS_FRAGMENTS(sBlk.flags);
4778
		always_use_fragments = SQUASHFS_ALWAYS_FRAGMENTS(sBlk.flags);
4604
		duplicate_checking = SQUASHFS_DUPLICATES(sBlk.flags);
4779
		duplicate_checking = SQUASHFS_DUPLICATES(sBlk.flags);
4605
		exportable = SQUASHFS_EXPORTABLE(sBlk.flags);
4780
		exportable = SQUASHFS_EXPORTABLE(sBlk.flags);
4781
	} else {
4782
		comp = lookup_compressor(comp_name);
4783
		if(!comp->supported) {
4784
			ERROR("FATAL_ERROR: Compressor \"%s\" is not "
4785
				"supported!\n", comp_name);
4786
			ERROR("Compressors available:\n");
4787
			display_compressors("", COMP_DEFAULT);
4788
			EXIT_MKSQUASHFS();
4789
		}
4606
	}
4790
	}
4607
4791
4608
	initialise_threads();
4792
	initialise_threads();
Lines 4648-4655 printOptions: Link Here
4648
			"size %d\n", SQUASHFS_MAJOR, s_minor, argv[source + 1],
4832
			"size %d\n", SQUASHFS_MAJOR, s_minor, argv[source + 1],
4649
			block_size);
4833
			block_size);
4650
		printf("All -b, -noI, -noD, -noF, no-duplicates, no-fragments, "
4834
		printf("All -b, -noI, -noD, -noF, no-duplicates, no-fragments, "
4651
			"-always-use-fragments and -exportable options ignored"
4835
			"-always-use-fragments,\n-exportable and -comp options "
4652
			"\n");
4836
			"ignored\n");
4653
		printf("\nIf appending is not wanted, please re-run with "
4837
		printf("\nIf appending is not wanted, please re-run with "
4654
			"-noappend specified!\n\n");
4838
			"-noappend specified!\n\n");
4655
4839
Lines 4803-4810 restore_filesystem: Link Here
4803
4987
4804
	sBlk.bytes_used = bytes;
4988
	sBlk.bytes_used = bytes;
4805
4989
4806
	/* Only compression supported */
4990
	sBlk.compression = comp->id;
4807
	sBlk.compression = ZLIB_COMPRESSION;
4808
4991
4809
	/* Xattrs are not currently supported */
4992
	/* Xattrs are not currently supported */
4810
	sBlk.xattr_table_start = SQUASHFS_INVALID_BLK;
4993
	sBlk.xattr_table_start = SQUASHFS_INVALID_BLK;
Lines 4820-4825 restore_filesystem: Link Here
4820
5003
4821
	close(fd);
5004
	close(fd);
4822
5005
5006
	delete_pseudo_files();
5007
4823
	if(recovery_file[0] != '\0')
5008
	if(recovery_file[0] != '\0')
4824
		unlink(recovery_file);
5009
		unlink(recovery_file);
4825
5010
Lines 4827-4835 restore_filesystem: Link Here
4827
		* sizeof(unsigned short) + guid_count * sizeof(unsigned short) +
5012
		* sizeof(unsigned short) + guid_count * sizeof(unsigned short) +
4828
		sizeof(squashfs_super_block);
5013
		sizeof(squashfs_super_block);
4829
5014
4830
	printf("\n%sSquashfs %d.%d filesystem, data block size %d\n",
5015
	printf("\n%sSquashfs %d.%d filesystem, %s compressed, data block size"
4831
		exportable ? "Exportable " : "", SQUASHFS_MAJOR, SQUASHFS_MINOR,
5016
		" %d\n", exportable ? "Exportable " : "", SQUASHFS_MAJOR,
4832
		block_size);
5017
		SQUASHFS_MINOR, comp->name, block_size);
4833
	printf("\t%s data, %s metadata, %s fragments\n",
5018
	printf("\t%s data, %s metadata, %s fragments\n",
4834
		noD ? "uncompressed" : "compressed", noI ?  "uncompressed" :
5019
		noD ? "uncompressed" : "compressed", noI ?  "uncompressed" :
4835
		"compressed", no_fragments ? "no" : noF ? "uncompressed" :
5020
		"compressed", no_fragments ? "no" : noF ? "uncompressed" :
(-)squashfs-tools/pseudo.c (-65 / +184 lines)
Lines 30-35 Link Here
30
#include <string.h>
30
#include <string.h>
31
#include <stdlib.h>
31
#include <stdlib.h>
32
#include <sys/types.h>
32
#include <sys/types.h>
33
#include <sys/wait.h>
33
34
34
#include "pseudo.h"
35
#include "pseudo.h"
35
36
Lines 55-60 Link Here
55
#define TRUE 1
56
#define TRUE 1
56
#define FALSE 0
57
#define FALSE 0
57
58
59
struct pseudo_dev **pseudo_file = NULL;
60
int pseudo_count = 0;
61
58
static void dump_pseudo(struct pseudo *pseudo, char *string)
62
static void dump_pseudo(struct pseudo *pseudo, char *string)
59
{
63
{
60
	int i;
64
	int i;
Lines 99-105 struct pseudo *add_pseudo(struct pseudo Link Here
99
	char *target, char *alltarget)
103
	char *target, char *alltarget)
100
{
104
{
101
	char targname[1024];
105
	char targname[1024];
102
	int i, error;
106
	int i;
103
107
104
	target = get_component(target, targname);
108
	target = get_component(target, targname);
105
109
Lines 128-139 struct pseudo *add_pseudo(struct pseudo Link Here
128
		if(target[0] == '\0') {
132
		if(target[0] == '\0') {
129
			/* at leaf pathname component */
133
			/* at leaf pathname component */
130
			pseudo->name[i].pseudo = NULL;
134
			pseudo->name[i].pseudo = NULL;
131
			pseudo->name[i].dev = malloc(sizeof(struct pseudo_dev));
132
			if(pseudo->name[i].dev == NULL)
133
				BAD_ERROR("failed to allocate pseudo file\n");
134
			pseudo->name[i].pathname = strdup(alltarget);
135
			pseudo->name[i].pathname = strdup(alltarget);
135
			memcpy(pseudo->name[i].dev, pseudo_dev,
136
			pseudo->name[i].dev = pseudo_dev;
136
				sizeof(struct pseudo_dev));
137
		} else {
137
		} else {
138
			/* recurse adding child components */
138
			/* recurse adding child components */
139
			pseudo->name[i].dev = NULL;
139
			pseudo->name[i].dev = NULL;
Lines 169-183 struct pseudo *add_pseudo(struct pseudo Link Here
169
			if(target[0] == '\0') {
169
			if(target[0] == '\0') {
170
				if(pseudo->name[i].dev == NULL &&
170
				if(pseudo->name[i].dev == NULL &&
171
						pseudo_dev->type == 'd') {
171
						pseudo_dev->type == 'd') {
172
					pseudo->name[i].dev =
173
						malloc(sizeof(struct pseudo_dev));
174
					if(pseudo->name[i].dev == NULL)
175
						BAD_ERROR("failed to allocate "
176
							"pseudo file\n");
177
					pseudo->name[i].pathname =
172
					pseudo->name[i].pathname =
178
						strdup(alltarget);
173
						strdup(alltarget);
179
					memcpy(pseudo->name[i].dev, pseudo_dev,
174
					pseudo->name[i].dev = pseudo_dev;
180
						sizeof(struct pseudo_dev));
181
				} else
175
				} else
182
					ERROR("%s already exists as a "
176
					ERROR("%s already exists as a "
183
						"directory.  Ignoring %s!\n",
177
						"directory.  Ignoring %s!\n",
Lines 229-244 struct pseudo_entry *pseudo_readdir(stru Link Here
229
}
223
}
230
224
231
225
226
int exec_file(char *command, struct pseudo_dev *dev)
227
{
228
	int child, res;
229
	static pid_t pid = -1;
230
	int pipefd[2];
231
#ifdef USE_TMP_FILE
232
	char filename[1024];
233
	int status;
234
	static int number = 0;
235
#endif
236
237
	if(pid == -1)
238
		pid = getpid();
239
240
#ifdef USE_TMP_FILE
241
	sprintf(filename, "/tmp/squashfs_pseudo_%d_%d", pid, number ++);
242
	pipefd[1] = open(filename, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
243
	if(pipefd[1] == -1) {
244
		printf("open failed\n");
245
		return -1;
246
	}
247
#else
248
	res = pipe(pipefd);
249
	if(res == -1) {
250
		printf("pipe failed\n");
251
		return -1;
252
	}
253
#endif
254
255
	child = fork();
256
	if(child == -1) {
257
		printf("fork failed\n");
258
		goto failed;
259
	}
260
261
	if(child == 0) {
262
		close(STDOUT_FILENO);
263
		res = dup(pipefd[1]);
264
		if(res == -1) {
265
			printf("dup failed\n");
266
			exit(EXIT_FAILURE);
267
		}
268
		execl("/bin/sh", "sh", "-c", command, (char *) NULL);
269
		printf("execl failed\n");
270
		exit(EXIT_FAILURE);
271
	}
272
273
#ifdef USE_TMP_FILE
274
	res = waitpid(child, &status, 0);
275
	close(pipefd[1]);
276
	if(res != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0) {
277
		dev->filename = strdup(filename);
278
		return 0;
279
	}
280
failed:
281
	unlink(filename);
282
	return -1;
283
#else
284
	close(pipefd[1]);
285
	dev->fd = pipefd[0];
286
	dev->child = child;
287
	return 0;
288
failed:
289
	return -1;
290
#endif
291
}
292
293
294
void add_pseudo_file(struct pseudo_dev *dev)
295
{
296
	pseudo_file = realloc(pseudo_file, (pseudo_count + 1) *
297
		sizeof(struct pseudo_dev *));
298
	if(pseudo_file == NULL)
299
		BAD_ERROR("Failed to realloc pseudo_file\n");
300
301
	dev->pseudo_id = pseudo_count;
302
	pseudo_file[pseudo_count ++] = dev;
303
}
304
305
306
void delete_pseudo_files()
307
{
308
#ifdef USE_TMP_FILE
309
	int i;
310
311
	for(i = 0; i < pseudo_count; i++)
312
		unlink(pseudo_file[i]->filename);
313
#endif
314
}
315
316
317
struct pseudo_dev *get_pseudo_file(int pseudo_id)
318
{
319
	return pseudo_file[pseudo_id];
320
}
321
322
232
int read_pseudo_def(struct pseudo **pseudo, char *def)
323
int read_pseudo_def(struct pseudo **pseudo, char *def)
233
{
324
{
234
	int n;
325
	int n, bytes;
235
	unsigned int major = 0, minor = 0, mode;
326
	unsigned int major = 0, minor = 0, mode;
236
	char filename[2048], type, suid[100], sgid[100], *ptr;
327
	char filename[2048], type, suid[100], sgid[100], *ptr;
237
	long long uid, gid;
328
	long long uid, gid;
238
	struct pseudo_dev dev;
329
	struct pseudo_dev *dev;
239
330
240
	n = sscanf(def, "%s %c %o %s %s %u %u", filename, &type, &mode, suid, sgid,
331
	n = sscanf(def, "%s %c %o %s %s %n", filename, &type, &mode, suid,
241
			&major, &minor);
332
			sgid, &bytes);
242
333
243
	if(n < 5) {
334
	if(n < 5) {
244
		ERROR("Not enough or invalid arguments in pseudo file "
335
		ERROR("Not enough or invalid arguments in pseudo file "
Lines 249-255 int read_pseudo_def(struct pseudo **pseu Link Here
249
	switch(type) {
340
	switch(type) {
250
	case 'b':
341
	case 'b':
251
	case 'c':
342
	case 'c':
252
		if(n < 7) {
343
		n = sscanf(def + bytes,  "%u %u", &major, &minor);
344
345
		if(n < 2) {
253
			ERROR("Not enough or invalid arguments in pseudo file "
346
			ERROR("Not enough or invalid arguments in pseudo file "
254
				"definition\n");
347
				"definition\n");
255
			goto error;
348
			goto error;
Lines 265-311 int read_pseudo_def(struct pseudo **pseu Link Here
265
			goto error;
358
			goto error;
266
		}
359
		}
267
360
268
		/* fall through */
361
	case 'f':
269
	case 'd':
362
		if(def[bytes] == '\0') {
270
		if(mode > 0777) {
363
			ERROR("Not enough arguments in pseudo file "
271
			ERROR("Mode %o out of range\n", mode);
364
				"definition\n");
272
			goto error;
365
			goto error;
273
		}
366
		}	
274
367
		break;
275
		uid = strtoll(suid, &ptr, 10);
368
	case 'd':
276
		if(*ptr == '\0') {
369
	case 'm':
277
			if(uid < 0 || uid > ((1LL << 32) - 1)) {
278
				ERROR("Uid %s out of range\n", suid);
279
				goto error;
280
			}
281
		} else {
282
			struct passwd *pwuid = getpwnam(suid);
283
			if(pwuid)
284
				uid = pwuid->pw_uid;
285
			else {
286
				ERROR("Uid %s invalid uid or unknown user\n",
287
					suid);
288
				goto error;
289
			}
290
		}
291
		
292
		gid = strtoll(sgid, &ptr, 10);
293
		if(*ptr == '\0') {
294
			if(gid < 0 || gid > ((1LL << 32) - 1)) {
295
				ERROR("Gid %s out of range\n", sgid);
296
				goto error;
297
			}
298
		} else {
299
			struct group *grgid = getgrnam(sgid);
300
			if(grgid)
301
				gid = grgid->gr_gid;
302
			else {
303
				ERROR("Gid %s invalid uid or unknown user\n",
304
					sgid);
305
				goto error;
306
			}
307
		}
308
309
		break;
370
		break;
310
	default:
371
	default:
311
		ERROR("Unsupported type %c\n", type);
372
		ERROR("Unsupported type %c\n", type);
Lines 313-318 int read_pseudo_def(struct pseudo **pseu Link Here
313
	}
374
	}
314
375
315
376
377
	if(mode > 0777) {
378
		ERROR("Mode %o out of range\n", mode);
379
		goto error;
380
	}
381
382
	uid = strtoll(suid, &ptr, 10);
383
	if(*ptr == '\0') {
384
		if(uid < 0 || uid > ((1LL << 32) - 1)) {
385
			ERROR("Uid %s out of range\n", suid);
386
			goto error;
387
		}
388
	} else {
389
		struct passwd *pwuid = getpwnam(suid);
390
		if(pwuid)
391
			uid = pwuid->pw_uid;
392
		else {
393
			ERROR("Uid %s invalid uid or unknown user\n", suid);
394
			goto error;
395
		}
396
	}
397
		
398
	gid = strtoll(sgid, &ptr, 10);
399
	if(*ptr == '\0') {
400
		if(gid < 0 || gid > ((1LL << 32) - 1)) {
401
			ERROR("Gid %s out of range\n", sgid);
402
			goto error;
403
		}
404
	} else {
405
		struct group *grgid = getgrnam(sgid);
406
		if(grgid)
407
			gid = grgid->gr_gid;
408
		else {
409
			ERROR("Gid %s invalid uid or unknown user\n", sgid);
410
			goto error;
411
		}
412
	}
413
316
	switch(type) {
414
	switch(type) {
317
	case 'b':
415
	case 'b':
318
		mode |= S_IFBLK;
416
		mode |= S_IFBLK;
Lines 323-338 int read_pseudo_def(struct pseudo **pseu Link Here
323
	case 'd':
421
	case 'd':
324
		mode |= S_IFDIR;
422
		mode |= S_IFDIR;
325
		break;
423
		break;
424
	case 'f':
425
		mode |= S_IFREG;
426
		break;
326
	}
427
	}
327
428
328
	dev.type = type;
429
	dev = malloc(sizeof(struct pseudo_dev));
329
	dev.mode = mode;
430
	if(dev == NULL)
330
	dev.uid = uid;
431
		BAD_ERROR("Failed to create pseudo_dev\n");
331
	dev.gid = gid;
432
332
	dev.major = major;
433
	dev->type = type;
333
	dev.minor = minor;
434
	dev->mode = mode;
435
	dev->uid = uid;
436
	dev->gid = gid;
437
	dev->major = major;
438
	dev->minor = minor;
439
440
	if(type == 'f') {
441
		int res;
442
443
		printf("Executing dynamic pseudo file\n");
444
		printf("\t\"%s\"\n", def);
445
		res = exec_file(def + bytes, dev);
446
		if(res == -1) {
447
			ERROR("Failed to execute dynamic pseudo file definition"
448
				" \"%s\"\n", def);
449
			return FALSE;
450
		}
451
		add_pseudo_file(dev);
452
	}
334
453
335
	*pseudo = add_pseudo(*pseudo, &dev, filename, filename);
454
	*pseudo = add_pseudo(*pseudo, dev, filename, filename);
336
455
337
	return TRUE;
456
	return TRUE;
338
457
(-)squashfs-tools/pseudo.h (+8 lines)
Lines 27-32 struct pseudo_dev { Link Here
27
	unsigned int	gid;
27
	unsigned int	gid;
28
	unsigned int	major;
28
	unsigned int	major;
29
	unsigned int	minor;
29
	unsigned int	minor;
30
	int		pseudo_id;
31
	int		fd;
32
	int		child;
33
#ifdef USE_TMP_FILE
34
	char		*filename;
35
#endif
30
};
36
};
31
37
32
struct pseudo_entry {
38
struct pseudo_entry {
Lines 46-48 extern int read_pseudo_def(struct pseudo Link Here
46
extern int read_pseudo_file(struct pseudo **, char *);
52
extern int read_pseudo_file(struct pseudo **, char *);
47
extern struct pseudo *pseudo_subdir(char *, struct pseudo *);
53
extern struct pseudo *pseudo_subdir(char *, struct pseudo *);
48
extern struct pseudo_entry *pseudo_readdir(struct pseudo *);
54
extern struct pseudo_entry *pseudo_readdir(struct pseudo *);
55
extern struct pseudo_dev *get_pseudo_file(int);
56
extern void delete_pseudo_files();
(-)squashfs-tools/read_fs.c (-23 / +46 lines)
Lines 36-42 extern unsigned int get_guid(unsigned in Link Here
36
#include <fcntl.h>
36
#include <fcntl.h>
37
#include <errno.h>
37
#include <errno.h>
38
#include <string.h>
38
#include <string.h>
39
#include <zlib.h>
40
#include <sys/mman.h>
39
#include <sys/mman.h>
41
40
42
#ifndef linux
41
#ifndef linux
Lines 51-56 extern unsigned int get_guid(unsigned in Link Here
51
#include "squashfs_swap.h"
50
#include "squashfs_swap.h"
52
#include "read_fs.h"
51
#include "read_fs.h"
53
#include "global.h"
52
#include "global.h"
53
#include "compressor.h"
54
54
55
#include <stdlib.h>
55
#include <stdlib.h>
56
56
Lines 66-72 extern unsigned int get_guid(unsigned in Link Here
66
						fprintf(stderr, s, ## args); \
66
						fprintf(stderr, s, ## args); \
67
					} while(0)
67
					} while(0)
68
68
69
int read_block(int fd, long long start, long long *next, unsigned char *block,
69
static struct compressor *comp;
70
71
int read_block(int fd, long long start, long long *next, void *block,
70
	squashfs_super_block *sBlk)
72
	squashfs_super_block *sBlk)
71
{
73
{
72
	unsigned short c_byte;
74
	unsigned short c_byte;
Lines 77-108 int read_block(int fd, long long start, Link Here
77
79
78
	if(SQUASHFS_COMPRESSED(c_byte)) {
80
	if(SQUASHFS_COMPRESSED(c_byte)) {
79
		char buffer[SQUASHFS_METADATA_SIZE];
81
		char buffer[SQUASHFS_METADATA_SIZE];
80
		int res;
82
		int error, res;
81
		unsigned long bytes = SQUASHFS_METADATA_SIZE;
82
83
83
		c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
84
		c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
84
		read_destination(fd, start + offset, c_byte, buffer);
85
		read_destination(fd, start + offset, c_byte, buffer);
85
86
86
		res = uncompress(block, &bytes, (const unsigned char *) buffer,
87
		res = comp->uncompress(block, buffer, c_byte,
87
			c_byte);
88
			SQUASHFS_METADATA_SIZE, &error);
88
		if(res != Z_OK) {
89
		if(res == -1) {
89
			if(res == Z_MEM_ERROR)
90
			ERROR("%s uncompress failed with error code %d\n",
90
				ERROR("zlib::uncompress failed, not enough "
91
				comp->name, error);
91
					"memory\n");
92
			else if(res == Z_BUF_ERROR)
93
				ERROR("zlib::uncompress failed, not enough "
94
					"room in output buffer\n");
95
			else
96
				ERROR("zlib::uncompress failed, unknown error "
97
					"%d\n", res);
98
			return 0;
92
			return 0;
99
		}
93
		}
100
		if(next)
94
		if(next)
101
			*next = start + offset + c_byte;
95
			*next = start + offset + c_byte;
102
		return bytes;
96
		return res;
103
	} else {
97
	} else {
104
		c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
98
		c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
105
		read_destination(fd, start + offset, c_byte, (char *) block);
99
		read_destination(fd, start + offset, c_byte, block);
106
		if(next)
100
		if(next)
107
			*next = start + offset + c_byte;
101
			*next = start + offset + c_byte;
108
		return c_byte;
102
		return c_byte;
Lines 356-362 failed: Link Here
356
}
350
}
357
351
358
352
359
int read_super(int fd, squashfs_super_block *sBlk, char *source)
353
struct compressor *read_super(int fd, squashfs_super_block *sBlk, char *source)
360
{
354
{
361
	read_destination(fd, SQUASHFS_START, sizeof(squashfs_super_block),
355
	read_destination(fd, SQUASHFS_START, sizeof(squashfs_super_block),
362
		(char *) sBlk);
356
		(char *) sBlk);
Lines 388-395 int read_super(int fd, squashfs_super_bl Link Here
388
		goto failed_mount;
382
		goto failed_mount;
389
	}
383
	}
390
384
385
	/* Check the compression type */
386
	comp = lookup_compressor_id(sBlk->compression);
387
	if(!comp->supported) {
388
		ERROR("Filesystem on %s uses %s compression, this is"
389
			"unsupported by this version\n", source, comp->name);
390
		display_compressors("", "");
391
		goto failed_mount;
392
	}
393
391
	printf("Found a valid %sSQUASHFS superblock on %s.\n",
394
	printf("Found a valid %sSQUASHFS superblock on %s.\n",
392
		SQUASHFS_EXPORTABLE(sBlk->flags) ? "exportable " : "", source);
395
		SQUASHFS_EXPORTABLE(sBlk->flags) ? "exportable " : "", source);
396
	printf("\tCompression used %s\n", comp->name);
393
	printf("\tInodes are %scompressed\n",
397
	printf("\tInodes are %scompressed\n",
394
		SQUASHFS_UNCOMPRESSED_INODES(sBlk->flags) ? "un" : "");
398
		SQUASHFS_UNCOMPRESSED_INODES(sBlk->flags) ? "un" : "");
395
	printf("\tData is %scompressed\n",
399
	printf("\tData is %scompressed\n",
Lines 417-426 int read_super(int fd, squashfs_super_bl Link Here
417
	TRACE("sBlk->lookup_table_start %llx\n", sBlk->lookup_table_start);
421
	TRACE("sBlk->lookup_table_start %llx\n", sBlk->lookup_table_start);
418
	printf("\n");
422
	printf("\n");
419
423
420
	return TRUE;
424
	return comp;
421
425
422
failed_mount:
426
failed_mount:
423
	return FALSE;
427
	return NULL;
424
}
428
}
425
429
426
430
Lines 514-525 unsigned int *read_id_table(int fd, squa Link Here
514
	SQUASHFS_INSWAP_ID_BLOCKS(index, indexes);
518
	SQUASHFS_INSWAP_ID_BLOCKS(index, indexes);
515
519
516
	for(i = 0; i < indexes; i++) {
520
	for(i = 0; i < indexes; i++) {
517
		int length;
521
		int length = read_block(fd, index[i], NULL,
518
		length = read_block(fd, index[i], NULL,
519
			((unsigned char *) id_table) +
522
			((unsigned char *) id_table) +
520
			(i * SQUASHFS_METADATA_SIZE), sBlk);
523
			(i * SQUASHFS_METADATA_SIZE), sBlk);
521
		TRACE("Read id table block %d, from 0x%llx, length %d\n", i,
524
		TRACE("Read id table block %d, from 0x%llx, length %d\n", i,
522
			index[i], length);
525
			index[i], length);
526
		if(length == 0) {
527
			ERROR("Failed to read id table block %d, from 0x%llx, "
528
				"length %d\n", i, index[i], length);
529
			free(id_table);
530
			return NULL;
531
		}
523
	}
532
	}
524
533
525
	SQUASHFS_INSWAP_INTS(id_table, sBlk->no_ids);
534
	SQUASHFS_INSWAP_INTS(id_table, sBlk->no_ids);
Lines 563-568 int read_fragment_table(int fd, squashfs Link Here
563
			(i * SQUASHFS_METADATA_SIZE), sBlk);
572
			(i * SQUASHFS_METADATA_SIZE), sBlk);
564
		TRACE("Read fragment table block %d, from 0x%llx, length %d\n",
573
		TRACE("Read fragment table block %d, from 0x%llx, length %d\n",
565
			i, fragment_table_index[i], length);
574
			i, fragment_table_index[i], length);
575
		if(length == 0) {
576
			ERROR("Failed to read fragment table block %d, from "
577
				"0x%llx, length %d\n", i,
578
				fragment_table_index[i], length);
579
			free(*fragment_table);
580
			return 0;
581
		}
566
	}
582
	}
567
583
568
	for(i = 0; i < sBlk->fragments; i++)
584
	for(i = 0; i < sBlk->fragments; i++)
Lines 599-604 int read_inode_lookup_table(int fd, squa Link Here
599
			(i * SQUASHFS_METADATA_SIZE), sBlk);
615
			(i * SQUASHFS_METADATA_SIZE), sBlk);
600
		TRACE("Read inode lookup table block %d, from 0x%llx, length "
616
		TRACE("Read inode lookup table block %d, from 0x%llx, length "
601
			"%d\n", i, index[i], length);
617
			"%d\n", i, index[i], length);
618
		if(length == 0) {
619
			ERROR("Failed to read inode lookup table block %d, "
620
				"from 0x%llx, length %d\n", i, index[i],
621
				length);
622
			free(*inode_lookup_table);
623
			return 0;
624
		}
602
	}
625
	}
603
626
604
	SQUASHFS_INSWAP_LONG_LONGS(*inode_lookup_table, sBlk->inodes);
627
	SQUASHFS_INSWAP_LONG_LONGS(*inode_lookup_table, sBlk->inodes);
(-)squashfs-tools/sort.c (-1 / +3 lines)
Lines 198-204 void generate_file_priorities(struct dir Link Here
198
	while(dir->current_count < dir->count) {
198
	while(dir->current_count < dir->count) {
199
		struct dir_ent *dir_ent = dir->list[dir->current_count++];
199
		struct dir_ent *dir_ent = dir->list[dir->current_count++];
200
		struct stat *buf = &dir_ent->inode->buf;
200
		struct stat *buf = &dir_ent->inode->buf;
201
		if(dir_ent->data)
201
		if(dir_ent->inode->root_entry)
202
			continue;
202
			continue;
203
203
204
		switch(buf->st_mode & S_IFMT) {
204
		switch(buf->st_mode & S_IFMT) {
Lines 254-259 void sort_files_and_write(struct dir_inf Link Here
254
				write_file(&inode, entry->dir, &duplicate_file);
254
				write_file(&inode, entry->dir, &duplicate_file);
255
				INFO("file %s, uncompressed size %lld bytes %s"
255
				INFO("file %s, uncompressed size %lld bytes %s"
256
					"\n", entry->dir->pathname,
256
					"\n", entry->dir->pathname,
257
					(long long)
257
					entry->dir->inode->buf.st_size,
258
					entry->dir->inode->buf.st_size,
258
					duplicate_file ? "DUPLICATE" : "");
259
					duplicate_file ? "DUPLICATE" : "");
259
				entry->dir->inode->inode = inode;
260
				entry->dir->inode->inode = inode;
Lines 261-266 void sort_files_and_write(struct dir_inf Link Here
261
			} else
262
			} else
262
				INFO("file %s, uncompressed size %lld bytes "
263
				INFO("file %s, uncompressed size %lld bytes "
263
					"LINK\n", entry->dir->pathname,
264
					"LINK\n", entry->dir->pathname,
265
					(long long)
264
					entry->dir->inode->buf.st_size);
266
					entry->dir->inode->buf.st_size);
265
		}
267
		}
266
}
268
}
(-)squashfs-tools/sort.h (-4 / +6 lines)
Lines 42-58 struct dir_ent { Link Here
42
	struct inode_info	*inode;
42
	struct inode_info	*inode;
43
	struct dir_info		*dir;
43
	struct dir_info		*dir;
44
	struct dir_info		*our_dir;
44
	struct dir_info		*our_dir;
45
	struct old_root_entry_info *data;
46
};
45
};
47
46
48
struct inode_info {
47
struct inode_info {
49
	unsigned int		nlink;
50
	struct stat		buf;
48
	struct stat		buf;
49
	struct inode_info	*next;
51
	squashfs_inode		inode;
50
	squashfs_inode		inode;
52
	unsigned int		type;
53
	unsigned int		inode_number;
51
	unsigned int		inode_number;
52
	unsigned int		nlink;
53
	int			pseudo_id;
54
	char			type;
54
	char			read;
55
	char			read;
55
	struct inode_info	*next;
56
	char			root_entry;
57
	char			pseudo_file;
56
};
58
};
57
59
58
struct priority_entry {
60
struct priority_entry {
(-)squashfs-tools/squashfs_compat.h (-5 / +4 lines)
Lines 777-787 typedef union squashfs_inode_header_2 sq Link Here
777
#endif
777
#endif
778
778
779
#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\
779
#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\
780
	int bits;\
780
	b_pos = pos % 8;\
781
	int b_pos = pos % 8;\
781
	val = 0;\
782
	unsigned long long val = 0;\
782
	s = (unsigned char *)p + (pos / 8);\
783
	unsigned char *s = (unsigned char *)p + (pos / 8);\
783
	d = ((unsigned char *) &val) + 7;\
784
	unsigned char *d = ((unsigned char *) &val) + 7;\
785
	for(bits = 0; bits < (tbits + b_pos); bits += 8) \
784
	for(bits = 0; bits < (tbits + b_pos); bits += 8) \
786
		*d-- = *s++;\
785
		*d-- = *s++;\
787
	value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\
786
	value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\
(-)squashfs-tools/squashfs_fs.h (+1 lines)
Lines 229-234 typedef long long squashfs_block_t; Link Here
229
typedef long long		squashfs_inode_t;
229
typedef long long		squashfs_inode_t;
230
230
231
#define ZLIB_COMPRESSION	1
231
#define ZLIB_COMPRESSION	1
232
#define LZMA_COMPRESSION	2
232
233
233
struct squashfs_super_block {
234
struct squashfs_super_block {
234
	unsigned int		s_magic;
235
	unsigned int		s_magic;
(-)squashfs-tools/unsquash-3.c (-1 / +1 lines)
Lines 36-42 int read_fragment_table_3() Link Here
36
		sBlk.fragment_table_start);
36
		sBlk.fragment_table_start);
37
37
38
	if(sBlk.fragments == 0)
38
	if(sBlk.fragments == 0)
39
		return;
39
		return TRUE;
40
40
41
	if((fragment_table = malloc(sBlk.fragments *
41
	if((fragment_table = malloc(sBlk.fragments *
42
			sizeof(squashfs_fragment_entry_3))) == NULL)
42
			sizeof(squashfs_fragment_entry_3))) == NULL)
(-)squashfs-tools/unsquash-4.c (-1 / +1 lines)
Lines 38-44 int read_fragment_table_4() Link Here
38
		sBlk.fragment_table_start);
38
		sBlk.fragment_table_start);
39
39
40
	if(sBlk.fragments == 0)
40
	if(sBlk.fragments == 0)
41
		return;
41
		return TRUE;
42
42
43
	if((fragment_table = malloc(sBlk.fragments *
43
	if((fragment_table = malloc(sBlk.fragments *
44
			sizeof(squashfs_fragment_entry))) == NULL)
44
			sizeof(squashfs_fragment_entry))) == NULL)
(-)squashfs-tools/unsquashfs.c (-56 / +54 lines)
Lines 25-30 Link Here
25
#include "squashfs_swap.h"
25
#include "squashfs_swap.h"
26
#include "squashfs_compat.h"
26
#include "squashfs_compat.h"
27
#include "read_fs.h"
27
#include "read_fs.h"
28
#include "compressor.h"
29
30
#include <sys/sysinfo.h>
28
31
29
struct cache *fragment_cache, *data_cache;
32
struct cache *fragment_cache, *data_cache;
30
struct queue *to_reader, *to_deflate, *to_writer, *from_writer;
33
struct queue *to_reader, *to_deflate, *to_writer, *from_writer;
Lines 36-41 int processors = -1; Link Here
36
39
37
struct super_block sBlk;
40
struct super_block sBlk;
38
squashfs_operations s_ops;
41
squashfs_operations s_ops;
42
struct compressor *comp;
39
43
40
int bytes = 0, swap, file_count = 0, dir_count = 0, sym_count = 0,
44
int bytes = 0, swap, file_count = 0, dir_count = 0, sym_count = 0,
41
	dev_count = 0, fifo_count = 0;
45
	dev_count = 0, fifo_count = 0;
Lines 590-620 int read_block(long long start, long lon Link Here
590
		offset = 3;
594
		offset = 3;
591
	if(SQUASHFS_COMPRESSED(c_byte)) {
595
	if(SQUASHFS_COMPRESSED(c_byte)) {
592
		char buffer[SQUASHFS_METADATA_SIZE];
596
		char buffer[SQUASHFS_METADATA_SIZE];
593
		int res;
597
		int error, res;
594
		unsigned long bytes = SQUASHFS_METADATA_SIZE;
595
598
596
		c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
599
		c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
597
		if(read_bytes(start + offset, c_byte, buffer) == FALSE)
600
		if(read_bytes(start + offset, c_byte, buffer) == FALSE)
598
			goto failed;
601
			goto failed;
599
602
600
		res = uncompress((unsigned char *) block, &bytes,
603
		res = comp->uncompress(block, buffer, c_byte,
601
			(const unsigned char *) buffer, c_byte);
604
			SQUASHFS_METADATA_SIZE, &error);
602
605
603
		if(res != Z_OK) {
606
		if(res == -1) {
604
			if(res == Z_MEM_ERROR)
607
			ERROR("%s uncompress failed with error code %d\n",
605
				ERROR("zlib::uncompress failed, not enough "
608
				comp->name, error);
606
					"memory\n");
607
			else if(res == Z_BUF_ERROR)
608
				ERROR("zlib::uncompress failed, not enough "
609
					"room in output buffer\n");
610
			else
611
				ERROR("zlib::uncompress failed, unknown error "
612
					"%d\n", res);
613
			goto failed;
609
			goto failed;
614
		}
610
		}
615
		if(next)
611
		if(next)
616
			*next = start + offset + c_byte;
612
			*next = start + offset + c_byte;
617
		return bytes;
613
		return res;
618
	} else {
614
	} else {
619
		c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
615
		c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
620
		if(read_bytes(start + offset, c_byte, block) == FALSE)
616
		if(read_bytes(start + offset, c_byte, block) == FALSE)
Lines 632-667 failed: Link Here
632
628
633
int read_data_block(long long start, unsigned int size, char *block)
629
int read_data_block(long long start, unsigned int size, char *block)
634
{
630
{
635
	int res;
631
	int error, res;
636
	unsigned long bytes = block_size;
637
	int c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(size);
632
	int c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(size);
638
633
639
	TRACE("read_data_block: block @0x%llx, %d %s bytes\n", start,
634
	TRACE("read_data_block: block @0x%llx, %d %s bytes\n", start,
640
		SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte),
635
		c_byte, SQUASHFS_COMPRESSED_BLOCK(size) ? "compressed" :
641
		SQUASHFS_COMPRESSED_BLOCK(c_byte) ? "compressed" :
642
		"uncompressed");
636
		"uncompressed");
643
637
644
	if(SQUASHFS_COMPRESSED_BLOCK(size)) {
638
	if(SQUASHFS_COMPRESSED_BLOCK(size)) {
645
		if(read_bytes(start, c_byte, data) == FALSE)
639
		if(read_bytes(start, c_byte, data) == FALSE)
646
			goto failed;
640
			goto failed;
647
641
648
		res = uncompress((unsigned char *) block, &bytes,
642
		res = comp->uncompress(block, data, c_byte, block_size, &error);
649
			(const unsigned char *) data, c_byte);
650
643
651
		if(res != Z_OK) {
644
		if(res == -1) {
652
			if(res == Z_MEM_ERROR)
645
			ERROR("%s uncompress failed with error code %d\n",
653
				ERROR("zlib::uncompress failed, not enough "
646
				comp->name, error);
654
					"memory\n");
655
			else if(res == Z_BUF_ERROR)
656
				ERROR("zlib::uncompress failed, not enough "
657
					"room in output buffer\n");
658
			else
659
				ERROR("zlib::uncompress failed, unknown error "
660
					"%d\n", res);
661
			goto failed;
647
			goto failed;
662
		}
648
		}
663
649
664
		return bytes;
650
		return res;
665
	} else {
651
	} else {
666
		if(read_bytes(start, c_byte, block) == FALSE)
652
		if(read_bytes(start, c_byte, block) == FALSE)
667
			goto failed;
653
			goto failed;
Lines 671-677 int read_data_block(long long start, uns Link Here
671
657
672
failed:
658
failed:
673
	ERROR("read_data_block: failed to read block @0x%llx, size %d\n", start,
659
	ERROR("read_data_block: failed to read block @0x%llx, size %d\n", start,
674
		size);
660
		c_byte);
675
	return FALSE;
661
	return FALSE;
676
}
662
}
677
663
Lines 1383-1388 void squashfs_stat(char *source) Link Here
1383
#endif
1369
#endif
1384
	printf("Creation or last append time %s", mkfs_str ? mkfs_str :
1370
	printf("Creation or last append time %s", mkfs_str ? mkfs_str :
1385
		"failed to get time\n");
1371
		"failed to get time\n");
1372
	printf("Filesystem size %.2f Kbytes (%.2f Mbytes)\n",
1373
		sBlk.bytes_used / 1024.0, sBlk.bytes_used / (1024.0 * 1024.0));
1374
	if(sBlk.s_major == 4)
1375
		printf("Compression %s\n", comp->name);
1376
	printf("Block size %d\n", sBlk.block_size);
1386
	printf("Filesystem is %sexportable via NFS\n",
1377
	printf("Filesystem is %sexportable via NFS\n",
1387
		SQUASHFS_EXPORTABLE(sBlk.flags) ? "" : "not ");
1378
		SQUASHFS_EXPORTABLE(sBlk.flags) ? "" : "not ");
1388
1379
Lines 1409-1417 void squashfs_stat(char *source) Link Here
1409
			SQUASHFS_DUPLICATES(sBlk.flags) ? "" : "not ");
1400
			SQUASHFS_DUPLICATES(sBlk.flags) ? "" : "not ");
1410
	else
1401
	else
1411
		printf("Duplicates are removed\n");
1402
		printf("Duplicates are removed\n");
1412
	printf("Filesystem size %.2f Kbytes (%.2f Mbytes)\n",
1413
		sBlk.bytes_used / 1024.0, sBlk.bytes_used / (1024.0 * 1024.0));
1414
	printf("Block size %d\n", sBlk.block_size);
1415
	if(sBlk.s_major > 1)
1403
	if(sBlk.s_major > 1)
1416
		printf("Number of fragments %d\n", sBlk.fragments);
1404
		printf("Number of fragments %d\n", sBlk.fragments);
1417
	printf("Number of inodes %d\n", sBlk.inodes);
1405
	printf("Number of inodes %d\n", sBlk.inodes);
Lines 1459-1464 int read_super(char *source) Link Here
1459
		s_ops.read_inode = read_inode_4;
1447
		s_ops.read_inode = read_inode_4;
1460
		s_ops.read_uids_guids = read_uids_guids_4;
1448
		s_ops.read_uids_guids = read_uids_guids_4;
1461
		memcpy(&sBlk, &sBlk_4, sizeof(sBlk_4));
1449
		memcpy(&sBlk, &sBlk_4, sizeof(sBlk_4));
1450
1451
		/*
1452
		 * Check the compression type
1453
		 */
1454
		comp = lookup_compressor_id(sBlk.compression);
1455
		if(!comp->supported) {
1456
			ERROR("Filesystem uses %s compression, this is "
1457
				"unsupported by this version\n", comp->name);
1458
			ERROR("Decompressors available:\n");
1459
			display_compressors("", "");
1460
			goto failed_mount;
1461
		}
1462
		return TRUE;
1462
		return TRUE;
1463
	}
1463
	}
1464
1464
Lines 1548-1553 int read_super(char *source) Link Here
1548
		goto failed_mount;
1548
		goto failed_mount;
1549
	}
1549
	}
1550
1550
1551
	/*
1552
	 * 1.x, 2.x and 3.x filesystems use gzip compression.  Gzip is always
1553
	 * suppported.
1554
	 */
1555
	comp = lookup_compressor("gzip");
1551
	return TRUE;
1556
	return TRUE;
1552
1557
1553
failed_mount:
1558
failed_mount:
Lines 1707-1738 void *deflator(void *arg) Link Here
1707
1712
1708
	while(1) {
1713
	while(1) {
1709
		struct cache_entry *entry = queue_get(to_deflate);
1714
		struct cache_entry *entry = queue_get(to_deflate);
1710
		int res;
1715
		int error, res;
1711
		unsigned long bytes = block_size;
1712
1716
1713
		res = uncompress((unsigned char *) tmp, &bytes,
1717
		res = comp->uncompress(tmp, entry->data,
1714
			(const unsigned char *) entry->data,
1718
			SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size), block_size,
1715
			SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size));
1719
			&error);
1716
1720
1717
		if(res != Z_OK) {
1721
		if(res == -1)
1718
			if(res == Z_MEM_ERROR)
1722
			ERROR("%s uncompress failed with error code %d\n",
1719
				ERROR("zlib::uncompress failed, not enough"
1723
				comp->name, error);
1720
					"memory\n");
1724
		else
1721
			else if(res == Z_BUF_ERROR)
1725
			memcpy(entry->data, tmp, res);
1722
				ERROR("zlib::uncompress failed, not enough "
1723
					"room in output buffer\n");
1724
			else
1725
				ERROR("zlib::uncompress failed, unknown error "
1726
					"%d\n", res);
1727
		} else
1728
			memcpy(entry->data, tmp, bytes);
1729
1726
1730
		/*
1727
		/*
1731
		 * block has been either successfully decompressed, or an error
1728
		 * block has been either successfully decompressed, or an error
1732
 		 * occurred, clear pending flag, set error appropriately and
1729
 		 * occurred, clear pending flag, set error appropriately and
1733
 		 * wake up any threads waiting on this block
1730
 		 * wake up any threads waiting on this block
1734
 		 */ 
1731
 		 */ 
1735
		cache_block_ready(entry, res != Z_OK);
1732
		cache_block_ready(entry, res == -1);
1736
	}
1733
	}
1737
}
1734
}
1738
1735
Lines 1938-1944 int main(int argc, char *argv[]) Link Here
1938
	int fragment_buffer_size = FRAGMENT_BUFFER_DEFAULT;
1935
	int fragment_buffer_size = FRAGMENT_BUFFER_DEFAULT;
1939
	int data_buffer_size = DATA_BUFFER_DEFAULT;
1936
	int data_buffer_size = DATA_BUFFER_DEFAULT;
1940
	char *b;
1937
	char *b;
1941
	struct winsize winsize;
1942
1938
1943
	pthread_mutex_init(&screen_mutex, NULL);
1939
	pthread_mutex_init(&screen_mutex, NULL);
1944
	root_process = geteuid() == 0;
1940
	root_process = geteuid() == 0;
Lines 2087-2092 options: Link Here
2087
				"regular expressions\n");
2083
				"regular expressions\n");
2088
			ERROR("\t\t\t\trather than use the default shell "
2084
			ERROR("\t\t\t\trather than use the default shell "
2089
				"wildcard\n\t\t\t\texpansion (globbing)\n");
2085
				"wildcard\n\t\t\t\texpansion (globbing)\n");
2086
			ERROR("\nDecompressors available:\n");
2087
			display_compressors("", "");
2090
		}
2088
		}
2091
		exit(1);
2089
		exit(1);
2092
	}
2090
	}
(-)squashfs-tools/unsquashfs.h (-1 lines)
Lines 31-37 Link Here
31
#include <fcntl.h>
31
#include <fcntl.h>
32
#include <errno.h>
32
#include <errno.h>
33
#include <string.h>
33
#include <string.h>
34
#include <zlib.h>
35
#include <sys/mman.h>
34
#include <sys/mman.h>
36
#include <utime.h>
35
#include <utime.h>
37
#include <pwd.h>
36
#include <pwd.h>

Return to bug 207737