Ignore:
Timestamp:
Nov 4, 2007, 3:16:40 AM (16 years ago)
Author:
Bruno Cornec
Message:

Update to busybox 1.7.2

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.5/mindi-busybox/coreutils/stat.c

    r821 r1765  
    1 /* vi:set ts=4:*/
     1/* vi: set sw=4 ts=4: */
    22/*
    33 * stat -- display file or file system status
     
    66 * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org>
    77 * Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org>
     8 * Copyright (C) 2006 by Yoshinori Sato <ysato@users.sourceforge.jp>
    89 *
    910 * Written by Michael Meskes
     
    1314 */
    1415
    15 #include <stdio.h>
    16 #include <stdint.h>
    17 #include <sys/types.h>
    18 #include <pwd.h>
    19 #include <grp.h>
    20 #include <sys/vfs.h>
    21 #include <time.h>
    22 #include <getopt.h> /* optind */
    23 #include <sys/stat.h>
    24 #include <sys/statfs.h>
    25 #include <sys/statvfs.h>
    26 #include <string.h>
    27 #include "busybox.h"
     16#include "libbb.h"
    2817
    2918/* vars to control behavior */
    30 #define OPT_TERSE 2
    31 #define OPT_DEREFERENCE 4
    32 static long flags;
    33 
    34 static char const *file_type(struct stat const *st)
     19#define OPT_FILESYS     (1<<0)
     20#define OPT_TERSE       (1<<1)
     21#define OPT_DEREFERENCE (1<<2)
     22#define OPT_SELINUX     (1<<3)
     23
     24static char buf[sizeof("YYYY-MM-DD HH:MM:SS.000000000")] ALIGN1;
     25
     26static char const * file_type(struct stat const *st)
    3527{
    3628    /* See POSIX 1003.1-2001 XCU Table 4-8 lines 17093-17107
     
    5749static char const *human_time(time_t t)
    5850{
     51    /* Old
    5952    static char *str;
    6053    str = ctime(&t);
    6154    str[strlen(str)-1] = '\0';
    6255    return str;
     56    */
     57    /* coreutils 6.3 compat: */
     58
     59    strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S.000000000", localtime(&t));
     60    return buf;
    6361}
    6462
     
    7371    static const struct types {
    7472        long type;
    75         const char *fs;
     73        const char *const fs;
    7674    } humantypes[] = {
    7775        { 0xADFF,     "affs" },
     
    112110        { 0, "UNKNOWN" }
    113111    };
    114     for (i=0; humantypes[i].type; ++i)
     112    for (i = 0; humantypes[i].type; ++i)
    115113        if (humantypes[i].type == f_type)
    116114            break;
     
    118116}
    119117
    120 #ifdef CONFIG_FEATURE_STAT_FORMAT
     118#if ENABLE_FEATURE_STAT_FORMAT
    121119/* print statfs info */
    122 static void print_statfs(char *pformat, size_t buf_len, char m,
    123              char const *filename, void const *data)
     120static void print_statfs(char *pformat, const size_t buf_len, const char m,
     121             const char *const filename, void const *data
     122             USE_SELINUX(, security_context_t scontext))
    124123{
    125124    struct statfs const *statfsbuf = data;
    126 
    127     switch (m) {
    128     case 'n':
     125    if (m == 'n') {
    129126        strncat(pformat, "s", buf_len);
    130127        printf(pformat, filename);
    131         break;
    132     case 'i':
     128    } else if (m == 'i') {
    133129        strncat(pformat, "Lx", buf_len);
    134130        printf(pformat, statfsbuf->f_fsid);
    135         break;
    136     case 'l':
     131    } else if (m == 'l') {
    137132        strncat(pformat, "lu", buf_len);
    138133        printf(pformat, statfsbuf->f_namelen);
    139         break;
    140     case 't':
     134    } else if (m == 't') {
    141135        strncat(pformat, "lx", buf_len);
    142         printf(pformat, (unsigned long int) (statfsbuf->f_type));  /* no equiv. */
    143         break;
    144     case 'T':
     136        printf(pformat, (unsigned long) (statfsbuf->f_type)); /* no equiv */
     137    } else if (m == 'T') {
    145138        strncat(pformat, "s", buf_len);
    146139        printf(pformat, human_fstype(statfsbuf->f_type));
    147         break;
    148     case 'b':
     140    } else if (m == 'b') {
    149141        strncat(pformat, "jd", buf_len);
    150142        printf(pformat, (intmax_t) (statfsbuf->f_blocks));
    151         break;
    152     case 'f':
     143    } else if (m == 'f') {
    153144        strncat(pformat, "jd", buf_len);
    154145        printf(pformat, (intmax_t) (statfsbuf->f_bfree));
    155         break;
    156     case 'a':
     146    } else if (m == 'a') {
    157147        strncat(pformat, "jd", buf_len);
    158148        printf(pformat, (intmax_t) (statfsbuf->f_bavail));
    159         break;
    160     case 'S':
    161     case 's':
     149    } else if (m == 's' || m == 'S') {
    162150        strncat(pformat, "lu", buf_len);
    163         printf(pformat, (unsigned long int) (statfsbuf->f_bsize));
    164         break;
    165     case 'c':
     151        printf(pformat, (unsigned long) (statfsbuf->f_bsize));
     152    } else if (m == 'c') {
    166153        strncat(pformat, "jd", buf_len);
    167154        printf(pformat, (intmax_t) (statfsbuf->f_files));
    168         break;
    169     case 'd':
     155    } else if (m == 'd') {
    170156        strncat(pformat, "jd", buf_len);
    171157        printf(pformat, (intmax_t) (statfsbuf->f_ffree));
    172         break;
    173     default:
     158#if ENABLE_SELINUX
     159    } else if (m == 'C' && (option_mask32 & OPT_SELINUX)) {
     160        strncat(pformat, "s", buf_len);
     161        printf(scontext);
     162#endif
     163    } else {
    174164        strncat(pformat, "c", buf_len);
    175165        printf(pformat, m);
    176         break;
    177166    }
    178167}
    179168
    180169/* print stat info */
    181 static void print_stat(char *pformat, size_t buf_len, char m,
    182                char const *filename, void const *data)
     170static void print_stat(char *pformat, const size_t buf_len, const char m,
     171               const char *const filename, void const *data
     172               USE_SELINUX(, security_context_t scontext))
    183173{
    184174#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
     
    187177    struct group *gw_ent;
    188178
    189     switch (m) {
    190     case 'n':
     179    if (m == 'n') {
    191180        strncat(pformat, "s", buf_len);
    192181        printf(pformat, filename);
    193         break;
    194     case 'N':
     182    } else if (m == 'N') {
    195183        strncat(pformat, "s", buf_len);
    196184        if (S_ISLNK(statbuf->st_mode)) {
    197             char *linkname = xreadlink(filename);
     185            char *linkname = xmalloc_readlink_or_warn(filename);
    198186            if (linkname == NULL) {
    199187                bb_perror_msg("cannot read symbolic link '%s'", filename);
     
    207195            printf(pformat, filename);
    208196        }
    209         break;
    210     case 'd':
     197    } else if (m == 'd') {
    211198        strncat(pformat, "ju", buf_len);
    212199        printf(pformat, (uintmax_t) statbuf->st_dev);
    213         break;
    214     case 'D':
     200    } else if (m == 'D') {
    215201        strncat(pformat, "jx", buf_len);
    216202        printf(pformat, (uintmax_t) statbuf->st_dev);
    217         break;
    218     case 'i':
     203    } else if (m == 'i') {
    219204        strncat(pformat, "ju", buf_len);
    220205        printf(pformat, (uintmax_t) statbuf->st_ino);
    221         break;
    222     case 'a':
     206    } else if (m == 'a') {
    223207        strncat(pformat, "lo", buf_len);
    224         printf(pformat, (unsigned long int) (statbuf->st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)));
    225         break;
    226     case 'A':
     208        printf(pformat, (unsigned long) (statbuf->st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)));
     209    } else if (m == 'A') {
    227210        strncat(pformat, "s", buf_len);
    228211        printf(pformat, bb_mode_string(statbuf->st_mode));
    229         break;
    230     case 'f':
     212    } else if (m == 'f') {
    231213        strncat(pformat, "lx", buf_len);
    232         printf(pformat, (unsigned long int) statbuf->st_mode);
    233         break;
    234     case 'F':
     214        printf(pformat, (unsigned long) statbuf->st_mode);
     215    } else if (m == 'F') {
    235216        strncat(pformat, "s", buf_len);
    236217        printf(pformat, file_type(statbuf));
    237         break;
    238     case 'h':
     218    } else if (m == 'h') {
    239219        strncat(pformat, "lu", buf_len);
    240         printf(pformat, (unsigned long int) statbuf->st_nlink);
    241         break;
    242     case 'u':
     220        printf(pformat, (unsigned long) statbuf->st_nlink);
     221    } else if (m == 'u') {
    243222        strncat(pformat, "lu", buf_len);
    244         printf(pformat, (unsigned long int) statbuf->st_uid);
    245         break;
    246     case 'U':
     223        printf(pformat, (unsigned long) statbuf->st_uid);
     224    } else if (m == 'U') {
    247225        strncat(pformat, "s", buf_len);
    248226        setpwent();
    249227        pw_ent = getpwuid(statbuf->st_uid);
    250228        printf(pformat, (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN");
    251         break;
    252     case 'g':
     229    } else if (m == 'g') {
    253230        strncat(pformat, "lu", buf_len);
    254         printf(pformat, (unsigned long int) statbuf->st_gid);
    255         break;
    256     case 'G':
     231        printf(pformat, (unsigned long) statbuf->st_gid);
     232    } else if (m == 'G') {
    257233        strncat(pformat, "s", buf_len);
    258234        setgrent();
    259235        gw_ent = getgrgid(statbuf->st_gid);
    260236        printf(pformat, (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN");
    261         break;
    262     case 't':
     237    } else if (m == 't') {
    263238        strncat(pformat, "lx", buf_len);
    264         printf(pformat, (unsigned long int) major(statbuf->st_rdev));
    265         break;
    266     case 'T':
     239        printf(pformat, (unsigned long) major(statbuf->st_rdev));
     240    } else if (m == 'T') {
    267241        strncat(pformat, "lx", buf_len);
    268         printf(pformat, (unsigned long int) minor(statbuf->st_rdev));
    269         break;
    270     case 's':
     242        printf(pformat, (unsigned long) minor(statbuf->st_rdev));
     243    } else if (m == 's') {
    271244        strncat(pformat, "ju", buf_len);
    272245        printf(pformat, (uintmax_t) (statbuf->st_size));
    273         break;
    274     case 'B':
     246    } else if (m == 'B') {
    275247        strncat(pformat, "lu", buf_len);
    276         printf(pformat, (unsigned long int) 512); //ST_NBLOCKSIZE
    277         break;
    278     case 'b':
     248        printf(pformat, (unsigned long) 512); //ST_NBLOCKSIZE
     249    } else if (m == 'b') {
    279250        strncat(pformat, "ju", buf_len);
    280251        printf(pformat, (uintmax_t) statbuf->st_blocks);
    281         break;
    282     case 'o':
     252    } else if (m == 'o') {
    283253        strncat(pformat, "lu", buf_len);
    284         printf(pformat, (unsigned long int) statbuf->st_blksize);
    285         break;
    286     case 'x':
     254        printf(pformat, (unsigned long) statbuf->st_blksize);
     255    } else if (m == 'x') {
    287256        strncat(pformat, "s", buf_len);
    288257        printf(pformat, human_time(statbuf->st_atime));
    289         break;
    290     case 'X':
     258    } else if (m == 'X') {
    291259        strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len);
    292         printf(pformat, (unsigned long int) statbuf->st_atime);
    293         break;
    294     case 'y':
     260        printf(pformat, (unsigned long) statbuf->st_atime);
     261    } else if (m == 'y') {
    295262        strncat(pformat, "s", buf_len);
    296263        printf(pformat, human_time(statbuf->st_mtime));
    297         break;
    298     case 'Y':
     264    } else if (m == 'Y') {
    299265        strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len);
    300         printf(pformat, (unsigned long int) statbuf->st_mtime);
    301         break;
    302     case 'z':
     266        printf(pformat, (unsigned long) statbuf->st_mtime);
     267    } else if (m == 'z') {
    303268        strncat(pformat, "s", buf_len);
    304269        printf(pformat, human_time(statbuf->st_ctime));
    305         break;
    306     case 'Z':
     270    } else if (m == 'Z') {
    307271        strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len);
    308         printf(pformat, (unsigned long int) statbuf->st_ctime);
    309         break;
    310     default:
     272        printf(pformat, (unsigned long) statbuf->st_ctime);
     273#if ENABLE_SELINUX
     274    } else if (m == 'C' && (option_mask32 & OPT_SELINUX)) {
     275        strncat(pformat, "s", buf_len);
     276        printf(pformat, scontext);
     277#endif
     278    } else {
    311279        strncat(pformat, "c", buf_len);
    312280        printf(pformat, m);
    313         break;
    314281    }
    315282}
    316283
    317284static void print_it(char const *masterformat, char const *filename,
    318              void (*print_func) (char *, size_t, char, char const *, void const *),
    319              void const *data)
     285             void (*print_func) (char *, size_t, char, char const *, void const *
     286                                 USE_SELINUX(, security_context_t scontext)),
     287                     void const *data USE_SELINUX(, security_context_t scontext) )
    320288{
    321289    char *b;
    322290
    323291    /* create a working copy of the format string */
    324     char *format = bb_xstrdup(masterformat);
    325 
    326     /* Add 2 to accommodate our conversion of the stat `%s' format string
    327      * to the printf `%llu' one.  */
     292    char *format = xstrdup(masterformat);
     293
     294    /* Add 2 to accomodate our conversion of the stat '%s' format string
     295     * to the printf '%llu' one.  */
    328296    size_t n_alloc = strlen(format) + 2 + 1;
    329297    char *dest = xmalloc(n_alloc);
     
    331299    b = format;
    332300    while (b) {
     301        size_t len;
    333302        char *p = strchr(b, '%');
    334         if (p != NULL) {
    335             size_t len;
    336             *p++ = '\0';
    337             fputs(b, stdout);
    338 
    339             len = strspn(p, "#-+.I 0123456789");
    340             dest[0] = '%';
    341             memcpy(dest + 1, p, len);
    342             dest[1 + len] = 0;
    343             p += len;
    344 
    345             b = p + 1;
    346             switch (*p) {
    347                 case '\0':
    348                     b = NULL;
    349                     /* fall through */
    350                 case '%':
    351                     putchar('%');
    352                     break;
    353                 default:
    354                     print_func(dest, n_alloc, *p, filename, data);
    355                     break;
    356             }
    357 
    358         } else {
    359             fputs(b, stdout);
     303        if (!p) {
     304            /* coreutils 6.3 always print <cr> at the end */
     305            /*fputs(b, stdout);*/
     306            puts(b);
     307            break;
     308        }
     309        *p++ = '\0';
     310        fputs(b, stdout);
     311
     312        len = strspn(p, "#-+.I 0123456789");
     313        dest[0] = '%';
     314        memcpy(dest + 1, p, len);
     315        dest[1 + len] = 0;
     316        p += len;
     317
     318        b = p + 1;
     319        switch (*p) {
     320        case '\0':
    360321            b = NULL;
     322            /* fall through */
     323        case '%':
     324            putchar('%');
     325            break;
     326        default:
     327            print_func(dest, n_alloc, *p, filename, data USE_SELINUX(,scontext));
     328            break;
    361329        }
    362330    }
     
    368336
    369337/* Stat the file system and print what we find.  */
    370 static int do_statfs(char const *filename, char const *format)
     338static bool do_statfs(char const *filename, char const *format)
    371339{
    372340    struct statfs statfsbuf;
    373 
     341#if ENABLE_SELINUX
     342    security_context_t scontext = NULL;
     343
     344    if (option_mask32 & OPT_SELINUX) {
     345        if ((option_mask32 & OPT_DEREFERENCE
     346             ? lgetfilecon(filename, &scontext)
     347             : getfilecon(filename, &scontext)
     348            ) < 0
     349        ) {
     350            bb_perror_msg(filename);
     351            return 0;
     352        }
     353    }
     354#endif
    374355    if (statfs(filename, &statfsbuf) != 0) {
    375356        bb_perror_msg("cannot read file system information for '%s'", filename);
     
    377358    }
    378359
    379 #ifdef CONFIG_FEATURE_STAT_FORMAT
     360#if ENABLE_FEATURE_STAT_FORMAT
    380361    if (format == NULL)
    381         format = (flags & OPT_TERSE
     362#if !ENABLE_SELINUX
     363        format = (option_mask32 & OPT_TERSE
    382364            ? "%n %i %l %t %s %b %f %a %c %d\n"
    383365            : "  File: \"%n\"\n"
     
    385367              "Block size: %-10s\n"
    386368              "Blocks: Total: %-10b Free: %-10f Available: %a\n"
    387               "Inodes: Total: %-10c Free: %d\n");
    388     print_it(format, filename, print_statfs, &statfsbuf);
     369              "Inodes: Total: %-10c Free: %d");
     370    print_it(format, filename, print_statfs, &statfsbuf USE_SELINUX(, scontext));
    389371#else
    390 
    391     format = (flags & OPT_TERSE
     372    format = (option_mask32 & OPT_TERSE
     373            ? (option_mask32 & OPT_SELINUX ? "%n %i %l %t %s %b %f %a %c %d %C\n":
     374            "%n %i %l %t %s %b %f %a %c %d\n")
     375            : (option_mask32 & OPT_SELINUX ?
     376            "  File: \"%n\"\n"
     377            "    ID: %-8i Namelen: %-7l Type: %T\n"
     378            "Block size: %-10s\n"
     379            "Blocks: Total: %-10b Free: %-10f Available: %a\n"
     380            "Inodes: Total: %-10c Free: %d"
     381            "  S_context: %C\n":
     382            "  File: \"%n\"\n"
     383            "    ID: %-8i Namelen: %-7l Type: %T\n"
     384            "Block size: %-10s\n"
     385            "Blocks: Total: %-10b Free: %-10f Available: %a\n"
     386            "Inodes: Total: %-10c Free: %d\n")
     387            );
     388    print_it(format, filename, print_statfs, &statfsbuf USE_SELINUX(, scontext));
     389#endif /* SELINUX */
     390#else /* FEATURE_STAT_FORMAT */
     391    format = (option_mask32 & OPT_TERSE
    392392        ? "%s %llx %lu "
    393393        : "  File: \"%s\"\n"
     
    398398           statfsbuf.f_namelen);
    399399
    400     if (flags & OPT_TERSE)
    401         printf("%lx ", (unsigned long int) (statfsbuf.f_type));
     400    if (option_mask32 & OPT_TERSE)
     401        printf("%lx ", (unsigned long) (statfsbuf.f_type));
    402402    else
    403403        printf("Type: %s\n", human_fstype(statfsbuf.f_type));
    404404
    405     format = (flags & OPT_TERSE
     405#if !ENABLE_SELINUX
     406    format = (option_mask32 & OPT_TERSE
    406407        ? "%lu %ld %ld %ld %ld %ld\n"
    407408        : "Block size: %-10lu\n"
     
    409410          "Inodes: Total: %-10jd Free: %jd\n");
    410411    printf(format,
    411            (unsigned long int) (statfsbuf.f_bsize),
     412           (unsigned long) (statfsbuf.f_bsize),
    412413           (intmax_t) (statfsbuf.f_blocks),
    413414           (intmax_t) (statfsbuf.f_bfree),
     
    415416           (intmax_t) (statfsbuf.f_files),
    416417           (intmax_t) (statfsbuf.f_ffree));
    417 #endif
    418 
     418#else
     419    format = (option_mask32 & OPT_TERSE
     420        ? (option_mask32 & OPT_SELINUX ? "%lu %ld %ld %ld %ld %ld %C\n":
     421        "%lu %ld %ld %ld %ld %ld\n")
     422        : (option_mask32 & OPT_SELINUX ?
     423        "Block size: %-10lu\n"
     424        "Blocks: Total: %-10jd Free: %-10jd Available: %jd\n"
     425        "Inodes: Total: %-10jd Free: %jd"
     426        "S_context: %C\n":
     427        "Block size: %-10lu\n"
     428        "Blocks: Total: %-10jd Free: %-10jd Available: %jd\n"
     429        "Inodes: Total: %-10jd Free: %jd\n"));
     430    printf(format,
     431           (unsigned long) (statfsbuf.f_bsize),
     432           (intmax_t) (statfsbuf.f_blocks),
     433           (intmax_t) (statfsbuf.f_bfree),
     434           (intmax_t) (statfsbuf.f_bavail),
     435           (intmax_t) (statfsbuf.f_files),
     436           (intmax_t) (statfsbuf.f_ffree),
     437        scontext);
     438
     439    if (scontext)
     440        freecon(scontext);
     441#endif
     442#endif  /* FEATURE_STAT_FORMAT */
    419443    return 1;
    420444}
    421445
    422446/* stat the file and print what we find */
    423 static int do_stat(char const *filename, char const *format)
     447static bool do_stat(char const *filename, char const *format)
    424448{
    425449    struct stat statbuf;
    426 
    427     if ((flags & OPT_DEREFERENCE ? stat : lstat) (filename, &statbuf) != 0) {
     450#if ENABLE_SELINUX
     451    security_context_t scontext = NULL;
     452
     453    if (option_mask32 & OPT_SELINUX) {
     454        if ((option_mask32 & OPT_DEREFERENCE
     455             ? lgetfilecon(filename, &scontext)
     456             : getfilecon(filename, &scontext)
     457            ) < 0
     458        ) {
     459            bb_perror_msg(filename);
     460            return 0;
     461        }
     462    }
     463#endif
     464    if ((option_mask32 & OPT_DEREFERENCE ? stat : lstat) (filename, &statbuf) != 0) {
    428465        bb_perror_msg("cannot stat '%s'", filename);
    429466        return 0;
    430467    }
    431468
    432 #ifdef CONFIG_FEATURE_STAT_FORMAT
     469#if ENABLE_FEATURE_STAT_FORMAT
    433470    if (format == NULL) {
    434         if (flags & OPT_TERSE) {
    435             format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n";
     471#if !ENABLE_SELINUX
     472        if (option_mask32 & OPT_TERSE) {
     473            format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o";
    436474        } else {
    437475            if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) {
     
    452490            }
    453491        }
    454     }
    455     print_it(format, filename, print_stat, &statbuf);
    456492#else
    457     if (flags & OPT_TERSE) {
    458         printf("%s %ju %ju %lx %lu %lu %jx %ju %lu %lx %lx %lu %lu %lu %lu\n",
     493        if (option_mask32 & OPT_TERSE) {
     494            format = (option_mask32 & OPT_SELINUX ?
     495                  "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n":
     496                  "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n");
     497        } else {
     498            if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) {
     499                format = (option_mask32 & OPT_SELINUX ?
     500                      "  File: \"%N\"\n"
     501                      "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
     502                      "Device: %Dh/%dd\tInode: %-10i  Links: %-5h"
     503                      " Device type: %t,%T\n"
     504                      "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
     505                      "   S_Context: %C\n"
     506                      "Access: %x\n" "Modify: %y\n" "Change: %z\n":
     507                      "  File: \"%N\"\n"
     508                      "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
     509                      "Device: %Dh/%dd\tInode: %-10i  Links: %-5h"
     510                      " Device type: %t,%T\n"
     511                      "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
     512                      "Access: %x\n" "Modify: %y\n" "Change: %z\n");
     513            } else {
     514                format = (option_mask32 & OPT_SELINUX ?
     515                      "  File: \"%N\"\n"
     516                      "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
     517                      "Device: %Dh/%dd\tInode: %-10i  Links: %h\n"
     518                      "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
     519                      "S_Context: %C\n"
     520                      "Access: %x\n" "Modify: %y\n" "Change: %z\n":
     521                      "  File: \"%N\"\n"
     522                      "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
     523                      "Device: %Dh/%dd\tInode: %-10i  Links: %h\n"
     524                      "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
     525                      "Access: %x\n" "Modify: %y\n" "Change: %z\n");
     526            }
     527        }
     528#endif
     529    }
     530    print_it(format, filename, print_stat, &statbuf USE_SELINUX(, scontext));
     531#else   /* FEATURE_STAT_FORMAT */
     532    if (option_mask32 & OPT_TERSE) {
     533        printf("%s %ju %ju %lx %lu %lu %jx %ju %lu %lx %lx %lu %lu %lu %lu"
     534               SKIP_SELINUX("\n"),
    459535               filename,
    460536               (uintmax_t) (statbuf.st_size),
    461537               (uintmax_t) statbuf.st_blocks,
    462                (unsigned long int) statbuf.st_mode,
    463                (unsigned long int) statbuf.st_uid,
    464                (unsigned long int) statbuf.st_gid,
     538               (unsigned long) statbuf.st_mode,
     539               (unsigned long) statbuf.st_uid,
     540               (unsigned long) statbuf.st_gid,
    465541               (uintmax_t) statbuf.st_dev,
    466542               (uintmax_t) statbuf.st_ino,
    467                (unsigned long int) statbuf.st_nlink,
    468                (unsigned long int) major(statbuf.st_rdev),
    469                (unsigned long int) minor(statbuf.st_rdev),
    470                (unsigned long int) statbuf.st_atime,
    471                (unsigned long int) statbuf.st_mtime,
    472                (unsigned long int) statbuf.st_ctime,
    473                (unsigned long int) statbuf.st_blksize
     543               (unsigned long) statbuf.st_nlink,
     544               (unsigned long) major(statbuf.st_rdev),
     545               (unsigned long) minor(statbuf.st_rdev),
     546               (unsigned long) statbuf.st_atime,
     547               (unsigned long) statbuf.st_mtime,
     548               (unsigned long) statbuf.st_ctime,
     549               (unsigned long) statbuf.st_blksize
    474550        );
     551#if ENABLE_SELINUX
     552        if (option_mask32 & OPT_SELINUX)
     553            printf(" %lc\n", *scontext);
     554        else
     555            putchar('\n');
     556#endif
    475557    } else {
    476558        char *linkname = NULL;
     
    484566
    485567        if (S_ISLNK(statbuf.st_mode))
    486             linkname = xreadlink(filename);
     568            linkname = xmalloc_readlink_or_warn(filename);
    487569        if (linkname)
    488570            printf("  File: \"%s\" -> \"%s\"\n", filename, linkname);
     
    494576               (uintmax_t) (statbuf.st_size),
    495577               (uintmax_t) statbuf.st_blocks,
    496                (unsigned long int) statbuf.st_blksize,
     578               (unsigned long) statbuf.st_blksize,
    497579               file_type(&statbuf),
    498580               (uintmax_t) statbuf.st_dev,
    499581               (uintmax_t) statbuf.st_dev,
    500582               (uintmax_t) statbuf.st_ino,
    501                (unsigned long int) statbuf.st_nlink);
     583               (unsigned long) statbuf.st_nlink);
    502584        if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode))
    503585            printf(" Device type: %lx,%lx\n",
    504                    (unsigned long int) major(statbuf.st_rdev),
    505                    (unsigned long int) minor(statbuf.st_rdev));
     586                   (unsigned long) major(statbuf.st_rdev),
     587                   (unsigned long) minor(statbuf.st_rdev));
    506588        else
    507589            putchar('\n');
    508         printf("Access: (%04lo/%10.10s)  Uid: (%5lu/%8s)   Gid: (%5lu/%8s)\n"
    509                "Access: %s\n" "Modify: %s\n" "Change: %s\n",
    510                (unsigned long int) (statbuf.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)),
     590        printf("Access: (%04lo/%10.10s)  Uid: (%5lu/%8s)   Gid: (%5lu/%8s)\n",
     591               (unsigned long) (statbuf.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)),
    511592               bb_mode_string(statbuf.st_mode),
    512                (unsigned long int) statbuf.st_uid,
     593               (unsigned long) statbuf.st_uid,
    513594               (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN",
    514                (unsigned long int) statbuf.st_gid,
    515                (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN",
     595               (unsigned long) statbuf.st_gid,
     596               (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN");
     597#if ENABLE_SELINUX
     598        printf("   S_Context: %lc\n", *scontext);
     599#endif
     600        printf("Access: %s\n" "Modify: %s\n" "Change: %s\n",
    516601               human_time(statbuf.st_atime),
    517602               human_time(statbuf.st_mtime),
    518603               human_time(statbuf.st_ctime));
    519604    }
    520 #endif
     605#endif  /* FEATURE_STAT_FORMAT */
    521606    return 1;
    522607}
    523608
     609int stat_main(int argc, char **argv);
    524610int stat_main(int argc, char **argv)
    525611{
     612    char *format = NULL;
    526613    int i;
    527     char *format = NULL;
    528614    int ok = 1;
    529     int (*statfunc)(char const *, char const *) = do_stat;
    530 
    531     flags = bb_getopt_ulflags(argc, argv, "ftL"
    532     USE_FEATURE_STAT_FORMAT("c:", &format)
     615    bool (*statfunc)(char const *, char const *) = do_stat;
     616
     617    getopt32(argv, "ftL"
     618        USE_SELINUX("Z")
     619        USE_FEATURE_STAT_FORMAT("c:", &format)
    533620    );
    534621
    535     if (flags & 1)                /* -f */
     622    if (option_mask32 & OPT_FILESYS) /* -f */
    536623        statfunc = do_statfs;
    537624    if (argc == optind)           /* files */
    538625        bb_show_usage();
    539626
     627#if ENABLE_SELINUX
     628    if (option_mask32 & OPT_SELINUX) {
     629        selinux_or_die();
     630    }
     631#endif  /* ENABLE_SELINUX */
    540632    for (i = optind; i < argc; ++i)
    541633        ok &= statfunc(argv[i], format);
Note: See TracChangeset for help on using the changeset viewer.