diff options
author | KaiGai Kohei <kaigai@ak.jp.nec.com> | 2007-11-16 20:54:06 -0800 |
---|---|---|
committer | Andrew Morgan <morgan@kernel.org> | 2007-11-16 20:54:06 -0800 |
commit | 7fc5f38e2156201580bab15b22fa581b42f5da91 (patch) | |
tree | b9bb621aa73748c9bfe38bedeea9ad559f15cd8f | |
parent | 35239032791848824244f7a01d3ee5f788469fc4 (diff) | |
download | libcap-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.8 | 14 | ||||
-rw-r--r-- | progs/getcap.c | 101 |
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; } |