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