Esempio n. 1
0
int read_super(int fd, squashfs_super_block *sBlk, int *be, char *source)
{
	read_bytes(fd, SQUASHFS_START, sizeof(squashfs_super_block), (char *) sBlk);

	/* 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;
		}
	}

	/* Check the MAJOR & MINOR versions */
	if(sBlk->s_major != SQUASHFS_MAJOR || sBlk->s_minor > SQUASHFS_MINOR) {
		if(sBlk->s_major == 1)
			ERROR("Filesystem on %s is a SQUASHFS 1.x filesystem.  Appending\nto SQUASHFS 1.x filesystems is not supported.  Please convert it to a SQUASHFS 2.1 filesystem...n", source);
		else
			ERROR("Major/Minor mismatch, filesystem on %s is (%d:%d), I support (%d: <= %d)\n",
				source, sBlk->s_major, sBlk->s_minor, SQUASHFS_MAJOR, SQUASHFS_MINOR);
		goto failed_mount;
	}

#if __BYTE_ORDER == __BIG_ENDIAN
	*be = !swap;
#else
	*be = swap;
#endif

	printf("Found a valid SQUASHFS superblock on %s.\n", source);
	printf("\tInodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(sBlk->flags) ? "un" : "");
	printf("\tData is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(sBlk->flags) ? "un" : "");
	printf("\tFragments are %scompressed\n", SQUASHFS_UNCOMPRESSED_FRAGMENTS(sBlk->flags) ? "un" : "");
	printf("\tCheck data is %s present in the filesystem\n", SQUASHFS_CHECK_DATA(sBlk->flags) ? "" : "not");
	printf("\tFragments are %s present in the filesystem\n", SQUASHFS_NO_FRAGMENTS(sBlk->flags) ? "not" : "");
	printf("\tAlways_use_fragments option is %s specified\n", SQUASHFS_ALWAYS_FRAGMENTS(sBlk->flags) ? "" : "not");
	printf("\tDuplicates are %s removed\n", SQUASHFS_DUPLICATES(sBlk->flags) ? "" : "not");
	printf("\tFilesystem size %d bytes\n", sBlk->bytes_used);
	printf("\tBlock size %d\n", sBlk->block_size);
	printf("\tNumber of fragments %d\n", sBlk->fragments);
	printf("\tNumber of inodes %d\n", sBlk->inodes);
	printf("\tNumber of uids %d\n", sBlk->no_uids);
	printf("\tNumber of gids %d\n", sBlk->no_guids);
	TRACE("sBlk->inode_table_start %x\n", sBlk->inode_table_start);
	TRACE("sBlk->directory_table_start %x\n", sBlk->directory_table_start);
	TRACE("sBlk->uid_start %x\n", sBlk->uid_start);
	TRACE("sBlk->fragment_table_start %x\n", sBlk->fragment_table_start);
	printf("\n");

	return TRUE;

failed_mount:
	return FALSE;
}
Esempio n. 2
0
int read_block(long long start, long long *next, char *block, squashfs_super_block *sBlk)
{
	unsigned short c_byte;
	int offset = 2;
	
	if(swap) {
		if(read_bytes(start, 2, block) == FALSE)
			goto failed;
		((unsigned char *) &c_byte)[1] = block[0];
		((unsigned char *) &c_byte)[0] = block[1]; 
	} else 
		if(read_bytes(start, 2, (char *)&c_byte) == FALSE)
			goto failed;

	TRACE("read_block: block @0x%llx, %d %s bytes\n", start, SQUASHFS_COMPRESSED_SIZE(c_byte), SQUASHFS_COMPRESSED(c_byte) ? "compressed" : "uncompressed");

	if(SQUASHFS_CHECK_DATA(sBlk->flags))
		offset = 3;
	if(SQUASHFS_COMPRESSED(c_byte)) {
		char buffer[SQUASHFS_METADATA_SIZE];
		int res;
		unsigned long bytes = SQUASHFS_METADATA_SIZE;

		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);
				exit(1);
			}
			goto failed;
		}
		if(next)
			*next = start + offset + c_byte;
		return bytes;
	} else {
		c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
		if(read_bytes(start + offset, c_byte, block) == FALSE)
			goto failed;
		if(next)
			*next = start + offset + c_byte;
		return c_byte;
	}

failed:
	return FALSE;
}
Esempio n. 3
0
int read_block(int fd, long long start, long long *next, unsigned char *block, squashfs_super_block *sBlk)
{
	unsigned short c_byte;
	int offset = 2;
	
	if(swap) {
		read_bytes(fd, start, 2, (char *) block);
		((unsigned char *) &c_byte)[1] = block[0];
		((unsigned char *) &c_byte)[0] = block[1]; 
	} else 
		read_bytes(fd, start, 2, (char *)&c_byte);

	if(SQUASHFS_CHECK_DATA(sBlk->flags))
		offset = 3;
	if(SQUASHFS_COMPRESSED(c_byte)) {
		char buffer[SQUASHFS_METADATA_SIZE];
		int res;
		unsigned long bytes = SQUASHFS_METADATA_SIZE;

		c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
		read_bytes(fd, start + offset, c_byte, buffer);

		if(!lzma) {
			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;
			}
		}
		/* lzma */
		else {
			if((res = LzmaUncompress(block, &bytes, buffer, c_byte)) != SZ_OK)
				ERROR("LzmaUncompress: error (%d)\n", res);
		}
		if(next)
			*next = start + offset + c_byte;
		return bytes;
	} else {
		c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
		read_bytes(fd, start + offset, c_byte, (char *) block);
		if(next)
			*next = start + offset + c_byte;
		return c_byte;
	}
}
Esempio n. 4
0
int read_block(int fd, long long start, long long *next, unsigned char *block, squashfs_super_block *sBlk)
{
	unsigned short c_byte;
	int offset = 2;
	
	if(swap) {
		read_bytes(fd, start, 2, (char *) block);
		((unsigned char *) &c_byte)[1] = block[0];
		((unsigned char *) &c_byte)[0] = block[1]; 
	} else 
		read_bytes(fd, start, 2, (char *)&c_byte);

	if(SQUASHFS_CHECK_DATA(sBlk->flags))
		offset = 3;
	if(SQUASHFS_COMPRESSED(c_byte)) {
		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}
		};
Esempio n. 5
0
int read_super(int fd, squashfs_super_block *sBlk, int *be, char *source)
{
	squashfs_super_block sblk;

	read_bytes(fd, SQUASHFS_START, sizeof(squashfs_super_block), (char *) sBlk);

	/* Check it is a SQUASHFS superblock */
	swap = 0;
	switch (sBlk->s_magic) {
	case SQUASHFS_MAGIC_LZMA:
		if (!lzma)
			goto bad;
		break;
	case SQUASHFS_MAGIC:
		break;
	case SQUASHFS_MAGIC_SWAP:
	case SQUASHFS_MAGIC_LZMA_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) {
		if(sBlk->s_major < 3)
			ERROR("Filesystem on %s is a SQUASHFS %d.%d filesystem.  Appending\nto SQUASHFS %d.%d filesystems is not supported.  Please convert it to a SQUASHFS 3.0 filesystem\n", source, sBlk->s_major, sBlk->s_minor, sBlk->s_major, sBlk->s_minor);
		else
			ERROR("Major/Minor mismatch, filesystem on %s is %d.%d, I support 3.0\n",
				source, sBlk->s_major, sBlk->s_minor);
		goto failed_mount;
	}

#if __BYTE_ORDER == __BIG_ENDIAN
	*be = !swap;
#else
	*be = swap;
#endif

	printf("Found a valid %s%s SQUASHFS superblock on %s.\n", SQUASHFS_EXPORTABLE(sBlk->flags) ? "exportable " : "", *be ? "big endian" : "little endian", source);
	printf("\tInodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(sBlk->flags) ? "un" : "");
	printf("\tData is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(sBlk->flags) ? "un" : "");
	printf("\tFragments are %scompressed\n", SQUASHFS_UNCOMPRESSED_FRAGMENTS(sBlk->flags) ? "un" : "");
	printf("\tCheck data is %spresent in the filesystem\n", SQUASHFS_CHECK_DATA(sBlk->flags) ? "" : "not ");
	printf("\tFragments are %spresent in the filesystem\n", SQUASHFS_NO_FRAGMENTS(sBlk->flags) ? "not " : "");
	printf("\tAlways_use_fragments option is %sspecified\n", SQUASHFS_ALWAYS_FRAGMENTS(sBlk->flags) ? "" : "not ");
	printf("\tDuplicates are %sremoved\n", SQUASHFS_DUPLICATES(sBlk->flags) ? "" : "not ");
	printf("\tFilesystem size %.2f Kbytes (%.2f Mbytes)\n", sBlk->bytes_used / 1024.0, sBlk->bytes_used / (1024.0 * 1024.0));
	printf("\tBlock size %d\n", sBlk->block_size);
	printf("\tNumber of fragments %d\n", sBlk->fragments);
	printf("\tNumber of inodes %d\n", sBlk->inodes);
	printf("\tNumber of uids %d\n", sBlk->no_uids);
	printf("\tNumber of gids %d\n", sBlk->no_guids);
	TRACE("sBlk->inode_table_start %llx\n", sBlk->inode_table_start);
	TRACE("sBlk->directory_table_start %llx\n", sBlk->directory_table_start);
	TRACE("sBlk->uid_start %llx\n", sBlk->uid_start);
	TRACE("sBlk->fragment_table_start %llx\n", sBlk->fragment_table_start);
	TRACE("sBlk->lookup_table_start %xllx\n", sBlk->lookup_table_start);
	printf("\n");

	return TRUE;

failed_mount:
	return FALSE;
}