• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ncheck_proc(struct ext2_dir_entry * dirent,int offset EXT2FS_ATTR ((unused)),int blocksize EXT2FS_ATTR ((unused)),char * buf EXT2FS_ATTR ((unused)),void * private)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 
do_ncheck(int argc,char ** argv)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