From a0a2366af69016adeecb3db86ebfa5bba7c93952 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 21 Jul 2008 15:43:30 +0200 Subject: [PATCH] ls: --color now highlights files with capabilities, too * configure.ac: --disable-libcap configure parameter, check for libcap usability * src/Makefile.am: libcap library linking * src/ls.c (has_capability): new function for capability detection (print_color_indicator): colorize file with capability * NEWS: mentioned the change --- NEWS | 2 ++ configure.ac | 13 +++++++++++++ src/Makefile.am | 6 +++--- src/ls.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 62 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index d6ed89e..16b721e 100644 --- a/NEWS +++ b/NEWS @@ -27,6 +27,8 @@ GNU coreutils NEWS -*- outline -*- represents the maximum number of inputs that will be merged at once. When processing more than NMERGE inputs, sort uses temporary files. + ls now colorizes files with capabilities if libcap is available + ** Bug fixes chcon --verbose now prints a newline after each message diff --git a/configure.ac b/configure.ac index ac93e1c..96b2fda 100644 --- a/configure.ac +++ b/configure.ac @@ -44,6 +44,19 @@ gl_EARLY gl_INIT coreutils_MACROS +dnl Check whether libcap is usable +AC_ARG_ENABLE([libcap], + AC_HELP_STRING([--disable-libcap], [disable libcap support]), + AC_MSG_WARN([libcap support disabled by user]), + [AC_CHECK_LIB([cap], [cap_get_file], + [AC_CHECK_HEADER([sys/capability.h], + [LIB_CAP="-lcap" AC_DEFINE(HAVE_CAP, 1, [libcap usability])], + [AC_MSG_WARN([header sys/capability.h was not found, support for libcap will not be built])] + )], + [AC_MSG_WARN([libcap library was not found or not usable, support for libcap will not be built])]) + ]) +AC_SUBST([LIB_CAP]) + AC_FUNC_FORK optional_bin_progs= diff --git a/src/Makefile.am b/src/Makefile.am index 65b20a2..41e3273 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -101,15 +101,15 @@ __LDADD = $(LDADD) $(LIB_EACCESS) # for clock_gettime and fdatasync dd_LDADD = $(LDADD) $(LIB_GETHRXTIME) $(LIB_FDATASYNC) -dir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) +dir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP) id_LDADD = $(LDADD) $(LIB_SELINUX) -ls_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) +ls_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP) mktemp_LDADD = $(LDADD) $(LIB_GETHRXTIME) pr_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) shred_LDADD = $(LDADD) $(LIB_GETHRXTIME) $(LIB_FDATASYNC) shuf_LDADD = $(LDADD) $(LIB_GETHRXTIME) tac_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) -vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) +vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP) ## If necessary, add -lm to resolve use of pow in lib/strtod.c. sort_LDADD = $(LDADD) $(POW_LIB) $(LIB_GETHRXTIME) diff --git a/src/ls.c b/src/ls.c index 4b69f7d..0a0f7eb 100644 --- a/src/ls.c +++ b/src/ls.c @@ -38,6 +38,10 @@ #include #include +#ifdef HAVE_CAP +# include +#endif + #if HAVE_TERMIOS_H # include #endif @@ -513,14 +517,14 @@ enum indicator_no C_LEFT, C_RIGHT, C_END, C_RESET, C_NORM, C_FILE, C_DIR, C_LINK, C_FIFO, C_SOCK, C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_DOOR, C_SETUID, C_SETGID, - C_STICKY, C_OTHER_WRITABLE, C_STICKY_OTHER_WRITABLE + C_STICKY, C_OTHER_WRITABLE, C_STICKY_OTHER_WRITABLE, C_CAP }; static const char *const indicator_name[]= { "lc", "rc", "ec", "rs", "no", "fi", "di", "ln", "pi", "so", "bd", "cd", "mi", "or", "ex", "do", "su", "sg", "st", - "ow", "tw", NULL + "ow", "tw", "ca", NULL }; struct color_ext_type @@ -553,6 +557,7 @@ static struct bin_str color_indicator[] = { LEN_STR_PAIR ("37;44") }, /* st: sticky: black on blue */ { LEN_STR_PAIR ("34;42") }, /* ow: other-writable: blue on green */ { LEN_STR_PAIR ("30;42") }, /* tw: ow w/ sticky: black on green */ + { LEN_STR_PAIR ("30;41") }, /* capability: black on red */ }; /* FIXME: comment */ @@ -3896,6 +3901,41 @@ print_type_indicator (bool stat_ok, mode_t mode, enum filetype type) DIRED_PUTCHAR (c); } +#ifdef HAVE_CAP +static bool +/* Return true if NAME has a capability (see linux/capability.h) */ +has_capability (const char *name) +{ + cap_t cap_d; + char *result; + bool has_cap; + + cap_d = cap_get_file (name); + if (cap_d == NULL) + return false; + + result = cap_to_text (cap_d, NULL); + if (!result) + { + cap_free (cap_d); + return false; + } + + /* check if human-readable capability string is empty */ + has_cap = !!*result; + + cap_free (cap_d); + cap_free (result); + return has_cap; +} +#else +static bool +has_capability (const char *name) +{ + return false; +} +#endif + /* Returns whether any color sequence was printed. */ static bool print_color_indicator (const char *name, mode_t mode, int linkok, @@ -3923,6 +3963,8 @@ print_color_indicator (const char *name, mode_t mode, int linkok, type = C_SETUID; else if ((mode & S_ISGID) != 0) type = C_SETGID; + else if (has_capability (name)) + type = C_CAP; else if ((mode & S_IXUGO) != 0) type = C_EXEC; } -- 1.5.4.1