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