#include <sys/types.h>
#include <sys/caps.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
__SYSCAP_ALLSTRINGS;
static void printallcaps(void);
static void listcaps(void);
int
main(int ac, char **av)
{
int quietopt = 0;
int c;
int i;
int j;
int estatus = 0;
int noargs = 1;
while ((c = getopt(ac, av, "plqh")) != -1) {
noargs = 0;
switch(c) {
case 'p':
printallcaps();
break;
case 'l':
listcaps();
break;
case 'q':
quietopt = 1;
break;
case 'h':
default:
if (c != 'h')
fprintf(stderr, "Bad option: -%c\n", c);
fprintf(stderr, "setcaps [-p] [-l] caps...\n");
fprintf(stderr, " -p - list available caps\n");
fprintf(stderr, " -l - list current caps\n");
fprintf(stderr, " -q - ignore unknown caps\n");
fprintf(stderr, " caps[:es] - set specific flags\n");
fprintf(stderr, " If no args, current caps are "
"listed\n");
if (c != 'h')
exit(1);
exit(0);
}
}
ac -= optind;
av += optind;
for (j = 0; j < ac; ++j) {
char *which;
char *scan;
int res;
int flags = __SYSCAP_SELF | __SYSCAP_EXEC;
int found = 0;
noargs = 0;
which = av[j];
if ((scan = strchr(which, ':')) != NULL) {
*scan++ = 0;
flags = 0;
while (*scan) {
switch (*scan) {
case 's':
flags |= __SYSCAP_SELF;
break;
case 'e':
flags |= __SYSCAP_EXEC;
break;
default:
fprintf(stderr, "unknown flag %s:%c\n",
which, *scan);
break;
}
++scan;
}
}
for (i = 0; i < __SYSCAP_COUNT; ++i) {
const char *ptr;
ptr = SyscapAllStrings[i / 16][i & 15];
if (ptr == NULL || strcmp(ptr, which) != 0)
continue;
found = 1;
res = syscap_set(i | __SYSCAP_INPARENT, flags, NULL, 0);
if (res < 0) {
fprintf(stderr, "%s: %s\n",
which, strerror(errno));
estatus = 1;
} else {
printf("%s: ", which);
if (res & __SYSCAP_EXEC)
printf(" on-exec");
if (res & __SYSCAP_SELF)
printf(" on-self");
printf("\n");
}
}
if (found == 0 && quietopt == 0) {
printf("%s: not-found\n", which);
}
}
if (noargs)
listcaps();
return estatus;
}
static void
printallcaps(void)
{
const char *ptr;
int i;
for (i = 0; i < __SYSCAP_COUNT; ++i) {
if ((ptr = SyscapAllStrings[i / 16][i & 15]) != NULL) {
printf("0x%04x %s\n", i, ptr);
}
}
}
static void
listcaps(void)
{
int i;
for (i = 0; i < __SYSCAP_COUNT; ++i) {
const char *ptr;
int res;
res = syscap_get(i | __SYSCAP_INPARENT, NULL, 0);
if (res < 0)
break;
if (res) {
if ((ptr = SyscapAllStrings[i / 16][i & 15]) != NULL) {
printf("%-15s", ptr);
} else {
printf("0x%04x ", res);
}
if (res & __SYSCAP_EXEC)
printf(" on-exec");
if (res & __SYSCAP_SELF)
printf(" on-self");
printf("\n");
}
}
}