1 /* $NetBSD: wsconsctl.c,v 1.13 2005/06/26 22:45:50 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Juergen Hannken-Illjes. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <fcntl.h> 40 #include <err.h> 41 #include <string.h> 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <unistd.h> 45 #include "wsconsctl.h" 46 47 #define PATH_KEYBOARD "/dev/wskbd" 48 #define PATH_MOUSE "/dev/wsmouse" 49 #define PATH_DISPLAY "/dev/ttyE0" 50 51 extern struct field keyboard_field_tab[]; 52 extern struct field mouse_field_tab[]; 53 extern struct field display_field_tab[]; 54 extern int keyboard_field_tab_len; 55 extern int mouse_field_tab_len; 56 extern int display_field_tab_len; 57 58 static void usage(const char *) __attribute__((__noreturn__)); 59 60 static void 61 usage(const char *msg) 62 { 63 const char *progname = getprogname(); 64 65 if (msg != NULL) 66 fprintf(stderr, "%s: %s\n\n", progname, msg); 67 68 fprintf(stderr, "Usage: %s [-kmd] [-f file] [-n] name ...\n", 69 progname); 70 fprintf(stderr, " -or- %s [-kmd] [-f file] [-n] -w name=value ...\n", 71 progname); 72 fprintf(stderr, " -or- %s [-kmd] [-f file] [-n] -w name+=value ...\n", 73 progname); 74 fprintf(stderr, " -or- %s [-kmd] [-f file] [-n] -a\n", progname); 75 76 exit(1); 77 } 78 79 int 80 main(int argc, char **argv) 81 { 82 int i, ch, fd; 83 int aflag, dflag, kflag, mflag, wflag; 84 char *p; 85 const char *sep, *file; 86 struct field *f, *field_tab; 87 int do_merge, field_tab_len; 88 void (*getval)(int); 89 void (*putval)(int); 90 91 aflag = 0; 92 dflag = 0; 93 kflag = 0; 94 mflag = 0; 95 wflag = 0; 96 file = NULL; 97 sep = "="; 98 field_tab = NULL; 99 field_tab_len = 0; 100 getval = NULL; 101 putval = NULL; 102 103 while ((ch = getopt(argc, argv, "adf:kmnw")) != -1) { 104 switch(ch) { 105 case 'a': 106 aflag = 1; 107 break; 108 case 'd': 109 dflag = 1; 110 break; 111 case 'f': 112 file = optarg; 113 break; 114 case 'k': 115 kflag = 1; 116 break; 117 case 'm': 118 mflag = 1; 119 break; 120 case 'n': 121 sep = NULL; 122 break; 123 case 'w': 124 wflag = 1; 125 break; 126 case '?': 127 default: 128 usage(NULL); 129 } 130 } 131 132 argc -= optind; 133 argv += optind; 134 135 if (dflag + kflag + mflag == 0) 136 kflag = 1; 137 if (dflag + kflag + mflag > 1) 138 usage("only one of -k, -d or -m may be given"); 139 if (argc > 0 && aflag != 0) 140 usage("excess arguments after -a"); 141 if (aflag != 0 && wflag != 0) 142 usage("only one of -a or -w may be given"); 143 144 if (kflag) { 145 if (file == NULL) 146 file = PATH_KEYBOARD; 147 field_tab = keyboard_field_tab; 148 field_tab_len = keyboard_field_tab_len; 149 getval = keyboard_get_values; 150 putval = keyboard_put_values; 151 } else if (mflag) { 152 if (file == NULL) 153 file = PATH_MOUSE; 154 field_tab = mouse_field_tab; 155 field_tab_len = mouse_field_tab_len; 156 getval = mouse_get_values; 157 putval = mouse_put_values; 158 } else if (dflag) { 159 if (file == NULL) 160 file = PATH_DISPLAY; 161 field_tab = display_field_tab; 162 field_tab_len = display_field_tab_len; 163 getval = display_get_values; 164 putval = display_put_values; 165 } 166 167 field_setup(field_tab, field_tab_len); 168 169 fd = open(file, O_WRONLY); 170 if (fd < 0) 171 fd = open(file, O_RDONLY); 172 if (fd < 0) 173 err(1, "%s", file); 174 175 if (aflag != 0) { 176 for (i = 0; i < field_tab_len; i++) 177 if ((field_tab[i].flags & (FLG_NOAUTO|FLG_WRONLY)) == 0) 178 field_tab[i].flags |= FLG_GET; 179 (*getval)(fd); 180 for (i = 0; i < field_tab_len; i++) 181 if (field_tab[i].flags & FLG_NOAUTO) 182 warnx("Use explicit arg to view %s.", 183 field_tab[i].name); 184 else if (field_tab[i].flags & FLG_GET && 185 !(field_tab[i].flags & FLG_DISABLED)) 186 pr_field(field_tab + i, sep); 187 } else if (argc > 0) { 188 if (wflag != 0) { 189 for (i = 0; i < argc; i++) { 190 p = strchr(argv[i], '='); 191 if (p == NULL) 192 errx(1, "'=' not found"); 193 if (p > argv[i] && *(p - 1) == '+') { 194 *(p - 1) = '\0'; 195 do_merge = 1; 196 } else 197 do_merge = 0; 198 *p++ = '\0'; 199 f = field_by_name(argv[i]); 200 if ((f->flags & FLG_RDONLY) != 0) 201 errx(1, "%s: read only", argv[i]); 202 if (do_merge) { 203 if ((f->flags & FLG_MODIFY) == 0) 204 errx(1, "%s: can only be set", 205 argv[i]); 206 f->flags |= FLG_GET; 207 (*getval)(fd); 208 f->flags &= ~FLG_GET; 209 } 210 rd_field(f, p, do_merge); 211 f->flags |= FLG_SET; 212 (*putval)(fd); 213 f->flags &= ~FLG_SET; 214 } 215 } else { 216 for (i = 0; i < argc; i++) { 217 f = field_by_name(argv[i]); 218 if ((f->flags & FLG_WRONLY) != 0) 219 errx(1, "%s: write only", argv[i]); 220 f->flags |= FLG_GET; 221 } 222 (*getval)(fd); 223 for (i = 0; i < field_tab_len; i++) { 224 if (field_tab[i].flags & FLG_DISABLED) 225 errx(1, "%s: no kernel support", 226 field_tab[i].name); 227 if (field_tab[i].flags & FLG_GET) 228 pr_field(field_tab + i, sep); 229 } 230 } 231 } else { 232 close(fd); 233 usage(NULL); 234 } 235 236 close(fd); 237 exit(0); 238 } 239