read_fs.c revision ce2fef5e9d6e31648e93bda430fee37f0929c583
11f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher/* 21ebb6e9932d448097d769f1366d8adaae797ea64plougher * Read a squashfs filesystem. This is a highly compressed read only 31ebb6e9932d448097d769f1366d8adaae797ea64plougher * filesystem. 41f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher * 5096135f7430824033f597e47906a24d087f47a34Phillip Lougher * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 6b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher * 2012, 2013 783d42a3fc898962aa1f1e8387f2ccb1114e0d294Phillip Lougher * Phillip Lougher <phillip@squashfs.org.uk> 81f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher * 91f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher * This program is free software; you can redistribute it and/or 101f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher * modify it under the terms of the GNU General Public License 111f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher * as published by the Free Software Foundation; either version 2, 121f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher * or (at your option) any later version. 131f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher * 141f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher * This program is distributed in the hope that it will be useful, 151f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher * but WITHOUT ANY WARRANTY; without even the implied warranty of 161f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 171f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher * GNU General Public License for more details. 181f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher * 191f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher * You should have received a copy of the GNU General Public License 201f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher * along with this program; if not, write to the Free Software 211f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 221f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher * 231f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher * read_fs.c 241f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher */ 251f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 261f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher#define TRUE 1 271f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher#define FALSE 0 281f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher#include <stdio.h> 291f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher#include <sys/types.h> 301f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher#include <sys/stat.h> 311f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher#include <fcntl.h> 321f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher#include <errno.h> 331f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher#include <string.h> 341f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher#include <sys/mman.h> 35125de73c204b2b92c03ee9bff16dd595e71656afPhillip Lougher#include <limits.h> 36ce2fef5e9d6e31648e93bda430fee37f0929c583Phillip Lougher#include <dirent.h> 378cb05cde913bb04297020629566540981a649273plougher 3887c0c4afbf3b8ecc814f6bac4d90b70d1e109f44plougher#ifndef linux 398cb05cde913bb04297020629566540981a649273plougher#define __BYTE_ORDER BYTE_ORDER 408cb05cde913bb04297020629566540981a649273plougher#define __BIG_ENDIAN BIG_ENDIAN 418cb05cde913bb04297020629566540981a649273plougher#define __LITTLE_ENDIAN LITTLE_ENDIAN 428cb05cde913bb04297020629566540981a649273plougher#else 431f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher#include <endian.h> 448cb05cde913bb04297020629566540981a649273plougher#endif 451f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 461f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher#include <stdlib.h> 471f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 48860c1f3d8aa4ba40d587382a91821bea03b023c5plougher#include "squashfs_fs.h" 49860c1f3d8aa4ba40d587382a91821bea03b023c5plougher#include "squashfs_swap.h" 50860c1f3d8aa4ba40d587382a91821bea03b023c5plougher#include "compressor.h" 51860c1f3d8aa4ba40d587382a91821bea03b023c5plougher#include "xattr.h" 522477d0defc9d6dade582bb36596eed2e3cfddf8cPhillip Lougher#include "error.h" 53ce2fef5e9d6e31648e93bda430fee37f0929c583Phillip Lougher#include "mksquashfs.h" 54374444c9b3c6331d781625bec0a7550e05d01ed6plougher 5534c07d5be0cabec0f7eac86d4b0b24392dcc07c0plougherstatic struct compressor *comp; 5634c07d5be0cabec0f7eac86d4b0b24392dcc07c0plougher 57b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougherint read_block(int fd, long long start, long long *next, int expected, 58b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher void *block) 591f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher{ 601f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher unsigned short c_byte; 61b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher int res, compressed; 62b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher int outlen = expected ? expected : SQUASHFS_METADATA_SIZE; 631f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 64b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher /* Read block size */ 653306cb2b54a60a32664617118336ac141e1471b6plougher res = read_fs_bytes(fd, start, 2, &c_byte); 661d065e9f3c6d22a629134837a55538fb8619cfb4plougher if(res == 0) 671d065e9f3c6d22a629134837a55538fb8619cfb4plougher return 0; 681d065e9f3c6d22a629134837a55538fb8619cfb4plougher 6961343797593e92ad2cf75b221398c138e1fee058plougher SQUASHFS_INSWAP_SHORTS(&c_byte, 1); 70b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher compressed = SQUASHFS_COMPRESSED(c_byte); 71b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); 721f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 73b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher /* 74b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher * The block size should not be larger than 75b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher * the uncompressed size (or max uncompressed size if 76b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher * expected is 0) 77b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher */ 78b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher if (c_byte > outlen) 79b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher return 0; 80b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher 81b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher if(compressed) { 82b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher char buffer[c_byte]; 83b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher int error; 841f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 85540c7abc405a7a26373d5299e77122eae1365c56plougher res = read_fs_bytes(fd, start + 2, c_byte, buffer); 861d065e9f3c6d22a629134837a55538fb8619cfb4plougher if(res == 0) 871d065e9f3c6d22a629134837a55538fb8619cfb4plougher return 0; 881f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 89b48442b2e37b3cb7efbffb032968f115eec7963cplougher res = compressor_uncompress(comp, block, buffer, c_byte, 90b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher outlen, &error); 919f1e0e214eaff51604105b88153f2d77bc398158plougher if(res == -1) { 929f1e0e214eaff51604105b88153f2d77bc398158plougher ERROR("%s uncompress failed with error code %d\n", 939f1e0e214eaff51604105b88153f2d77bc398158plougher comp->name, error); 941f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher return 0; 951f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher } 961f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher } else { 97540c7abc405a7a26373d5299e77122eae1365c56plougher res = read_fs_bytes(fd, start + 2, c_byte, block); 981d065e9f3c6d22a629134837a55538fb8619cfb4plougher if(res == 0) 991d065e9f3c6d22a629134837a55538fb8619cfb4plougher return 0; 100b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher res = c_byte; 1011f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher } 102b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher 103b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher if(next) 104b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher *next = start + 2 + c_byte; 105b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher 106b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher /* 107b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher * if expected, then check the (uncompressed) return data 108b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher * is of the expected size 109b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher */ 110b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher if(expected && expected != res) 111b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher return 0; 112b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher else 113b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher return res; 1147e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher} 115b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher 116b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher 1177e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher#define NO_BYTES(SIZE) \ 1187e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher (bytes - (cur_ptr - *inode_table) < (SIZE)) 1191f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 1207e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher#define NO_INODE_BYTES(INODE) NO_BYTES(sizeof(struct INODE)) 1211f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 1221b899fc316f7eba7a31da12dc0c9b69ada441059plougherint scan_inode_table(int fd, long long start, long long end, 1231b899fc316f7eba7a31da12dc0c9b69ada441059plougher long long root_inode_start, int root_inode_offset, 124e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher struct squashfs_super_block *sBlk, union squashfs_inode_header 125e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher *dir_inode, unsigned char **inode_table, unsigned int *root_inode_block, 1261b899fc316f7eba7a31da12dc0c9b69ada441059plougher unsigned int *root_inode_size, long long *uncompressed_file, 1271b899fc316f7eba7a31da12dc0c9b69ada441059plougher unsigned int *uncompressed_directory, int *file_count, int *sym_count, 1281b899fc316f7eba7a31da12dc0c9b69ada441059plougher int *dev_count, int *dir_count, int *fifo_count, int *sock_count, 1291b899fc316f7eba7a31da12dc0c9b69ada441059plougher unsigned int *id_table) 1301f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher{ 1311f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher unsigned char *cur_ptr; 1327e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher int byte, files = 0; 1337e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher unsigned int directory_start_block, bytes = 0, size = 0; 1347e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher struct squashfs_base_inode_header base; 1351f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 136e69aac119c4660c567d5159729b9875c3330e4bbplougher TRACE("scan_inode_table: start 0x%llx, end 0x%llx, root_inode_start " 137e69aac119c4660c567d5159729b9875c3330e4bbplougher "0x%llx\n", start, end, root_inode_start); 138e69aac119c4660c567d5159729b9875c3330e4bbplougher 139125de73c204b2b92c03ee9bff16dd595e71656afPhillip Lougher *root_inode_block = UINT_MAX; 1401f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher while(start < end) { 1411f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher if(start == root_inode_start) { 142e69aac119c4660c567d5159729b9875c3330e4bbplougher TRACE("scan_inode_table: read compressed block 0x%llx " 143e69aac119c4660c567d5159729b9875c3330e4bbplougher "containing root inode\n", start); 1441f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher *root_inode_block = bytes; 1451f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher } 146e69aac119c4660c567d5159729b9875c3330e4bbplougher if(size - bytes < SQUASHFS_METADATA_SIZE) { 147e69aac119c4660c567d5159729b9875c3330e4bbplougher *inode_table = realloc(*inode_table, size 148e69aac119c4660c567d5159729b9875c3330e4bbplougher += SQUASHFS_METADATA_SIZE); 149e69aac119c4660c567d5159729b9875c3330e4bbplougher if(*inode_table == NULL) 1509facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher MEM_ERROR(); 151e69aac119c4660c567d5159729b9875c3330e4bbplougher } 1524c9b090b96c10193f33f9985a5a5c11eb1d23ae3plougher TRACE("scan_inode_table: reading block 0x%llx\n", start); 153b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher byte = read_block(fd, start, &start, 0, *inode_table + bytes); 1547e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher if(byte == 0) 15545f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 1562b7242f3271eabb76c6c8ecdfeb9db2e97376488Phillip Lougher 1574c9b090b96c10193f33f9985a5a5c11eb1d23ae3plougher bytes += byte; 1582b7242f3271eabb76c6c8ecdfeb9db2e97376488Phillip Lougher 1592b7242f3271eabb76c6c8ecdfeb9db2e97376488Phillip Lougher /* If this is not the last metadata block in the inode table 1602b7242f3271eabb76c6c8ecdfeb9db2e97376488Phillip Lougher * then it should be SQUASHFS_METADATA_SIZE in size. 1612b7242f3271eabb76c6c8ecdfeb9db2e97376488Phillip Lougher * Note, we can't use expected in read_block() above for this 1622b7242f3271eabb76c6c8ecdfeb9db2e97376488Phillip Lougher * because we don't know if this is the last block until 1632b7242f3271eabb76c6c8ecdfeb9db2e97376488Phillip Lougher * after reading. 1642b7242f3271eabb76c6c8ecdfeb9db2e97376488Phillip Lougher */ 1657e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher if(start != end && byte != SQUASHFS_METADATA_SIZE) 16645f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 1671f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher } 1681f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 1691f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher /* 170125de73c204b2b92c03ee9bff16dd595e71656afPhillip Lougher * We expect to have found the metadata block containing the 171125de73c204b2b92c03ee9bff16dd595e71656afPhillip Lougher * root inode in the above inode_table metadata block scan. If it 172125de73c204b2b92c03ee9bff16dd595e71656afPhillip Lougher * hasn't been found then the filesystem is corrupted 173125de73c204b2b92c03ee9bff16dd595e71656afPhillip Lougher */ 1747e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher if(*root_inode_block == UINT_MAX) 17545f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 1767e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 1777e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher /* 1787e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher * The number of bytes available after the root inode medata block 1797e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher * should be at least the root inode offset + the size of a 1807e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher * regular directory inode, if not the filesystem is corrupted 1817e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher * 1827e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher * +-----------------------+-----------------------+ 1837e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher * | | directory | 1847e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher * | | inode | 1857e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher * +-----------------------+-----------------------+ 1867e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher * ^ ^ ^ 1877e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher * *root_inode_block root_inode_offset bytes 1887e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher */ 1897e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher if((bytes - *root_inode_block) < (root_inode_offset + 1907e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher sizeof(struct squashfs_dir_inode_header))) 19145f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 192125de73c204b2b92c03ee9bff16dd595e71656afPhillip Lougher 193125de73c204b2b92c03ee9bff16dd595e71656afPhillip Lougher /* 194e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher * Read last inode entry which is the root directory inode, and obtain 195e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher * the last directory start block index. This is used when calculating 196e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher * the total uncompressed directory size. The directory bytes in the 197e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher * last * block will be counted as normal. 1981f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher * 1997e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher * Note, the previous check ensures the following calculation won't 2007e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher * underflow, and we won't access beyond the buffer 2011f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher */ 2021f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher *root_inode_size = bytes - (*root_inode_block + root_inode_offset); 2031f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher bytes = *root_inode_block + root_inode_offset; 204690d91306e8b20400ae8c36fd558604189b70bdcPhillip Lougher SQUASHFS_SWAP_DIR_INODE_HEADER(*inode_table + bytes, &dir_inode->dir); 2057e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 2067e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher if(dir_inode->base.inode_type == SQUASHFS_DIR_TYPE) 2071f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher directory_start_block = dir_inode->dir.start_block; 2087e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher else if(dir_inode->base.inode_type == SQUASHFS_LDIR_TYPE) { 2097e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher if(*root_inode_size < sizeof(struct squashfs_ldir_inode_header)) 2107e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher /* corrupted filesystem */ 21145f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 212690d91306e8b20400ae8c36fd558604189b70bdcPhillip Lougher SQUASHFS_SWAP_LDIR_INODE_HEADER(*inode_table + bytes, 213690d91306e8b20400ae8c36fd558604189b70bdcPhillip Lougher &dir_inode->ldir); 2141f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher directory_start_block = dir_inode->ldir.start_block; 2157e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher } else 2167e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher /* bad type, corrupted filesystem */ 21745f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 2187e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 2191b899fc316f7eba7a31da12dc0c9b69ada441059plougher get_uid(id_table[dir_inode->base.uid]); 2201b899fc316f7eba7a31da12dc0c9b69ada441059plougher get_guid(id_table[dir_inode->base.guid]); 2211f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 2221f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher for(cur_ptr = *inode_table; cur_ptr < *inode_table + bytes; files ++) { 2237e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher if(NO_INODE_BYTES(squashfs_base_inode_header)) 2247e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher /* corrupted filesystem */ 22545f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 2267e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 227690d91306e8b20400ae8c36fd558604189b70bdcPhillip Lougher SQUASHFS_SWAP_BASE_INODE_HEADER(cur_ptr, &base); 2281f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 229e69aac119c4660c567d5159729b9875c3330e4bbplougher TRACE("scan_inode_table: processing inode @ byte position " 230363ddaa1fcfd7e2bb186cb78990c43e491ea981dplougher "0x%x, type 0x%x\n", 231363ddaa1fcfd7e2bb186cb78990c43e491ea981dplougher (unsigned int) (cur_ptr - *inode_table), 2327e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher base.inode_type); 2331b899fc316f7eba7a31da12dc0c9b69ada441059plougher 2347e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher get_uid(id_table[base.uid]); 2357e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher get_guid(id_table[base.guid]); 2361b899fc316f7eba7a31da12dc0c9b69ada441059plougher 2377e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher switch(base.inode_type) { 238e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher case SQUASHFS_FILE_TYPE: { 239e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher struct squashfs_reg_inode_header inode; 240e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher int frag_bytes, blocks, i; 241e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher long long start, file_bytes = 0; 242e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher unsigned int *block_list; 243e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 244e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(NO_INODE_BYTES(squashfs_reg_inode_header)) 245e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher /* corrupted filesystem */ 24645f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 2477e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 248690d91306e8b20400ae8c36fd558604189b70bdcPhillip Lougher SQUASHFS_SWAP_REG_INODE_HEADER(cur_ptr, &inode); 2497e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 250e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher frag_bytes = inode.fragment == SQUASHFS_INVALID_FRAG ? 251e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 0 : inode.file_size % sBlk->block_size; 252e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher blocks = inode.fragment == SQUASHFS_INVALID_FRAG ? 253e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher (inode.file_size + sBlk->block_size - 1) >> 254e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher sBlk->block_log : inode.file_size >> 255e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher sBlk->block_log; 256e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher start = inode.start_block; 2577e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 258e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher TRACE("scan_inode_table: regular file, file_size %d, " 259e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher "blocks %d\n", inode.file_size, blocks); 2601f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 261e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(NO_BYTES(blocks * sizeof(unsigned int))) 262e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher /* corrupted filesystem */ 26345f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 2641f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 265e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher block_list = malloc(blocks * sizeof(unsigned int)); 2669facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher if(block_list == NULL) 2679facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher MEM_ERROR(); 2687e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 269e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher cur_ptr += sizeof(inode); 270690d91306e8b20400ae8c36fd558604189b70bdcPhillip Lougher SQUASHFS_SWAP_INTS(cur_ptr, block_list, blocks); 2717e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 272e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher *uncompressed_file += inode.file_size; 273e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher (*file_count) ++; 274058eae41952c33345bd0ef290aea8eef37f3ca92plougher 275e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher for(i = 0; i < blocks; i++) 276e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher file_bytes += 277e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher SQUASHFS_COMPRESSED_SIZE_BLOCK 278e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher (block_list[i]); 279058eae41952c33345bd0ef290aea8eef37f3ca92plougher 280e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher add_file(start, inode.file_size, file_bytes, 281e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher block_list, blocks, inode.fragment, 282e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher inode.offset, frag_bytes); 283e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 284e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher cur_ptr += blocks * sizeof(unsigned int); 285e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher break; 286e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher } 287e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher case SQUASHFS_LREG_TYPE: { 288e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher struct squashfs_lreg_inode_header inode; 289e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher int frag_bytes, blocks, i; 290e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher long long start, file_bytes = 0; 291e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher unsigned int *block_list; 292e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 293e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(NO_INODE_BYTES(squashfs_lreg_inode_header)) 294e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher /* corrupted filesystem */ 29545f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 296f1cdb557030f345c6cc1f68b52ab89589f2fed81plougher 297690d91306e8b20400ae8c36fd558604189b70bdcPhillip Lougher SQUASHFS_SWAP_LREG_INODE_HEADER(cur_ptr, &inode); 2987e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 299e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher frag_bytes = inode.fragment == SQUASHFS_INVALID_FRAG ? 300e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 0 : inode.file_size % sBlk->block_size; 301e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher blocks = inode.fragment == SQUASHFS_INVALID_FRAG ? 302e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher (inode.file_size + sBlk->block_size - 1) >> 303e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher sBlk->block_log : inode.file_size >> 304e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher sBlk->block_log; 305e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher start = inode.start_block; 306570f436c85a99435180a3ec9aeb1c94135ab0e77plougher 307e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher TRACE("scan_inode_table: extended regular " 308e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher "file, file_size %lld, blocks %d\n", 309e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher inode.file_size, blocks); 310570f436c85a99435180a3ec9aeb1c94135ab0e77plougher 311e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(NO_BYTES(blocks * sizeof(unsigned int))) 312e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher /* corrupted filesystem */ 31345f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 3147e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 315e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher block_list = malloc(blocks * sizeof(unsigned int)); 3169facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher if(block_list == NULL) 3179facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher MEM_ERROR(); 3181f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 319e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher cur_ptr += sizeof(inode); 320690d91306e8b20400ae8c36fd558604189b70bdcPhillip Lougher SQUASHFS_SWAP_INTS(cur_ptr, block_list, blocks); 3211f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 322e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher *uncompressed_file += inode.file_size; 323e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher (*file_count) ++; 3247e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 325e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher for(i = 0; i < blocks; i++) 326e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher file_bytes += 327e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher SQUASHFS_COMPRESSED_SIZE_BLOCK 328e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher (block_list[i]); 3297e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 330e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher add_file(start, inode.file_size, file_bytes, 331e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher block_list, blocks, inode.fragment, 332e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher inode.offset, frag_bytes); 3337e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 334e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher cur_ptr += blocks * sizeof(unsigned int); 335e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher break; 336e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher } 337e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher case SQUASHFS_SYMLINK_TYPE: 338e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher case SQUASHFS_LSYMLINK_TYPE: { 339e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher struct squashfs_symlink_inode_header inode; 34061343797593e92ad2cf75b221398c138e1fee058plougher 341e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(NO_INODE_BYTES(squashfs_symlink_inode_header)) 342e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher /* corrupted filesystem */ 34345f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 3447e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 345690d91306e8b20400ae8c36fd558604189b70bdcPhillip Lougher SQUASHFS_SWAP_SYMLINK_INODE_HEADER(cur_ptr, &inode); 3467e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 347e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher (*sym_count) ++; 3487e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 349e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if (inode.inode_type == SQUASHFS_LSYMLINK_TYPE) { 350e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(NO_BYTES(inode.symlink_size + 351e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher sizeof(unsigned int))) 3527e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher /* corrupted filesystem */ 35345f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 354e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher cur_ptr += sizeof(inode) + inode.symlink_size + 355e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher sizeof(unsigned int); 356e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher } else { 357e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(NO_BYTES(inode.symlink_size)) 3587e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher /* corrupted filesystem */ 35945f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 360e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher cur_ptr += sizeof(inode) + inode.symlink_size; 361e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher } 362e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher break; 363e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher } 364e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher case SQUASHFS_DIR_TYPE: { 365e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher struct squashfs_dir_inode_header dir_inode; 3667e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 367e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(NO_INODE_BYTES(squashfs_dir_inode_header)) 368e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher /* corrupted filesystem */ 36945f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 370e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 371690d91306e8b20400ae8c36fd558604189b70bdcPhillip Lougher SQUASHFS_SWAP_DIR_INODE_HEADER(cur_ptr, &dir_inode); 372e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 373e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(dir_inode.start_block < directory_start_block) 374e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher *uncompressed_directory += dir_inode.file_size; 375e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 376e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher (*dir_count) ++; 377e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher cur_ptr += sizeof(struct squashfs_dir_inode_header); 378e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher break; 379e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher } 380e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher case SQUASHFS_LDIR_TYPE: { 381e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher struct squashfs_ldir_inode_header dir_inode; 382e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher int i; 3837e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 384e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(NO_INODE_BYTES(squashfs_ldir_inode_header)) 385e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher /* corrupted filesystem */ 38645f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 387e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 388690d91306e8b20400ae8c36fd558604189b70bdcPhillip Lougher SQUASHFS_SWAP_LDIR_INODE_HEADER(cur_ptr, &dir_inode); 389e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 390e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(dir_inode.start_block < directory_start_block) 391e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher *uncompressed_directory += dir_inode.file_size; 392e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 393e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher (*dir_count) ++; 394e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher cur_ptr += sizeof(struct squashfs_ldir_inode_header); 395e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 396e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher for(i = 0; i < dir_inode.i_count; i++) { 397e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher struct squashfs_dir_index index; 398e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 399e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(NO_BYTES(sizeof(index))) 4007e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher /* corrupted filesystem */ 40145f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 402e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 403690d91306e8b20400ae8c36fd558604189b70bdcPhillip Lougher SQUASHFS_SWAP_DIR_INDEX(cur_ptr, &index); 4047e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 405e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(NO_BYTES(index.size + 1)) 4067e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher /* corrupted filesystem */ 40745f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 4087e08fad7a62bdbbbe39e1248c3c4b05f5caf9e2cPhillip Lougher 409e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher cur_ptr += sizeof(index) + index.size + 1; 410e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher } 411e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher break; 412e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher } 413e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher case SQUASHFS_BLKDEV_TYPE: 414e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher case SQUASHFS_CHRDEV_TYPE: 415e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(NO_INODE_BYTES(squashfs_dev_inode_header)) 416e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher /* corrupted filesystem */ 41745f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 418e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 419e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher (*dev_count) ++; 420e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher cur_ptr += sizeof(struct squashfs_dev_inode_header); 421e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher break; 422e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher case SQUASHFS_LBLKDEV_TYPE: 423e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher case SQUASHFS_LCHRDEV_TYPE: 424e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(NO_INODE_BYTES(squashfs_ldev_inode_header)) 425e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher /* corrupted filesystem */ 42645f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 427e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 428e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher (*dev_count) ++; 429e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher cur_ptr += sizeof(struct squashfs_ldev_inode_header); 430e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher break; 431e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher case SQUASHFS_FIFO_TYPE: 432e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(NO_INODE_BYTES(squashfs_ipc_inode_header)) 433e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher /* corrupted filesystem */ 43445f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 435e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 436e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher (*fifo_count) ++; 437e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher cur_ptr += sizeof(struct squashfs_ipc_inode_header); 438e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher break; 439e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher case SQUASHFS_LFIFO_TYPE: 440e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(NO_INODE_BYTES(squashfs_lipc_inode_header)) 441e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher /* corrupted filesystem */ 44245f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 443e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 444e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher (*fifo_count) ++; 445e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher cur_ptr += sizeof(struct squashfs_lipc_inode_header); 446e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher break; 447e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher case SQUASHFS_SOCKET_TYPE: 448e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(NO_INODE_BYTES(squashfs_ipc_inode_header)) 449e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher /* corrupted filesystem */ 45045f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 451e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 452e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher (*sock_count) ++; 453e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher cur_ptr += sizeof(struct squashfs_ipc_inode_header); 454e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher break; 455e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher case SQUASHFS_LSOCKET_TYPE: 456e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher if(NO_INODE_BYTES(squashfs_lipc_inode_header)) 457e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher /* corrupted filesystem */ 45845f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 459e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher 460e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher (*sock_count) ++; 461e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher cur_ptr += sizeof(struct squashfs_lipc_inode_header); 462e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher break; 463e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher default: 464e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher ERROR("Unknown inode type %d in scan_inode_table!\n", 465e465085a0a75ed749a9ec5edaff2ea5cd5b47997Phillip Lougher base.inode_type); 46645f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher goto corrupted; 4671f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher } 4681f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher } 4691f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 4701a00ad1a4d97d54f83e41cc3d684de048bad3c10plougher printf("Read existing filesystem, %d inodes scanned\n", files); 4711a00ad1a4d97d54f83e41cc3d684de048bad3c10plougher return TRUE; 472058eae41952c33345bd0ef290aea8eef37f3ca92plougher 47345f78347049325b32c0ab96e6858f3f2bb993532Phillip Loughercorrupted: 47445f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher ERROR("scan_inode_table: filesystem corruption detected in " 47545f78347049325b32c0ab96e6858f3f2bb993532Phillip Lougher "scanning metadata\n"); 476058eae41952c33345bd0ef290aea8eef37f3ca92plougher free(*inode_table); 477058eae41952c33345bd0ef290aea8eef37f3ca92plougher return FALSE; 4781f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher} 4791f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 4801f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 48164e83fda63a1b8408ffbfa466e6c67b0de7a8c99plougherstruct compressor *read_super(int fd, struct squashfs_super_block *sBlk, char *source) 4821f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher{ 483317959322c665d211788f07227abcba61984ec88plougher int res, bytes = 0; 484f6310758b1c84e5f7223425bfaaee97eb962a506plougher char buffer[SQUASHFS_METADATA_SIZE] __attribute__ ((aligned)); 4851d065e9f3c6d22a629134837a55538fb8619cfb4plougher 48664e83fda63a1b8408ffbfa466e6c67b0de7a8c99plougher res = read_fs_bytes(fd, SQUASHFS_START, sizeof(struct squashfs_super_block), 4873306cb2b54a60a32664617118336ac141e1471b6plougher sBlk); 48863ce1770edbdcc36ab48a1dba63af4636dcb69bdPhillip Lougher if(res == 0) { 48963ce1770edbdcc36ab48a1dba63af4636dcb69bdPhillip Lougher ERROR("Can't find a SQUASHFS superblock on %s\n", 49063ce1770edbdcc36ab48a1dba63af4636dcb69bdPhillip Lougher source); 49163ce1770edbdcc36ab48a1dba63af4636dcb69bdPhillip Lougher ERROR("Wrong filesystem or filesystem is corrupted!\n"); 4921d065e9f3c6d22a629134837a55538fb8619cfb4plougher goto failed_mount; 49363ce1770edbdcc36ab48a1dba63af4636dcb69bdPhillip Lougher } 4941d065e9f3c6d22a629134837a55538fb8619cfb4plougher 49561343797593e92ad2cf75b221398c138e1fee058plougher SQUASHFS_INSWAP_SUPER_BLOCK(sBlk); 4961f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 4971f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher if(sBlk->s_magic != SQUASHFS_MAGIC) { 4982702e98268c66397751f9ed996a6460f216dba34plougher if(sBlk->s_magic == SQUASHFS_MAGIC_SWAP) 4992702e98268c66397751f9ed996a6460f216dba34plougher ERROR("Pre 4.0 big-endian filesystem on %s, appending" 5002702e98268c66397751f9ed996a6460f216dba34plougher " to this is unsupported\n", source); 5010372aa056962a0dbdcbb45de9be23f522d645029Phillip Lougher else { 502e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher ERROR("Can't find a SQUASHFS superblock on %s\n", 503e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher source); 5040372aa056962a0dbdcbb45de9be23f522d645029Phillip Lougher ERROR("Wrong filesystem or filesystem is corrupted!\n"); 5050372aa056962a0dbdcbb45de9be23f522d645029Phillip Lougher } 5062702e98268c66397751f9ed996a6460f216dba34plougher goto failed_mount; 5071f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher } 5081f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 5091f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher /* Check the MAJOR & MINOR versions */ 5101f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher if(sBlk->s_major != SQUASHFS_MAJOR || sBlk->s_minor > SQUASHFS_MINOR) { 511f83fbe8fc5e688b288f34865cc885a5711118221plougher if(sBlk->s_major < 4) 512e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher ERROR("Filesystem on %s is a SQUASHFS %d.%d filesystem." 513e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher " Appending\nto SQUASHFS %d.%d filesystems is " 514e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher "not supported. Please convert it to a " 515e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher "SQUASHFS 4 filesystem\n", source, 516e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher sBlk->s_major, 517e69aac119c4660c567d5159729b9875c3330e4bbplougher sBlk->s_minor, sBlk->s_major, sBlk->s_minor); 5181f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher else 519e69aac119c4660c567d5159729b9875c3330e4bbplougher ERROR("Filesystem on %s is %d.%d, which is a later " 520e69aac119c4660c567d5159729b9875c3330e4bbplougher "filesystem version than I support\n", 521df70c3e920ad82bcc5f5f33d5b7c313be6c2ea4fplougher source, sBlk->s_major, sBlk->s_minor); 5221f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher goto failed_mount; 5231f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher } 5241f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 52534c07d5be0cabec0f7eac86d4b0b24392dcc07c0plougher /* Check the compression type */ 52634c07d5be0cabec0f7eac86d4b0b24392dcc07c0plougher comp = lookup_compressor_id(sBlk->compression); 52734c07d5be0cabec0f7eac86d4b0b24392dcc07c0plougher if(!comp->supported) { 52848c97065cf29dff24d01d94b39f4fdc6cef815f2Phillip Lougher ERROR("Filesystem on %s uses %s compression, this is " 52934c07d5be0cabec0f7eac86d4b0b24392dcc07c0plougher "unsupported by this version\n", source, comp->name); 530f09d9a6589de25eb4b9c9891277a717c1053a400plougher ERROR("Compressors available:\n"); 531764dab5cd71bda25bc755de08908dbbd58c1a450plougher display_compressors("", ""); 53234c07d5be0cabec0f7eac86d4b0b24392dcc07c0plougher goto failed_mount; 53334c07d5be0cabec0f7eac86d4b0b24392dcc07c0plougher } 53434c07d5be0cabec0f7eac86d4b0b24392dcc07c0plougher 5355924372bba7ac923cca996e74716128a98f668afplougher /* 5365924372bba7ac923cca996e74716128a98f668afplougher * Read extended superblock information from disk. 5375924372bba7ac923cca996e74716128a98f668afplougher * 5385924372bba7ac923cca996e74716128a98f668afplougher * Read compressor specific options from disk if present, and pass 5395924372bba7ac923cca996e74716128a98f668afplougher * to compressor to set compressor options. 540317959322c665d211788f07227abcba61984ec88plougher * 541317959322c665d211788f07227abcba61984ec88plougher * Note, if there's no compressor options present, the compressor 542317959322c665d211788f07227abcba61984ec88plougher * is still called to set the default options (the defaults may have 543317959322c665d211788f07227abcba61984ec88plougher * been changed by the user specifying options on the command 544317959322c665d211788f07227abcba61984ec88plougher * line which need to be over-ridden). 54547d52fe6f28cb8650ed8d1abb745137579f35e13Phillip Lougher * 54647d52fe6f28cb8650ed8d1abb745137579f35e13Phillip Lougher * Compressor_extract_options is also used to ensure that 54747d52fe6f28cb8650ed8d1abb745137579f35e13Phillip Lougher * we know how decompress a filesystem compressed with these 54847d52fe6f28cb8650ed8d1abb745137579f35e13Phillip Lougher * compression options. 5495924372bba7ac923cca996e74716128a98f668afplougher */ 5505924372bba7ac923cca996e74716128a98f668afplougher if(SQUASHFS_COMP_OPTS(sBlk->flags)) { 551b5db9ddc5eadd38b7a34b50ac64c9c4f61a551b2Phillip Lougher bytes = read_block(fd, sizeof(*sBlk), NULL, 0, buffer); 5525924372bba7ac923cca996e74716128a98f668afplougher 5533d5c06089c65e94ad819477d8a933f93476e8b7dPhillip Lougher if(bytes == 0) { 5542a315732458c990f8e8185aac72d6c0a55350fffPhillip Lougher ERROR("Failed to read compressor options from append " 5553d5c06089c65e94ad819477d8a933f93476e8b7dPhillip Lougher "filesystem\n"); 5562a315732458c990f8e8185aac72d6c0a55350fffPhillip Lougher ERROR("Filesystem corrupted?\n"); 5575924372bba7ac923cca996e74716128a98f668afplougher goto failed_mount; 5583d5c06089c65e94ad819477d8a933f93476e8b7dPhillip Lougher } 559317959322c665d211788f07227abcba61984ec88plougher } 5605924372bba7ac923cca996e74716128a98f668afplougher 561317959322c665d211788f07227abcba61984ec88plougher res = compressor_extract_options(comp, sBlk->block_size, buffer, bytes); 562317959322c665d211788f07227abcba61984ec88plougher if(res == -1) { 563317959322c665d211788f07227abcba61984ec88plougher ERROR("Compressor failed to set compressor options\n"); 564317959322c665d211788f07227abcba61984ec88plougher goto failed_mount; 5655924372bba7ac923cca996e74716128a98f668afplougher } 5665924372bba7ac923cca996e74716128a98f668afplougher 567e69aac119c4660c567d5159729b9875c3330e4bbplougher printf("Found a valid %sSQUASHFS superblock on %s.\n", 568e69aac119c4660c567d5159729b9875c3330e4bbplougher SQUASHFS_EXPORTABLE(sBlk->flags) ? "exportable " : "", source); 569bb98803edb506b6e99693892350ebeca99c6a3dfplougher printf("\tCompression used %s\n", comp->name); 570e69aac119c4660c567d5159729b9875c3330e4bbplougher printf("\tInodes are %scompressed\n", 571e69aac119c4660c567d5159729b9875c3330e4bbplougher SQUASHFS_UNCOMPRESSED_INODES(sBlk->flags) ? "un" : ""); 572e69aac119c4660c567d5159729b9875c3330e4bbplougher printf("\tData is %scompressed\n", 573e69aac119c4660c567d5159729b9875c3330e4bbplougher SQUASHFS_UNCOMPRESSED_DATA(sBlk->flags) ? "un" : ""); 574e69aac119c4660c567d5159729b9875c3330e4bbplougher printf("\tFragments are %scompressed\n", 575e69aac119c4660c567d5159729b9875c3330e4bbplougher SQUASHFS_UNCOMPRESSED_FRAGMENTS(sBlk->flags) ? "un" : ""); 576a10230e410599e3cf1c4ea7fa9a2ba11d4e8eaa1plougher printf("\tXattrs are %scompressed\n", 577a10230e410599e3cf1c4ea7fa9a2ba11d4e8eaa1plougher SQUASHFS_UNCOMPRESSED_XATTRS(sBlk->flags) ? "un" : ""); 578e69aac119c4660c567d5159729b9875c3330e4bbplougher printf("\tFragments are %spresent in the filesystem\n", 579e69aac119c4660c567d5159729b9875c3330e4bbplougher SQUASHFS_NO_FRAGMENTS(sBlk->flags) ? "not " : ""); 5809077fad8779e259fa03326b567644374e98ff171Phillip Lougher printf("\tAlways-use-fragments option is %sspecified\n", 581e69aac119c4660c567d5159729b9875c3330e4bbplougher SQUASHFS_ALWAYS_FRAGMENTS(sBlk->flags) ? "" : "not "); 582e69aac119c4660c567d5159729b9875c3330e4bbplougher printf("\tDuplicates are %sremoved\n", 583e69aac119c4660c567d5159729b9875c3330e4bbplougher SQUASHFS_DUPLICATES(sBlk->flags) ? "" : "not "); 5841031268dc09bac693d8c6d8e913cbf984f0592f5plougher printf("\tXattrs are %sstored\n", 5851031268dc09bac693d8c6d8e913cbf984f0592f5plougher SQUASHFS_NO_XATTRS(sBlk->flags) ? "not " : ""); 586e69aac119c4660c567d5159729b9875c3330e4bbplougher printf("\tFilesystem size %.2f Kbytes (%.2f Mbytes)\n", 587e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher sBlk->bytes_used / 1024.0, sBlk->bytes_used 588e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher / (1024.0 * 1024.0)); 5891f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher printf("\tBlock size %d\n", sBlk->block_size); 5901f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher printf("\tNumber of fragments %d\n", sBlk->fragments); 5911f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher printf("\tNumber of inodes %d\n", sBlk->inodes); 5921b899fc316f7eba7a31da12dc0c9b69ada441059plougher printf("\tNumber of ids %d\n", sBlk->no_ids); 5931f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher TRACE("sBlk->inode_table_start %llx\n", sBlk->inode_table_start); 594e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher TRACE("sBlk->directory_table_start %llx\n", 595e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher sBlk->directory_table_start); 5961b899fc316f7eba7a31da12dc0c9b69ada441059plougher TRACE("sBlk->id_table_start %llx\n", sBlk->id_table_start); 5971f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher TRACE("sBlk->fragment_table_start %llx\n", sBlk->fragment_table_start); 598f1cdb557030f345c6cc1f68b52ab89589f2fed81plougher TRACE("sBlk->lookup_table_start %llx\n", sBlk->lookup_table_start); 5999c0688ef8954e7e335a62479ba0408d585d47853plougher TRACE("sBlk->xattr_id_table_start %llx\n", sBlk->xattr_id_table_start); 6001f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher printf("\n"); 6011f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 60234c07d5be0cabec0f7eac86d4b0b24392dcc07c0plougher return comp; 6031f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 6041f413c84d736495fd61ff05ebe52c3a01a4d95c2plougherfailed_mount: 60534c07d5be0cabec0f7eac86d4b0b24392dcc07c0plougher return NULL; 6061f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher} 6071f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 6081f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 609e69aac119c4660c567d5159729b9875c3330e4bbplougherunsigned char *squashfs_readdir(int fd, int root_entries, 610e69aac119c4660c567d5159729b9875c3330e4bbplougher unsigned int directory_start_block, int offset, int size, 61164e83fda63a1b8408ffbfa466e6c67b0de7a8c99plougher unsigned int *last_directory_block, struct squashfs_super_block *sBlk, 612e69aac119c4660c567d5159729b9875c3330e4bbplougher void (push_directory_entry)(char *, squashfs_inode, int, int)) 6131f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher{ 614520e1a144c9a6c957754f93dc8830f884fe5669bplougher struct squashfs_dir_header dirh; 6159b393553bbca1d7efc755a4b73e64407a526ef11plougher char buffer[sizeof(struct squashfs_dir_entry) + SQUASHFS_NAME_LEN + 1] 61646aefa984f924b2187e8f104fafed15899200237plougher __attribute__ ((aligned)); 6179b393553bbca1d7efc755a4b73e64407a526ef11plougher struct squashfs_dir_entry *dire = (struct squashfs_dir_entry *) buffer; 6181f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher unsigned char *directory_table = NULL; 619df70c3e920ad82bcc5f5f33d5b7c313be6c2ea4fplougher int byte, bytes = 0, dir_count; 620e69aac119c4660c567d5159729b9875c3330e4bbplougher long long start = sBlk->directory_table_start + directory_start_block, 621e69aac119c4660c567d5159729b9875c3330e4bbplougher last_start_block = start; 6221f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 6231f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher size += offset; 624e69aac119c4660c567d5159729b9875c3330e4bbplougher directory_table = malloc((size + SQUASHFS_METADATA_SIZE * 2 - 1) & 625e69aac119c4660c567d5159729b9875c3330e4bbplougher ~(SQUASHFS_METADATA_SIZE - 1)); 626e69aac119c4660c567d5159729b9875c3330e4bbplougher if(directory_table == NULL) 6279facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher MEM_ERROR(); 6289facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher 6291f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher while(bytes < size) { 630a761c26cd25620f6dfaf7a452ee2ad6cfab9e1e3Phillip Lougher int expected = (size - bytes) >= SQUASHFS_METADATA_SIZE ? 631a761c26cd25620f6dfaf7a452ee2ad6cfab9e1e3Phillip Lougher SQUASHFS_METADATA_SIZE : 0; 632a761c26cd25620f6dfaf7a452ee2ad6cfab9e1e3Phillip Lougher 633e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher TRACE("squashfs_readdir: reading block 0x%llx, bytes read so " 634e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher "far %d\n", start, bytes); 635a761c26cd25620f6dfaf7a452ee2ad6cfab9e1e3Phillip Lougher 6361f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher last_start_block = start; 637a761c26cd25620f6dfaf7a452ee2ad6cfab9e1e3Phillip Lougher byte = read_block(fd, start, &start, expected, directory_table + bytes); 638e69aac119c4660c567d5159729b9875c3330e4bbplougher if(byte == 0) { 6392a315732458c990f8e8185aac72d6c0a55350fffPhillip Lougher ERROR("Failed to read directory\n"); 6402a315732458c990f8e8185aac72d6c0a55350fffPhillip Lougher ERROR("Filesystem corrupted?\n"); 6411f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher free(directory_table); 6421f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher return NULL; 6431f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher } 644df70c3e920ad82bcc5f5f33d5b7c313be6c2ea4fplougher bytes += byte; 6451f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher } 6461f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 6471f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher if(!root_entries) 6481f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher goto all_done; 6491f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 6501f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher bytes = offset; 6511f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher while(bytes < size) { 652690d91306e8b20400ae8c36fd558604189b70bdcPhillip Lougher SQUASHFS_SWAP_DIR_HEADER(directory_table + bytes, &dirh); 6531f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 6541f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher dir_count = dirh.count + 1; 655e69aac119c4660c567d5159729b9875c3330e4bbplougher TRACE("squashfs_readdir: Read directory header @ byte position " 656e69aac119c4660c567d5159729b9875c3330e4bbplougher "0x%x, 0x%x directory entries\n", bytes, dir_count); 6571f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher bytes += sizeof(dirh); 6581f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 6591f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher while(dir_count--) { 660690d91306e8b20400ae8c36fd558604189b70bdcPhillip Lougher SQUASHFS_SWAP_DIR_ENTRY(directory_table + bytes, dire); 6611f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher bytes += sizeof(*dire); 6621f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 663e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher memcpy(dire->name, directory_table + bytes, 664e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher dire->size + 1); 6651f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher dire->name[dire->size + 1] = '\0'; 666e69aac119c4660c567d5159729b9875c3330e4bbplougher TRACE("squashfs_readdir: pushing directory entry %s, " 667e69aac119c4660c567d5159729b9875c3330e4bbplougher "inode %x:%x, type 0x%x\n", dire->name, 668e69aac119c4660c567d5159729b9875c3330e4bbplougher dirh.start_block, dire->offset, dire->type); 669e69aac119c4660c567d5159729b9875c3330e4bbplougher push_directory_entry(dire->name, 670e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher SQUASHFS_MKINODE(dirh.start_block, 671e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher dire->offset), dirh.inode_number + 672e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher dire->inode_number, dire->type); 6731f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher bytes += dire->size + 1; 6741f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher } 6751f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher } 6761f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 6771f413c84d736495fd61ff05ebe52c3a01a4d95c2plougherall_done: 678e69aac119c4660c567d5159729b9875c3330e4bbplougher *last_directory_block = (unsigned int) last_start_block - 679e69aac119c4660c567d5159729b9875c3330e4bbplougher sBlk->directory_table_start; 6801f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher return directory_table; 6811f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher} 6821f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 6831f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 68464e83fda63a1b8408ffbfa466e6c67b0de7a8c99plougherunsigned int *read_id_table(int fd, struct squashfs_super_block *sBlk) 6851b899fc316f7eba7a31da12dc0c9b69ada441059plougher{ 6861b899fc316f7eba7a31da12dc0c9b69ada441059plougher int indexes = SQUASHFS_ID_BLOCKS(sBlk->no_ids); 6871b899fc316f7eba7a31da12dc0c9b69ada441059plougher long long index[indexes]; 6881b899fc316f7eba7a31da12dc0c9b69ada441059plougher int bytes = SQUASHFS_ID_BYTES(sBlk->no_ids); 68961343797593e92ad2cf75b221398c138e1fee058plougher unsigned int *id_table; 6901d065e9f3c6d22a629134837a55538fb8619cfb4plougher int res, i; 6911b899fc316f7eba7a31da12dc0c9b69ada441059plougher 6921b899fc316f7eba7a31da12dc0c9b69ada441059plougher id_table = malloc(bytes); 6939facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher if(id_table == NULL) 6949facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher MEM_ERROR(); 6951b899fc316f7eba7a31da12dc0c9b69ada441059plougher 6961d065e9f3c6d22a629134837a55538fb8619cfb4plougher res = read_fs_bytes(fd, sBlk->id_table_start, 6973306cb2b54a60a32664617118336ac141e1471b6plougher SQUASHFS_ID_BLOCK_BYTES(sBlk->no_ids), index); 6981d065e9f3c6d22a629134837a55538fb8619cfb4plougher if(res == 0) { 6999f0a2c69377ffd7b2d066a4a06963d895727ae52Phillip Lougher ERROR("Failed to read id table index\n"); 7009f0a2c69377ffd7b2d066a4a06963d895727ae52Phillip Lougher ERROR("Filesystem corrupted?\n"); 7011d065e9f3c6d22a629134837a55538fb8619cfb4plougher free(id_table); 7021d065e9f3c6d22a629134837a55538fb8619cfb4plougher return NULL; 7031d065e9f3c6d22a629134837a55538fb8619cfb4plougher } 7041d065e9f3c6d22a629134837a55538fb8619cfb4plougher 70561343797593e92ad2cf75b221398c138e1fee058plougher SQUASHFS_INSWAP_ID_BLOCKS(index, indexes); 7061b899fc316f7eba7a31da12dc0c9b69ada441059plougher 7071b899fc316f7eba7a31da12dc0c9b69ada441059plougher for(i = 0; i < indexes; i++) { 708197c9f6f6fde6e9aea7e269c936f26ff2f8466fePhillip Lougher int expected = (i + 1) != indexes ? SQUASHFS_METADATA_SIZE : 709197c9f6f6fde6e9aea7e269c936f26ff2f8466fePhillip Lougher bytes & (SQUASHFS_METADATA_SIZE - 1); 710197c9f6f6fde6e9aea7e269c936f26ff2f8466fePhillip Lougher int length = read_block(fd, index[i], NULL, expected, 711e69aac119c4660c567d5159729b9875c3330e4bbplougher ((unsigned char *) id_table) + 712923b301e304637fd5e587eb05a6f44558abae2bdplougher (i * SQUASHFS_METADATA_SIZE)); 713e69aac119c4660c567d5159729b9875c3330e4bbplougher TRACE("Read id table block %d, from 0x%llx, length %d\n", i, 714e69aac119c4660c567d5159729b9875c3330e4bbplougher index[i], length); 715730ef508553ce562277b5d34fd272716e7ed6f13plougher if(length == 0) { 716730ef508553ce562277b5d34fd272716e7ed6f13plougher ERROR("Failed to read id table block %d, from 0x%llx, " 717730ef508553ce562277b5d34fd272716e7ed6f13plougher "length %d\n", i, index[i], length); 7182a315732458c990f8e8185aac72d6c0a55350fffPhillip Lougher ERROR("Filesystem corrupted?\n"); 719730ef508553ce562277b5d34fd272716e7ed6f13plougher free(id_table); 720730ef508553ce562277b5d34fd272716e7ed6f13plougher return NULL; 721730ef508553ce562277b5d34fd272716e7ed6f13plougher } 7221b899fc316f7eba7a31da12dc0c9b69ada441059plougher } 7231b899fc316f7eba7a31da12dc0c9b69ada441059plougher 72461343797593e92ad2cf75b221398c138e1fee058plougher SQUASHFS_INSWAP_INTS(id_table, sBlk->no_ids); 7251b899fc316f7eba7a31da12dc0c9b69ada441059plougher 7261b899fc316f7eba7a31da12dc0c9b69ada441059plougher for(i = 0; i < sBlk->no_ids; i++) { 7271b899fc316f7eba7a31da12dc0c9b69ada441059plougher TRACE("Adding id %d to id tables\n", id_table[i]); 7281b899fc316f7eba7a31da12dc0c9b69ada441059plougher create_id(id_table[i]); 7291b899fc316f7eba7a31da12dc0c9b69ada441059plougher } 7301b899fc316f7eba7a31da12dc0c9b69ada441059plougher 7311b899fc316f7eba7a31da12dc0c9b69ada441059plougher return id_table; 7321b899fc316f7eba7a31da12dc0c9b69ada441059plougher} 7331b899fc316f7eba7a31da12dc0c9b69ada441059plougher 7341b899fc316f7eba7a31da12dc0c9b69ada441059plougher 73564e83fda63a1b8408ffbfa466e6c67b0de7a8c99plougherint read_fragment_table(int fd, struct squashfs_super_block *sBlk, 7368ed84b96ca36da8147993935b951918359d8f20aplougher struct squashfs_fragment_entry **fragment_table) 7371f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher{ 738852db8287892bb34537830311de63c0cc5563783Phillip Lougher int res, i; 739852db8287892bb34537830311de63c0cc5563783Phillip Lougher int bytes = SQUASHFS_FRAGMENT_BYTES(sBlk->fragments); 740852db8287892bb34537830311de63c0cc5563783Phillip Lougher int indexes = SQUASHFS_FRAGMENT_INDEXES(sBlk->fragments); 7412625a3d8f39b94c4841bd605361f4b575b0dc1a5plougher long long fragment_table_index[indexes]; 7421f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 743e69aac119c4660c567d5159729b9875c3330e4bbplougher TRACE("read_fragment_table: %d fragments, reading %d fragment indexes " 744e69aac119c4660c567d5159729b9875c3330e4bbplougher "from 0x%llx\n", sBlk->fragments, indexes, 745e69aac119c4660c567d5159729b9875c3330e4bbplougher sBlk->fragment_table_start); 746852db8287892bb34537830311de63c0cc5563783Phillip Lougher 7471f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher if(sBlk->fragments == 0) 7481f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher return 1; 7491f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 750852db8287892bb34537830311de63c0cc5563783Phillip Lougher *fragment_table = malloc(bytes); 7519facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher if(*fragment_table == NULL) 7529facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher MEM_ERROR(); 7531f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 7541d065e9f3c6d22a629134837a55538fb8619cfb4plougher res = read_fs_bytes(fd, sBlk->fragment_table_start, 755e69aac119c4660c567d5159729b9875c3330e4bbplougher SQUASHFS_FRAGMENT_INDEX_BYTES(sBlk->fragments), 7563306cb2b54a60a32664617118336ac141e1471b6plougher fragment_table_index); 7571d065e9f3c6d22a629134837a55538fb8619cfb4plougher if(res == 0) { 7589f0a2c69377ffd7b2d066a4a06963d895727ae52Phillip Lougher ERROR("Failed to read fragment table index\n"); 7599f0a2c69377ffd7b2d066a4a06963d895727ae52Phillip Lougher ERROR("Filesystem corrupted?\n"); 7601d065e9f3c6d22a629134837a55538fb8619cfb4plougher free(*fragment_table); 7611d065e9f3c6d22a629134837a55538fb8619cfb4plougher return 0; 7621d065e9f3c6d22a629134837a55538fb8619cfb4plougher } 7631d065e9f3c6d22a629134837a55538fb8619cfb4plougher 76461343797593e92ad2cf75b221398c138e1fee058plougher SQUASHFS_INSWAP_FRAGMENT_INDEXES(fragment_table_index, indexes); 7651f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 7661f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher for(i = 0; i < indexes; i++) { 767852db8287892bb34537830311de63c0cc5563783Phillip Lougher int expected = (i + 1) != indexes ? SQUASHFS_METADATA_SIZE : 768852db8287892bb34537830311de63c0cc5563783Phillip Lougher bytes & (SQUASHFS_METADATA_SIZE - 1); 769852db8287892bb34537830311de63c0cc5563783Phillip Lougher int length = read_block(fd, fragment_table_index[i], NULL, 770852db8287892bb34537830311de63c0cc5563783Phillip Lougher expected, ((unsigned char *) *fragment_table) + 771923b301e304637fd5e587eb05a6f44558abae2bdplougher (i * SQUASHFS_METADATA_SIZE)); 772e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher TRACE("Read fragment table block %d, from 0x%llx, length %d\n", 773e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher i, fragment_table_index[i], length); 774730ef508553ce562277b5d34fd272716e7ed6f13plougher if(length == 0) { 775730ef508553ce562277b5d34fd272716e7ed6f13plougher ERROR("Failed to read fragment table block %d, from " 776730ef508553ce562277b5d34fd272716e7ed6f13plougher "0x%llx, length %d\n", i, 777730ef508553ce562277b5d34fd272716e7ed6f13plougher fragment_table_index[i], length); 7782a315732458c990f8e8185aac72d6c0a55350fffPhillip Lougher ERROR("Filesystem corrupted?\n"); 779730ef508553ce562277b5d34fd272716e7ed6f13plougher free(*fragment_table); 780730ef508553ce562277b5d34fd272716e7ed6f13plougher return 0; 781730ef508553ce562277b5d34fd272716e7ed6f13plougher } 7821f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher } 7831f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 78461343797593e92ad2cf75b221398c138e1fee058plougher for(i = 0; i < sBlk->fragments; i++) 78561343797593e92ad2cf75b221398c138e1fee058plougher SQUASHFS_INSWAP_FRAGMENT_ENTRY(&(*fragment_table)[i]); 7861f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 7871f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher return 1; 7881f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher} 7891f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 7901f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 79164e83fda63a1b8408ffbfa466e6c67b0de7a8c99plougherint read_inode_lookup_table(int fd, struct squashfs_super_block *sBlk, 792e69aac119c4660c567d5159729b9875c3330e4bbplougher squashfs_inode **inode_lookup_table) 7930e45365737bf5283627e32253f2279c4d9fa32d0plougher{ 7940e45365737bf5283627e32253f2279c4d9fa32d0plougher int lookup_bytes = SQUASHFS_LOOKUP_BYTES(sBlk->inodes); 7950e45365737bf5283627e32253f2279c4d9fa32d0plougher int indexes = SQUASHFS_LOOKUP_BLOCKS(sBlk->inodes); 7960e45365737bf5283627e32253f2279c4d9fa32d0plougher long long index[indexes]; 7971d065e9f3c6d22a629134837a55538fb8619cfb4plougher int res, i; 7980e45365737bf5283627e32253f2279c4d9fa32d0plougher 7990e45365737bf5283627e32253f2279c4d9fa32d0plougher if(sBlk->lookup_table_start == SQUASHFS_INVALID_BLK) 8000e45365737bf5283627e32253f2279c4d9fa32d0plougher return 1; 8010e45365737bf5283627e32253f2279c4d9fa32d0plougher 802e69aac119c4660c567d5159729b9875c3330e4bbplougher *inode_lookup_table = malloc(lookup_bytes); 8039facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher if(*inode_lookup_table == NULL) 8049facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher MEM_ERROR(); 8050e45365737bf5283627e32253f2279c4d9fa32d0plougher 8061d065e9f3c6d22a629134837a55538fb8619cfb4plougher res = read_fs_bytes(fd, sBlk->lookup_table_start, 8073306cb2b54a60a32664617118336ac141e1471b6plougher SQUASHFS_LOOKUP_BLOCK_BYTES(sBlk->inodes), index); 8081d065e9f3c6d22a629134837a55538fb8619cfb4plougher if(res == 0) { 8099f0a2c69377ffd7b2d066a4a06963d895727ae52Phillip Lougher ERROR("Failed to read inode lookup table index\n"); 8109f0a2c69377ffd7b2d066a4a06963d895727ae52Phillip Lougher ERROR("Filesystem corrupted?\n"); 8111d065e9f3c6d22a629134837a55538fb8619cfb4plougher free(*inode_lookup_table); 8121d065e9f3c6d22a629134837a55538fb8619cfb4plougher return 0; 8131d065e9f3c6d22a629134837a55538fb8619cfb4plougher } 8141d065e9f3c6d22a629134837a55538fb8619cfb4plougher 81561343797593e92ad2cf75b221398c138e1fee058plougher SQUASHFS_INSWAP_LONG_LONGS(index, indexes); 8160e45365737bf5283627e32253f2279c4d9fa32d0plougher 8170e45365737bf5283627e32253f2279c4d9fa32d0plougher for(i = 0; i < indexes; i++) { 818751e32fd169afa63e97a2d4d6f47aede3e98862aPhillip Lougher int expected = (i + 1) != indexes ? SQUASHFS_METADATA_SIZE : 819751e32fd169afa63e97a2d4d6f47aede3e98862aPhillip Lougher lookup_bytes & (SQUASHFS_METADATA_SIZE - 1); 820751e32fd169afa63e97a2d4d6f47aede3e98862aPhillip Lougher int length = read_block(fd, index[i], NULL, expected, 821e69aac119c4660c567d5159729b9875c3330e4bbplougher ((unsigned char *) *inode_lookup_table) + 822923b301e304637fd5e587eb05a6f44558abae2bdplougher (i * SQUASHFS_METADATA_SIZE)); 823e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher TRACE("Read inode lookup table block %d, from 0x%llx, length " 824e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher "%d\n", i, index[i], length); 825730ef508553ce562277b5d34fd272716e7ed6f13plougher if(length == 0) { 826730ef508553ce562277b5d34fd272716e7ed6f13plougher ERROR("Failed to read inode lookup table block %d, " 827730ef508553ce562277b5d34fd272716e7ed6f13plougher "from 0x%llx, length %d\n", i, index[i], 828730ef508553ce562277b5d34fd272716e7ed6f13plougher length); 8292a315732458c990f8e8185aac72d6c0a55350fffPhillip Lougher ERROR("Filesystem corrupted?\n"); 830730ef508553ce562277b5d34fd272716e7ed6f13plougher free(*inode_lookup_table); 831730ef508553ce562277b5d34fd272716e7ed6f13plougher return 0; 832730ef508553ce562277b5d34fd272716e7ed6f13plougher } 8330e45365737bf5283627e32253f2279c4d9fa32d0plougher } 8340e45365737bf5283627e32253f2279c4d9fa32d0plougher 83561343797593e92ad2cf75b221398c138e1fee058plougher SQUASHFS_INSWAP_LONG_LONGS(*inode_lookup_table, sBlk->inodes); 8360e45365737bf5283627e32253f2279c4d9fa32d0plougher 8370e45365737bf5283627e32253f2279c4d9fa32d0plougher return 1; 8380e45365737bf5283627e32253f2279c4d9fa32d0plougher} 8390e45365737bf5283627e32253f2279c4d9fa32d0plougher 8400e45365737bf5283627e32253f2279c4d9fa32d0plougher 84164e83fda63a1b8408ffbfa466e6c67b0de7a8c99plougherlong long read_filesystem(char *root_name, int fd, struct squashfs_super_block *sBlk, 842e69aac119c4660c567d5159729b9875c3330e4bbplougher char **cinode_table, char **data_cache, char **cdirectory_table, 843e69aac119c4660c567d5159729b9875c3330e4bbplougher char **directory_data_cache, unsigned int *last_directory_block, 844e69aac119c4660c567d5159729b9875c3330e4bbplougher unsigned int *inode_dir_offset, unsigned int *inode_dir_file_size, 845e69aac119c4660c567d5159729b9875c3330e4bbplougher unsigned int *root_inode_size, unsigned int *inode_dir_start_block, 846e69aac119c4660c567d5159729b9875c3330e4bbplougher int *file_count, int *sym_count, int *dev_count, int *dir_count, 847e69aac119c4660c567d5159729b9875c3330e4bbplougher int *fifo_count, int *sock_count, long long *uncompressed_file, 848e69aac119c4660c567d5159729b9875c3330e4bbplougher unsigned int *uncompressed_inode, unsigned int *uncompressed_directory, 849e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher unsigned int *inode_dir_inode_number, 850e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher unsigned int *inode_dir_parent_inode, 851e69aac119c4660c567d5159729b9875c3330e4bbplougher void (push_directory_entry)(char *, squashfs_inode, int, int), 8528ed84b96ca36da8147993935b951918359d8f20aplougher struct squashfs_fragment_entry **fragment_table, 853e69aac119c4660c567d5159729b9875c3330e4bbplougher squashfs_inode **inode_lookup_table) 8541f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher{ 855096135f7430824033f597e47906a24d087f47a34Phillip Lougher unsigned char *inode_table = NULL, *directory_table = NULL; 856e69aac119c4660c567d5159729b9875c3330e4bbplougher long long start = sBlk->inode_table_start; 857e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher long long end = sBlk->directory_table_start; 858e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher long long root_inode_start = start + 8591f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher SQUASHFS_INODE_BLK(sBlk->root_inode); 860e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher unsigned int root_inode_offset = 861e6d6143d60f8f71167f8bb3e4d21a43188dd95fbplougher SQUASHFS_INODE_OFFSET(sBlk->root_inode); 8621a00ad1a4d97d54f83e41cc3d684de048bad3c10plougher unsigned int root_inode_block; 8638973a12943b86e759a6391995271fa620d73483fplougher union squashfs_inode_header inode; 864096135f7430824033f597e47906a24d087f47a34Phillip Lougher unsigned int *id_table = NULL; 8651d065e9f3c6d22a629134837a55538fb8619cfb4plougher int res; 8661f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 8671f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher printf("Scanning existing filesystem...\n"); 8681f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 869570f436c85a99435180a3ec9aeb1c94135ab0e77plougher if(get_xattrs(fd, sBlk) == 0) 870570f436c85a99435180a3ec9aeb1c94135ab0e77plougher goto error; 871570f436c85a99435180a3ec9aeb1c94135ab0e77plougher 8724c9b090b96c10193f33f9985a5a5c11eb1d23ae3plougher if(read_fragment_table(fd, sBlk, fragment_table) == 0) 8731f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher goto error; 8741f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 8750e45365737bf5283627e32253f2279c4d9fa32d0plougher if(read_inode_lookup_table(fd, sBlk, inode_lookup_table) == 0) 8760e45365737bf5283627e32253f2279c4d9fa32d0plougher goto error; 8770e45365737bf5283627e32253f2279c4d9fa32d0plougher 8781b899fc316f7eba7a31da12dc0c9b69ada441059plougher id_table = read_id_table(fd, sBlk); 8791b899fc316f7eba7a31da12dc0c9b69ada441059plougher if(id_table == NULL) 8801b899fc316f7eba7a31da12dc0c9b69ada441059plougher goto error; 8811b899fc316f7eba7a31da12dc0c9b69ada441059plougher 88296eedecdf4d075f5b860f8bf3eaab2a8ea2a805bplougher res = scan_inode_table(fd, start, end, root_inode_start, 88396eedecdf4d075f5b860f8bf3eaab2a8ea2a805bplougher root_inode_offset, sBlk, &inode, &inode_table, 88496eedecdf4d075f5b860f8bf3eaab2a8ea2a805bplougher &root_inode_block, root_inode_size, uncompressed_file, 88596eedecdf4d075f5b860f8bf3eaab2a8ea2a805bplougher uncompressed_directory, file_count, sym_count, dev_count, 88696eedecdf4d075f5b860f8bf3eaab2a8ea2a805bplougher dir_count, fifo_count, sock_count, id_table); 8871a734af8bd761a7737b56a55a9de04f3753500acPhillip Lougher if(res == 0) 8881f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher goto error; 8891f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 8901f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher *uncompressed_inode = root_inode_block; 8911f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 892e69aac119c4660c567d5159729b9875c3330e4bbplougher if(inode.base.inode_type == SQUASHFS_DIR_TYPE || 893e69aac119c4660c567d5159729b9875c3330e4bbplougher inode.base.inode_type == SQUASHFS_LDIR_TYPE) { 8941f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher if(inode.base.inode_type == SQUASHFS_DIR_TYPE) { 8951f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher *inode_dir_start_block = inode.dir.start_block; 8961f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher *inode_dir_offset = inode.dir.offset; 897058eae41952c33345bd0ef290aea8eef37f3ca92plougher *inode_dir_file_size = inode.dir.file_size - 3; 898df70c3e920ad82bcc5f5f33d5b7c313be6c2ea4fplougher *inode_dir_inode_number = inode.dir.inode_number; 899df70c3e920ad82bcc5f5f33d5b7c313be6c2ea4fplougher *inode_dir_parent_inode = inode.dir.parent_inode; 9001f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher } else { 9011f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher *inode_dir_start_block = inode.ldir.start_block; 9021f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher *inode_dir_offset = inode.ldir.offset; 903058eae41952c33345bd0ef290aea8eef37f3ca92plougher *inode_dir_file_size = inode.ldir.file_size - 3; 904df70c3e920ad82bcc5f5f33d5b7c313be6c2ea4fplougher *inode_dir_inode_number = inode.ldir.inode_number; 905df70c3e920ad82bcc5f5f33d5b7c313be6c2ea4fplougher *inode_dir_parent_inode = inode.ldir.parent_inode; 9061f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher } 9071f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 908e69aac119c4660c567d5159729b9875c3330e4bbplougher directory_table = squashfs_readdir(fd, !root_name, 909e69aac119c4660c567d5159729b9875c3330e4bbplougher *inode_dir_start_block, *inode_dir_offset, 910e69aac119c4660c567d5159729b9875c3330e4bbplougher *inode_dir_file_size, last_directory_block, sBlk, 911e69aac119c4660c567d5159729b9875c3330e4bbplougher push_directory_entry); 9124d7c0724196a5fce8fefa6ee923c79be7c94301bPhillip Lougher if(directory_table == NULL) 9131f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher goto error; 9141f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 9151f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher root_inode_start -= start; 916169d54f8cd07949d5708ff6ca7d48a06185ff604plougher *cinode_table = malloc(root_inode_start); 9179facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher if(*cinode_table == NULL) 9189facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher MEM_ERROR(); 9199facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher 9201d065e9f3c6d22a629134837a55538fb8619cfb4plougher res = read_fs_bytes(fd, start, root_inode_start, *cinode_table); 9219f0a2c69377ffd7b2d066a4a06963d895727ae52Phillip Lougher if(res == 0) { 9229f0a2c69377ffd7b2d066a4a06963d895727ae52Phillip Lougher ERROR("Failed to read inode table\n"); 9239f0a2c69377ffd7b2d066a4a06963d895727ae52Phillip Lougher ERROR("Filesystem corrupted?\n"); 9241d065e9f3c6d22a629134837a55538fb8619cfb4plougher goto error; 9259f0a2c69377ffd7b2d066a4a06963d895727ae52Phillip Lougher } 9261f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 927e69aac119c4660c567d5159729b9875c3330e4bbplougher *cdirectory_table = malloc(*last_directory_block); 9289facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher if(*cdirectory_table == NULL) 9299facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher MEM_ERROR(); 9309facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher 9311d065e9f3c6d22a629134837a55538fb8619cfb4plougher res = read_fs_bytes(fd, sBlk->directory_table_start, 932e69aac119c4660c567d5159729b9875c3330e4bbplougher *last_directory_block, *cdirectory_table); 9339f0a2c69377ffd7b2d066a4a06963d895727ae52Phillip Lougher if(res == 0) { 9349f0a2c69377ffd7b2d066a4a06963d895727ae52Phillip Lougher ERROR("Failed to read directory table\n"); 9359451938650abe45e8714660f420c0546ccb7a6aaPhillip Lougher ERROR("Filesystem corrupted?\n"); 9361d065e9f3c6d22a629134837a55538fb8619cfb4plougher goto error; 9379f0a2c69377ffd7b2d066a4a06963d895727ae52Phillip Lougher } 9381f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 939e69aac119c4660c567d5159729b9875c3330e4bbplougher *data_cache = malloc(root_inode_offset + *root_inode_size); 9409facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher if(*data_cache == NULL) 9419facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher MEM_ERROR(); 9429facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher 943e69aac119c4660c567d5159729b9875c3330e4bbplougher memcpy(*data_cache, inode_table + root_inode_block, 944e69aac119c4660c567d5159729b9875c3330e4bbplougher root_inode_offset + *root_inode_size); 945e69aac119c4660c567d5159729b9875c3330e4bbplougher 946e69aac119c4660c567d5159729b9875c3330e4bbplougher *directory_data_cache = malloc(*inode_dir_offset + 947e69aac119c4660c567d5159729b9875c3330e4bbplougher *inode_dir_file_size); 9489facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher if(*directory_data_cache == NULL) 9499facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher MEM_ERROR(); 9509facf01876801ce86eb06004959ab4aebb27fd39Phillip Lougher 951e69aac119c4660c567d5159729b9875c3330e4bbplougher memcpy(*directory_data_cache, directory_table, 952e69aac119c4660c567d5159729b9875c3330e4bbplougher *inode_dir_offset + *inode_dir_file_size); 9531f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 954096135f7430824033f597e47906a24d087f47a34Phillip Lougher free(id_table); 9551f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher free(inode_table); 9561f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher free(directory_table); 9571f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher return sBlk->inode_table_start; 9581f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher } 9591f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher 9601f413c84d736495fd61ff05ebe52c3a01a4d95c2ploughererror: 961096135f7430824033f597e47906a24d087f47a34Phillip Lougher free(id_table); 962096135f7430824033f597e47906a24d087f47a34Phillip Lougher free(inode_table); 963096135f7430824033f597e47906a24d087f47a34Phillip Lougher free(directory_table); 9641f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher return 0; 9651f413c84d736495fd61ff05ebe52c3a01a4d95c2plougher} 966