Whamcloud - gitweb
Add support for the half-MD4 HTREE hash.
[tools/e2fsprogs.git] / debugfs / ls.c
index e24bdb3..3064598 100644 (file)
 #include <errno.h>
 #endif
 #include <sys/types.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#else 
+extern int optind;
+extern char *optarg;
+#endif
+#ifdef HAVE_OPTRESET
+extern int optreset;           /* defined by BSD, but not others */
+#endif
 
 #include "debugfs.h"
 
@@ -23,6 +32,7 @@
  */
 
 #define LONG_OPT       0x0001
+#define DELETED_OPT    0x0002
 
 struct list_dir_struct {
        FILE    *f;
@@ -33,73 +43,73 @@ struct list_dir_struct {
 static const char *monstr[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
                                "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
                                        
-static void ls_l_file(struct list_dir_struct *ls, char *name, ext2_ino_t ino)
-{
-       struct ext2_inode       inode;
-       errcode_t               retval;
-       struct tm               *tm_p;
-       time_t                  modtime;
-       char                    datestr[80];
-
-       retval = ext2fs_read_inode(current_fs, ino, &inode);
-       if (retval) {
-               fprintf(ls->f, "%5ld --- error ---  %s\n", retval, name);
-               return;
-       }
-       modtime = inode.i_mtime;
-       tm_p = localtime(&modtime);
-       sprintf(datestr, "%2d-%s-%4d %02d:%02d",
-               tm_p->tm_mday, monstr[tm_p->tm_mon], 1900 + tm_p->tm_year,
-               tm_p->tm_hour, tm_p->tm_min);
-       fprintf(ls->f, "%6u %6o  %5d  %5d   ", ino, inode.i_mode,
-              inode.i_uid, inode.i_gid);
-       if (LINUX_S_ISDIR(inode.i_mode))
-               fprintf(ls->f, "%5d", inode.i_size);
-       else
-               fprintf(ls->f, "%5lld", inode.i_size |
-                       ((__u64)inode.i_size_high << 32));
-       fprintf (ls->f, " %s %s\n", datestr, name);
-}
-
-static void ls_file(struct list_dir_struct *ls, char *name,
-                   ext2_ino_t ino, int rec_len)
-{
-       char    tmp[EXT2_NAME_LEN + 16];
-       int     thislen;
-
-       sprintf(tmp, "%u (%d) %s   ", ino, rec_len, name);
-       thislen = strlen(tmp);
-
-       if (ls->col + thislen > 80) {
-               fprintf(ls->f, "\n");
-               ls->col = 0;
-       }
-       fprintf(ls->f, "%s", tmp);
-       ls->col += thislen;
-}      
-
-
-static int list_dir_proc(struct ext2_dir_entry *dirent,
+static int list_dir_proc(ext2_ino_t dir,
+                        int    entry,
+                        struct ext2_dir_entry *dirent,
                         int    offset,
                         int    blocksize,
                         char   *buf,
                         void   *private)
 {
-       char    name[EXT2_NAME_LEN];
-
+       struct ext2_inode       inode;
+       ext2_ino_t              ino;
+       struct tm               *tm_p;
+       time_t                  modtime;
+       char                    name[EXT2_NAME_LEN];
+       char                    tmp[EXT2_NAME_LEN + 16];
+       char                    datestr[80];
+       char                    lbr, rbr;
+       int                     thislen;
        struct list_dir_struct *ls = (struct list_dir_struct *) private;
-       int     thislen;
 
        thislen = ((dirent->name_len & 0xFF) < EXT2_NAME_LEN) ?
                (dirent->name_len & 0xFF) : EXT2_NAME_LEN;
        strncpy(name, dirent->name, thislen);
        name[thislen] = '\0';
-
-       if (ls->options & LONG_OPT) 
-               ls_l_file(ls, name, dirent->inode);
-       else
-               ls_file(ls, name, dirent->inode, dirent->rec_len);
-       
+       ino = dirent->inode;
+
+       if (entry == DIRENT_DELETED_FILE) {
+               lbr = '<';
+               rbr = '>';
+               ino = 0;
+       } else {
+               lbr = rbr = ' ';
+       }
+       if (ls->options & LONG_OPT) {
+               if (ino) {
+                       if (debugfs_read_inode(ino, &inode, name))
+                               return 0;
+                       modtime = inode.i_mtime;
+                       tm_p = localtime(&modtime);
+                       sprintf(datestr, "%2d-%s-%4d %02d:%02d",
+                               tm_p->tm_mday, monstr[tm_p->tm_mon],
+                               1900 + tm_p->tm_year, tm_p->tm_hour,
+                               tm_p->tm_min);
+               } else {
+                       strcpy(datestr, "                 ");
+                       memset(&inode, 0, sizeof(struct ext2_inode));
+               }
+               fprintf(ls->f, "%c%6u%c %6o (%d)  %5d  %5d   ", lbr, ino, rbr,
+                       inode.i_mode, dirent->name_len >> 8,
+                       inode.i_uid, inode.i_gid);
+               if (LINUX_S_ISDIR(inode.i_mode))
+                       fprintf(ls->f, "%5d", inode.i_size);
+               else
+                       fprintf(ls->f, "%5lld", inode.i_size |
+                               ((__u64)inode.i_size_high << 32));
+               fprintf (ls->f, " %s %s\n", datestr, name);
+       } else {
+               sprintf(tmp, "%c%u%c (%d) %s   ", lbr, dirent->inode, rbr,
+                       dirent->rec_len, name);
+               thislen = strlen(tmp);
+
+               if (ls->col + thislen > 80) {
+                       fprintf(ls->f, "\n");
+                       ls->col = 0;
+               }
+               fprintf(ls->f, "%s", tmp);
+               ls->col += thislen;
+       }
        return 0;
 }
 
@@ -107,29 +117,48 @@ void do_list_dir(int argc, char *argv[])
 {
        ext2_ino_t      inode;
        int             retval;
+       int             c;
+       int             flags;
        struct list_dir_struct ls;
-       int             argptr = 1;
        
        ls.options = 0;
        if (check_fs_open(argv[0]))
                return;
 
-       if ((argc > argptr) && (argv[argptr][0] == '-')) {
-               argptr++;
-               ls.options = LONG_OPT;
+       optind = 0;
+#ifdef HAVE_OPTRESET
+       optreset = 1;           /* Makes BSD getopt happy */
+#endif
+       while ((c = getopt (argc, argv, "dl")) != EOF) {
+               switch (c) {
+               case 'l':
+                       ls.options |= LONG_OPT;
+                       break;
+               case 'd':
+                       ls.options |= DELETED_OPT;
+                       break;
+               }
+       }
+
+       if (argc > optind+1) {
+               com_err(0, 0, "Usage: ls [-l] [-d] file");
+               return;
        }
 
-       if (argc <= argptr)
+       if (argc == optind)
                inode = cwd;
        else
-               inode = string_to_inode(argv[argptr]);
+               inode = string_to_inode(argv[optind]);
        if (!inode)
                return;
 
        ls.f = open_pager();
        ls.col = 0;
-       retval = ext2fs_dir_iterate(current_fs, inode,
-                                   DIRENT_FLAG_INCLUDE_EMPTY,
+       flags = DIRENT_FLAG_INCLUDE_EMPTY;
+       if (ls.options & DELETED_OPT)
+               flags |= DIRENT_FLAG_INCLUDE_REMOVED;
+
+       retval = ext2fs_dir_iterate2(current_fs, inode, flags,
                                    0, list_dir_proc, &ls);
        fprintf(ls.f, "\n");
        close_pager(ls.f);