GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: sbin/wsconsctl/wsconsctl.c Lines: 0 150 0.0 %
Date: 2017-11-07 Branches: 0 137 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: wsconsctl.c,v 1.31 2017/07/21 20:38:20 bru Exp $	*/
2
/*	$NetBSD: wsconsctl.c,v 1.2 1998/12/29 22:40:20 hannken Exp $ */
3
4
/*-
5
 * Copyright (c) 1998 The NetBSD Foundation, Inc.
6
 * All rights reserved.
7
 *
8
 * This code is derived from software contributed to The NetBSD Foundation
9
 * by Juergen Hannken-Illjes.
10
 *
11
 * Redistribution and use in source and binary forms, with or without
12
 * modification, are permitted provided that the following conditions
13
 * are met:
14
 * 1. Redistributions of source code must retain the above copyright
15
 *    notice, this list of conditions and the following disclaimer.
16
 * 2. Redistributions in binary form must reproduce the above copyright
17
 *    notice, this list of conditions and the following disclaimer in the
18
 *    documentation and/or other materials provided with the distribution.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
 * POSSIBILITY OF SUCH DAMAGE.
31
 */
32
33
#include <fcntl.h>
34
#include <err.h>
35
#include <errno.h>
36
#include <string.h>
37
#include <stdio.h>
38
#include <stdlib.h>
39
#include <unistd.h>
40
#include "wsconsctl.h"
41
42
extern const char *__progname;		/* from crt0.o */
43
44
extern struct field keyboard_field_tab[];
45
extern struct field mouse_field_tab[];
46
extern struct field display_field_tab[];
47
48
void	usage(void);
49
50
struct vartypesw {
51
	const	char *name;
52
	struct field *field_tab;
53
	void	(*init)(int,int);
54
	void	(*getval)(int);
55
	int	(*putval)(int);
56
	char *	(*nextdev)(int);
57
} typesw[] = {
58
	{ "keyboard", keyboard_field_tab, NULL,
59
	  keyboard_get_values, keyboard_put_values, keyboard_next_device },
60
	{ "mouse", mouse_field_tab, mouse_init,
61
	  mouse_get_values, mouse_put_values, mouse_next_device },
62
	{ "display", display_field_tab, NULL,
63
	  display_get_values, display_put_values, display_next_device },
64
	{ NULL }
65
};
66
67
struct vartypesw *tab_by_name(const char *, int *);
68
69
void
70
usage(void)
71
{
72
	fprintf(stderr,
73
	    "usage: %s [-an]\n"
74
	    "       %s [-n] [-f file] name ...\n"
75
	    "       %s [-n] [-f file] name=value ...\n",
76
	    __progname, __progname, __progname);
77
	exit(1);
78
}
79
80
int
81
main(int argc, char *argv[])
82
{
83
	int i, ch, error = 0, aflag = 0, do_merge, putval, devidx, devfd;
84
	struct vartypesw *sw = NULL;
85
	char *getsep = "=", *setsep = " -> ", *p;
86
	char *wdev = NULL;
87
	char *device;
88
	struct field *f;
89
	char devname[20];
90
91
	while ((ch = getopt(argc, argv, "af:nw")) != -1) {
92
		switch(ch) {
93
		case 'a':
94
			aflag = 1;
95
			break;
96
		case 'f':
97
			wdev = optarg;
98
			break;
99
		case 'n':
100
			getsep = setsep = NULL;
101
			break;
102
		case 'w':
103
			/* compat */
104
			break;
105
		default:
106
			usage();
107
		}
108
	}
109
110
	argc -= optind;
111
	argv += optind;
112
113
	if (argc > 0 && aflag != 0)
114
		errx(1, "excess arguments after -a");
115
	if (argc == 0)
116
		aflag = 1;
117
118
	if (aflag != 0) {
119
		for (sw = typesw; sw->name; sw++) {
120
			for (devidx = 0;; devidx++) {
121
				device = (*sw->nextdev)(devidx);
122
				if (!device ||
123
				    ((devfd = open(device, O_WRONLY)) < 0 &&
124
				     (devfd = open(device, O_RDONLY)) < 0)) {
125
					if (!device || errno != ENXIO) {
126
						if (device && errno != ENOENT) {
127
							warn("%s", device);
128
							error = 1;
129
						}
130
						break;
131
					} else
132
						continue;
133
				}
134
135
				if (devidx == 0)
136
					snprintf(devname, sizeof(devname),
137
					    "%s", sw->name);
138
				else
139
					snprintf(devname, sizeof(devname),
140
					    "%s%d", sw->name, devidx);
141
142
				if (sw->init != NULL)
143
					(*sw->init)(devfd, devidx);
144
145
				for (f = sw->field_tab; f->name; f++)
146
					if (!(f->flags &
147
					    (FLG_NOAUTO|FLG_WRONLY)))
148
						f->flags |= FLG_GET;
149
				(*sw->getval)(devfd);
150
				for (f = sw->field_tab; f->name; f++)
151
					if (f->flags & FLG_DEAD)
152
						continue;
153
					else if (f->flags & FLG_NOAUTO)
154
						warnx("Use explicit arg to "
155
						    "view %s.%s.",
156
						    devname, f->name);
157
					else if (f->flags & FLG_GET)
158
						pr_field(devname, f, getsep);
159
			}
160
		}
161
	} else if (argc > 0) {
162
		for (i = 0; i < argc; i++) {
163
			sw = tab_by_name(argv[i], &devidx);
164
			if (!sw)
165
				continue;
166
167
			if (!wdev)
168
				device = (*sw->nextdev)(devidx);
169
			else
170
				device = wdev;
171
172
			if (!device ||
173
			    ((devfd = open(device, O_WRONLY)) < 0 &&
174
			     (devfd = open(device, O_RDONLY)) < 0)) {
175
				if (!device) {
176
					const char *c = strchr(argv[i], '.');
177
					int k;
178
					if (!c)
179
						c = strchr(argv[i], '\0');
180
					k = c - argv[i];
181
					warnx("%*.*s: no such variable",
182
					    k, k, argv[i]);
183
				} else
184
					warn("%s", device);
185
				error = 1;
186
				continue;
187
			}
188
189
			if (devidx == 0)
190
				snprintf(devname, sizeof(devname),
191
				    "%s", sw->name);
192
			else
193
				snprintf(devname, sizeof(devname),
194
				    "%s%d", sw->name, devidx);
195
196
			if (sw->init != NULL)
197
				(*sw->init)(devfd, devidx);
198
199
			p = strchr(argv[i], '=');
200
			if (p == NULL) {
201
				if (!strchr(argv[i], '.')) {
202
					for (f = sw->field_tab; f->name; f++)
203
						if (!(f->flags &
204
						    (FLG_NOAUTO|FLG_WRONLY)))
205
							f->flags |= FLG_GET;
206
					(*sw->getval)(devfd);
207
					for (f = sw->field_tab; f->name; f++)
208
						if (f->flags & FLG_DEAD)
209
							continue;
210
						else if (f->flags & FLG_NOAUTO)
211
							warnx("Use explicit "
212
							    "arg to view "
213
							    "%s.%s.",
214
							    devname, f->name);
215
						else if (f->flags & FLG_GET)
216
							pr_field(devname, f,
217
							    getsep);
218
					continue;
219
				}
220
221
				f = field_by_name(sw->field_tab, argv[i]);
222
				if (f->flags & FLG_DEAD)
223
					continue;
224
				if ((f->flags & FLG_WRONLY)) {
225
					warnx("%s: write only", argv[i]);
226
					continue;
227
				}
228
				f->flags |= FLG_GET;
229
				(*sw->getval)(devfd);
230
				if (f->flags & FLG_DEAD)
231
					continue;
232
				pr_field(devname, f, getsep);
233
			} else {
234
				if (!strchr(argv[i], '.') ||
235
				    (strchr(argv[i], '.') > p)) {
236
					warnx("%s: illegal variable name",
237
					    argv[i]);
238
					continue;
239
				}
240
				if (p > argv[i] &&
241
				    (*(p - 1) == '+' || *(p - 1) == '-')) {
242
					do_merge = *(p - 1);
243
					*(p - 1) = '\0';
244
				} else
245
					do_merge = 0;
246
				*p++ = '\0';
247
248
				f = field_by_name(sw->field_tab, argv[i]);
249
				if (f->flags & FLG_DEAD)
250
					continue;
251
				if (f->flags & FLG_RDONLY) {
252
					warnx("%s: read only", argv[i]);
253
					continue;
254
				}
255
				if (do_merge || f->flags & FLG_INIT) {
256
					if (!(f->flags & FLG_MODIFY))
257
						errx(1, "%s: can only be set",
258
						    argv[i]);
259
					f->flags |= FLG_GET;
260
					(*sw->getval)(devfd);
261
					f->flags &= ~FLG_GET;
262
				}
263
				rd_field(f, p, do_merge);
264
				f->flags |= FLG_SET;
265
				putval = (*sw->putval)(devfd);
266
				f->flags &= ~FLG_SET;
267
				if (putval != 0 ||
268
				    f->flags & (FLG_DEAD|FLG_NOAUTO))
269
					continue;
270
				if (f->flags & FLG_WRONLY) {
271
					pr_field(devname, f, setsep);
272
				} else {
273
					if (!(f->flags & FLG_NORDBACK)) {
274
						f->flags |= FLG_GET;
275
						(*sw->getval)(devfd);
276
					}
277
					if (f->flags & FLG_DEAD)
278
						continue;
279
					pr_field(devname, f, setsep);
280
				}
281
			}
282
283
			close(devfd);
284
		}
285
	} else
286
		usage();
287
288
	exit(error);
289
}
290
291
struct vartypesw *
292
tab_by_name(const char *var, int *idx)
293
{
294
	struct vartypesw *sw;
295
	const char *p = strchr(var, '.');
296
	char *c;
297
	int i;
298
299
	for (sw = typesw; sw->name; sw++)
300
		if (!strncmp(sw->name, var, strlen(sw->name)))
301
			break;
302
303
	if (!p)
304
		p = strchr(var, '\0');
305
306
	if (!sw->name) {
307
		i = p - var;
308
		warnx("%*.*s: no such variable", i, i, var);
309
		return (NULL);
310
	}
311
312
	if ((p - var) > strlen(sw->name)) {
313
		c = (char *)var;
314
		c = c + strlen(sw->name);
315
		i = 0;
316
		while (c < p) {
317
			if (*c >= '0' && *c <= '9')
318
				i = i * 10 + *c - '0';
319
			else
320
				i = -1;
321
			c++;
322
		}
323
		if (i < 0 || i > 32) {
324
			i = p - var;
325
			warnx("%*.*s: no such variable", i, i, var);
326
			return (NULL);
327
		}
328
	} else
329
		i = 0;
330
331
	*idx = i;
332
333
	return (sw);
334
}