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 if (LINUX_S_ISDIR(inode
.i_mode
))
156 fprintf(ls
->f
, "%5d", inode
.i_size
);
158 fprintf(ls
->f
, "%5llu", EXT2_I_SIZE(&inode
));
159 fputs(datestr
, ls
->f
);
161 print_filename(ls
->f
, dirent
, options
);
164 if (entry
== DIRENT_CHECKSUM
) {
165 sprintf(tmp
, "%c%u%c (dirblock checksum: 0x%08x) ",
166 lbr
, dirent
->inode
, rbr
, t
->det_checksum
);
167 thislen
= strlen(tmp
);
168 if (ls
->col
+ thislen
> 80) {
172 fprintf(ls
->f
, "%s", tmp
);
176 sprintf(tmp
, "%c%u%c (%d) ", lbr
, dirent
->inode
, rbr
,
178 thislen
= strlen(tmp
) + 3;
179 thislen
+= print_filename(NULL
, dirent
, options
);
181 if (ls
->col
+ thislen
> 80) {
185 fprintf(ls
->f
, "%s", tmp
);
186 print_filename(ls
->f
, dirent
, options
);
193 void do_list_dir(int argc
, char *argv
[])
195 struct ext2_inode inode
;
199 int flags
= DIRENT_FLAG_INCLUDE_EMPTY
;
200 struct list_dir_struct ls
;
204 if (check_fs_open(argv
[0]))
208 while ((c
= getopt (argc
, argv
, "cdlpr")) != EOF
) {
211 flags
|= DIRENT_FLAG_INCLUDE_CSUM
;
214 ls
.options
|= LONG_OPT
;
217 flags
|= DIRENT_FLAG_INCLUDE_REMOVED
;
220 ls
.options
|= PARSE_OPT
;
223 ls
.options
|= RAW_OPT
;
230 if (argc
> optind
+1) {
232 com_err(0, 0, "Usage: ls [-l] [-d] [-p] file");
239 ino
= string_to_inode(argv
[optind
]);
246 if (debugfs_read_inode(ino
, &inode
, argv
[0]))
249 if (inode
.i_flags
& EXT4_ENCRYPT_FL
)
250 ls
.options
|= ENCRYPT_OPT
;
252 retval
= ext2fs_dir_iterate2(current_fs
, ino
, flags
,
253 0, list_dir_proc
, &ls
);
257 com_err(argv
[1], retval
, 0);