1 /* 2 * ncheck.c --- given a list of inodes, generate a list of names 3 * 4 * Copyright (C) 1994 Theodore Ts'o. This file may be redistributed 5 * under the terms of the GNU Public License. 6 */ 7 8 #include <stdio.h> 9 #include <unistd.h> 10 #include <stdlib.h> 11 #include <ctype.h> 12 #include <string.h> 13 #include <time.h> 14 #ifdef HAVE_ERRNO_H 15 #include <errno.h> 16 #endif 17 #include <sys/types.h> 18 19 #include "debugfs.h" 20 21 struct inode_walk_struct { 22 ext2_ino_t *iarray; 23 int inodes_left; 24 int num_inodes; 25 int position; 26 char *parent; 27 }; 28 29 static int ncheck_proc(struct ext2_dir_entry *dirent, 30 int offset EXT2FS_ATTR((unused)), 31 int blocksize EXT2FS_ATTR((unused)), 32 char *buf EXT2FS_ATTR((unused)), 33 void *private) 34 { 35 struct inode_walk_struct *iw = (struct inode_walk_struct *) private; 36 int i; 37 38 iw->position++; 39 if (iw->position <= 2) 40 return 0; 41 for (i=0; i < iw->num_inodes; i++) { 42 if (iw->iarray[i] == dirent->inode) { 43 printf("%u\t%s/%.*s\n", iw->iarray[i], iw->parent, 44 (dirent->name_len & 0xFF), dirent->name); 45 } 46 } 47 if (!iw->inodes_left) 48 return DIRENT_ABORT; 49 50 return 0; 51 } 52 53 void do_ncheck(int argc, char **argv) 54 { 55 struct inode_walk_struct iw; 56 int i; 57 ext2_inode_scan scan = 0; 58 ext2_ino_t ino; 59 struct ext2_inode inode; 60 errcode_t retval; 61 char *tmp; 62 63 if (argc < 2) { 64 com_err(argv[0], 0, "Usage: ncheck <inode number> ..."); 65 return; 66 } 67 if (check_fs_open(argv[0])) 68 return; 69 70 iw.iarray = malloc(sizeof(ext2_ino_t) * argc); 71 if (!iw.iarray) { 72 com_err("ncheck", ENOMEM, 73 "while allocating inode info array"); 74 return; 75 } 76 memset(iw.iarray, 0, sizeof(ext2_ino_t) * argc); 77 78 for (i=1; i < argc; i++) { 79 iw.iarray[i-1] = strtol(argv[i], &tmp, 0); 80 if (*tmp) { 81 com_err(argv[0], 0, "Bad inode - %s", argv[i]); 82 goto error_out; 83 } 84 } 85 86 iw.num_inodes = iw.inodes_left = argc-1; 87 88 retval = ext2fs_open_inode_scan(current_fs, 0, &scan); 89 if (retval) { 90 com_err("ncheck", retval, "while opening inode scan"); 91 goto error_out; 92 } 93 94 do { 95 retval = ext2fs_get_next_inode(scan, &ino, &inode); 96 } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE); 97 if (retval) { 98 com_err("ncheck", retval, "while starting inode scan"); 99 goto error_out; 100 } 101 102 printf("Inode\tPathname\n"); 103 while (ino) { 104 if (!inode.i_links_count) 105 goto next; 106 /* 107 * To handle filesystems touched by 0.3c extfs; can be 108 * removed later. 109 */ 110 if (inode.i_dtime) 111 goto next; 112 /* Ignore anything that isn't a directory */ 113 if (!LINUX_S_ISDIR(inode.i_mode)) 114 goto next; 115 116 iw.position = 0; 117 118 retval = ext2fs_get_pathname(current_fs, ino, 0, &iw.parent); 119 if (retval) { 120 com_err("ncheck", retval, 121 "while calling ext2fs_get_pathname"); 122 goto next; 123 } 124 125 retval = ext2fs_dir_iterate(current_fs, ino, 0, 0, 126 ncheck_proc, &iw); 127 ext2fs_free_mem(&iw.parent); 128 if (retval) { 129 com_err("ncheck", retval, 130 "while calling ext2_dir_iterate"); 131 goto next; 132 } 133 134 if (iw.inodes_left == 0) 135 break; 136 137 next: 138 do { 139 retval = ext2fs_get_next_inode(scan, &ino, &inode); 140 } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE); 141 142 if (retval) { 143 com_err("ncheck", retval, 144 "while doing inode scan"); 145 goto error_out; 146 } 147 } 148 149 error_out: 150 free(iw.iarray); 151 if (scan) 152 ext2fs_close_inode_scan(scan); 153 return; 154 } 155 156 157 158