Home | History | Annotate | Download | only in debugfs
      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