int __DBG(const char *file, int line, ext2_ino_t ino, int rc) { if (rc == 0) printf("at %s:%d : offending inode %lu found !\n", file, line, (unsigned long)ino); return rc; } #define DBG(rc) __DBG(__FILE__, __LINE__, ino, rc) /* * Check to make sure a symlink inode is real. Returns 1 if the symlink * checks out, 0 if not. */ int e2fsck_pass1_check_symlink(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode, char *buf) { unsigned int len; int i; blk64_t blocks; ext2_extent_handle_t handle; struct ext2_extent_info info; struct ext2fs_extent extent; if ((inode->i_size_high || inode->i_size == 0) || (inode->i_flags & EXT2_INDEX_FL)) return DBG(0); if (inode->i_flags & EXT4_EXTENTS_FL) { if (inode->i_size > fs->blocksize) return DBG(0); if (ext2fs_extent_open2(fs, ino, inode, &handle)) return DBG(0); i = 0; if (ext2fs_extent_get_info(handle, &info) || (info.num_entries != 1) || (info.max_depth != 0)) goto exit_extent; if (ext2fs_extent_get(handle, EXT2_EXTENT_ROOT, &extent) || (extent.e_lblk != 0) || (extent.e_len != 1) || (extent.e_pblk < fs->super->s_first_data_block) || (extent.e_pblk >= ext2fs_blocks_count(fs->super))) goto exit_extent; i = 1; exit_extent: ext2fs_extent_free(handle); return DBG(i); } blocks = ext2fs_inode_data_blocks2(fs, inode); if (blocks) { if ((inode->i_size >= fs->blocksize) || (blocks != fs->blocksize >> 9) || (inode->i_block[0] < fs->super->s_first_data_block) || (inode->i_block[0] >= ext2fs_blocks_count(fs->super))) return DBG(0); for (i = 1; i < EXT2_N_BLOCKS; i++) if (inode->i_block[i]) return DBG(0); if (io_channel_read_blk64(fs->io, inode->i_block[0], 1, buf)) return DBG(0); printf("blocks != 0 && fs->blocksize = %d, buf = %%%s%%\n", fs->blocksize, buf); len = strnlen(buf, fs->blocksize); if (len == fs->blocksize) return DBG(0); } else { if (inode->i_size >= sizeof(inode->i_block)) return DBG(0); printf("blocks == 0 && inode->i_size = %d, inode->i_block = %%%s%%\n", inode->i_size, (char *)inode->i_block); len = strnlen((char *)inode->i_block, sizeof(inode->i_block)); if (len == sizeof(inode->i_block)) return DBG(0); } if (len != inode->i_size) { printf("len = %d, inode->i_size = %d\n", len, inode->i_size); return DBG(0); } return 1; }