2 * ls.c --- list directories
4 * Copyright (C) 1997 Theodore Ts'o. This file may be redistributed
5 * under the terms of the GNU Public License.
18 #include <sys/types.h>
32 #define LONG_OPT 0x0001
33 #define PARSE_OPT 0x0002
34 #define RAW_OPT 0x0004
35 #define ENCRYPT_OPT 0x8000
37 struct list_dir_struct
{
44 static const char *monstr
[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
45 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
47 static int print_filename(FILE *f
, struct ext2_dir_entry
*dirent
, int options
)
50 const char *cp
= dirent
->name
;
51 int len
= ext2fs_dirent_name_len(dirent
);
54 if ((options
& ENCRYPT_OPT
) && !(options
& RAW_OPT
)) {
56 return fprintf(f
, "<encrypted (%d)>", len
);
58 return snprintf(NULL
, 0, "<encrypted (%d)>", len
);
62 if (ch
< 32 || ch
>= 127 || ch
== '\\') {
64 fprintf(f
, "\\x%02x", ch
);
75 static int list_dir_proc(ext2_ino_t dir
EXT2FS_ATTR((unused
)),
77 struct ext2_dir_entry
*dirent
,
78 int offset
EXT2FS_ATTR((unused
)),
79 int blocksize
EXT2FS_ATTR((unused
)),
80 char *buf
EXT2FS_ATTR((unused
)),
83 struct ext2_inode inode
;
87 char tmp
[EXT2_NAME_LEN
+ 16];
92 struct list_dir_struct
*ls
= (struct list_dir_struct
*) private;
93 struct ext2_dir_entry_tail
*t
= (struct ext2_dir_entry_tail
*) dirent
;
95 thislen
= ext2fs_dirent_name_len(dirent
);
97 options
= ls
->options
;
103 if (entry
== DIRENT_DELETED_FILE
) {
110 if (options
& PARSE_OPT
) {
112 if (debugfs_read_inode(ino
, &inode
, "ls"))
115 memset(&inode
, 0, sizeof(struct ext2_inode
));
116 fprintf(ls
->f
,"/%u/%06o/%d/%d/%.*s/", ino
, inode
.i_mode
,
117 inode
.i_uid
, inode
.i_gid
, thislen
, dirent
->name
);
118 if (LINUX_S_ISDIR(inode
.i_mode
))
121 fprintf(ls
->f
, "%lld/", EXT2_I_SIZE(&inode
));
122 fprintf(ls
->f
, "\n");
123 } else if (options
& LONG_OPT
) {
125 if (debugfs_read_inode(ino
, &inode
, "ls"))
127 modtime
= inode
.i_mtime
;
128 tm_p
= localtime(&modtime
);
129 sprintf(datestr
, "%2d-%s-%4d %02d:%02d",
130 tm_p
->tm_mday
, monstr
[tm_p
->tm_mon
],
131 1900 + tm_p
->tm_year
, tm_p
->tm_hour
,
134 strcpy(datestr
, " ");
135 memset(&inode
, 0, sizeof(struct ext2_inode
));
137 fprintf(ls
->f
, "%c%6u%c %6o ", lbr
, ino
, rbr
, inode
.i_mode
);
138 if (entry
== DIRENT_CHECKSUM
) {
139 fprintf(ls
->f
, "(dirblock checksum: 0x%08x)\n",
143 fprintf(ls
->f
, "(%d) %5d %5d ",
144 ext2fs_dirent_file_type(dirent
),
145 inode_uid(inode
), inode_gid(inode
));
146 fprintf(ls
->f
, "%5llu", EXT2_I_SIZE(&inode
));
147 fprintf(ls
->f
, " %s ", datestr
);
148 print_filename(ls
->f
, dirent
, options
);
151 if (entry
== DIRENT_CHECKSUM
) {
152 sprintf(tmp
, "%c%u%c (dirblock checksum: 0x%08x) ",
153 lbr
, dirent
->inode
, rbr
, t
->det_checksum
);
154 thislen
= strlen(tmp
);
155 if (ls
->col
+ thislen
> 80) {
159 fprintf(ls
->f
, "%s", tmp
);
163 sprintf(tmp
, "%c%u%c (%d) ", lbr
, dirent
->inode
, rbr
,
165 thislen
= strlen(tmp
) + 3;
166 thislen
+= print_filename(NULL
, dirent
, options
);
168 if (ls
->col
+ thislen
> 80) {
172 fprintf(ls
->f
, "%s", tmp
);
173 print_filename(ls
->f
, dirent
, options
);
180 void do_list_dir(int argc
, char *argv
[], int sci_idx
EXT2FS_ATTR((unused
)),
181 void *infop
EXT2FS_ATTR((unused
)))
183 struct ext2_inode inode
;
187 int flags
= DIRENT_FLAG_INCLUDE_EMPTY
;
188 struct list_dir_struct ls
;
192 if (check_fs_open(argv
[0]))
196 while ((c
= getopt (argc
, argv
, "cdlpr")) != EOF
) {
199 flags
|= DIRENT_FLAG_INCLUDE_CSUM
;
202 ls
.options
|= LONG_OPT
;
205 flags
|= DIRENT_FLAG_INCLUDE_REMOVED
;
208 ls
.options
|= PARSE_OPT
;
211 ls
.options
|= RAW_OPT
;
218 if (argc
> optind
+1) {
220 com_err(0, 0, "Usage: ls [-c] [-d] [-l] [-p] [-r] file");
227 ino
= string_to_inode(argv
[optind
]);
234 if (debugfs_read_inode(ino
, &inode
, argv
[0]))
237 if (inode
.i_flags
& EXT4_ENCRYPT_FL
)
238 ls
.options
|= ENCRYPT_OPT
;
240 retval
= ext2fs_dir_iterate2(current_fs
, ino
, flags
,
241 0, list_dir_proc
, &ls
);
245 com_err(argv
[1], retval
, 0);