]> git.ipfire.org Git - thirdparty/e2fsprogs.git/blobdiff - debugfs/ncheck.c
libext2fs: fix potential divide by zero bug caused by a lxcfs bug
[thirdparty/e2fsprogs.git] / debugfs / ncheck.c
index 5d9b5d21c27e0630125f23e18b6e5fd4320c0197..1410e7c6dc68edeb176975512876e27ea1367778 100644 (file)
@@ -28,7 +28,7 @@ extern char *optarg;
 struct inode_walk_struct {
        ext2_ino_t              dir;
        ext2_ino_t              *iarray;
-       int                     inodes_left;
+       int                     names_left;
        int                     num_inodes;
        int                     position;
        char                    *parent;
@@ -81,15 +81,17 @@ static int ncheck_proc(struct ext2_dir_entry *dirent,
                                }
                        }
                        putc('\n', stdout);
+                       iw->names_left--;
                }
        }
-       if (!iw->inodes_left)
+       if (!iw->names_left)
                return DIRENT_ABORT;
 
        return 0;
 }
 
-void do_ncheck(int argc, char **argv)
+void do_ncheck(int argc, ss_argv_t argv, int sci_idx EXT2FS_ATTR((unused)),
+              void *infop EXT2FS_ATTR((unused)))
 {
        struct inode_walk_struct iw;
        int                     c, i;
@@ -111,10 +113,8 @@ void do_ncheck(int argc, char **argv)
                        goto print_usage;
                }
        }
-       argc -= optind;
-       argv += optind;
 
-       if (argc < 1) {
+       if (argc <= 1) {
        print_usage:
                com_err(argv[0], 0, "Usage: ncheck [-c] <inode number> ...");
                return;
@@ -122,6 +122,8 @@ void do_ncheck(int argc, char **argv)
        if (check_fs_open(argv[0]))
                return;
 
+       argc -= optind;
+       argv += optind;
        iw.iarray = malloc(sizeof(ext2_ino_t) * argc);
        if (!iw.iarray) {
                com_err("ncheck", ENOMEM,
@@ -130,15 +132,28 @@ void do_ncheck(int argc, char **argv)
        }
        memset(iw.iarray, 0, sizeof(ext2_ino_t) * argc);
 
+       iw.names_left = 0;
        for (i=0; i < argc; i++) {
-               iw.iarray[i] = strtol(argv[i], &tmp, 0);
-               if (*tmp) {
-                       com_err(argv[0], 0, "Bad inode - %s", argv[i]);
+               char *str = argv[i];
+               int len = strlen(str);
+
+               if ((len > 2) && (str[0] == '<') && (str[len - 1] == '>'))
+                       str++;
+               iw.iarray[i] = strtol(str, &tmp, 0);
+               if (*tmp && (str == argv[i] || *tmp != '>')) {
+                       com_err("ncheck", 0, "Invalid inode number - '%s'",
+                               argv[i]);
                        goto error_out;
                }
+               if (debugfs_read_inode(iw.iarray[i], &inode, *argv))
+                       goto error_out;
+               if (LINUX_S_ISDIR(inode.i_mode))
+                       iw.names_left += 1;
+               else
+                       iw.names_left += inode.i_links_count;
        }
 
-       iw.num_inodes = iw.inodes_left = argc;
+       iw.num_inodes = argc;
 
        retval = ext2fs_open_inode_scan(current_fs, 0, &scan);
        if (retval) {
@@ -182,7 +197,7 @@ void do_ncheck(int argc, char **argv)
                        goto next;
                }
 
-               if (iw.inodes_left == 0)
+               if (iw.names_left == 0)
                        break;
 
        next: