On Monday 21 July 2008 17:43:52 you wrote:
> Kamil Dudka <[EMAIL PROTECTED]> wrote:
> Don't pessimize your code because doing it cleanly might not work.
> Have no fear ;-), and do it cleanly.
> The documentation ("man cap_to_text") appears to guarantee
> the required semantics, so it ought to work.
> If in doubt, test it with valgrind.
Ok, rewritten to do it cleanly...

> >  /* 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;
> >     }
Caused by mixing tabs and spaces in original code, which I didn't recognized 
at first glance. Fixed...

> Oops.  Mangled indentation.
> BTW, I noticed something similar in your dd patch.
> Do you use unusual TAB-stop settings?
I guess usual TAB-stop for coreutils is 8, noexpandtab - I am changing 
my .vimrc...

> Otherwise, so far, so good.  Whenever we add a new ls-color-related
> capability, the corresponding list in dircolors.c must be updated
> to match.  Otherwise, "make check-ls-dircolors" will fail.  Also,
> dircolors.hin must be updated to add a brief description.
Fixed, make check-ls-dircolors now passes...

> And of course, we'll need at least one test.
> To test it, you'll have to require a cap-related
> command-line tool (i.e., skip the test if it doesn't
> exist -- there are similar functions in test-lib.sh,
> e.g., require_strace_ and require_acl_), and then run
> LS_COLORS='...' ls --color=always file-with-cap > out
> and confirm that the expected (new) mark-up is present.
> See tests/ls/stat-free-symlinks for a similar test that
> runs ls with a custom LS_COLORS setting.
I have made new test ls/capability which need to be run under root - only root 
can set capability of file.

> And here you thought this would be simple.
Of course it was simple - that's why I am working on it ;-)

Kamil
From 4f14f5e39d7687ddb252f5a7560724179635c944 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <[EMAIL PROTECTED]>
Date: Tue, 22 Jul 2008 12:53:00 +0200
Subject: [PATCH] --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
 * src/dircolors.c: updated color lists
 * src/dircolors.hin: brief description of CAPABILITY color attribute
 (print_color_indicator): colorize file with capability
 * tests/Makefile.am: added new test ls/capability
 * tests/ls/capability: test for ls - colorize file with capability (root only)
 * NEWS: mentioned 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 100644 tests/ls/capability

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/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..b3aba38 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 <config.h>
 #include <sys/types.h>
 
+#ifdef HAVE_CAP
+# include <sys/capability.h>
+#endif
+
 #if HAVE_TERMIOS_H
 # include <termios.h>
 #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 100644
index 0000000..6d6fab1
--- /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 <http://www.gnu.org/licenses/>.
+
+if test "$VERBOSE" = yes; then
+  set -x
+  ls --version
+fi
+
+. $srcdir/test-lib.sh
+require_root_
+
+which 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 || \
+  skip_test_ "can't set capability"
+LS_COLORS='ca=30;41' \
+  ls --color=always test > out || fail=1
+printf "\033[0m\033[30;41mtest\033[0m\n\033[m" > out_ok
+diff out out_ok || fail=1
+
+rm -f test
+
+(exit $fail); exit $fail
-- 
1.5.4.1

_______________________________________________
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils

Reply via email to