static void do_caps(capng_type_t type, const char *caps) { char *my_caps = xstrdup(caps); char *c; while ((c = strsep(&my_caps, ","))) { capng_act_t action; if (*c == '+') action = CAPNG_ADD; else if (*c == '-') action = CAPNG_DROP; else errx(EXIT_FAILURE, _("bad capability string")); if (!strcmp(c + 1, "all")) { int i; /* It would be really bad if -all didn't drop all * caps. It's better to just fail. */ if (real_cap_last_cap() > CAP_LAST_CAP) errx(SETPRIV_EXIT_PRIVERR, _("libcap-ng is too old for \"all\" caps")); for (i = 0; i <= CAP_LAST_CAP; i++) capng_update(action, type, i); } else { int cap = capng_name_to_capability(c + 1); if (0 <= cap) capng_update(action, type, cap); else errx(EXIT_FAILURE, _("unknown capability \"%s\""), c + 1); } } free(my_caps); }
/* Returns the number of capabilities printed. */ static int print_caps(FILE *f, enum cap_type which) { int i, n = 0, max = real_cap_last_cap(); for (i = 0; i <= max; i++) { int ret = has_cap(which, i); if (i == 0 && ret < 0) return -1; if (ret == 1) { const char *name = capng_capability_to_name(i); if (n) fputc(',', f); if (name) fputs(name, f); else /* cap-ng has very poor handling of * CAP_LAST_CAP changes. This is the * best we can do. */ printf("cap_%d", i); n++; } } return n; }
static void list_known_caps(void) { int i, max = real_cap_last_cap(); for (i = 0; i <= max; i++) { const char *name = capng_capability_to_name(i); if (name) printf("%s\n", name); else warnx(_("cap %d: libcap-ng is broken"), i); } }