Index: squashfs3.3/squashfs-tools/Makefile =================================================================== RCS file: squashfs3.3/squashfs-tools/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -r1.1 -r1.2 --- squashfs3.3/squashfs-tools/Makefile 4 Nov 2007 13:19:11 -0000 1.1 +++ squashfs3.3/squashfs-tools/Makefile 5 Nov 2007 05:43:36 -0000 1.2 @@ -1,19 +1,42 @@ -INCLUDEDIR = . -CFLAGS := -I$(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE -O2 +ifndef Sqlzma +$(error Sqlzma is not defined) +endif -all: mksquashfs unsquashfs +INCLUDEDIR = . -mksquashfs: mksquashfs.o read_fs.o sort.o - $(CC) mksquashfs.o read_fs.o sort.o -lz -lpthread -lm -o $@ +CFLAGS := -I$(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE -O2 +ifdef UseDebugFlags +DebugFlags = -g -Wall -Wno-unused-variable -O0 -UNDEBUG +endif +CFLAGS += -I${Sqlzma} -D_REENTRANT -DNDEBUG ${DebugFlags} +LDLIBS += -lz -L${LzmaAlone} -L${LzmaC} +Tgt = mksquashfs unsquashfs -mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h +all: ${Tgt} -read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h +read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h \ + ${Sqlzma}/sqlzma.h ${Sqlzma}/sqmagic.h sort.o: sort.c squashfs_fs.h global.h sort.h +mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h \ + ${Sqlzma}/sqlzma.h ${Sqlzma}/sqmagic.h \ + ${LzmaAlone}/liblzma_r.a ${LzmaC}/libunlzma_r.a +mksquashfs: LDLIBS += -lpthread -lunlzma_r -llzma_r -lstdc++ +mksquashfs: mksquashfs.o read_fs.o sort.o + +unsquashfs.o: CFLAGS += -U_REENTRANT +unsquashfs.o: unsquashfs.c squashfs_fs.h read_fs.h global.h \ + ${Sqlzma}/sqlzma.h ${Sqlzma}/sqmagic.h ${LzmaC}/libunlzma.a +unsquashfs: LDLIBS += -lunlzma unsquashfs: unsquashfs.o - $(CC) unsquashfs.o -lz -o $@ -unsquashfs.o: unsquashfs.c squashfs_fs.h read_fs.h global.h +clean: + ${RM} *~ *.o ${Tgt} + +-include test.mk + +# Local variables: ; +# compile-command: (concat "make Sqlzma=../.. -f " (file-name-nondirectory (buffer-file-name))); +# End: ; Index: squashfs3.3/squashfs-tools/mksquashfs.c =================================================================== RCS file: squashfs3.3/squashfs-tools/mksquashfs.c,v retrieving revision 1.1 retrieving revision 1.4 diff -u -p -r1.1 -r1.4 --- squashfs3.3/squashfs-tools/mksquashfs.c 4 Nov 2007 13:19:11 -0000 1.1 +++ squashfs3.3/squashfs-tools/mksquashfs.c 13 Nov 2007 13:27:23 -0000 1.4 @@ -61,6 +61,8 @@ #include "mksquashfs.h" #include "global.h" #include "sort.h" +#include "sqlzma.h" +#include "sqmagic.h" #ifdef SQUASHFS_TRACE #define TRACE(s, args...) do { \ @@ -112,6 +114,11 @@ unsigned short uid_count = 0, guid_count squashfs_uid uids[SQUASHFS_UIDS], guids[SQUASHFS_GUIDS]; int block_offset; int file_count = 0, sym_count = 0, dev_count = 0, dir_count = 0, fifo_count = 0, sock_count = 0; +struct sqlzma_un un; +struct sqlzma_opts sqlzma_opts = { + .try_lzma = 1, + .dicsize = SQUASHFS_FILE_SIZE +}; /* write position within data section */ long long bytes = 0, total_bytes = 0; @@ -626,21 +633,8 @@ unsigned int mangle2(z_stream **strm, ch BAD_ERROR("zlib::compress failed, unknown error %d\n", res); } - stream->next_in = (unsigned char *) s; - stream->avail_in = size; - stream->next_out = (unsigned char *) d; - stream->avail_out = block_size; - - res = deflate(stream, Z_FINISH); - if(res != Z_STREAM_END && res != Z_OK) { - if(res == Z_STREAM_ERROR) - BAD_ERROR("zlib::compress failed, stream state inconsistent\n"); - else if(res == Z_BUF_ERROR) - BAD_ERROR("zlib::compress failed, no progress possible\n"); - else - BAD_ERROR("zlib::compress failed, unknown error %d\n", res); - } - + res = sqlzma_cm(&sqlzma_opts, stream, (void *)s, size, (void *)d, + block_size); c_byte = stream->total_out; if(res != Z_STREAM_END || c_byte >= size) { @@ -739,6 +733,7 @@ void write_bytes(int fd, long long byte, EXIT_MKSQUASHFS(); } + //printf("%d bytes at %Ld\n", bytes, off); if(write(fd, buff, bytes) == -1) { perror("Write on destination failed"); EXIT_MKSQUASHFS(); @@ -991,12 +986,12 @@ int create_inode(squashfs_inode *i_no, s char buff[65536]; if((byte = readlink(filename, buff, 65536)) == -1) { - ERROR("Failed to read symlink %d, creating empty symlink\n", filename); + ERROR("Failed to read symlink %s, creating empty symlink\n", filename); byte = 0; } if(byte == 65536) { - ERROR("Symlink %d is greater than 65536 bytes! Creating empty symlink\n", filename); + ERROR("Symlink %s is greater than 65536 bytes! Creating empty symlink\n", filename); byte = 0; } @@ -1022,7 +1017,7 @@ int create_inode(squashfs_inode *i_no, s SQUASHFS_SWAP_IPC_INODE_HEADER(ipc, inode); TRACE("ipc inode, type %s, nlink %d\n", type == SQUASHFS_FIFO_TYPE ? "fifo" : "socket", nlink); } else - BAD_ERROR("Unrecognised inode %d in create_inode\n"); + BAD_ERROR("Unrecognised inode %d in create_inode\n", type); *i_no = MKINODE(inode); inode_count ++; @@ -1250,17 +1245,17 @@ char *get_fragment(char *buffer, struct int res; unsigned long bytes = block_size; char cbuffer[block_size]; + enum {Src, Dst}; + struct sized_buf sbuf[] = { + {.buf = (void *)cbuffer, .sz = size}, + {.buf = (void *)buffer, .sz = bytes} + }; read_bytes(fd, disk_fragment->start_block, size, cbuffer); - if((res = uncompress((unsigned char *) buffer, &bytes, (const unsigned char *) cbuffer, size)) != Z_OK) { - if(res == Z_MEM_ERROR) - BAD_ERROR("zlib::uncompress failed, not enough memory\n"); - else if(res == Z_BUF_ERROR) - BAD_ERROR("zlib::uncompress failed, not enough room in output buffer\n"); - else - BAD_ERROR("zlib::uncompress failed, unknown error %d\n", res); - } + res = sqlzma_un(&un, sbuf + Src, sbuf + Dst); + if (res) + BAD_ERROR("%s:%d: res %d\n", __func__, __LINE__, res); } else read_bytes(fd, disk_fragment->start_block, size, buffer); @@ -1687,7 +1682,8 @@ again: goto restat; } - if(file_buffer->fragment = file_buffer->block == frag_block) + file_buffer->fragment = (file_buffer->block == frag_block); + if(file_buffer->fragment) queue_put(from_deflate, file_buffer); else queue_put(from_reader, file_buffer); @@ -1755,6 +1751,7 @@ void *reader(void *arg) for(entry = priority_list[i]; entry; entry = entry->next) reader_read_file(entry->dir); } + return NULL; } @@ -1784,6 +1781,7 @@ void *writer(void *arg) write_error = TRUE; } + //printf("%d bytes at %Ld\n", file_buffer->size, off); if(!write_error && write(fd, file_buffer->data, file_buffer->size) == -1) { perror("Write on destination failed"); write_error = TRUE; @@ -1926,7 +1924,7 @@ int progress_bar(long long current, long int spaces = columns - used - hashes; if(!progress || columns - used < 0) - return; + return 0; printf("\r["); @@ -1939,6 +1937,7 @@ int progress_bar(long long current, long printf("] %*lld/%*lld", max_digits, current, max_digits, max); printf(" %3lld%%", current * 100 / max); fflush(stdout); + return 0; } @@ -2243,7 +2242,8 @@ void write_file(squashfs_inode *inode, s again: read_buffer = get_file_buffer(from_deflate); - if(status = read_buffer->error) { + status = read_buffer->error; + if(status) { alloc_free(read_buffer); goto file_err; } @@ -2635,7 +2635,7 @@ error: void dir_scan2(squashfs_inode *inode, struct dir_info *dir_info) { - int squashfs_type; + int squashfs_type = -1; int duplicate_file; char *pathname = dir_info->pathname; struct directory dir; @@ -2918,7 +2918,7 @@ skip_inode_hash_table: char *get_component(char *target, char *targname) { while(*target == '/') - *target ++; + target ++; while(*target != '/' && *target!= '\0') *targname ++ = *target ++; @@ -2974,7 +2974,8 @@ struct pathname *add_path(struct pathnam paths->name[i].paths = NULL; if(use_regex) { paths->name[i].preg = malloc(sizeof(regex_t)); - if(error = regcomp(paths->name[i].preg, targname, REG_EXTENDED|REG_NOSUB)) { + error = regcomp(paths->name[i].preg, targname, REG_EXTENDED|REG_NOSUB); + if(error) { char str[1024]; regerror(error, paths->name[i].preg, str, 1024); @@ -3242,7 +3243,8 @@ void read_recovery_data(char *recovery_f printf("This program is distributed in the hope that it will be useful,\n");\ printf("but WITHOUT ANY WARRANTY; without even the implied warranty of\n");\ printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");\ - printf("GNU General Public License for more details.\n"); + printf("GNU General Public License for more details.\n");\ + printf("and LZMA support for slax.org by jro.\n"); int main(int argc, char *argv[]) { struct winsize winsize; @@ -3261,6 +3263,7 @@ int main(int argc, char *argv[]) be = FALSE; #endif + un.un_lzma = 1; block_log = slog(block_size); if(argc > 1 && strcmp(argv[1], "-version") == 0) { VERSION(); @@ -3319,24 +3322,33 @@ int main(int argc, char *argv[]) ERROR("%s: -write-queue should be 1 megabyte or larger\n", argv[0]); exit(1); } - } else if(strcmp(argv[i], "-b") == 0) { + } else if(strcmp(argv[i], "-b") == 0 + || strcmp(argv[i], "-lzmadic") == 0) { + long bs; + unsigned int bl; if(++i == argc) { - ERROR("%s: -b missing block size\n", argv[0]); + ERROR("%s: -b|-lzmadic missing block size\n", argv[0]); exit(1); } - block_size = strtol(argv[i], &b, 10); + bs = strtol(argv[i], &b, 10); if(*b == 'm' || *b == 'M') - block_size *= 1048576; + bs *= 1048576; else if(*b == 'k' || *b == 'K') - block_size *= 1024; + bs *= 1024; else if(*b != '\0') { - ERROR("%s: -b invalid block size\n", argv[0]); + ERROR("%s: -b|-lzmadic invalid size\n", argv[0]); exit(1); } - if((block_log = slog(block_size)) == 0) { - ERROR("%s: -b block size not power of two or not between 4096 and 1Mbyte\n", argv[0]); + bl = slog(bs); + if(bl == 0) { + ERROR("%s: -b|-lzmadic size not power of two or not between 4096 and 1Mbyte\n", argv[0]); exit(1); } + if (!strcmp(argv[i - 1], "-b")) { + block_size = bs; + block_log = bl; + } + sqlzma_opts.dicsize = bs; } else if(strcmp(argv[i], "-ef") == 0) { if(++i == argc) { ERROR("%s: -ef missing filename\n", argv[0]); @@ -3440,6 +3452,9 @@ int main(int argc, char *argv[]) exit(1); } root_name = argv[i]; + } else if(strcmp(argv[i], "-nolzma") == 0) { + un.un_lzma = 0; + sqlzma_opts.try_lzma = 0; } else if(strcmp(argv[i], "-version") == 0) { VERSION(); } else { @@ -3489,6 +3504,12 @@ printOptions: ERROR("-ef \tlist of exclude dirs/files. One per line\n"); ERROR("-wildcards\t\tAllow extended shell wildcards (globbing) to be used in\n\t\t\texclude dirs/files\n"); ERROR("-regex\t\t\tAllow POSIX regular expressions to be used in exclude\n\t\t\tdirs/files\n"); + ERROR("-lzmadic \tset the LZMA dictionary" + " size to \n" + "\t\t\tDefault value always follow the block" + " size\n" + "\t\t\tUse this alone or AFTER -b option\n"); + ERROR("-nolzma\t\t\tnever try LZMA compression\n"); exit(1); } } @@ -3595,6 +3616,7 @@ printOptions: be = orig_be; block_log = slog(block_size = sBlk.block_size); + //sqlzma_opts.dicsize = block_size; s_minor = sBlk.s_minor; noI = SQUASHFS_UNCOMPRESSED_INODES(sBlk.flags); noD = SQUASHFS_UNCOMPRESSED_DATA(sBlk.flags); @@ -3608,10 +3630,18 @@ printOptions: initialise_threads(); + i = sqlzma_init(&un, un.un_lzma, 0); + if (i != Z_OK) { + ERROR("%s:%d: %d\n", __func__, __LINE__, i); + EXIT_MKSQUASHFS(); + } + if(delete) { printf("Creating %s %d.%d filesystem on %s, block size %d.\n", be ? "big endian" : "little endian", SQUASHFS_MAJOR, s_minor, argv[source + 1], block_size); bytes = sizeof(squashfs_super_block); + if (sqlzma_opts.try_lzma) + printf("lzmadic %u\n", sqlzma_opts.dicsize); } else { unsigned int last_directory_block, inode_dir_offset, inode_dir_file_size, root_inode_size, inode_dir_start_block, uncompressed_data, compressed_data, inode_dir_inode_number, @@ -3635,11 +3665,13 @@ printOptions: printf("Appending to existing %s %d.%d filesystem on %s, block size %d\n", be ? "big endian" : "little endian", SQUASHFS_MAJOR, s_minor, argv[source + 1], block_size); + if (sqlzma_opts.try_lzma) + printf("lzmadic %u\n", sqlzma_opts.dicsize); printf("All -be, -le, -b, -noI, -noD, -noF, -check_data, no-duplicates, no-fragments, -always-use-fragments and -exportable options ignored\n"); printf("\nIf appending is not wanted, please re-run with -noappend specified!\n\n"); - compressed_data = inode_dir_offset + inode_dir_file_size & ~(SQUASHFS_METADATA_SIZE - 1); - uncompressed_data = inode_dir_offset + inode_dir_file_size & (SQUASHFS_METADATA_SIZE - 1); + compressed_data = inode_dir_offset + (inode_dir_file_size & ~(SQUASHFS_METADATA_SIZE - 1)); //?? + uncompressed_data = inode_dir_offset + (inode_dir_file_size & (SQUASHFS_METADATA_SIZE - 1)); //?? /* save original filesystem state for restoring ... */ sfragments = fragments; @@ -3733,7 +3765,9 @@ printOptions: dir_scan(&inode, "", scan1_encomp_readdir); sBlk.root_inode = inode; sBlk.inodes = inode_count; - sBlk.s_magic = SQUASHFS_MAGIC; + sBlk.s_magic = SQUASHFS_MAGIC_LZMA; + if (!un.un_lzma) + sBlk.s_magic = SQUASHFS_MAGIC; sBlk.s_major = SQUASHFS_MAJOR; sBlk.s_minor = s_minor; sBlk.block_size = block_size; @@ -3762,7 +3796,8 @@ restore_filesystem: if(exportable) TRACE("sBlk->lookup_table_start 0x%llx\n", sBlk.lookup_table_start); - if(sBlk.no_uids = uid_count) { + sBlk.no_uids = uid_count; + if(sBlk.no_uids) { if(!swap) write_bytes(fd, bytes, uid_count * sizeof(squashfs_uid), (char *) uids); else { @@ -3776,7 +3811,8 @@ restore_filesystem: } else sBlk.uid_start = 0; - if(sBlk.no_guids = guid_count) { + sBlk.no_guids = guid_count; + if(sBlk.no_guids) { if(!swap) write_bytes(fd, bytes, guid_count * sizeof(squashfs_uid), (char *) guids); else { @@ -3819,6 +3855,8 @@ restore_filesystem: exportable ? "Exportable " : "", be ? "Big endian" : "Little endian", block_size, noD ? "uncompressed" : "compressed", noI ? "uncompressed" : "compressed", no_fragments ? "no" : noF ? "uncompressed" : "compressed", duplicate_checking ? "" : "not "); + if (sqlzma_opts.try_lzma) + printf("lzmadic %u\n", sqlzma_opts.dicsize); printf("Filesystem size %.2f Kbytes (%.2f Mbytes)\n", bytes / 1024.0, bytes / (1024.0 * 1024.0)); printf("\t%.2f%% of uncompressed filesystem size (%.2f Kbytes)\n", ((float) bytes / total_bytes) * 100.0, total_bytes / 1024.0); Index: squashfs3.3/squashfs-tools/read_fs.c =================================================================== RCS file: squashfs3.3/squashfs-tools/read_fs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -r1.1 -r1.2 --- squashfs3.3/squashfs-tools/read_fs.c 4 Nov 2007 13:19:11 -0000 1.1 +++ squashfs3.3/squashfs-tools/read_fs.c 5 Nov 2007 05:43:36 -0000 1.2 @@ -46,6 +46,8 @@ extern int add_file(long long, long long #include #include "read_fs.h" #include "global.h" +#include "sqlzma.h" +#include "sqmagic.h" #include @@ -62,6 +64,7 @@ extern int add_file(long long, long long } while(0) int swap; +extern struct sqlzma_un un; int read_block(int fd, long long start, long long *next, unsigned char *block, squashfs_super_block *sBlk) { @@ -81,19 +84,20 @@ int read_block(int fd, long long start, char buffer[SQUASHFS_METADATA_SIZE]; int res; unsigned long bytes = SQUASHFS_METADATA_SIZE; + enum {Src, Dst}; + struct sized_buf sbuf[] = { + {.buf = (void *)buffer}, + {.buf = (void *)block, .sz = bytes} + }; c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); read_bytes(fd, start + offset, c_byte, buffer); - if((res = uncompress(block, &bytes, (const unsigned char *) buffer, c_byte)) != Z_OK) { - if(res == Z_MEM_ERROR) - ERROR("zlib::uncompress failed, not enough memory\n"); - else if(res == Z_BUF_ERROR) - ERROR("zlib::uncompress failed, not enough room in output buffer\n"); - else - ERROR("zlib::uncompress failed, unknown error %d\n", res); - return 0; - } + sbuf[Src].sz = c_byte; + res = sqlzma_un(&un, sbuf + Src, sbuf + Dst); + if (res) + abort(); + bytes = un.un_reslen; if(next) *next = start + offset + c_byte; return bytes; @@ -351,18 +355,30 @@ int read_super(int fd, squashfs_super_bl /* Check it is a SQUASHFS superblock */ swap = 0; - if(sBlk->s_magic != SQUASHFS_MAGIC) { - if(sBlk->s_magic == SQUASHFS_MAGIC_SWAP) { - squashfs_super_block sblk; - ERROR("Reading a different endian SQUASHFS filesystem on %s - ignoring -le/-be options\n", source); - SQUASHFS_SWAP_SUPER_BLOCK(&sblk, sBlk); - memcpy(sBlk, &sblk, sizeof(squashfs_super_block)); - swap = 1; - } else { - ERROR("Can't find a SQUASHFS superblock on %s\n", source); - goto failed_mount; - } - } + switch (sBlk->s_magic) { + squashfs_super_block sblk; + + case SQUASHFS_MAGIC_LZMA: + if (!un.un_lzma) + goto bad; + break; + case SQUASHFS_MAGIC: + break; + case SQUASHFS_MAGIC_LZMA_SWAP: + if (!un.un_lzma) + goto bad; + /*FALLTHROUGH*/ + case SQUASHFS_MAGIC_SWAP: + ERROR("Reading a different endian SQUASHFS filesystem on %s - ignoring -le/-be options\n", source); + SQUASHFS_SWAP_SUPER_BLOCK(&sblk, sBlk); + memcpy(sBlk, &sblk, sizeof(squashfs_super_block)); + swap = 1; + break; + bad: + default: + ERROR("Can't find a SQUASHFS superblock on %s\n", source); + goto failed_mount; + } /* Check the MAJOR & MINOR versions */ if(sBlk->s_major != SQUASHFS_MAJOR || sBlk->s_minor > SQUASHFS_MINOR) { @@ -416,7 +432,7 @@ unsigned char *squashfs_readdir(int fd, squashfs_dir_entry *dire = (squashfs_dir_entry *) buffer; unsigned char *directory_table = NULL; int byte, bytes = 0, dir_count; - long long start = sBlk->directory_table_start + directory_start_block, last_start_block; + long long start = sBlk->directory_table_start + directory_start_block, last_start_block = -1; size += offset; if((directory_table = malloc((size + SQUASHFS_METADATA_SIZE * 2 - 1) & ~(SQUASHFS_METADATA_SIZE - 1))) == NULL) Index: squashfs3.3/squashfs-tools/sort.c =================================================================== RCS file: squashfs3.3/squashfs-tools/sort.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -r1.1 -r1.2 --- squashfs3.3/squashfs-tools/sort.c 4 Nov 2007 13:19:11 -0000 1.1 +++ squashfs3.3/squashfs-tools/sort.c 5 Nov 2007 05:43:36 -0000 1.2 @@ -74,7 +74,7 @@ struct sort_info *sort_info_list[65536]; struct priority_entry *priority_list[65536]; extern int silent; -extern write_file(squashfs_inode *inode, struct dir_ent *dir_ent, int *c_size); +extern void write_file(squashfs_inode *inode, struct dir_ent *dir_ent, int *c_size); int add_priority_list(struct dir_ent *dir, int priority) Index: squashfs3.3/squashfs-tools/unsquashfs.c =================================================================== RCS file: squashfs3.3/squashfs-tools/unsquashfs.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -r1.1 -r1.2 --- squashfs3.3/squashfs-tools/unsquashfs.c 4 Nov 2007 13:19:11 -0000 1.1 +++ squashfs3.3/squashfs-tools/unsquashfs.c 5 Nov 2007 05:43:36 -0000 1.2 @@ -52,6 +52,8 @@ #include #include "read_fs.h" #include "global.h" +#include "sqlzma.h" +#include "sqmagic.h" #include #include @@ -131,6 +133,7 @@ unsigned int block_size; int lsonly = FALSE, info = FALSE, force = FALSE, short_ls = TRUE, use_regex = FALSE; char **created_inode; int root_process; +struct sqlzma_un un; int lookup_type[] = { 0, @@ -287,6 +290,7 @@ int read_bytes(long long byte, int bytes return FALSE; } + /* printf("%d bytes at %Ld\n", bytes, off); */ if(read(fd, buff, bytes) == -1) { ERROR("Read on destination failed because %s\n", strerror(errno)); return FALSE; @@ -318,21 +322,21 @@ int read_block(long long start, long lon char buffer[SQUASHFS_METADATA_SIZE]; int res; unsigned long bytes = SQUASHFS_METADATA_SIZE; + enum {Src, Dst}; + struct sized_buf sbuf[] = { + {.buf = (void *)buffer}, + {.buf = (void *)block, .sz = bytes} + }; c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); if(read_bytes(start + offset, c_byte, buffer) == FALSE) goto failed; - if((res = uncompress((unsigned char *) block, &bytes, - (const unsigned char *) buffer, c_byte)) != Z_OK) { - if(res == Z_MEM_ERROR) - ERROR("zlib::uncompress failed, not enough memory\n"); - else if(res == Z_BUF_ERROR) - ERROR("zlib::uncompress failed, not enough room in output buffer\n"); - else - ERROR("zlib::uncompress failed, unknown error %d\n", res); - goto failed; - } + sbuf[Src].sz = c_byte; + res = sqlzma_un(&un, sbuf + Src, sbuf + Dst); + if (res) + abort(); + bytes = un.un_reslen; if(next) *next = start + offset + c_byte; return bytes; @@ -359,20 +363,19 @@ int read_data_block(long long start, uns TRACE("read_data_block: block @0x%llx, %d %s bytes\n", start, SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte), SQUASHFS_COMPRESSED_BLOCK(c_byte) ? "compressed" : "uncompressed"); if(SQUASHFS_COMPRESSED_BLOCK(size)) { - if(read_bytes(start, c_byte, data) == FALSE) - return 0; + enum {Src, Dst}; + struct sized_buf sbuf[] = { + {.buf = (void *)data, .sz = c_byte}, + {.buf = (void *)block, .sz = bytes} + }; - if((res = uncompress((unsigned char *) block, &bytes, - (const unsigned char *) data, c_byte)) != Z_OK) { - if(res == Z_MEM_ERROR) - ERROR("zlib::uncompress failed, not enough memory\n"); - else if(res == Z_BUF_ERROR) - ERROR("zlib::uncompress failed, not enough room in output buffer\n"); - else - ERROR("zlib::uncompress failed, unknown error %d\n", res); + if(read_bytes(start, c_byte, data) == FALSE) return 0; - } + res = sqlzma_un(&un, sbuf + Src, sbuf + Dst); + if (res) + abort(); + bytes = un.un_reslen; return bytes; } else { if(read_bytes(start, c_byte, block) == FALSE) @@ -653,7 +656,7 @@ unsigned int mode) return FALSE; } - s_ops.read_block_list(block_list, block_ptr, blocks); + s_ops.read_block_list(block_list, (void *)block_ptr, blocks); if((file_fd = open(pathname, O_CREAT | O_WRONLY | (force ? O_TRUNC : 0), (mode_t) mode & 0777)) == -1) { ERROR("write_file: failed to create file %s, because %s\n", pathname, @@ -921,7 +924,7 @@ int create_inode(char *pathname, struct set_attributes(pathname, i->mode, i->uid, i->gid, i->time, TRUE); dev_count ++; } else - ERROR("create_inode: could not create %s device %s, because you're not superuser!\n", + ERROR("create_inode: could not create %s device %s, because you're not superuser! %s\n", chrdev ? "character" : "block", pathname, strerror(errno)); break; } @@ -1456,7 +1459,7 @@ void squashfs_closedir(struct dir *dir) char *get_component(char *target, char *targname) { while(*target == '/') - *target ++; + target ++; while(*target != '/' && *target!= '\0') *targname ++ = *target ++; @@ -1529,7 +1532,8 @@ struct pathname *add_path(struct pathnam paths->name[i].paths = NULL; if(use_regex) { paths->name[i].preg = malloc(sizeof(regex_t)); - if(error = regcomp(paths->name[i].preg, targname, REG_EXTENDED|REG_NOSUB)) { + error = regcomp(paths->name[i].preg, targname, REG_EXTENDED|REG_NOSUB); + if(error) { char str[1024]; regerror(error, paths->name[i].preg, str, 1024); @@ -1717,7 +1721,8 @@ int dir_scan(char *parent_name, unsigned free_subdir(new); } - !lsonly && set_attributes(parent_name, dir->mode, dir->uid, dir->guid, dir->mtime, force); + if (!lsonly) //?? + set_attributes(parent_name, dir->mode, dir->uid, dir->guid, dir->mtime, force); squashfs_closedir(dir); dir_count ++; @@ -1775,19 +1780,27 @@ int read_super(char *source) read_bytes(SQUASHFS_START, sizeof(squashfs_super_block), (char *) &sBlk); /* Check it is a SQUASHFS superblock */ + un.un_lzma = 1; swap = 0; - if(sBlk.s_magic != SQUASHFS_MAGIC) { - if(sBlk.s_magic == SQUASHFS_MAGIC_SWAP) { - squashfs_super_block sblk; - ERROR("Reading a different endian SQUASHFS filesystem on %s\n", source); - SQUASHFS_SWAP_SUPER_BLOCK(&sblk, &sBlk); - memcpy(&sBlk, &sblk, sizeof(squashfs_super_block)); - swap = 1; - } else { - ERROR("Can't find a SQUASHFS superblock on %s\n", source); - goto failed_mount; - } - } + switch (sBlk.s_magic) { + squashfs_super_block sblk; + case SQUASHFS_MAGIC: + un.un_lzma = 0; + /*FALLTHROUGH*/ + case SQUASHFS_MAGIC_LZMA: + break; + case SQUASHFS_MAGIC_SWAP: + un.un_lzma = 0; + /*FALLTHROUGH*/ + case SQUASHFS_MAGIC_LZMA_SWAP: + ERROR("Reading a different endian SQUASHFS filesystem on %s\n", source); + SQUASHFS_SWAP_SUPER_BLOCK(&sblk, &sBlk); + memcpy(&sBlk, &sblk, sizeof(squashfs_super_block)); + swap = 1; + default: + ERROR("Can't find a SQUASHFS superblock on %s\n", source); + goto failed_mount; + } /* Check the MAJOR & MINOR versions */ if(sBlk.s_major == 1 || sBlk.s_major == 2) { @@ -1857,7 +1870,8 @@ struct pathname *process_extract_files(s printf("This program is distributed in the hope that it will be useful,\n");\ printf("but WITHOUT ANY WARRANTY; without even the implied warranty of\n");\ printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");\ - printf("GNU General Public License for more details.\n"); + printf("GNU General Public License for more details.\n");\ + printf("and LZMA support for slax.org by jro.\n"); int main(int argc, char *argv[]) { char *dest = "squashfs-root"; @@ -1867,7 +1881,8 @@ int main(int argc, char *argv[]) struct pathnames *paths = NULL; struct pathname *path = NULL; - if(root_process = geteuid() == 0) + root_process = geteuid() == 0; + if(root_process) umask(0); for(i = 1; i < argc; i++) { @@ -1957,6 +1972,11 @@ options: EXIT_UNSQUASH("failed to allocate created_inode\n"); memset(created_inode, 0, sBlk.inodes * sizeof(char *)); + i = sqlzma_init(&un, un.un_lzma, 0); + if (i != Z_OK) { + fputs("sqlzma_init failed", stderr); + abort(); + } read_uids_guids();