1/* 2 * Copyright (c) 1997,2007 Andrew G. Morgan <morgan@kernel.org> 3 * 4 * This displays the capabilities of a given file. 5 */ 6 7#define _XOPEN_SOURCE 500 8 9#include <errno.h> 10#include <stdio.h> 11#include <string.h> 12#include <stdlib.h> 13#include <unistd.h> 14#include <dirent.h> 15#include <sys/stat.h> 16#include <sys/types.h> 17#include <sys/capability.h> 18 19#include <ftw.h> 20 21static int verbose = 0; 22static int recursive = 0; 23 24static void usage(void) 25{ 26 fprintf(stderr, 27 "usage: getcap [-v] [-r] [-h] <filename> [<filename> ...]\n" 28 "\n" 29 "\tdisplays the capabilities on the queried file(s).\n" 30 ); 31 exit(1); 32} 33 34static int do_getcap(const char *fname, const struct stat *stbuf, 35 int tflag, struct FTW* ftwbuf) 36{ 37 cap_t cap_d; 38 char *result; 39 40 if (tflag != FTW_F) { 41 if (verbose) { 42 printf("%s (Not a regular file)\n", fname); 43 } 44 return 0; 45 } 46 47 cap_d = cap_get_file(fname); 48 if (cap_d == NULL) { 49 if (errno != ENODATA) { 50 fprintf(stderr, "Failed to get capabilities of file `%s' (%s)\n", 51 fname, strerror(errno)); 52 } else if (verbose) { 53 printf("%s\n", fname); 54 } 55 return 0; 56 } 57 58 result = cap_to_text(cap_d, NULL); 59 if (!result) { 60 fprintf(stderr, 61 "Failed to get capabilities of human readable format at `%s' (%s)\n", 62 fname, strerror(errno)); 63 cap_free(cap_d); 64 return 0; 65 } 66 printf("%s %s\n", fname, result); 67 cap_free(cap_d); 68 cap_free(result); 69 70 return 0; 71} 72 73int main(int argc, char **argv) 74{ 75 int i, c; 76 77 while ((c = getopt(argc, argv, "rvh")) > 0) { 78 switch(c) { 79 case 'r': 80 recursive = 1; 81 break; 82 case 'v': 83 verbose = 1; 84 break; 85 default: 86 usage(); 87 } 88 } 89 90 if (!argv[optind]) 91 usage(); 92 93 for (i=optind; argv[i] != NULL; i++) { 94 struct stat stbuf; 95 96 if (lstat(argv[i], &stbuf) != 0) { 97 fprintf(stderr, "%s (%s)\n", argv[i], strerror(errno)); 98 } else if (recursive) { 99 nftw(argv[i], do_getcap, 20, FTW_PHYS); 100 } else { 101 int tflag = S_ISREG(stbuf.st_mode) ? FTW_F : 102 (S_ISLNK(stbuf.st_mode) ? FTW_SL : FTW_NS); 103 do_getcap(argv[i], &stbuf, tflag, 0); 104 } 105 } 106 107 return 0; 108} 109