config: trim/improve item names and help texts.
[oweals/busybox.git] / coreutils / stat.c
index c8677ebaa93b71705b510bbff8dd04296c7c4b9d..3b85808b5d7dbb57f0f6f2e3eca4965f0a4e3dc0 100644 (file)
  *
  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  */
+//config:config STAT
+//config:      bool "stat (10 kb)"
+//config:      default y
+//config:      help
+//config:      display file or filesystem status.
+//config:
+//config:config FEATURE_STAT_FORMAT
+//config:      bool "Enable custom formats (-c)"
+//config:      default y
+//config:      depends on STAT
+//config:      help
+//config:      Without this, stat will not support the '-c format' option where
+//config:      users can pass a custom format string for output. This adds about
+//config:      7k to a nonstatic build on amd64.
+//config:
+//config:config FEATURE_STAT_FILESYSTEM
+//config:      bool "Enable display of filesystem status (-f)"
+//config:      default y
+//config:      depends on STAT
+//config:      select PLATFORM_LINUX # statfs()
+//config:      help
+//config:      Without this, stat will not support the '-f' option to display
+//config:      information about filesystem status.
+
+//applet:IF_STAT(APPLET(stat, BB_DIR_BIN, BB_SUID_DROP))
+
+//kbuild:lib-$(CONFIG_STAT) += stat.o
 
 //usage:#define stat_trivial_usage
 //usage:       "[OPTIONS] FILE..."
 //usage:#define stat_full_usage "\n\n"
-//usage:       "Display file (default) or filesystem status\n"
+//usage:       "Display file"
+//usage:            IF_FEATURE_STAT_FILESYSTEM(" (default) or filesystem")
+//usage:            " status\n"
 //usage:       IF_FEATURE_STAT_FORMAT(
-//usage:     "\n       -c fmt  Use the specified format"
+//usage:     "\n       -c FMT  Use the specified format"
 //usage:       )
+//usage:       IF_FEATURE_STAT_FILESYSTEM(
 //usage:     "\n       -f      Display filesystem status"
+//usage:       )
 //usage:     "\n       -L      Follow links"
-//usage:     "\n       -t      Display info in terse form"
+//usage:     "\n       -t      Terse display"
 //usage:       IF_SELINUX(
 //usage:     "\n       -Z      Print security context"
 //usage:       )
 //usage:       IF_FEATURE_STAT_FORMAT(
-//usage:       "\n\nValid format sequences for files:\n"
+//usage:       "\n\nFMT sequences"IF_FEATURE_STAT_FILESYSTEM(" for files")":\n"
 //usage:       " %a    Access rights in octal\n"
 //usage:       " %A    Access rights in human readable form\n"
 //usage:       " %b    Number of blocks allocated (see %B)\n"
-//usage:       " %B    The size in bytes of each block reported by %b\n"
+//usage:       " %B    Size in bytes of each block reported by %b\n"
 //usage:       " %d    Device number in decimal\n"
 //usage:       " %D    Device number in hex\n"
 //usage:       " %f    Raw mode in hex\n"
 //usage:       " %F    File type\n"
-//usage:       " %g    Group ID of owner\n"
-//usage:       " %G    Group name of owner\n"
+//usage:       " %g    Group ID\n"
+//usage:       " %G    Group name\n"
 //usage:       " %h    Number of hard links\n"
 //usage:       " %i    Inode number\n"
 //usage:       " %n    File name\n"
 //usage:       " %N    File name, with -> TARGET if symlink\n"
 //usage:       " %o    I/O block size\n"
-//usage:       " %s    Total size, in bytes\n"
+//usage:       " %s    Total size in bytes\n"
 //usage:       " %t    Major device type in hex\n"
 //usage:       " %T    Minor device type in hex\n"
-//usage:       " %u    User ID of owner\n"
-//usage:       " %U    User name of owner\n"
+//usage:       " %u    User ID\n"
+//usage:       " %U    User name\n"
 //usage:       " %x    Time of last access\n"
 //usage:       " %X    Time of last access as seconds since Epoch\n"
 //usage:       " %y    Time of last modification\n"
 //usage:       " %Y    Time of last modification as seconds since Epoch\n"
 //usage:       " %z    Time of last change\n"
 //usage:       " %Z    Time of last change as seconds since Epoch\n"
-//usage:       "\nValid format sequences for file systems:\n"
+//usage:       IF_FEATURE_STAT_FILESYSTEM(
+//usage:       "\nFMT sequences for file systems:\n"
 //usage:       " %a    Free blocks available to non-superuser\n"
-//usage:       " %b    Total data blocks in file system\n"
-//usage:       " %c    Total file nodes in file system\n"
-//usage:       " %d    Free file nodes in file system\n"
-//usage:       " %f    Free blocks in file system\n"
+//usage:       " %b    Total data blocks\n"
+//usage:       " %c    Total file nodes\n"
+//usage:       " %d    Free file nodes\n"
+//usage:       " %f    Free blocks\n"
 //usage:       IF_SELINUX(
 //usage:       " %C    Security context in selinux\n"
 //usage:       )
 //usage:       " %t    Type in hex\n"
 //usage:       " %T    Type in human readable form"
 //usage:       )
+//usage:       )
 
 #include "libbb.h"
+#include "common_bufsiz.h"
 
-#define OPT_FILESYS     (1 << 0)
-#define OPT_TERSE       (1 << 1)
-#define OPT_DEREFERENCE (1 << 2)
-#define OPT_SELINUX     (1 << 3)
+enum {
+       OPT_TERSE       = (1 << 0),
+       OPT_DEREFERENCE = (1 << 1),
+       OPT_FILESYS     = (1 << 2) * ENABLE_FEATURE_STAT_FILESYSTEM,
+       OPT_SELINUX     = (1 << (2+ENABLE_FEATURE_STAT_FILESYSTEM)) * ENABLE_SELINUX,
+};
 
 #if ENABLE_FEATURE_STAT_FORMAT
 typedef bool (*statfunc_ptr)(const char *, const char *);
@@ -126,12 +162,13 @@ static const char *human_time(time_t t)
 
        /*static char buf[sizeof("YYYY-MM-DD HH:MM:SS.000000000")] ALIGN1;*/
 #define buf bb_common_bufsiz1
-
-       strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S.000000000", localtime(&t));
+       setup_common_bufsiz();
+       strcpy(strftime_YYYYMMDDHHMMSS(buf, COMMON_BUFSIZE, &t), ".000000000");
        return buf;
 #undef buf
 }
 
+#if ENABLE_FEATURE_STAT_FILESYSTEM
 /* Return the type of the specified file system.
  * Some systems have statfvs.f_basetype[FSTYPSZ]. (AIX, HP-UX, and Solaris)
  * Others have statfs.f_fstypename[MFSNAMELEN]. (NetBSD 1.5.2)
@@ -202,6 +239,7 @@ static unsigned long long get_f_fsid(const struct statfs *statfsbuf)
        while (--sz > 0);
        return r;
 }
+#endif  /* FEATURE_STAT_FILESYSTEM */
 
 #if ENABLE_FEATURE_STAT_FORMAT
 static void strcatc(char *str, char c)
@@ -217,6 +255,7 @@ static void printfs(char *pformat, const char *msg)
        printf(pformat, msg);
 }
 
+#if ENABLE_FEATURE_STAT_FILESYSTEM
 /* print statfs info */
 static void FAST_FUNC print_statfs(char *pformat, const char m,
                const char *const filename, const void *data
@@ -263,6 +302,7 @@ static void FAST_FUNC print_statfs(char *pformat, const char m,
                printf(pformat, m);
        }
 }
+#endif
 
 /* print stat info */
 static void FAST_FUNC print_stat(char *pformat, const char m,
@@ -374,7 +414,7 @@ static void print_it(const char *masterformat,
 {
        /* Create a working copy of the format string */
        char *format = xstrdup(masterformat);
-       /* Add 2 to accomodate our conversion of the stat '%s' format string
+       /* Add 2 to accommodate our conversion of the stat '%s' format string
         * to the printf '%llu' one.  */
        char *dest = xmalloc(strlen(format) + 2 + 1);
        char *b;
@@ -423,6 +463,7 @@ static void print_it(const char *masterformat,
 }
 #endif  /* FEATURE_STAT_FORMAT */
 
+#if ENABLE_FEATURE_STAT_FILESYSTEM
 /* Stat the file system and print what we find.  */
 #if !ENABLE_FEATURE_STAT_FORMAT
 #define do_statfs(filename, format) do_statfs(filename)
@@ -538,6 +579,7 @@ static bool do_statfs(const char *filename, const char *format)
 #endif  /* FEATURE_STAT_FORMAT */
        return 1;
 }
+#endif  /* FEATURE_STAT_FILESYSTEM */
 
 /* stat the file and print what we find */
 #if !ENABLE_FEATURE_STAT_FORMAT
@@ -655,7 +697,7 @@ static bool do_stat(const char *filename, const char *format)
                );
 # if ENABLE_SELINUX
                if (option_mask32 & OPT_SELINUX)
-                       printf(" %lc\n", *scontext);
+                       printf(" %s\n", scontext);
                else
                        bb_putchar('\n');
 # endif
@@ -700,7 +742,8 @@ static bool do_stat(const char *filename, const char *format)
                       (unsigned long) statbuf.st_gid,
                       (gw_ent != NULL) ? gw_ent->gr_name : "UNKNOWN");
 # if ENABLE_SELINUX
-               printf("   S_Context: %lc\n", *scontext);
+               if (option_mask32 & OPT_SELINUX)
+                       printf("   S_Context: %s\n", scontext);
 # endif
                printf("Access: %s\n", human_time(statbuf.st_atime));
                printf("Modify: %s\n", human_time(statbuf.st_mtime));
@@ -720,12 +763,15 @@ int stat_main(int argc UNUSED_PARAM, char **argv)
        statfunc_ptr statfunc = do_stat;
 
        opt_complementary = "-1"; /* min one arg */
-       opts = getopt32(argv, "ftL"
+       opts = getopt32(argv, "tL"
+               IF_FEATURE_STAT_FILESYSTEM("f")
                IF_SELINUX("Z")
                IF_FEATURE_STAT_FORMAT("c:", &format)
        );
+#if ENABLE_FEATURE_STAT_FILESYSTEM
        if (opts & OPT_FILESYS) /* -f */
                statfunc = do_statfs;
+#endif
 #if ENABLE_SELINUX
        if (opts & OPT_SELINUX) {
                selinux_or_die();