1 /* vi: set sw=4 ts=4: */
3 * ls.c - List the contents of an ext2fs superblock
5 * Copyright (C) 1992, 1993, 1994 Remy Card <card@masi.ibp.fr>
6 * Laboratoire MASI, Institut Blaise Pascal
7 * Universite Pierre et Marie Curie (Paris VI)
9 * Copyright (C) 1995, 1996, 1997 Theodore Ts'o <tytso@mit.edu>
11 * This file can be redistributed under the terms of the GNU Library General
17 #include <sys/types.h>
24 #include "../../e2fs_lib.h"
26 static void print_user(unsigned short uid
, FILE *f
)
28 struct passwd
*pw
= getpwuid(uid
);
29 fprintf(f
, "%u (user %s)\n", uid
,
30 (pw
== NULL
? "unknown" : pw
->pw_name
));
33 static void print_group(unsigned short gid
, FILE *f
)
35 struct group
*gr
= getgrgid(gid
);
36 fprintf(f
, "%u (group %s)\n", gid
,
37 (gr
== NULL
? "unknown" : gr
->gr_name
));
40 #define MONTH_INT (86400 * 30)
41 #define WEEK_INT (86400 * 7)
42 #define DAY_INT (86400)
43 #define HOUR_INT (60 * 60)
44 #define MINUTE_INT (60)
46 static const char *interval_string(unsigned int secs
)
48 static char buf
[256], tmp
[80];
56 if (secs
>= MONTH_INT
) {
57 num
= secs
/ MONTH_INT
;
58 secs
-= num
*MONTH_INT
;
59 sprintf(buf
, "%d month%s", num
, (num
>1) ? "s" : "");
61 if (secs
>= WEEK_INT
) {
62 num
= secs
/ WEEK_INT
;
64 sprintf(tmp
, "%s%d week%s", buf
[0] ? ", " : "",
65 num
, (num
>1) ? "s" : "");
68 if (secs
>= DAY_INT
) {
71 sprintf(tmp
, "%s%d day%s", buf
[0] ? ", " : "",
72 num
, (num
>1) ? "s" : "");
78 min
= secs
/ MINUTE_INT
;
79 secs
-= min
*MINUTE_INT
;
80 sprintf(tmp
, "%s%d:%02d:%02d", buf
[0] ? ", " : "",
87 static void print_features(struct ext2_super_block
* s
, FILE *f
)
89 #ifdef EXT2_DYNAMIC_REV
91 __u32
*mask
= &s
->s_feature_compat
, m
;
93 fprintf(f
, "Filesystem features: ");
94 for (i
=0; i
<3; i
++,mask
++) {
95 for (j
=0,m
=1; j
< 32; j
++, m
<<=1) {
97 fprintf(f
, " %s", e2p_feature2string(i
, m
));
103 fprintf(f
, " (none)");
108 static void print_mntopts(struct ext2_super_block
* s
, FILE *f
)
110 #ifdef EXT2_DYNAMIC_REV
112 __u32 mask
= s
->s_default_mount_opts
, m
;
114 fprintf(f
, "Default mount options: ");
115 if (mask
& EXT3_DEFM_JMODE
) {
116 fprintf(f
, " %s", e2p_mntopt2string(mask
& EXT3_DEFM_JMODE
));
119 for (i
=0,m
=1; i
< 32; i
++, m
<<=1) {
120 if (m
& EXT3_DEFM_JMODE
)
123 fprintf(f
, " %s", e2p_mntopt2string(m
));
128 fprintf(f
, " (none)");
134 #ifndef EXT2_INODE_SIZE
135 #define EXT2_INODE_SIZE(s) sizeof(struct ext2_inode)
138 #ifndef EXT2_GOOD_OLD_REV
139 #define EXT2_GOOD_OLD_REV 0
142 void list_super2(struct ext2_super_block
* sb
, FILE *f
)
144 int inode_blocks_per_group
;
145 char buf
[80], uuid_buf
[37], *str
;
148 inode_blocks_per_group
= (((sb
->s_inodes_per_group
*
149 EXT2_INODE_SIZE(sb
)) +
150 EXT2_BLOCK_SIZE(sb
) - 1) /
151 EXT2_BLOCK_SIZE(sb
));
152 if (sb
->s_volume_name
[0]) {
153 memset(buf
, 0, sizeof(buf
));
154 strncpy(buf
, sb
->s_volume_name
, sizeof(sb
->s_volume_name
));
156 strcpy(buf
, "<none>");
157 fprintf(f
, "Filesystem volume name: %s\n", buf
);
158 if (sb
->s_last_mounted
[0]) {
159 memset(buf
, 0, sizeof(buf
));
160 strncpy(buf
, sb
->s_last_mounted
, sizeof(sb
->s_last_mounted
));
162 strcpy(buf
, "<not available>");
164 "Last mounted on: %s\n"
165 "Filesystem UUID: %s\n"
166 "Filesystem magic number: 0x%04X\n"
167 "Filesystem revision #: %d",
168 buf
, unparse_uuid(sb
->s_uuid
, uuid_buf
), sb
->s_magic
, sb
->s_rev_level
);
169 if (sb
->s_rev_level
== EXT2_GOOD_OLD_REV
) {
170 fprintf(f
, " (original)\n");
171 #ifdef EXT2_DYNAMIC_REV
172 } else if (sb
->s_rev_level
== EXT2_DYNAMIC_REV
) {
173 fprintf(f
, " (dynamic)\n");
176 fprintf(f
, " (unknown)\n");
177 print_features(sb
, f
);
178 print_mntopts(sb
, f
);
179 fprintf(f
, "Filesystem state: ");
180 print_fs_state (f
, sb
->s_state
);
181 fprintf(f
, "\nErrors behavior: ");
182 print_fs_errors(f
, sb
->s_errors
);
183 str
= e2p_os2string(sb
->s_creator_os
);
186 "Filesystem OS type: %s\n"
189 "Reserved block count: %u\n"
194 "Fragment size: %u\n",
195 str
, sb
->s_inodes_count
, sb
->s_blocks_count
, sb
->s_r_blocks_count
,
196 sb
->s_free_blocks_count
, sb
->s_free_inodes_count
,
197 sb
->s_first_data_block
, EXT2_BLOCK_SIZE(sb
), EXT2_FRAG_SIZE(sb
));
199 if (sb
->s_reserved_gdt_blocks
)
200 fprintf(f
, "Reserved GDT blocks: %u\n",
201 sb
->s_reserved_gdt_blocks
);
203 "Blocks per group: %u\n"
204 "Fragments per group: %u\n"
205 "Inodes per group: %u\n"
206 "Inode blocks per group: %u\n",
207 sb
->s_blocks_per_group
, sb
->s_frags_per_group
,
208 sb
->s_inodes_per_group
, inode_blocks_per_group
);
209 if (sb
->s_first_meta_bg
)
210 fprintf(f
, "First meta block group: %u\n",
211 sb
->s_first_meta_bg
);
212 if (sb
->s_mkfs_time
) {
213 tm
= sb
->s_mkfs_time
;
214 fprintf(f
, "Filesystem created: %s", ctime(&tm
));
217 fprintf(f
, "Last mount time: %s",
218 sb
->s_mtime
? ctime(&tm
) : "n/a\n");
221 "Last write time: %s"
223 "Maximum mount count: %d\n",
224 ctime(&tm
), sb
->s_mnt_count
, sb
->s_max_mnt_count
);
225 tm
= sb
->s_lastcheck
;
228 "Check interval: %u (%s)\n",
230 sb
->s_checkinterval
, interval_string(sb
->s_checkinterval
));
231 if (sb
->s_checkinterval
)
235 next
= sb
->s_lastcheck
+ sb
->s_checkinterval
;
236 fprintf(f
, "Next check after: %s", ctime(&next
));
238 fprintf(f
, "Reserved blocks uid: ");
239 print_user(sb
->s_def_resuid
, f
);
240 fprintf(f
, "Reserved blocks gid: ");
241 print_group(sb
->s_def_resgid
, f
);
242 if (sb
->s_rev_level
>= EXT2_DYNAMIC_REV
) {
246 sb
->s_first_ino
, sb
->s_inode_size
);
248 if (!uuid_is_null(sb
->s_journal_uuid
))
249 fprintf(f
, "Journal UUID: %s\n",
250 unparse_uuid(sb
->s_journal_uuid
, uuid_buf
));
251 if (sb
->s_journal_inum
)
252 fprintf(f
, "Journal inode: %u\n",
254 if (sb
->s_journal_dev
)
255 fprintf(f
, "Journal device: 0x%04x\n",
257 if (sb
->s_last_orphan
)
258 fprintf(f
, "First orphan inode: %u\n",
260 if ((sb
->s_feature_compat
& EXT2_FEATURE_COMPAT_DIR_INDEX
) ||
261 sb
->s_def_hash_version
)
262 fprintf(f
, "Default directory hash: %s\n",
263 e2p_hash2string(sb
->s_def_hash_version
));
264 if (!uuid_is_null(sb
->s_hash_seed
))
265 fprintf(f
, "Directory Hash Seed: %s\n",
266 unparse_uuid((unsigned char *)sb
->s_hash_seed
, uuid_buf
));
267 if (sb
->s_jnl_backup_type
) {
268 fprintf(f
, "Journal backup: ");
269 if (sb
->s_jnl_backup_type
== 1)
270 fprintf(f
, "inode blocks\n");
272 fprintf(f
, "type %u\n", sb
->s_jnl_backup_type
);