xref: /openbsd/sbin/wsconsctl/wsconsctl.c (revision b0520bc4)
1 /*	$OpenBSD: wsconsctl.c,v 1.9 2001/10/24 17:45:59 miod 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  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *	This product includes software developed by the NetBSD
22  *	Foundation, Inc. and its contributors.
23  * 4. Neither the name of The NetBSD Foundation nor the names of its
24  *    contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 #include <fcntl.h>
41 #include <err.h>
42 #include <string.h>
43 #include <stdio.h>
44 #include <unistd.h>
45 #include "wsconsctl.h"
46 
47 #define PATH_KEYBOARD		"/dev/wskbd0"
48 #define PATH_MOUSE		"/dev/wsmouse0"
49 #define PATH_DISPLAY		"/dev/ttyC0"
50 
51 extern const char *__progname;		/* from crt0.o */
52 
53 extern struct field keyboard_field_tab[];
54 extern struct field mouse_field_tab[];
55 extern struct field display_field_tab[];
56 
57 void usage __P((char *));
58 
59 struct vartypesw {
60 	const char *name, *file;
61 	int fd;
62 	struct field *field_tab;
63 	void (*getval) __P((const char *pre, int));
64 	void (*putval) __P((const char *pre, int));
65 } typesw[] = {
66 	{ "keyboard", PATH_KEYBOARD, -1, keyboard_field_tab,
67 	  keyboard_get_values, keyboard_put_values },
68 	{ "mouse", PATH_MOUSE, -1, mouse_field_tab,
69 	  mouse_get_values, mouse_put_values },
70 	{ "display", PATH_DISPLAY, -1, display_field_tab,
71 	  display_get_values, display_put_values },
72 	{ NULL }
73 };
74 
75 struct vartypesw *tab_by_name __P((const char *));
76 
77 void
78 usage(msg)
79 	char *msg;
80 {
81 	if (msg != NULL)
82 		fprintf(stderr, "%s: %s\n", __progname, msg);
83 
84 	fprintf(stderr,
85 	    "usage: %s [-n] name ...\n"
86 	    "       %s [-n] -w name=value ...\n"
87 	    "       %s [-n] -a\n", __progname,
88 		__progname, __progname);
89 
90 	exit(1);
91 }
92 
93 int
94 main(argc, argv)
95 	int argc;
96 	char **argv;
97 {
98 	int i, ch, error;
99 	int aflag, wflag;
100 	char *sep, *p;
101 	struct vartypesw *sw;
102 	struct field *f;
103 	int do_merge;
104 
105 	error = aflag = wflag = 0;
106 	sw = NULL;
107 	sep = "=";
108 
109 	while ((ch = getopt(argc, argv, "anw")) != -1) {
110 		switch(ch) {
111 		case 'a':
112 			aflag = 1;
113 			break;
114 		case 'n':
115 			sep = NULL;
116 			break;
117 		case 'w':
118 			wflag = 1;
119 			break;
120 		default:
121 			usage(NULL);
122 		}
123 	}
124 
125 	argc -= optind;
126 	argv += optind;
127 
128 	if (argc > 0 && aflag != 0)
129 		usage("excess arguments after -a");
130 	if (aflag != 0 && wflag != 0)
131 		usage("only one of -a or -w may be given");
132 
133 	if (aflag != 0) {
134 		for (sw = typesw; sw->name; sw++) {
135 			if (sw->fd < 0 &&
136 			    (sw->fd = open(sw->file, O_WRONLY)) < 0 &&
137 			    (sw->fd = open(sw->file, O_RDONLY)) < 0) {
138 				warn("%s", sw->file);
139 				error = 1;
140 				continue;
141 			}
142 			for (i = 0; sw->field_tab[i].name; i++)
143 				if ((sw->field_tab[i].flags &
144 				    (FLG_NOAUTO|FLG_WRONLY)) == 0)
145 					sw->field_tab[i].flags |= FLG_GET;
146 			(*sw->getval)(sw->name, sw->fd);
147 			for (i = 0; sw->field_tab[i].name; i++)
148 				if (sw->field_tab[i].flags & FLG_NOAUTO)
149 					warnx("Use explicit arg to view %s.%s.",
150 					      sw->name, sw->field_tab[i].name);
151 				else if (sw->field_tab[i].flags & FLG_GET)
152 					pr_field(sw->name, sw->field_tab + i, sep);
153 		}
154 	} else if (argc > 0) {
155 		if (wflag != 0)
156 			for (i = 0; i < argc; i++) {
157 				p = strchr(argv[i], '=');
158 				if (p == NULL) {
159 					warnx("'=' not found");
160 					continue;
161 				}
162 				if (p > argv[i] && *(p - 1) == '+') {
163 					*(p - 1) = '\0';
164 					do_merge = 1;
165 				} else
166 					do_merge = 0;
167 				*p++ = '\0';
168 				sw = tab_by_name(argv[i]);
169 				if (!sw)
170 					continue;
171 				if (sw->fd < 0 &&
172 				    (sw->fd = open(sw->file, O_WRONLY)) < 0 &&
173 				    (sw->fd = open(sw->file, O_RDONLY)) < 0) {
174 					warn("open: %s", sw->file);
175 					error = 1;
176 					continue;
177 				}
178 				f = field_by_name(sw->field_tab, argv[i]);
179 				if ((f->flags & FLG_RDONLY) != 0) {
180 					warnx("%s: read only", argv[i]);
181 					continue;
182 				}
183 				if (do_merge) {
184 					if ((f->flags & FLG_MODIFY) == 0)
185 						errx(1, "%s: can only be set",
186 						     argv[i]);
187 					f->flags |= FLG_GET;
188 					(*sw->getval)(sw->name, sw->fd);
189 					f->flags &= ~FLG_GET;
190 				}
191 				rd_field(f, p, do_merge);
192 				f->flags |= FLG_SET;
193 				(*sw->putval)(sw->name, sw->fd);
194 				f->flags &= ~FLG_SET;
195 			}
196 		else
197 			for (i = 0; i < argc; i++) {
198 				sw = tab_by_name(argv[i]);
199 				if (!sw)
200 					continue;
201 				if (sw->fd < 0 &&
202 				    (sw->fd = open(sw->file, O_WRONLY)) < 0 &&
203 				    (sw->fd = open(sw->file, O_RDONLY)) < 0) {
204 					warn("open: %s", sw->file);
205 					error = 1;
206 					continue;
207 				}
208 				f = field_by_name(sw->field_tab, argv[i]);
209 				if ((f->flags & FLG_WRONLY) != 0) {
210 					warnx("%s: write only", argv[i]);
211 					continue;
212 				}
213 				f->flags |= FLG_GET;
214 				(*sw->getval)(sw->name, sw->fd);
215 				pr_field(sw->name, f, sep);
216 			}
217 	} else
218 		usage(NULL);
219 
220 	return (error);
221 }
222 
223 struct vartypesw *
224 tab_by_name(var)
225 	const char *var;
226 {
227 	struct vartypesw *sw;
228 	const char *p = strchr(var, '.');
229 
230 	if (!p) {
231 		warnx("%s: illegal variable name", var);
232 		return (NULL);
233 	}
234 
235 	for (sw = typesw; sw->name; sw++)
236 		if (!strncmp(sw->name, var, p - var))
237 			break;
238 
239 	if (!sw->name) {
240 		warnx("%s: no such variable", var);
241 		return (NULL);
242 	}
243 
244 	return (sw);
245 }
246