xref: /aosp_15_r20/external/libcap/progs/getpcaps.c (revision 2810ac1b38eead2603277920c78344c84ddf3aff)
1*2810ac1bSKiyoung Kim /*
2*2810ac1bSKiyoung Kim  * Copyright (c) 1997-8,2007-8,19,21-22 Andrew G. Morgan  <[email protected]>
3*2810ac1bSKiyoung Kim  *
4*2810ac1bSKiyoung Kim  * This displays the capabilities of given target process(es).
5*2810ac1bSKiyoung Kim  */
6*2810ac1bSKiyoung Kim 
7*2810ac1bSKiyoung Kim #include <sys/types.h>
8*2810ac1bSKiyoung Kim #include <errno.h>
9*2810ac1bSKiyoung Kim #include <stdio.h>
10*2810ac1bSKiyoung Kim #include <string.h>
11*2810ac1bSKiyoung Kim #include <stdlib.h>
12*2810ac1bSKiyoung Kim #include <sys/capability.h>
13*2810ac1bSKiyoung Kim 
usage(int code)14*2810ac1bSKiyoung Kim static void usage(int code)
15*2810ac1bSKiyoung Kim {
16*2810ac1bSKiyoung Kim     fprintf(stderr,
17*2810ac1bSKiyoung Kim "usage: getcaps [opts] <pid> [<pid> ...]\n\n"
18*2810ac1bSKiyoung Kim "  This program displays the capabilities on the queried process(es).\n"
19*2810ac1bSKiyoung Kim 	    "  The capabilities are displayed in the cap_from_text(3) format.\n"
20*2810ac1bSKiyoung Kim 	    "\n"
21*2810ac1bSKiyoung Kim 	    "  Optional arguments:\n"
22*2810ac1bSKiyoung Kim 	    "     --help, -h or --usage display this message.\n"
23*2810ac1bSKiyoung Kim 	    "     --verbose             use a more verbose output format.\n"
24*2810ac1bSKiyoung Kim 	    "     --ugly or --legacy    use the archaic legacy output format.\n"
25*2810ac1bSKiyoung Kim 	    "     --iab                 show IAB of process too.\n"
26*2810ac1bSKiyoung Kim 	    "     --license             display license info\n");
27*2810ac1bSKiyoung Kim     exit(code);
28*2810ac1bSKiyoung Kim }
29*2810ac1bSKiyoung Kim 
main(int argc,char ** argv)30*2810ac1bSKiyoung Kim int main(int argc, char **argv)
31*2810ac1bSKiyoung Kim {
32*2810ac1bSKiyoung Kim     int retval = 0;
33*2810ac1bSKiyoung Kim     int verbose = 0;
34*2810ac1bSKiyoung Kim     int iab = 0;
35*2810ac1bSKiyoung Kim     cap_iab_t noiab = cap_iab_init();
36*2810ac1bSKiyoung Kim 
37*2810ac1bSKiyoung Kim     if (argc < 2) {
38*2810ac1bSKiyoung Kim 	usage(1);
39*2810ac1bSKiyoung Kim     }
40*2810ac1bSKiyoung Kim 
41*2810ac1bSKiyoung Kim     for (++argv; --argc > 0; ++argv) {
42*2810ac1bSKiyoung Kim 	long lpid;
43*2810ac1bSKiyoung Kim 	int pid;
44*2810ac1bSKiyoung Kim 	char *endarg;
45*2810ac1bSKiyoung Kim 	cap_t cap_d;
46*2810ac1bSKiyoung Kim 	const char *arg = *argv;
47*2810ac1bSKiyoung Kim 
48*2810ac1bSKiyoung Kim 	if (!strcmp(arg, "--help") || !strcmp(arg, "--usage") ||
49*2810ac1bSKiyoung Kim 	    !strcmp(arg, "-h")) {
50*2810ac1bSKiyoung Kim 	    usage(0);
51*2810ac1bSKiyoung Kim 	} else if (!strcmp(arg, "--license")) {
52*2810ac1bSKiyoung Kim 	    printf("%s see LICENSE file for details.\n"
53*2810ac1bSKiyoung Kim 		   "[Copyright (c) 1997-8,2007-8,19,21-22"
54*2810ac1bSKiyoung Kim 		   " Andrew G. Morgan <[email protected]>]\n",
55*2810ac1bSKiyoung Kim 		   arg);
56*2810ac1bSKiyoung Kim 	    exit(0);
57*2810ac1bSKiyoung Kim 	} else if (!strcmp(arg, "--verbose")) {
58*2810ac1bSKiyoung Kim 	    verbose = 1;
59*2810ac1bSKiyoung Kim 	    continue;
60*2810ac1bSKiyoung Kim 	} else if (!strcmp(arg, "--ugly") || !strcmp(arg, "--legacy")) {
61*2810ac1bSKiyoung Kim 	    verbose = 2;
62*2810ac1bSKiyoung Kim 	    continue;
63*2810ac1bSKiyoung Kim 	} else if (!strcmp(arg, "--iab")) {
64*2810ac1bSKiyoung Kim 	    iab = 1;
65*2810ac1bSKiyoung Kim 	    continue;
66*2810ac1bSKiyoung Kim 	}
67*2810ac1bSKiyoung Kim 
68*2810ac1bSKiyoung Kim 	errno = 0;
69*2810ac1bSKiyoung Kim 	lpid = strtol(arg, &endarg, 10);
70*2810ac1bSKiyoung Kim 	if (errno == 0) {
71*2810ac1bSKiyoung Kim 	    if (*endarg != '\0') {
72*2810ac1bSKiyoung Kim 		errno = EINVAL;
73*2810ac1bSKiyoung Kim 	    } else if (lpid < 0 || lpid != (pid_t) lpid) {
74*2810ac1bSKiyoung Kim 		errno = EOVERFLOW;
75*2810ac1bSKiyoung Kim 	    }
76*2810ac1bSKiyoung Kim 	}
77*2810ac1bSKiyoung Kim 	if (errno != 0) {
78*2810ac1bSKiyoung Kim 	    fprintf(stderr, "Cannot parse pid %s: (%s)\n", arg, strerror(errno));
79*2810ac1bSKiyoung Kim 	    retval = 1;
80*2810ac1bSKiyoung Kim 	    continue;
81*2810ac1bSKiyoung Kim 	}
82*2810ac1bSKiyoung Kim 	pid = lpid;
83*2810ac1bSKiyoung Kim 
84*2810ac1bSKiyoung Kim 	cap_d = cap_get_pid(pid);
85*2810ac1bSKiyoung Kim 	if (cap_d == NULL) {
86*2810ac1bSKiyoung Kim 		fprintf(stderr, "Failed to get cap's for process %d:"
87*2810ac1bSKiyoung Kim 			" (%s)\n", pid, strerror(errno));
88*2810ac1bSKiyoung Kim 		retval = 1;
89*2810ac1bSKiyoung Kim 		continue;
90*2810ac1bSKiyoung Kim 	}
91*2810ac1bSKiyoung Kim 
92*2810ac1bSKiyoung Kim 	char *result = cap_to_text(cap_d, NULL);
93*2810ac1bSKiyoung Kim 	if (iab) {
94*2810ac1bSKiyoung Kim 	    printf("%s:", arg);
95*2810ac1bSKiyoung Kim 	    if (verbose || strcmp("=", result) != 0) {
96*2810ac1bSKiyoung Kim 		printf(" \"%s\"", result);
97*2810ac1bSKiyoung Kim 	    }
98*2810ac1bSKiyoung Kim 	    cap_iab_t iab_val = cap_iab_get_pid(pid);
99*2810ac1bSKiyoung Kim 	    if (iab_val == NULL) {
100*2810ac1bSKiyoung Kim 		fprintf(stderr, " no IAB value for %d\n", pid);
101*2810ac1bSKiyoung Kim 		exit(1);
102*2810ac1bSKiyoung Kim 	    }
103*2810ac1bSKiyoung Kim 	    int cf = cap_iab_compare(noiab, iab_val);
104*2810ac1bSKiyoung Kim 	    if (verbose ||
105*2810ac1bSKiyoung Kim 		CAP_IAB_DIFFERS(cf, CAP_IAB_AMB) ||
106*2810ac1bSKiyoung Kim 		CAP_IAB_DIFFERS(cf, CAP_IAB_BOUND)) {
107*2810ac1bSKiyoung Kim 		char *iab_text = cap_iab_to_text(iab_val);
108*2810ac1bSKiyoung Kim 		if (iab_text == NULL) {
109*2810ac1bSKiyoung Kim 		    perror(" no text for IAB");
110*2810ac1bSKiyoung Kim 		    exit(1);
111*2810ac1bSKiyoung Kim 		}
112*2810ac1bSKiyoung Kim 		printf(" [%s]", iab_text);
113*2810ac1bSKiyoung Kim 		cap_free(iab_text);
114*2810ac1bSKiyoung Kim 	    }
115*2810ac1bSKiyoung Kim 	    cap_free(iab_val);
116*2810ac1bSKiyoung Kim 	    printf("\n");
117*2810ac1bSKiyoung Kim 	} else if (verbose == 1) {
118*2810ac1bSKiyoung Kim 	    printf("Capabilities for '%s': %s\n", arg, result);
119*2810ac1bSKiyoung Kim 	} else if (verbose == 2) {
120*2810ac1bSKiyoung Kim 	    fprintf(stderr, "Capabilities for `%s': %s\n", arg, result);
121*2810ac1bSKiyoung Kim 	} else {
122*2810ac1bSKiyoung Kim 	    printf("%s: %s\n", arg, result);
123*2810ac1bSKiyoung Kim 	}
124*2810ac1bSKiyoung Kim 
125*2810ac1bSKiyoung Kim 	cap_free(result);
126*2810ac1bSKiyoung Kim 	result = NULL;
127*2810ac1bSKiyoung Kim 	cap_free(cap_d);
128*2810ac1bSKiyoung Kim     }
129*2810ac1bSKiyoung Kim 
130*2810ac1bSKiyoung Kim     return retval;
131*2810ac1bSKiyoung Kim }
132