Ignore:
Timestamp:
Nov 6, 2007, 11:01:53 AM (16 years ago)
Author:
Bruno Cornec
Message:
  • Better output for mindi-busybox revision
  • Remove dummy file created on NFS - report from Arnaud Tiger <arnaud.tiger_at_hp.com>
  • strace useful for debug
  • fix new versions for pb (2.0.0 for mindi and 1.7.2 for mindi-busybox)
  • fix build process for mindi-busybox + options used in that version (dd for label-partitions-as-necessary)
  • fix typo in label-partitions-as-necessary which doesn't seem to work
  • Update to busybox 1.7.2
  • perl is now required at restore time to support uuid swap partitions (and will be used for many other thigs

in the future for sure)

  • next mindi version will be 2.0.0 due to all the changes made in it (udev may break working distros)
  • small optimization in mindi on keyboard handling (one single find instead of multiple)
  • better interaction for USB device when launching mindi manually
  • attempt to automatically guess block disk size for ramdisk
  • fix typos in bkphw
  • Fix the remaining problem with UUID support for swap partitions
  • Updates mondoarchive man page for USB support
  • Adds preliminary Hardware support to mindi (Proliant SSSTK)
  • Tries to add udev support also for rhel4
  • Fix UUID support which was still broken.
  • Be conservative in test for the start-nfs script
  • Update config file for mindi-busybox for 1.7.2 migration
  • Try to run around a busybox bug (1.2.2 pb on inexistant links)
  • Add build content for mindi-busybox in pb
  • Remove distributions content for mindi-busybox
  • Fix a warning on inexistant raidtab
  • Solve problem on tmpfs in restore init (Problem of inexistant symlink and busybox)
  • Create MONDO_CACHE and use it everywhere + creation at start
  • Really never try to eject a USB device
  • Fix a issue with &> usage (replaced with 1> and 2>)
  • Adds magic file to depllist in order to have file working + ldd which helps for debugging issues
  • tty modes correct to avoid sh error messages
  • Use ext3 normally and not ext2 instead
  • USB device should be corrected after reading (take 1st part)
  • Adds a mount_USB_here function derived from mount_CDROM_here
  • usb detection place before /dev detection in device name at restore time
  • Fix when restoring from USB: media is asked in interactive mode
  • Adds USB support for mondorestore
  • mount_cdrom => mount_media
  • elilo.efi is now searched throughout /boot/efi and not in a fixed place as there is no standard
  • untar-and-softlink => untar (+ interface change)
  • suppress useless softlinks creation/removal in boot process
  • avoids udevd messages on groups
  • Increase # of disks to 99 as in mindi at restore time (should be a conf file parameter)
  • skip existing big file creation
  • seems to work correctly for USB mindi boot
  • Adds group and tty link to udev conf
  • Always load usb-torage (even 2.6) to initiate USB bus discovery
  • Better printing of messages
  • Attempt to fix a bug in supporting OpenSusE 10.3 kernel for initramfs (mindi may now use multiple regex for kernel initrd detection)
  • Links were not correctly done as non relative for modules in mindi
  • exclusion of modules denied now works
  • Also create modules in their ordinary place, so that classical modprobe works + copy modules.dep
  • Fix bugs for DENY_MODS handling
  • Add device /dev/console for udev
  • ide-generic should now really be excluded
  • Fix a bug in major number for tty
  • If udev then adds modprobe/insmod to rootfs
  • tty0 is also cretaed with udev
  • ide-generic put rather in DENY_MODS
  • udevd remove from deplist s handled in mindi directly
  • better default for mindi when using --usb
  • Handles dynamically linked busybox (in case we want to use it soon ;-)
  • Adds fixed devices to create for udev
  • ide-generic should not be part of the initrd when using libata v2
  • support a dynamically linked udev (case on Ubuntu 7.10 and Mandriva 2008.0 so should be quite generic) This will give incitation to move to dyn. linked binaries in the initrd which will help for other tasks (ia6 4)
  • Improvement in udev support (do not use cl options not available in busybox)
  • Udev in mindi
    • auto creation of the right links at boot time with udev-links.conf(from Mandriva 2008.0)
    • rework startup of udev as current makes kernel crash (from Mandriva 2008.0)
    • add support for 64 bits udev
  • Try to render MyInsmod silent at boot time
  • Adds udev support (mandatory for newest distributions to avoid remapping of devices in a different way as on the original system)
  • We also need vaft format support for USB boot
  • Adds libusual support (Ubuntu 7.10 needs it for USB)
  • Improve Ubuntu/Debian keyboard detection and support
  • pbinit adapted to new pb (0.8.10). Filtering of docs done in it
  • Suppress some mondo warnings and errors on USB again
  • Tries to fix lack of files in deb mindi package
  • Verify should now work for USB devices
  • More log/mesages improvement for USB support
  • - Supress g_erase_tmpdir_and_scratchdir
  • Improve some log messages for USB support
  • Try to improve install in mindi to avoid issues with isolinux.cfg not installed vene if in the pkg :-(
  • Improve mindi-busybox build
  • In conformity with pb 0.8.9
  • Add support for Ubuntu 7.10 in build process
  • Add USB Key button to Menu UI (CD streamer removed)
  • Attempt to fix error messages on tmp/scratch files at the end by removing those dir at the latest possible.
  • Fix a bug linked to the size of the -E param which could be used (Arnaud Tiger/René Ribaud).
  • Integrate ~/.pbrc content into mondorescue.pb (required project-builder >= 0.8.7)
  • Put mondorescue in conformity with new pb filtering rules
  • Add USB support at restore time (no test done yet). New start-usb script PB varibale added where useful
  • Unmounting USB device before removal of temporary scratchdir
  • Stil refining USB copy back to mondo (one command was not executed)
  • No need to have the image subdor in the csratchdir when USB.
  • umount the USB partition before attempting to use it
  • Remove useless copy from mindi to mondo at end of USB handling

(risky merge, we are raising the limits of 2 diverging branches. The status of stable is not completely sure as such. Will need lots of tests, but it's not yet done :-()
(merge -r1692:1769 $SVN_M/branches/2.2.5)

File:
1 edited

Legend:

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

    r821 r1770  
    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.