// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2020 Bootlin * * Author: Joao Marcos Costa */ #include #include #include #include #include #include #include "sqfs_filesystem.h" #include "sqfs_utils.h" bool sqfs_is_dir(u16 type) { return type == SQFS_DIR_TYPE || type == SQFS_LDIR_TYPE; } /* * Receives a pointer (void *) to a position in the inode table containing the * directory's inode. Returns directory inode offset into the directory table. * m_list contains each metadata block's position, and m_count is the number of * elements of m_list. Those metadata blocks come from the compressed directory * table. */ int sqfs_dir_offset(void *dir_i, u32 *m_list, int m_count) { struct squashfs_base_inode *base = dir_i; struct squashfs_ldir_inode *ldir; struct squashfs_dir_inode *dir; u32 start_block; int j, offset; switch (get_unaligned_le16(&base->inode_type)) { case SQFS_DIR_TYPE: dir = (struct squashfs_dir_inode *)base; start_block = get_unaligned_le32(&dir->start_block); offset = get_unaligned_le16(&dir->offset); break; case SQFS_LDIR_TYPE: ldir = (struct squashfs_ldir_inode *)base; start_block = get_unaligned_le32(&ldir->start_block); offset = get_unaligned_le16(&ldir->offset); break; default: printf("Error: this is not a directory.\n"); return -EINVAL; } if (offset < 0) return -EINVAL; for (j = 0; j < m_count; j++) { if (m_list[j] == start_block) return (++j * SQFS_METADATA_BLOCK_SIZE) + offset; } if (start_block == 0) return offset; printf("Error: invalid inode reference to directory table.\n"); return -EINVAL; } bool sqfs_is_empty_dir(void *dir_i) { struct squashfs_base_inode *base = dir_i; struct squashfs_ldir_inode *ldir; struct squashfs_dir_inode *dir; u32 file_size; switch (get_unaligned_le16(&base->inode_type)) { case SQFS_DIR_TYPE: dir = (struct squashfs_dir_inode *)base; file_size = get_unaligned_le16(&dir->file_size); break; case SQFS_LDIR_TYPE: ldir = (struct squashfs_ldir_inode *)base; file_size = get_unaligned_le16(&ldir->file_size); break; default: printf("Error: this is not a directory.\n"); return false; } return file_size == SQFS_EMPTY_FILE_SIZE; }