aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaiGai Kohei <kaigai@ak.jp.nec.com>2007-11-16 20:54:06 -0800
committerAndrew Morgan <morgan@kernel.org>2007-11-16 20:54:06 -0800
commit7fc5f38e2156201580bab15b22fa581b42f5da91 (patch)
treeb9bb621aa73748c9bfe38bedeea9ad559f15cd8f
parent35239032791848824244f7a01d3ee5f788469fc4 (diff)
downloadlibcap-7fc5f38e2156201580bab15b22fa581b42f5da91.tar.gz
The following patch to libcap enables to display file capabilities
recursively on the enumerated directories when -r is specified. In addition, some other features are ported from my getfcap. When an entry contains no file-capabilities, displaying it will be skipped without returning an error. However, -v option enables to display those filenames with no capabilities. -h options displays short usage message. Please consider to apply it on your tree. EXAMPLE: [kaigai@saba libcap]$ ./progs/getcap -r /tmp /tmp/ping = cap_net_raw+ep [kaigai@saba libcap]$ Thanks, -- OSS Platform Development Division, NEC KaiGai Kohei <kaigai@ak.jp.nec.com>
-rw-r--r--doc/getcap.814
-rw-r--r--progs/getcap.c101
2 files changed, 96 insertions, 19 deletions
diff --git a/doc/getcap.8 b/doc/getcap.8
index a0e2c41..9ed5c33 100644
--- a/doc/getcap.8
+++ b/doc/getcap.8
@@ -2,14 +2,24 @@
.\" $Id: getcap.8,v 1.1.1.1 1999/04/17 22:16:31 morgan Exp $
.\" written by Andrew Main <zefram@dcs.warwick.ac.uk>
.\"
-.TH GETCAP 8 "26th April 1997"
+.TH GETCAP 8 "12 Nov 2007"
.SH NAME
getcap \- examine file capabilities
.SH SYNOPSIS
-\fBgetcap\fP \fIfilename\fP [ ... ]
+\fBgetcap\fP [-v] [-r] [-h] \fIfilename\fP [ ... ]
.SH DESCRIPTION
.B getcap
displays the name and capabilities of each specified
+.SH OPTIONS
+.TP 4
+.B -r
+enables recursive search.
+.TP 4
+.B -v
+enables to display all searched entries, even if it has no file-capabilities.
+.TP 4
+.B -h
+prints quick usage.
.IR filename .
One file per line.
.SH "SEE ALSO"
diff --git a/progs/getcap.c b/progs/getcap.c
index 1fbf5d2..a1daa30 100644
--- a/progs/getcap.c
+++ b/progs/getcap.c
@@ -8,45 +8,112 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include <sys/capability.h>
+static int verbose = 0;
+static int recursive = 0;
+
static void usage(void)
{
fprintf(stderr,
- "usage: getcap <filename> [<filename> ...]\n"
+ "usage: getcap [-v] [-r] [-h] <filename> [<filename> ...]\n"
"\n"
"\tdisplays the capabilities on the queried file(s).\n"
);
exit(1);
}
-int main(int argc, char **argv)
+static void do_recursive(const char *fname);
+
+static void do_getcap(const char *fname)
{
- char *result=NULL;
+ cap_t cap_d;
+ char *result;
- if (argc < 2) {
- usage();
+ cap_d = cap_get_file(fname);
+ if (cap_d == NULL) {
+ if (errno != ENODATA) {
+ fprintf(stderr, "Failed to get capabilities of file `%s' (%s)\n",
+ fname, strerror(errno));
+ } else if (verbose) {
+ printf("%s\n", fname);
+ }
+ goto out;
}
- for ( ++argv; --argc > 0; ++argv ) {
- ssize_t length;
- cap_t cap_d;
+ result = cap_to_text(cap_d, NULL);
+ if (!result) {
+ fprintf(stderr,
+ "Failed to get capabilities of human readable format at `%s' (%s)\n",
+ fname, strerror(errno));
+ cap_free(cap_d);
+ return;
+ }
+ printf("%s %s\n", fname, result);
+ cap_free(cap_d);
+ cap_free(result);
- cap_d = cap_get_file(argv[0]);
+ out:
+ if (recursive) {
+ struct stat stbuf;
- if (cap_d == NULL) {
- fprintf(stderr, "Failed to get capabilities for file `%s' (%s)\n",
- argv[0], strerror(errno));
- continue;
+ if (stat(fname, &stbuf)) {
+ fprintf(stderr, "Failed to get attribute of file `%s' (%s)\n",
+ fname, strerror(errno));
+ } else if (S_ISDIR(stbuf.st_mode)) {
+ do_recursive(fname);
}
+ }
+}
+
+static void do_recursive(const char *fname)
+{
+ DIR *dirp;
+ struct dirent *dent;
+ char buffer[PATH_MAX];
- result = cap_to_text(cap_d, &length);
+ dirp = opendir(fname);
+ if (dirp == NULL) {
+ fprintf(stderr, "Failed to open directory `%s' (%s)\n",
+ fname, strerror(errno));
+ return;
+ }
- printf("%s: %s\n", *argv, result);
+ while ((dent = readdir(dirp)) != NULL) {
+ if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
+ continue;
+ snprintf(buffer, PATH_MAX, "%s/%s", fname, dent->d_name);
+ do_getcap(buffer);
+ }
+ closedir(dirp);
+}
- cap_free(result);
- cap_free(cap_d);
+int main(int argc, char **argv)
+{
+ int i, c;
+
+ while ((c = getopt(argc, argv, "rvh")) > 0) {
+ switch(c) {
+ case 'r':
+ recursive = 1;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ default:
+ usage();
+ }
}
+ if (!argv[optind])
+ usage();
+
+ for (i=optind; argv[i] != NULL; i++)
+ do_getcap(argv[i]);
+
return 0;
}