1 /* $OpenBSD: wsconsctl.c,v 1.14 2004/06/23 07:37:23 david 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 <stdlib.h> 45 #include <unistd.h> 46 #include "wsconsctl.h" 47 48 #define PATH_KEYBOARD "/dev/wskbd0" 49 #define PATH_MOUSE "/dev/wsmouse0" 50 #define PATH_DISPLAY "/dev/ttyC0" 51 52 extern const char *__progname; /* from crt0.o */ 53 54 extern struct field keyboard_field_tab[]; 55 extern struct field mouse_field_tab[]; 56 extern struct field display_field_tab[]; 57 58 void usage(char *); 59 60 struct vartypesw { 61 const char *name, *file; 62 int fd; 63 struct field *field_tab; 64 void (*getval)(const char *pre, int); 65 void (*putval)(const char *pre, int); 66 } typesw[] = { 67 { "keyboard", PATH_KEYBOARD, -1, keyboard_field_tab, 68 keyboard_get_values, keyboard_put_values }, 69 { "mouse", PATH_MOUSE, -1, mouse_field_tab, 70 mouse_get_values, mouse_put_values }, 71 { "display", PATH_DISPLAY, -1, display_field_tab, 72 display_get_values, display_put_values }, 73 { NULL } 74 }; 75 76 struct vartypesw *tab_by_name(const char *); 77 78 void 79 usage(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] name=value ...\n" 87 " %s [-n] -a\n", __progname, 88 __progname, __progname); 89 90 exit(1); 91 } 92 93 int 94 main(int argc, char *argv[]) 95 { 96 int i, ch, error; 97 int aflag; 98 char *sep, *p; 99 struct vartypesw *sw; 100 struct field *f; 101 int do_merge; 102 103 error = aflag = 0; 104 sw = NULL; 105 sep = "="; 106 107 while ((ch = getopt(argc, argv, "anw")) != -1) { 108 switch(ch) { 109 case 'a': 110 aflag = 1; 111 break; 112 case 'n': 113 sep = NULL; 114 break; 115 case 'w': 116 /* compat */ 117 break; 118 default: 119 usage(NULL); 120 } 121 } 122 123 argc -= optind; 124 argv += optind; 125 126 if (argc > 0 && aflag != 0) 127 usage("excess arguments after -a"); 128 129 if (aflag != 0) { 130 for (sw = typesw; sw->name; sw++) { 131 if (sw->fd < 0 && 132 (sw->fd = open(sw->file, O_WRONLY)) < 0 && 133 (sw->fd = open(sw->file, O_RDONLY)) < 0) { 134 warn("%s", sw->file); 135 error = 1; 136 continue; 137 } 138 for (f = sw->field_tab; f->name; f++) 139 if ((f->flags & (FLG_NOAUTO|FLG_WRONLY)) == 0) 140 f->flags |= FLG_GET; 141 (*sw->getval)(sw->name, sw->fd); 142 for (f = sw->field_tab; f->name; f++) 143 if (f->flags & FLG_DEAD) 144 continue; 145 else if (f->flags & FLG_NOAUTO) 146 warnx("Use explicit arg to view %s.%s.", 147 sw->name, f->name); 148 else if (f->flags & FLG_GET) 149 pr_field(sw->name, f, sep); 150 } 151 } else if (argc > 0) { 152 for (i = 0; i < argc; i++) { 153 p = strchr(argv[i], '='); 154 if (p == NULL) { 155 sw = tab_by_name(argv[i]); 156 if (!sw) 157 continue; 158 if (sw->fd < 0 && 159 (sw->fd = open(sw->file, O_WRONLY)) < 0 && 160 (sw->fd = open(sw->file, O_RDONLY)) < 0) { 161 warn("open: %s", sw->file); 162 error = 1; 163 continue; 164 } 165 f = field_by_name(sw->field_tab, argv[i]); 166 if (f->flags & FLG_DEAD) 167 continue; 168 if ((f->flags & FLG_WRONLY) != 0) { 169 warnx("%s: write only", argv[i]); 170 continue; 171 } 172 f->flags |= FLG_GET; 173 (*sw->getval)(sw->name, sw->fd); 174 pr_field(sw->name, f, sep); 175 continue; 176 } 177 if (p > argv[i] && 178 (*(p - 1) == '+' || *(p - 1) == '-')) { 179 do_merge = *(p - 1); 180 *(p - 1) = '\0'; 181 } else 182 do_merge = 0; 183 *p++ = '\0'; 184 sw = tab_by_name(argv[i]); 185 if (!sw) 186 continue; 187 if (sw->fd < 0 && 188 (sw->fd = open(sw->file, O_WRONLY)) < 0 && 189 (sw->fd = open(sw->file, O_RDONLY)) < 0) { 190 warn("open: %s", sw->file); 191 error = 1; 192 continue; 193 } 194 f = field_by_name(sw->field_tab, argv[i]); 195 if (f->flags & FLG_DEAD) 196 continue; 197 if ((f->flags & FLG_RDONLY) != 0) { 198 warnx("%s: read only", argv[i]); 199 continue; 200 } 201 if (do_merge || f->flags & FLG_INIT) { 202 if ((f->flags & FLG_MODIFY) == 0) 203 errx(1, "%s: can only be set", 204 argv[i]); 205 f->flags |= FLG_GET; 206 (*sw->getval)(sw->name, sw->fd); 207 f->flags &= ~FLG_GET; 208 } 209 rd_field(f, p, do_merge); 210 f->flags |= FLG_SET; 211 (*sw->putval)(sw->name, sw->fd); 212 f->flags &= ~FLG_SET; 213 } 214 } else 215 usage(NULL); 216 217 return (error); 218 } 219 220 struct vartypesw * 221 tab_by_name(const char *var) 222 { 223 struct vartypesw *sw; 224 const char *p = strchr(var, '.'); 225 226 if (!p) { 227 warnx("%s: illegal variable name", var); 228 return (NULL); 229 } 230 231 for (sw = typesw; sw->name; sw++) 232 if (!strncmp(sw->name, var, p - var)) 233 break; 234 235 if (!sw->name) { 236 warnx("%s: no such variable", var); 237 return (NULL); 238 } 239 240 return (sw); 241 } 242