From 4010e2d077e5031c464ead0f0ec0e664264d4107 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Sun, 7 Jan 2007 09:15:42 +0100 Subject: stat: Add support for SELinux in the form of a %C format directive. * src/stat.c (follow_links): Make this variable file-global. (out_file_context): New function. (print_statfs): Honor %C. (print_stat): Honor %C. (do_stat): Remove follow_links parameter. (usage): Document the two %C directives. (main): Accept -Z (though it's a no-op). * src/Makefile.am (stat_LDADD): Define. --- src/Makefile.am | 2 ++ src/stat.c | 47 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 8d2580631..4bc4faefb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -112,6 +112,8 @@ cp_LDADD += $(LIB_ACL) mv_LDADD += $(LIB_ACL) ginstall_LDADD += $(LIB_ACL) +stat_LDADD = $(LDADD) $(LIB_SELINUX) + $(PROGRAMS): ../lib/libcoreutils.a SUFFIXES = .sh diff --git a/src/stat.c b/src/stat.c index 29a222ac5..b8cbbf58f 100644 --- a/src/stat.c +++ b/src/stat.c @@ -54,6 +54,7 @@ #elif HAVE_OS_H /* BeOS */ # include #endif +#include #include "system.h" @@ -158,6 +159,7 @@ enum }; static struct option const long_options[] = { + {"context", no_argument, 0, 'Z'}, {"dereference", no_argument, NULL, 'L'}, {"file-system", no_argument, NULL, 'f'}, {"filesystem", no_argument, NULL, 'f'}, /* obsolete and undocumented alias */ @@ -171,6 +173,9 @@ static struct option const long_options[] = { char *program_name; +/* Whether to follow symbolic links; True for --dereference (-L). */ +static bool follow_links; + /* Whether to interpret backslash-escape sequences. True for --printf=FMT, not for --format=FMT (-c). */ static bool interpret_backslash_escapes; @@ -394,6 +399,26 @@ out_uint_x (char *pformat, size_t prefix_len, uintmax_t arg) printf (pformat, arg); } +/* Very specialized function (modifies FORMAT), just so as to avoid + duplicating this code between both print_statfs and print_stat. */ +static void +out_file_context (char const *filename, char *pformat, size_t prefix_len) +{ + char *scontext; + if ((follow_links + ? getfilecon (filename, &scontext) + : lgetfilecon (filename, &scontext)) < 0) + { + error (0, errno, _("failed to get security context of %s"), + quote (filename)); + scontext = NULL; + } + strcpy (pformat + prefix_len, "s"); + printf (pformat, (scontext ? scontext : "?")); + if (scontext) + freecon (scontext); +} + /* print statfs info */ static void print_statfs (char *pformat, size_t prefix_len, char m, char const *filename, @@ -472,7 +497,9 @@ print_statfs (char *pformat, size_t prefix_len, char m, char const *filename, case 'd': out_int (pformat, prefix_len, statfsbuf->f_ffree); break; - + case 'C': + out_file_context (filename, pformat, prefix_len); + break; default: fputc ('?', stdout); break; @@ -595,6 +622,9 @@ print_stat (char *pformat, size_t prefix_len, char m, else out_uint (pformat, prefix_len, statbuf->st_ctime); break; + case 'C': + out_file_context (filename, pformat, prefix_len); + break; default: fputc ('?', stdout); break; @@ -774,8 +804,7 @@ do_statfs (char const *filename, bool terse, char const *format) /* stat the file and print what we find */ static bool -do_stat (char const *filename, bool follow_links, bool terse, - char const *format) +do_stat (char const *filename, bool terse, char const *format) { struct stat statbuf; @@ -853,6 +882,7 @@ The valid format sequences for files (without --file-system):\n\ %A Access rights in human readable form\n\ %b Number of blocks allocated (see %B)\n\ %B The size in bytes of each block reported by %b\n\ + %C SELinux security context string\n\ "), stdout); fputs (_("\ %d Device number in decimal\n\ @@ -892,6 +922,7 @@ Valid format sequences for file systems:\n\ %c Total file nodes in file system\n\ %d Free file nodes in file system\n\ %f Free blocks in file system\n\ + %C SELinux security context string\n\ "), stdout); fputs (_("\ %i File System ID in hex\n\ @@ -913,7 +944,6 @@ main (int argc, char *argv[]) { int c; int i; - bool follow_links = false; bool fs = false; bool terse = false; char *format = NULL; @@ -927,7 +957,7 @@ main (int argc, char *argv[]) atexit (close_stdout); - while ((c = getopt_long (argc, argv, "c:fLt", long_options, NULL)) != -1) + while ((c = getopt_long (argc, argv, "c:fLtZ", long_options, NULL)) != -1) { switch (c) { @@ -955,6 +985,11 @@ main (int argc, char *argv[]) terse = true; break; + case 'Z': /* FIXME: remove in 2008, warn in 2007 */ + /* Ignored, for compatibility with distributions + that implemented this before upstream. */ + break; + case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); @@ -973,7 +1008,7 @@ main (int argc, char *argv[]) for (i = optind; i < argc; i++) ok &= (fs ? do_statfs (argv[i], terse, format) - : do_stat (argv[i], follow_links, terse, format)); + : do_stat (argv[i], terse, format)); exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); } -- cgit v1.2.3-54-g00ecf