busybox/e2fsprogs/old_e2fsprogs/e2p/ls.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * ls.c                 - List the contents of an ext2fs superblock
   4 *
   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)
   8 *
   9 * Copyright (C) 1995, 1996, 1997  Theodore Ts'o <tytso@mit.edu>
  10 *
  11 * This file can be redistributed under the terms of the GNU Library General
  12 * Public License
  13 */
  14
  15#include <stdio.h>
  16#include <stdlib.h>
  17#include <sys/types.h>
  18#include <string.h>
  19#include <grp.h>
  20#include <pwd.h>
  21#include <time.h>
  22
  23#include "e2p.h"
  24
  25static void print_user(unsigned short uid, FILE *f)
  26{
  27        struct passwd *pw = getpwuid(uid);
  28        fprintf(f, "%u (user %s)\n", uid,
  29                        (pw == NULL ? "unknown" : pw->pw_name));
  30}
  31
  32static void print_group(unsigned short gid, FILE *f)
  33{
  34        struct group *gr = getgrgid(gid);
  35        fprintf(f, "%u (group %s)\n", gid,
  36                        (gr == NULL ? "unknown" : gr->gr_name));
  37}
  38
  39#define MONTH_INT (86400 * 30)
  40#define WEEK_INT (86400 * 7)
  41#define DAY_INT (86400)
  42#define HOUR_INT (60 * 60)
  43#define MINUTE_INT (60)
  44
  45static const char *interval_string(unsigned int secs)
  46{
  47        static char buf[256], tmp[80];
  48        int             hr, min, num;
  49
  50        buf[0] = 0;
  51
  52        if (secs == 0)
  53                return "<none>";
  54
  55        if (secs >= MONTH_INT) {
  56                num = secs / MONTH_INT;
  57                secs -= num*MONTH_INT;
  58                sprintf(buf, "%d month%s", num, (num>1) ? "s" : "");
  59        }
  60        if (secs >= WEEK_INT) {
  61                num = secs / WEEK_INT;
  62                secs -= num*WEEK_INT;
  63                sprintf(tmp, "%s%d week%s", buf[0] ? ", " : "",
  64                        num, (num>1) ? "s" : "");
  65                strcat(buf, tmp);
  66        }
  67        if (secs >= DAY_INT) {
  68                num = secs / DAY_INT;
  69                secs -= num*DAY_INT;
  70                sprintf(tmp, "%s%d day%s", buf[0] ? ", " : "",
  71                        num, (num>1) ? "s" : "");
  72                strcat(buf, tmp);
  73        }
  74        if (secs > 0) {
  75                hr = secs / HOUR_INT;
  76                secs -= hr*HOUR_INT;
  77                min = secs / MINUTE_INT;
  78                secs -= min*MINUTE_INT;
  79                sprintf(tmp, "%s%d:%02d:%02d", buf[0] ? ", " : "",
  80                        hr, min, secs);
  81                strcat(buf, tmp);
  82        }
  83        return buf;
  84}
  85
  86static void print_features(struct ext2_super_block * s, FILE *f)
  87{
  88#ifdef EXT2_DYNAMIC_REV
  89        int     i, j, printed=0;
  90        __u32   *mask = &s->s_feature_compat, m;
  91
  92        fprintf(f, "Filesystem features:     ");
  93        for (i=0; i <3; i++,mask++) {
  94                for (j=0,m=1; j < 32; j++, m<<=1) {
  95                        if (*mask & m) {
  96                                fprintf(f, " %s", e2p_feature2string(i, m));
  97                                printed++;
  98                        }
  99                }
 100        }
 101        if (printed == 0)
 102                fprintf(f, " (none)");
 103        fprintf(f, "\n");
 104#endif
 105}
 106
 107static void print_mntopts(struct ext2_super_block * s, FILE *f)
 108{
 109#ifdef EXT2_DYNAMIC_REV
 110        int     i, printed=0;
 111        __u32   mask = s->s_default_mount_opts, m;
 112
 113        fprintf(f, "Default mount options:   ");
 114        if (mask & EXT3_DEFM_JMODE) {
 115                fprintf(f, " %s", e2p_mntopt2string(mask & EXT3_DEFM_JMODE));
 116                printed++;
 117        }
 118        for (i=0,m=1; i < 32; i++, m<<=1) {
 119                if (m & EXT3_DEFM_JMODE)
 120                        continue;
 121                if (mask & m) {
 122                        fprintf(f, " %s", e2p_mntopt2string(m));
 123                        printed++;
 124                }
 125        }
 126        if (printed == 0)
 127                fprintf(f, " (none)");
 128        fprintf(f, "\n");
 129#endif
 130}
 131
 132
 133#ifndef EXT2_INODE_SIZE
 134#define EXT2_INODE_SIZE(s) sizeof(struct ext2_inode)
 135#endif
 136
 137#ifndef EXT2_GOOD_OLD_REV
 138#define EXT2_GOOD_OLD_REV 0
 139#endif
 140
 141void list_super2(struct ext2_super_block * sb, FILE *f)
 142{
 143        int inode_blocks_per_group;
 144        char buf[80], *str;
 145        time_t  tm;
 146
 147        inode_blocks_per_group = (((sb->s_inodes_per_group *
 148                                    EXT2_INODE_SIZE(sb)) +
 149                                   EXT2_BLOCK_SIZE(sb) - 1) /
 150                                  EXT2_BLOCK_SIZE(sb));
 151        if (sb->s_volume_name[0]) {
 152                memset(buf, 0, sizeof(buf));
 153                strncpy(buf, sb->s_volume_name, sizeof(sb->s_volume_name));
 154        } else
 155                strcpy(buf, "<none>");
 156        fprintf(f, "Filesystem volume name:   %s\n", buf);
 157        if (sb->s_last_mounted[0]) {
 158                memset(buf, 0, sizeof(buf));
 159                strncpy(buf, sb->s_last_mounted, sizeof(sb->s_last_mounted));
 160        } else
 161                strcpy(buf, "<not available>");
 162        fprintf(f,
 163                "Last mounted on:          %s\n"
 164                "Filesystem UUID:          %s\n"
 165                "Filesystem magic number:  0x%04X\n"
 166                "Filesystem revision #:    %d",
 167                buf, e2p_uuid2str(sb->s_uuid), sb->s_magic, sb->s_rev_level);
 168        if (sb->s_rev_level == EXT2_GOOD_OLD_REV) {
 169                fprintf(f, " (original)\n");
 170#ifdef EXT2_DYNAMIC_REV
 171        } else if (sb->s_rev_level == EXT2_DYNAMIC_REV) {
 172                fprintf(f, " (dynamic)\n");
 173#endif
 174        } else
 175                fprintf(f, " (unknown)\n");
 176        print_features(sb, f);
 177        print_mntopts(sb, f);
 178        fprintf(f, "Filesystem state:        ");
 179        print_fs_state (f, sb->s_state);
 180        fprintf(f, "\nErrors behavior:          ");
 181        print_fs_errors(f, sb->s_errors);
 182        str = e2p_os2string(sb->s_creator_os);
 183        fprintf(f,
 184                "\n"
 185                "Filesystem OS type:       %s\n"
 186                "Inode count:              %u\n"
 187                "Block count:              %u\n"
 188                "Reserved block count:     %u\n"
 189                "Free blocks:              %u\n"
 190                "Free inodes:              %u\n"
 191                "First block:              %u\n"
 192                "Block size:               %u\n"
 193                "Fragment size:            %u\n",
 194                str, sb->s_inodes_count, sb->s_blocks_count, sb->s_r_blocks_count,
 195                sb->s_free_blocks_count, sb->s_free_inodes_count,
 196                sb->s_first_data_block, EXT2_BLOCK_SIZE(sb), EXT2_FRAG_SIZE(sb));
 197        free(str);
 198        if (sb->s_reserved_gdt_blocks)
 199                fprintf(f, "Reserved GDT blocks:      %u\n",
 200                        sb->s_reserved_gdt_blocks);
 201        fprintf(f,
 202                "Blocks per group:         %u\n"
 203                "Fragments per group:      %u\n"
 204                "Inodes per group:         %u\n"
 205                "Inode blocks per group:   %u\n",
 206                sb->s_blocks_per_group, sb->s_frags_per_group,
 207                sb->s_inodes_per_group, inode_blocks_per_group);
 208        if (sb->s_first_meta_bg)
 209                fprintf(f, "First meta block group:   %u\n",
 210                        sb->s_first_meta_bg);
 211        if (sb->s_mkfs_time) {
 212                tm = sb->s_mkfs_time;
 213                fprintf(f, "Filesystem created:       %s", ctime(&tm));
 214        }
 215        tm = sb->s_mtime;
 216        fprintf(f, "Last mount time:          %s",
 217                sb->s_mtime ? ctime(&tm) : "n/a\n");
 218        tm = sb->s_wtime;
 219        fprintf(f,
 220                "Last write time:          %s"
 221                "Mount count:              %u\n"
 222                "Maximum mount count:      %d\n",
 223                ctime(&tm), sb->s_mnt_count, sb->s_max_mnt_count);
 224        tm = sb->s_lastcheck;
 225        fprintf(f,
 226                "Last checked:             %s"
 227                "Check interval:           %u (%s)\n",
 228                ctime(&tm),
 229                sb->s_checkinterval, interval_string(sb->s_checkinterval));
 230        if (sb->s_checkinterval)
 231        {
 232                time_t next;
 233
 234                next = sb->s_lastcheck + sb->s_checkinterval;
 235                fprintf(f, "Next check after:         %s", ctime(&next));
 236        }
 237        fprintf(f, "Reserved blocks uid:      ");
 238        print_user(sb->s_def_resuid, f);
 239        fprintf(f, "Reserved blocks gid:      ");
 240        print_group(sb->s_def_resgid, f);
 241        if (sb->s_rev_level >= EXT2_DYNAMIC_REV) {
 242                fprintf(f,
 243                        "First inode:              %d\n"
 244                        "Inode size:              %d\n",
 245                        sb->s_first_ino, sb->s_inode_size);
 246        }
 247        if (!e2p_is_null_uuid(sb->s_journal_uuid))
 248                fprintf(f, "Journal UUID:             %s\n",
 249                        e2p_uuid2str(sb->s_journal_uuid));
 250        if (sb->s_journal_inum)
 251                fprintf(f, "Journal inode:            %u\n",
 252                        sb->s_journal_inum);
 253        if (sb->s_journal_dev)
 254                fprintf(f, "Journal device:               0x%04x\n",
 255                        sb->s_journal_dev);
 256        if (sb->s_last_orphan)
 257                fprintf(f, "First orphan inode:       %u\n",
 258                        sb->s_last_orphan);
 259        if ((sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
 260            sb->s_def_hash_version)
 261                fprintf(f, "Default directory hash:   %s\n",
 262                        e2p_hash2string(sb->s_def_hash_version));
 263        if (!e2p_is_null_uuid(sb->s_hash_seed))
 264                fprintf(f, "Directory Hash Seed:      %s\n",
 265                        e2p_uuid2str(sb->s_hash_seed));
 266        if (sb->s_jnl_backup_type) {
 267                fprintf(f, "Journal backup:           ");
 268                if (sb->s_jnl_backup_type == 1)
 269                        fprintf(f, "inode blocks\n");
 270                else
 271                        fprintf(f, "type %u\n", sb->s_jnl_backup_type);
 272        }
 273}
 274