From 7634188624dc7f48c047b29fab3715dc7a468059 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 23 Jul 2008 09:52:05 +0200 Subject: [PATCH] ls: --color now highlights files with capabilities, too * configure.ac: New option: --disable-libcap. Check for libcap usability. * src/Makefile.am (dir_LDADD, ls_LDADD, ...): Append $(LIB_CAP). * src/ls.c: [HAVE_CAP] Include . (has_capability): New function for capability detection. (print_color_indicator): Colorize file with capability. * src/dircolors.c: Update color lists. * src/dircolors.hin: Mention new CAPABILITY color attribute. * tests/ls/capability: Test for ls - colorize file with capability. * tests/Makefile.am (TESTS): Add ls/capability. * NEWS: Mention the change. --- NEWS | 2 ++ configure.ac | 13 +++++++++++++ src/Makefile.am | 6 +++--- src/dircolors.c | 4 ++-- src/dircolors.hin | 1 + src/ls.c | 43 +++++++++++++++++++++++++++++++++++++++++-- tests/Makefile.am | 1 + tests/ls/capability | 43 +++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 106 insertions(+), 7 deletions(-) create mode 100755 tests/ls/capability diff -ruN coreutils-6.12.old/configure.ac coreutils-6.12/configure.ac --- coreutils-6.12.old/configure.ac 2008-07-24 14:16:32.000000000 +0200 +++ coreutils-6.12/configure.ac 2008-07-24 14:18:51.000000000 +0200 @@ -58,6 +58,19 @@ LIB_SELINUX="-lselinux" AC_SUBST(LIB_SELINUX)]) +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 -ruN coreutils-6.12.orig/src/Makefile.am coreutils-6.12/src/Makefile.am --- coreutils-6.12.orig/src/Makefile.am 2008-07-10 12:30:03.000000000 +0200 +++ coreutils-6.12/src/Makefile.am 2008-07-24 13:18:43.000000000 +0200 @@ -98,15 +98,15 @@ # 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) tac_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) ## If necessary, add -lm to resolve use of pow in lib/strtod.c. diff --git a/src/dircolors.c b/src/dircolors.c index 56194f7..79109b9 100644 --- a/src/dircolors.c +++ b/src/dircolors.c @@ -63,14 +63,14 @@ static const char *const slack_codes[] = "SYMLINK", "ORPHAN", "MISSING", "FIFO", "PIPE", "SOCK", "BLK", "BLOCK", "CHR", "CHAR", "DOOR", "EXEC", "LEFT", "LEFTCODE", "RIGHT", "RIGHTCODE", "END", "ENDCODE", "SUID", "SETUID", "SGID", "SETGID", "STICKY", - "OTHER_WRITABLE", "OWR", "STICKY_OTHER_WRITABLE", "OWT", NULL + "OTHER_WRITABLE", "OWR", "STICKY_OTHER_WRITABLE", "OWT", "CAPABILITY", NULL }; static const char *const ls_codes[] = { "no", "no", "fi", "rs", "di", "ln", "ln", "ln", "or", "mi", "pi", "pi", "so", "bd", "bd", "cd", "cd", "do", "ex", "lc", "lc", "rc", "rc", "ec", "ec", - "su", "su", "sg", "sg", "st", "ow", "ow", "tw", "tw", NULL + "su", "su", "sg", "sg", "st", "ow", "ow", "tw", "tw", "ca", NULL }; #define array_len(Array) (sizeof (Array) / sizeof *(Array)) verify (array_len (slack_codes) == array_len (ls_codes)); diff --git a/src/dircolors.hin b/src/dircolors.hin index 38914c8..5137cc6 100644 --- a/src/dircolors.hin +++ b/src/dircolors.hin @@ -77,6 +77,7 @@ CHR 40;33;01 # character device driver ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) +CAPABILITY 30;41 # file with capability STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w) OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable diff --git a/src/ls.c b/src/ls.c index 4b69f7d..9bc66a1 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,38 @@ 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); + cap_free (cap_d); + if (!result) + return false; + + /* check if human-readable capability string is empty */ + has_cap = !!*result; + + 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 +3960,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; } diff --git a/tests/Makefile.am b/tests/Makefile.am index c2da630..309d174 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -313,6 +313,7 @@ TESTS = \ ln/misc \ ln/sf-1 \ ln/target-1 \ + ls/capability \ ls/color-dtype-dir \ ls/dangle \ ls/dired \ diff --git a/tests/ls/capability b/tests/ls/capability new file mode 100755 index 0000000..549e06b --- /dev/null +++ b/tests/ls/capability @@ -0,0 +1,43 @@ +#!/bin/sh +# Ensure "ls --color" properly colorizes file with capability. + +# Copyright (C) 2008 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +if test "$VERBOSE" = yes; then + set -x + ls --version +fi + +. $srcdir/test-lib.sh +require_root_ + +(setcap --help) 2>&1 |grep 'usage: setcap' > /dev/null \ + || skip_test_ "setcap utility not found" +fail=0 + +# Don't let a different umask perturb the results. +umask 22 + +touch test +setcap cap_net_bind_service=ep test \ + || framework_failure +code='30;41' +LS_COLORS="ca=$code" \ + ls --color=always test > out || fail=1 +printf "\033[0m\033[${code}mtest\033[0m\n\033[m" > out_ok || fail=1 +compare out out_ok || fail=1 + +(exit $fail); exit $fail -- 1.5.4.1