GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/getcap/getcap.c Lines: 17 83 20.5 %
Date: 2017-11-13 Branches: 14 60 23.3 %

Line Branch Exec Source
1
/*	$OpenBSD: getcap.c,v 1.7 2017/01/20 03:47:31 krw 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
#include <unistd.h>
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
32
	char *cp, *buf, *cap = NULL, **pathvec = NULL;
41
	size_t n;
42
43
16
	if (pledge("stdio rpath flock cpath wpath", NULL) == -1)
44
		err(1, "pledge");
45
46
	aflag = type = 0;
47
64
	while ((ch = getopt(argc, argv, "ab:c:f:n:s:")) != -1) {
48

16
		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
16
			if (pathvec != NULL)
78
				errx(1, "only one -f option may be specified");
79
32
			for (n = 1, cp = optarg; (cp = strchr(cp, ':')); n++)
80
				continue;
81
16
			pathvec = calloc(n + 1, sizeof(char *));
82
64
			for (n = 0; (pathvec[n] = strsep(&optarg, ":"));) {
83
16
				if (*pathvec[n] != '\0')
84
16
					n++;
85
			}
86
			break;
87
		default:
88
			usage();
89
		}
90
	}
91
16
	argc -= optind;
92
16
	argv += optind;
93
94
16
	if (pathvec == NULL) {
95
		warnx("no path specified");
96
		usage();
97
	}
98
16
	if (!aflag && !argc) {
99
		warnx("must specify -a or a record name");
100
		usage();
101
	}
102
103
16
	if (aflag) {
104
		while (cgetnext(&buf, pathvec) > 0) {
105
			lookup_cap(buf, cap, type, 1);
106
			free(buf);
107
		}
108
	} else {
109
32
		while (*argv != NULL) {
110
16
		    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,
164
				    useprefix ? ": " : "", (int)(endp - cp),
165
				    cp);
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
179
	fprintf(stderr, "usage: %s [-b boolean | -c capability | "
180
	    "-n number | -s string] -f path\n"
181
	    "              -a | record ...\n",
182
	    __progname);
183
	exit(1);
184
}