Whamcloud - gitweb
Fix gcc -Wall nitpicks
[tools/e2fsprogs.git] / debugfs / ncheck.c
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_info {
22         ext2_ino_t      ino;
23         ext2_ino_t      parent;
24         char            *pathname;
25 };
26
27 struct inode_walk_struct {
28         struct inode_info       *iarray;
29         int                     inodes_left;
30         int                     num_inodes;
31         int                     position;
32         ext2_ino_t              parent;
33 };
34
35 static int ncheck_proc(struct ext2_dir_entry *dirent,
36                        int      offset EXT2FS_ATTR((unused)),
37                        int      blocksize EXT2FS_ATTR((unused)),
38                        char     *buf EXT2FS_ATTR((unused)),
39                        void     *private)
40 {
41         struct inode_walk_struct *iw = (struct inode_walk_struct *) private;
42         int     i;
43
44         iw->position++;
45         if (iw->position <= 2)
46                 return 0;
47         for (i=0; i < iw->num_inodes; i++) {
48                 if (iw->iarray[i].ino == dirent->inode) {
49                         iw->iarray[i].parent = iw->parent;
50                         iw->inodes_left--;
51                 }
52         }
53         if (!iw->inodes_left)
54                 return DIRENT_ABORT;
55         
56         return 0;
57 }
58
59 void do_ncheck(int argc, char **argv)
60 {
61         struct inode_walk_struct iw;
62         struct inode_info       *iinfo;
63         int                     i;
64         ext2_inode_scan         scan = 0;
65         ext2_ino_t              ino;
66         struct ext2_inode       inode;
67         errcode_t               retval;
68         char                    *tmp;
69         
70         if (argc < 2) {
71                 com_err(argv[0], 0, "Usage: ncheck <inode number> ...");
72                 return;
73         }
74         if (check_fs_open(argv[0]))
75                 return;
76
77         iw.iarray = malloc(sizeof(struct inode_info) * argc);
78         if (!iw.iarray) {
79                 com_err("do_ncheck", ENOMEM,
80                         "while allocating inode info array");
81                 return;
82         }
83         memset(iw.iarray, 0, sizeof(struct inode_info) * argc);
84
85         for (i=1; i < argc; i++) {
86                 iw.iarray[i-1].ino = strtol(argv[i], &tmp, 0);
87                 if (*tmp) {
88                         com_err(argv[0], 0, "Bad inode - %s", argv[i]);
89                         return;
90                 }
91         }
92
93         iw.num_inodes = iw.inodes_left = argc-1;
94
95         retval = ext2fs_open_inode_scan(current_fs, 0, &scan);
96         if (retval) {
97                 com_err("ncheck", retval, "while opening inode scan");
98                 goto error_out;
99         }
100
101         do {
102                 retval = ext2fs_get_next_inode(scan, &ino, &inode);
103         } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE);
104         if (retval) {
105                 com_err("ncheck", retval, "while starting inode scan");
106                 goto error_out;
107         }
108         
109         while (ino) {
110                 if (!inode.i_links_count)
111                         goto next;
112                 /*
113                  * To handle filesystems touched by 0.3c extfs; can be
114                  * removed later.
115                  */
116                 if (inode.i_dtime)
117                         goto next;
118                 /* Ignore anything that isn't a directory */
119                 if (!LINUX_S_ISDIR(inode.i_mode))
120                         goto next;
121
122                 iw.position = 0;
123                 iw.parent = ino;
124                 
125                 retval = ext2fs_dir_iterate(current_fs, ino, 0, 0,
126                                             ncheck_proc, &iw);
127                 if (retval) {
128                         com_err("ncheck", retval,
129                                 "while calling ext2_dir_iterate");
130                         goto next;
131                 }
132
133                 if (iw.inodes_left == 0)
134                         break;
135
136         next:
137                 do {
138                         retval = ext2fs_get_next_inode(scan, &ino, &inode);
139                 } while (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE);
140
141                 if (retval) {
142                         com_err("ncheck", retval,
143                                 "while doing inode scan");
144                         goto error_out;
145                 }
146         }
147
148         for (i=0, iinfo = iw.iarray; i < iw.num_inodes; i++, iinfo++) {
149                 if (iinfo->parent == 0)
150                         continue;
151                 retval = ext2fs_get_pathname(current_fs, iinfo->parent,
152                                              iinfo->ino, &iinfo->pathname);
153                 if (retval)
154                         com_err("ncheck", retval,
155                                 "while resolving pathname for inode %d (%d)",
156                                 iinfo->parent, iinfo->ino);
157         }
158         
159         printf("Inode\tPathname\n");
160         for (i=0, iinfo = iw.iarray; i < iw.num_inodes; i++, iinfo++) {
161                 if (iinfo->parent == 0) {
162                         printf("%u\t<inode not found>\n", iinfo->ino);
163                         continue;
164                 }
165                 printf("%u\t%s\n", iinfo->ino, iinfo->pathname ?
166                        iinfo->pathname : "<unknown pathname>");
167                 if (iinfo->pathname)
168                         free(iinfo->pathname);
169         }
170
171 error_out:
172         free(iw.iarray);
173         if (scan)
174                 ext2fs_close_inode_scan(scan);
175         return;
176 }
177
178
179