]>
Commit | Line | Data |
---|---|---|
3839e657 TT |
1 | /* |
2 | * ncheck.c --- given a list of inodes, generate a list of names | |
efc6f628 | 3 | * |
3839e657 TT |
4 | * Copyright (C) 1994 Theodore Ts'o. This file may be redistributed |
5 | * under the terms of the GNU Public License. | |
6 | */ | |
7 | ||
d1154eb4 | 8 | #include "config.h" |
3839e657 TT |
9 | #include <stdio.h> |
10 | #include <unistd.h> | |
11 | #include <stdlib.h> | |
12 | #include <ctype.h> | |
13 | #include <string.h> | |
14 | #include <time.h> | |
50e1e10f TT |
15 | #ifdef HAVE_ERRNO_H |
16 | #include <errno.h> | |
17 | #endif | |
3839e657 | 18 | #include <sys/types.h> |
8bf1e918 TT |
19 | #ifdef HAVE_GETOPT_H |
20 | #include <getopt.h> | |
21 | #else | |
22 | extern int optind; | |
23 | extern char *optarg; | |
24 | #endif | |
3839e657 TT |
25 | |
26 | #include "debugfs.h" | |
27 | ||
3839e657 | 28 | struct inode_walk_struct { |
2b1cae7a | 29 | ext2_ino_t dir; |
03206bd8 | 30 | ext2_ino_t *iarray; |
3839e657 TT |
31 | int inodes_left; |
32 | int num_inodes; | |
33 | int position; | |
a25f0e73 | 34 | char *parent; |
8bf1e918 TT |
35 | unsigned int get_pathname_failed:1; |
36 | unsigned int check_dirent:1; | |
3839e657 TT |
37 | }; |
38 | ||
50e1e10f | 39 | static int ncheck_proc(struct ext2_dir_entry *dirent, |
54434927 TT |
40 | int offset EXT2FS_ATTR((unused)), |
41 | int blocksize EXT2FS_ATTR((unused)), | |
42 | char *buf EXT2FS_ATTR((unused)), | |
50e1e10f | 43 | void *private) |
3839e657 TT |
44 | { |
45 | struct inode_walk_struct *iw = (struct inode_walk_struct *) private; | |
8bf1e918 | 46 | struct ext2_inode inode; |
2b1cae7a | 47 | errcode_t retval; |
70f4632b | 48 | int filetype = ext2fs_dirent_file_type(dirent); |
2b1cae7a | 49 | int i; |
3839e657 TT |
50 | |
51 | iw->position++; | |
52 | if (iw->position <= 2) | |
53 | return 0; | |
54 | for (i=0; i < iw->num_inodes; i++) { | |
03206bd8 | 55 | if (iw->iarray[i] == dirent->inode) { |
2b1cae7a TT |
56 | if (!iw->parent && !iw->get_pathname_failed) { |
57 | retval = ext2fs_get_pathname(current_fs, | |
58 | iw->dir, | |
59 | 0, &iw->parent); | |
60 | if (retval) { | |
61 | com_err("ncheck", retval, | |
62 | "while calling ext2fs_get_pathname for inode #%u", iw->dir); | |
63 | iw->get_pathname_failed = 1; | |
64 | } | |
65 | } | |
66 | if (iw->parent) | |
8bf1e918 | 67 | printf("%u\t%s/%.*s", iw->iarray[i], |
2b1cae7a | 68 | iw->parent, |
70f4632b JK |
69 | ext2fs_dirent_name_len(dirent), |
70 | dirent->name); | |
2b1cae7a | 71 | else |
8bf1e918 | 72 | printf("%u\t<%u>/%.*s", iw->iarray[i], |
2b1cae7a | 73 | iw->dir, |
70f4632b JK |
74 | ext2fs_dirent_name_len(dirent), |
75 | dirent->name); | |
8bf1e918 TT |
76 | if (iw->check_dirent && filetype) { |
77 | if (!debugfs_read_inode(dirent->inode, &inode, | |
78 | "ncheck") && | |
79 | filetype != ext2_file_type(inode.i_mode)) { | |
622cee88 | 80 | printf(" <--- BAD FILETYPE"); |
8bf1e918 TT |
81 | } |
82 | } | |
83 | putc('\n', stdout); | |
3839e657 TT |
84 | } |
85 | } | |
86 | if (!iw->inodes_left) | |
87 | return DIRENT_ABORT; | |
efc6f628 | 88 | |
3839e657 TT |
89 | return 0; |
90 | } | |
91 | ||
92 | void do_ncheck(int argc, char **argv) | |
93 | { | |
94 | struct inode_walk_struct iw; | |
8bf1e918 | 95 | int c, i; |
3839e657 | 96 | ext2_inode_scan scan = 0; |
b044c2e0 | 97 | ext2_ino_t ino; |
3839e657 TT |
98 | struct ext2_inode inode; |
99 | errcode_t retval; | |
100 | char *tmp; | |
efc6f628 | 101 | |
8bf1e918 TT |
102 | iw.check_dirent = 0; |
103 | ||
104 | reset_getopt(); | |
105 | while ((c = getopt (argc, argv, "c")) != EOF) { | |
106 | switch (c) { | |
107 | case 'c': | |
108 | iw.check_dirent = 1; | |
109 | break; | |
110 | default: | |
111 | goto print_usage; | |
112 | } | |
113 | } | |
114 | argc -= optind; | |
115 | argv += optind; | |
116 | ||
117 | if (argc < 1) { | |
118 | print_usage: | |
119 | com_err(argv[0], 0, "Usage: ncheck [-c] <inode number> ..."); | |
3839e657 TT |
120 | return; |
121 | } | |
122 | if (check_fs_open(argv[0])) | |
123 | return; | |
124 | ||
03206bd8 | 125 | iw.iarray = malloc(sizeof(ext2_ino_t) * argc); |
3839e657 | 126 | if (!iw.iarray) { |
87dd569b | 127 | com_err("ncheck", ENOMEM, |
8bf1e918 | 128 | "while allocating inode number array"); |
3839e657 TT |
129 | return; |
130 | } | |
03206bd8 | 131 | memset(iw.iarray, 0, sizeof(ext2_ino_t) * argc); |
3839e657 | 132 | |
8bf1e918 TT |
133 | for (i=0; i < argc; i++) { |
134 | iw.iarray[i] = strtol(argv[i], &tmp, 0); | |
3839e657 TT |
135 | if (*tmp) { |
136 | com_err(argv[0], 0, "Bad inode - %s", argv[i]); | |
87dd569b | 137 | goto error_out; |
3839e657 TT |
138 | } |
139 | } | |
140 | ||
8bf1e918 | 141 | iw.num_inodes = iw.inodes_left = argc; |
3839e657 | 142 | |
1e3472c5 | 143 | retval = ext2fs_open_inode_scan(current_fs, 0, &scan); |
3839e657 TT |
144 | if (retval) { |
145 | com_err("ncheck", retval, "while opening inode scan"); | |
146 | goto error_out; | |
147 | } | |
148 | ||
643efb8a TT |
149 | do { |
150 | retval = ext2fs_get_next_inode(scan, &ino, &inode); | |
151 | } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE); | |
3839e657 TT |
152 | if (retval) { |
153 | com_err("ncheck", retval, "while starting inode scan"); | |
154 | goto error_out; | |
155 | } | |
efc6f628 | 156 | |
03206bd8 | 157 | printf("Inode\tPathname\n"); |
3839e657 TT |
158 | while (ino) { |
159 | if (!inode.i_links_count) | |
160 | goto next; | |
161 | /* | |
162 | * To handle filesystems touched by 0.3c extfs; can be | |
163 | * removed later. | |
164 | */ | |
165 | if (inode.i_dtime) | |
166 | goto next; | |
167 | /* Ignore anything that isn't a directory */ | |
50e1e10f | 168 | if (!LINUX_S_ISDIR(inode.i_mode)) |
3839e657 TT |
169 | goto next; |
170 | ||
171 | iw.position = 0; | |
2b1cae7a TT |
172 | iw.parent = 0; |
173 | iw.dir = ino; | |
174 | iw.get_pathname_failed = 0; | |
efc6f628 | 175 | |
1e3472c5 | 176 | retval = ext2fs_dir_iterate(current_fs, ino, 0, 0, |
3839e657 | 177 | ncheck_proc, &iw); |
a25f0e73 | 178 | ext2fs_free_mem(&iw.parent); |
3839e657 TT |
179 | if (retval) { |
180 | com_err("ncheck", retval, | |
181 | "while calling ext2_dir_iterate"); | |
182 | goto next; | |
183 | } | |
184 | ||
185 | if (iw.inodes_left == 0) | |
186 | break; | |
187 | ||
188 | next: | |
643efb8a TT |
189 | do { |
190 | retval = ext2fs_get_next_inode(scan, &ino, &inode); | |
191 | } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE); | |
192 | ||
3839e657 TT |
193 | if (retval) { |
194 | com_err("ncheck", retval, | |
195 | "while doing inode scan"); | |
196 | goto error_out; | |
197 | } | |
198 | } | |
199 | ||
3839e657 TT |
200 | error_out: |
201 | free(iw.iarray); | |
202 | if (scan) | |
203 | ext2fs_close_inode_scan(scan); | |
204 | return; | |
205 | } | |
206 | ||
207 | ||
208 |