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