Annotation of src/usr.bin/getcap/getcap.c, Revision 1.7
1.7 ! krw 1: /* $OpenBSD: getcap.c,v 1.6 2015/10/10 05:43:48 deraadt Exp $ */
1.1 millert 2:
3: /*
4: * Copyright (c) 2005 Todd C. Miller <Todd.Miller@courtesan.com>
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18:
19: #include <err.h>
20: #include <stdio.h>
21: #include <stdlib.h>
22: #include <string.h>
1.4 millert 23: #include <unistd.h>
1.1 millert 24:
25: enum captype {
26: boolean,
27: number,
28: string,
29: raw
30: };
31:
32: void lookup_cap(char *, char *, enum captype, int);
33: __dead void usage(void);
34:
35: int
36: main(int argc, char *argv[])
37: {
38: int ch, aflag;
39: enum captype type;
40: char *cp, *buf, *cap = NULL, **pathvec = NULL;
41: size_t n;
1.6 deraadt 42:
43: if (pledge("stdio rpath", NULL) == -1)
44: err(1, "pledge");
1.1 millert 45:
46: aflag = type = 0;
47: while ((ch = getopt(argc, argv, "ab:c:f:n:s:")) != -1) {
48: switch (ch) {
49: case 'a':
50: aflag = 1;
51: break;
52: case 'b':
53: if (*optarg == '\0')
54: usage();
55: cap = optarg;
56: type = boolean;
57: break;
58: case 'n':
59: if (*optarg == '\0')
60: usage();
61: cap = optarg;
62: type = number;
63: break;
64: case 's':
65: if (*optarg == '\0')
66: usage();
67: cap = optarg;
68: type = string;
69: break;
70: case 'c':
71: if (*optarg == '\0')
72: usage();
73: cap = optarg;
74: type = raw;
75: break;
76: case 'f':
77: if (pathvec != NULL)
78: errx(1, "only one -f option may be specified");
79: for (n = 1, cp = optarg; (cp = strchr(cp, ':')); n++)
80: continue;
81: pathvec = calloc(n + 1, sizeof(char *));
82: for (n = 0; (pathvec[n] = strsep(&optarg, ":"));) {
83: if (*pathvec[n] != '\0')
84: n++;
85: }
86: break;
87: default:
88: usage();
89: }
90: }
91: argc -= optind;
92: argv += optind;
93:
94: if (pathvec == NULL) {
95: warnx("no path specified");
96: usage();
97: }
98: if (!aflag && !argc) {
99: warnx("must specify -a or a record name");
100: usage();
101: }
102:
103: if (aflag) {
104: while (cgetnext(&buf, pathvec) > 0) {
105: lookup_cap(buf, cap, type, 1);
106: free(buf);
107: }
108: } else {
109: while (*argv != NULL) {
110: if (cgetent(&buf, pathvec, *argv) != 0)
111: errx(1, "unable to lookup %s", *argv); /* XXX */
112: lookup_cap(buf, cap, type, argc > 1);
113: free(buf);
114: argv++;
115: }
116: }
117: exit(0);
118: }
119:
120: void
121: lookup_cap(char *buf, char *cap, enum captype type, int useprefix)
122: {
123: char *cp, *endp;
124: long l;
125: int ch, n, prefixlen;
126:
127: if (cap == NULL) {
128: puts(buf);
129: return;
130: }
131:
132: prefixlen = useprefix ? strcspn(buf, "|:") : 0;
133:
134: switch (type) {
135: case boolean:
136: if (cgetcap(buf, cap, ':') == NULL)
137: return;
138: printf("%.*s%s%s\n", prefixlen, buf,
139: useprefix ? ": " : "", cap);
140: break;
141: case number:
142: if (cgetnum(buf, cap, &l) == -1)
143: return;
144: printf("%.*s%s%ld\n", prefixlen, buf,
145: useprefix ? ": " : "", l);
146: break;
147: case string:
148: if ((n = cgetstr(buf, cap, &cp)) == -1)
149: return;
150: else if (n == -2)
151: err(1, NULL); /* ENOMEM */
152: printf("%.*s%s%s\n", prefixlen, buf,
153: useprefix ? ": " : "", cp);
154: break;
155: case raw:
156: n = strlen(cap) - 1;
157: ch = cap[n];
158: cap[n] = '\0';
159: cp = cgetcap(buf, cap, ch);
160: cap[n] = ch;
161: if (cp != NULL) {
162: if ((endp = strchr(cp, ':')) != NULL)
163: printf("%.*s%s%.*s\n", prefixlen, buf,
1.7 ! krw 164: useprefix ? ": " : "", (int)(endp - cp),
! 165: cp);
1.1 millert 166: else
167: printf("%.*s%s%s\n", prefixlen, buf,
168: useprefix ? ": " : "", cp);
169: }
170: break;
171: }
172: }
173:
174: __dead void
175: usage(void)
176: {
177: extern char *__progname;
178:
1.5 schwarze 179: fprintf(stderr, "usage: %s [-b boolean | -c capability | "
180: "-n number | -s string] -f path\n"
181: " -a | record ...\n",
182: __progname);
1.1 millert 183: exit(1);
184: }