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