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; }
struct compressor *read_super(int fd, struct squashfs_super_block *sBlk, char *source) { int res, bytes = 0; char buffer[SQUASHFS_METADATA_SIZE] __attribute__ ((aligned)); res = read_fs_bytes(fd, SQUASHFS_START, sizeof(struct squashfs_super_block), sBlk); if(res == 0) { ERROR("Can't find a SQUASHFS superblock on %s\n", source); ERROR("Wrong filesystem or filesystem is corrupted!\n"); goto failed_mount; } SQUASHFS_INSWAP_SUPER_BLOCK(sBlk); if(sBlk->s_magic != SQUASHFS_MAGIC) { if(sBlk->s_magic == SQUASHFS_MAGIC_SWAP) ERROR("Pre 4.0 big-endian filesystem on %s, appending" " to this is unsupported\n", source); else { ERROR("Can't find a SQUASHFS superblock on %s\n", source); ERROR("Wrong filesystem or filesystem is corrupted!\n"); } goto failed_mount; } /* Check the MAJOR & MINOR versions */ if(sBlk->s_major != SQUASHFS_MAJOR || sBlk->s_minor > SQUASHFS_MINOR) { if(sBlk->s_major < 4) 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 4 filesystem\n", source, sBlk->s_major, sBlk->s_minor, sBlk->s_major, sBlk->s_minor); else ERROR("Filesystem on %s is %d.%d, which is a later " "filesystem version than I support\n", source, sBlk->s_major, sBlk->s_minor); goto failed_mount; } /* Check the compression type */ comp = lookup_compressor_id(sBlk->compression); if(!comp->supported) { ERROR("Filesystem on %s uses %s compression, this is " "unsupported by this version\n", source, comp->name); ERROR("Compressors available:\n"); display_compressors("", ""); goto failed_mount; } /* * Read extended superblock information from disk. * * Read compressor specific options from disk if present, and pass * to compressor to set compressor options. * * Note, if there's no compressor options present, the compressor * is still called to set the default options (the defaults may have * been changed by the user specifying options on the command * line which need to be over-ridden). * * Compressor_extract_options is also used to ensure that * we know how decompress a filesystem compressed with these * compression options. */ if(SQUASHFS_COMP_OPTS(sBlk->flags)) { bytes = read_block(fd, sizeof(*sBlk), NULL, 0, buffer); if(bytes == 0) { ERROR("Failed to read compressor options from append " "filesystem\n"); ERROR("Filesystem corrupted?\n"); goto failed_mount; } } res = compressor_extract_options(comp, sBlk->block_size, buffer, bytes); if(res == -1) { ERROR("Compressor failed to set compressor options\n"); goto failed_mount; } printf("Found a valid %sSQUASHFS superblock on %s.\n", SQUASHFS_EXPORTABLE(sBlk->flags) ? "exportable " : "", source); printf("\tCompression used %s\n", comp->name); 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("\tXattrs are %scompressed\n", SQUASHFS_UNCOMPRESSED_XATTRS(sBlk->flags) ? "un" : ""); 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("\tXattrs are %sstored\n", SQUASHFS_NO_XATTRS(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 ids %d\n", sBlk->no_ids); TRACE("sBlk->inode_table_start %llx\n", sBlk->inode_table_start); TRACE("sBlk->directory_table_start %llx\n", sBlk->directory_table_start); TRACE("sBlk->id_table_start %llx\n", sBlk->id_table_start); TRACE("sBlk->fragment_table_start %llx\n", sBlk->fragment_table_start); TRACE("sBlk->lookup_table_start %llx\n", sBlk->lookup_table_start); TRACE("sBlk->xattr_id_table_start %llx\n", sBlk->xattr_id_table_start); printf("\n"); return comp; failed_mount: return NULL; }
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; }