Thank you for patience. I have made improvements you suggested.

On Saturday 19 July 2008 06:16:20 pm you wrote:
> Thanks for working on this.
> Sounds worthwhile, though maybe worth
> giving it a separate attribute rather than
> sharing the one currently used for set-user-ID programs.
Ok, added new color indicator for file with capability.

> Have you considered enabling it by default, when the library is usable?
Now enabled by default, can be disabled by --disable-libcap configure option.

> It's better to use AC_HELP_STRING:
Ok, now using AC_HELP_STRING for configure help.

> Re LIB_CAP2,
> if you don't embed the library version number in the symbol name,
> then we won't have to change it when libcap3 comes along.
Ok, renamed to LIB_CAP (and HAVE_CAP).

> Use underscores, (i.e., has_capability, has_cap), not mixed case.
Sorry for that - now using underscores.

> > +    cap_free(cap_d);
>
> Move this cap_free call "up".  Then you can remove
> the repeated call below.
>
> > +    return false;
> > +  }
> > +
> > +  /* check if human-readable capability string is empty */
> > +  hasCap = *result;
I am not sure about this change. libcap API is not well documented, so I 
decided to take code directly from getcap.c(do_getcap) - this utility is 
already tested by users. In other case I am afraid of possible premature free 
of libcap resource.

> I seem to recall that this idiom is slightly better
> from a portability standpoint, e.g., when bool is simulated
> with an 8-bit type:
>
>     hasCap = !!*result;
Ok, fixed.

> Remove these in-function #ifdefs.
> Instead, define has_capability to return false when the library
> is not available.
Ok, no problem.

Kamil
From a0a2366af69016adeecb3db86ebfa5bba7c93952 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <[EMAIL PROTECTED]>
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 <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,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

_______________________________________________
Bug-coreutils mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-coreutils

Reply via email to