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 
21 static int verbose = 0;
22 static int recursive = 0;
23 
usage(void)24 static 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 
do_getcap(const char * fname,const struct stat * stbuf,int tflag,struct FTW * ftwbuf)34 static 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 
main(int argc,char ** argv)73 int 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