1 /* $OpenBSD: getcap.c,v 1.1 2005/02/19 22:15:41 millert Exp $ */
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>
23
24 __RCSID("$MirOS: src/usr.bin/getcap/getcap.c,v 1.2 2006/09/21 03:46:52 tg Exp $");
25
26 enum captype {
27 boolean,
28 number,
29 string,
30 raw
31 };
32
33 void lookup_cap(char *, char *, enum captype, int);
34 __dead void usage(void);
35
36 int
main(int argc,char * argv[])37 main(int argc, char *argv[])
38 {
39 int ch, aflag;
40 enum captype type;
41 char *cp, *buf, *cap = NULL, **pathvec = NULL;
42 size_t n;
43
44 aflag = type = 0;
45 while ((ch = getopt(argc, argv, "ab:c:f:n:s:")) != -1) {
46 switch (ch) {
47 case 'a':
48 aflag = 1;
49 break;
50 case 'b':
51 if (*optarg == '\0')
52 usage();
53 cap = optarg;
54 type = boolean;
55 break;
56 case 'n':
57 if (*optarg == '\0')
58 usage();
59 cap = optarg;
60 type = number;
61 break;
62 case 's':
63 if (*optarg == '\0')
64 usage();
65 cap = optarg;
66 type = string;
67 break;
68 case 'c':
69 if (*optarg == '\0')
70 usage();
71 cap = optarg;
72 type = raw;
73 break;
74 case 'f':
75 if (pathvec != NULL)
76 errx(1, "only one -f option may be specified");
77 for (n = 1, cp = optarg; (cp = strchr(cp, ':')); n++)
78 continue;
79 pathvec = calloc(n + 1, sizeof(char *));
80 for (n = 0; (pathvec[n] = strsep(&optarg, ":"));) {
81 if (*pathvec[n] != '\0')
82 n++;
83 }
84 break;
85 default:
86 usage();
87 }
88 }
89 argc -= optind;
90 argv += optind;
91
92 if (pathvec == NULL) {
93 warnx("no path specified");
94 usage();
95 }
96 if (!aflag && !argc) {
97 warnx("must specify -a or a record name");
98 usage();
99 }
100
101 if (aflag) {
102 while (cgetnext(&buf, pathvec) > 0) {
103 lookup_cap(buf, cap, type, 1);
104 free(buf);
105 }
106 } else {
107 while (*argv != NULL) {
108 if (cgetent(&buf, pathvec, *argv) != 0)
109 errx(1, "unable to lookup %s", *argv); /* XXX */
110 lookup_cap(buf, cap, type, argc > 1);
111 free(buf);
112 argv++;
113 }
114 }
115 exit(0);
116 }
117
118 void
lookup_cap(char * buf,char * cap,enum captype type,int useprefix)119 lookup_cap(char *buf, char *cap, enum captype type, int useprefix)
120 {
121 char *cp, *endp;
122 long l;
123 int ch, n, prefixlen;
124
125 if (cap == NULL) {
126 puts(buf);
127 return;
128 }
129
130 prefixlen = useprefix ? strcspn(buf, "|:") : 0;
131
132 switch (type) {
133 case boolean:
134 if (cgetcap(buf, cap, ':') == NULL)
135 return;
136 printf("%.*s%s%s\n", prefixlen, buf,
137 useprefix ? ": " : "", cap);
138 break;
139 case number:
140 if (cgetnum(buf, cap, &l) == -1)
141 return;
142 printf("%.*s%s%ld\n", prefixlen, buf,
143 useprefix ? ": " : "", l);
144 break;
145 case string:
146 if ((n = cgetstr(buf, cap, &cp)) == -1)
147 return;
148 else if (n == -2)
149 err(1, NULL); /* ENOMEM */
150 if (cgetstr(buf, cap, &cp) < 0)
151 return;
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,
164 useprefix ? ": " : "",
165 (int)(endp - cp), cp);
166 else
167 printf("%.*s%s%s\n", prefixlen, buf,
168 useprefix ? ": " : "", cp);
169 }
170 break;
171 }
172 }
173
174 __dead void
usage(void)175 usage(void)
176 {
177 extern char *__progname;
178
179 fprintf(stderr, "usage: %s [-b boolean | -c capability | -n number | -s string] -a -f path\n"
180 " %s [-b boolean | -c capability | -n number | -s string] -f path record ...\n",
181 __progname, __progname);
182 exit(1);
183 }
184