diff options
author | Lukas Kuklinek <lkukline@redhat.com> | 2008-11-20 22:19:30 -0800 |
---|---|---|
committer | Andrew G. Morgan <morgan@kernel.org> | 2008-11-20 22:19:30 -0800 |
commit | a88ab3ba8f68c888f8df679b028498e7131ee2ff (patch) | |
tree | ee00b5a0c89be3100db87543c52aa098f50f0855 | |
parent | f4e983641cf3b07e917eeaa82351533ef37e3c1f (diff) | |
download | libcap2-a88ab3ba8f68c888f8df679b028498e7131ee2ff.tar.gz |
Fix getcap utility in recursive modelibcap-2.15
When scanning filesystem subtree with symbolic links to parent
directories the old code would get into an infinite loop. This fixes
the code to not follow symbolic links.
Relevant bugzilla entry:
https://bugzilla.redhat.com/show_bug.cgi?id=454987
[Ed., Minor style modifications by Andrew]
Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
-rw-r--r-- | progs/getcap.c | 69 |
1 files changed, 29 insertions, 40 deletions
diff --git a/progs/getcap.c b/progs/getcap.c index a1daa30..f6debc0 100644 --- a/progs/getcap.c +++ b/progs/getcap.c @@ -4,6 +4,8 @@ * This displays the capabilities of a given file. */ +#define _XOPEN_SOURCE 500 + #include <errno.h> #include <stdio.h> #include <string.h> @@ -14,6 +16,8 @@ #include <sys/types.h> #include <sys/capability.h> +#include <ftw.h> + static int verbose = 0; static int recursive = 0; @@ -27,13 +31,19 @@ static void usage(void) exit(1); } -static void do_recursive(const char *fname); - -static void do_getcap(const char *fname) +static int do_getcap(const char *fname, const struct stat *stbuf, + int tflag, struct FTW* ftwbuf) { cap_t cap_d; char *result; + if (tflag != FTW_F) { + if (verbose) { + printf("%s (Not a regular file)\n", fname); + } + return 0; + } + cap_d = cap_get_file(fname); if (cap_d == NULL) { if (errno != ENODATA) { @@ -42,7 +52,7 @@ static void do_getcap(const char *fname) } else if (verbose) { printf("%s\n", fname); } - goto out; + return 0; } result = cap_to_text(cap_d, NULL); @@ -51,45 +61,13 @@ static void do_getcap(const char *fname) "Failed to get capabilities of human readable format at `%s' (%s)\n", fname, strerror(errno)); cap_free(cap_d); - return; + return 0; } printf("%s %s\n", fname, result); cap_free(cap_d); cap_free(result); - out: - if (recursive) { - struct stat stbuf; - - 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]; - - dirp = opendir(fname); - if (dirp == NULL) { - fprintf(stderr, "Failed to open directory `%s' (%s)\n", - fname, strerror(errno)); - return; - } - - 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); + return 0; } int main(int argc, char **argv) @@ -112,8 +90,19 @@ int main(int argc, char **argv) if (!argv[optind]) usage(); - for (i=optind; argv[i] != NULL; i++) - do_getcap(argv[i]); + for (i=optind; argv[i] != NULL; i++) { + struct stat stbuf; + + if (lstat(argv[i], &stbuf) != 0) { + fprintf(stderr, "%s (%s)\n", argv[i], strerror(errno)); + } else if (recursive) { + nftw(argv[i], do_getcap, 20, FTW_PHYS); + } else { + int tflag = S_ISREG(stbuf.st_mode) ? FTW_F : + (S_ISLNK(stbuf.st_mode) ? FTW_SL : FTW_NS); + do_getcap(argv[i], &stbuf, tflag, 0); + } + } return 0; } |