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
);
59 return snprintf(tmp
, sizeof(tmp
),
60 "<encrypted (%d)>", len
);
71 if ((ch
< 32) || (ch
== 0x7f)) {
74 ch
^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
84 static int list_dir_proc(ext2_ino_t dir
EXT2FS_ATTR((unused
)),
86 struct ext2_dir_entry
*dirent
,
87 int offset
EXT2FS_ATTR((unused
)),
88 int blocksize
EXT2FS_ATTR((unused
)),
89 char *buf
EXT2FS_ATTR((unused
)),
92 struct ext2_inode inode
;
96 char tmp
[EXT2_NAME_LEN
+ 16];
101 struct list_dir_struct
*ls
= (struct list_dir_struct
*) private;
102 struct ext2_dir_entry_tail
*t
= (struct ext2_dir_entry_tail
*) dirent
;
104 thislen
= ext2fs_dirent_name_len(dirent
);
106 options
= ls
->options
;
112 if (entry
== DIRENT_DELETED_FILE
) {
119 if (options
& PARSE_OPT
) {
121 if (debugfs_read_inode(ino
, &inode
, "ls"))
124 memset(&inode
, 0, sizeof(struct ext2_inode
));
125 fprintf(ls
->f
,"/%u/%06o/%d/%d/%.*s/", ino
, inode
.i_mode
,
126 inode
.i_uid
, inode
.i_gid
, thislen
, dirent
->name
);
127 if (LINUX_S_ISDIR(inode
.i_mode
))
130 fprintf(ls
->f
, "%lld/", EXT2_I_SIZE(&inode
));
131 fprintf(ls
->f
, "\n");
132 } else if (options
& LONG_OPT
) {
134 if (debugfs_read_inode(ino
, &inode
, "ls"))
136 modtime
= inode
.i_mtime
;
137 tm_p
= localtime(&modtime
);
138 sprintf(datestr
, "%2d-%s-%4d %02d:%02d",
139 tm_p
->tm_mday
, monstr
[tm_p
->tm_mon
],
140 1900 + tm_p
->tm_year
, tm_p
->tm_hour
,
143 strcpy(datestr
, " ");
144 memset(&inode
, 0, sizeof(struct ext2_inode
));
146 fprintf(ls
->f
, "%c%6u%c %6o ", lbr
, ino
, rbr
, inode
.i_mode
);
147 if (entry
== DIRENT_CHECKSUM
) {
148 fprintf(ls
->f
, "(dirblock checksum: 0x%08x)\n",
152 fprintf(ls
->f
, "(%d) %5d %5d ",
153 ext2fs_dirent_file_type(dirent
),
154 inode_uid(inode
), inode_gid(inode
));
155 fprintf(ls
->f
, "%5llu", EXT2_I_SIZE(&inode
));
156 fprintf(ls
->f
, " %s ", datestr
);
157 print_filename(ls
->f
, dirent
, options
);
160 if (entry
== DIRENT_CHECKSUM
) {
161 sprintf(tmp
, "%c%u%c (dirblock checksum: 0x%08x) ",
162 lbr
, dirent
->inode
, rbr
, t
->det_checksum
);
163 thislen
= strlen(tmp
);
164 if (ls
->col
+ thislen
> 80) {
168 fprintf(ls
->f
, "%s", tmp
);
172 sprintf(tmp
, "%c%u%c (%d) ", lbr
, dirent
->inode
, rbr
,
174 thislen
= strlen(tmp
) + 3;
175 thislen
+= print_filename(NULL
, dirent
, options
);
177 if (ls
->col
+ thislen
> 80) {
181 fprintf(ls
->f
, "%s", tmp
);
182 print_filename(ls
->f
, dirent
, options
);
189 void do_list_dir(int argc
, char *argv
[], int sci_idx
EXT2FS_ATTR((unused
)),
190 void *infop
EXT2FS_ATTR((unused
)))
192 struct ext2_inode inode
;
196 int flags
= DIRENT_FLAG_INCLUDE_EMPTY
;
197 struct list_dir_struct ls
;
201 if (check_fs_open(argv
[0]))
205 while ((c
= getopt (argc
, argv
, "cdlpr")) != EOF
) {
208 flags
|= DIRENT_FLAG_INCLUDE_CSUM
;
211 ls
.options
|= LONG_OPT
;
214 flags
|= DIRENT_FLAG_INCLUDE_REMOVED
;
217 ls
.options
|= PARSE_OPT
;
220 ls
.options
|= RAW_OPT
;
227 if (argc
> optind
+1) {
229 com_err(0, 0, "Usage: ls [-c] [-d] [-l] [-p] [-r] file");
236 ino
= string_to_inode(argv
[optind
]);
243 if (debugfs_read_inode(ino
, &inode
, argv
[0]))
246 if (inode
.i_flags
& EXT4_ENCRYPT_FL
)
247 ls
.options
|= ENCRYPT_OPT
;
249 retval
= ext2fs_dir_iterate2(current_fs
, ino
, flags
,
250 0, list_dir_proc
, &ls
);
254 com_err(argv
[1], retval
, 0);