+void do_idump(int argc, char *argv[], int sci_idx EXT2FS_ATTR((unused)),
+ void *infop EXT2FS_ATTR((unused)))
+{
+ struct ext2_inode_large *inode;
+ ext2_ino_t ino;
+ unsigned char *buf;
+ errcode_t err;
+ unsigned int isize, size, offset = 0;
+ int c, mode = 0;
+
+ reset_getopt();
+ while ((c = getopt (argc, argv, "bex")) != EOF) {
+ if (mode || c == '?') {
+ com_err(argv[0], 0,
+ "Usage: inode_dump [-b]|[-e] <file>");
+ return;
+ }
+ mode = c;
+ }
+ if (optind != argc-1)
+ return;
+
+ if (check_fs_open(argv[0]))
+ return;
+
+ ino = string_to_inode(argv[optind]);
+ if (!ino)
+ return;
+
+ isize = EXT2_INODE_SIZE(current_fs->super);
+ err = ext2fs_get_mem(isize, &buf);
+ if (err) {
+ com_err(argv[0], err, "while allocating memory");
+ return;
+ }
+
+ err = ext2fs_read_inode_full(current_fs, ino,
+ (struct ext2_inode *)buf, isize);
+ if (err) {
+ com_err(argv[0], err, "while reading inode %u", ino);
+ goto err;
+ }
+
+ inode = (struct ext2_inode_large *) buf;
+ size = isize;
+ switch (mode) {
+ case 'b':
+ offset = ((char *) (&inode->i_block)) - ((char *) buf);
+ size = sizeof(inode->i_block);
+ break;
+ case 'x':
+ case 'e':
+ if (size <= EXT2_GOOD_OLD_INODE_SIZE) {
+ com_err(argv[0], 0, "No extra space in inode");
+ goto err;
+ }
+ offset = EXT2_GOOD_OLD_INODE_SIZE + inode->i_extra_isize;
+ if (offset > size)
+ goto err;
+ size -= offset;
+ break;
+ }
+ if (mode == 'x')
+ raw_inode_xattr_dump(stdout, buf + offset, size);
+ else
+ do_byte_hexdump(stdout, buf + offset, size);
+err:
+ ext2fs_free_mem(&buf);
+}
+