1 /* $NetBSD: wsconsctl.c,v 1.16 2007/12/15 19:44:48 perry 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 <sys/cdefs.h> 40 #include <err.h> 41 #include <fcntl.h> 42 #include <string.h> 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <unistd.h> 46 47 #include "wsconsctl.h" 48 49 #define PATH_KEYBOARD "/dev/wskbd" 50 #define PATH_MOUSE "/dev/wsmouse" 51 #define PATH_DISPLAY "/dev/ttyE0" 52 53 extern struct field keyboard_field_tab[]; 54 extern struct field mouse_field_tab[]; 55 extern struct field display_field_tab[]; 56 extern int keyboard_field_tab_len; 57 extern int mouse_field_tab_len; 58 extern int display_field_tab_len; 59 60 static void usage(const char *) __dead; 61 62 static void 63 usage(const char *msg) 64 { 65 const char *progname = getprogname(); 66 67 if (msg != NULL) 68 (void)fprintf(stderr, "%s: %s\n\n", progname, msg); 69 70 (void)fprintf(stderr, 71 "Usage: %s [-kmd] [-f file] [-n] name ...\n" 72 " -or- %s [-kmd] [-f file] [-n] -w name=value ...\n" 73 " -or- %s [-kmd] [-f file] [-n] -w name+=value ...\n" 74 " -or- %s [-kmd] [-f file] [-n] -a\n", 75 progname, progname, progname, progname); 76 77 exit(EXIT_FAILURE); 78 } 79 80 int 81 main(int argc, char **argv) 82 { 83 int i, ch, fd; 84 int aflag, dflag, kflag, mflag, wflag; 85 char *p; 86 const char *sep, *file; 87 struct field *f, *field_tab; 88 int do_merge, field_tab_len; 89 void (*getval)(int); 90 void (*putval)(int); 91 92 aflag = 0; 93 dflag = 0; 94 kflag = 0; 95 mflag = 0; 96 wflag = 0; 97 file = NULL; 98 sep = "="; 99 field_tab = NULL; 100 field_tab_len = 0; 101 getval = NULL; 102 putval = NULL; 103 104 while ((ch = getopt(argc, argv, "adf:kmnw")) != -1) { 105 switch(ch) { 106 case 'a': 107 aflag = 1; 108 break; 109 case 'd': 110 dflag = 1; 111 break; 112 case 'f': 113 file = optarg; 114 break; 115 case 'k': 116 kflag = 1; 117 break; 118 case 'm': 119 mflag = 1; 120 break; 121 case 'n': 122 sep = NULL; 123 break; 124 case 'w': 125 wflag = 1; 126 break; 127 case '?': 128 default: 129 usage(NULL); 130 } 131 } 132 133 argc -= optind; 134 argv += optind; 135 136 if (dflag + kflag + mflag == 0) 137 kflag = 1; 138 if (dflag + kflag + mflag > 1) 139 usage("only one of -k, -d or -m may be given"); 140 if (argc > 0 && aflag != 0) 141 usage("excess arguments after -a"); 142 if (aflag != 0 && wflag != 0) 143 usage("only one of -a or -w may be given"); 144 145 if (kflag) { 146 if (file == NULL) 147 file = PATH_KEYBOARD; 148 field_tab = keyboard_field_tab; 149 field_tab_len = keyboard_field_tab_len; 150 getval = keyboard_get_values; 151 putval = keyboard_put_values; 152 } else if (mflag) { 153 if (file == NULL) 154 file = PATH_MOUSE; 155 field_tab = mouse_field_tab; 156 field_tab_len = mouse_field_tab_len; 157 getval = mouse_get_values; 158 putval = mouse_put_values; 159 } else if (dflag) { 160 if (file == NULL) 161 file = PATH_DISPLAY; 162 field_tab = display_field_tab; 163 field_tab_len = display_field_tab_len; 164 getval = display_get_values; 165 putval = display_put_values; 166 } 167 168 field_setup(field_tab, field_tab_len); 169 170 fd = open(file, O_WRONLY); 171 if (fd < 0) 172 fd = open(file, O_RDONLY); 173 if (fd < 0) 174 err(EXIT_FAILURE, "%s", file); 175 176 if (aflag != 0) { 177 for (i = 0; i < field_tab_len; i++) 178 if ((field_tab[i].flags & (FLG_NOAUTO|FLG_WRONLY)) == 0) 179 field_tab[i].flags |= FLG_GET; 180 (*getval)(fd); 181 for (i = 0; i < field_tab_len; i++) 182 if (field_tab[i].flags & FLG_NOAUTO) 183 warnx("Use explicit arg to view %s.", 184 field_tab[i].name); 185 else if (field_tab[i].flags & FLG_GET && 186 !(field_tab[i].flags & FLG_DISABLED)) 187 pr_field(field_tab + i, sep); 188 } else if (argc > 0) { 189 if (wflag != 0) { 190 for (i = 0; i < argc; i++) { 191 p = strchr(argv[i], '='); 192 if (p == NULL) 193 errx(EXIT_FAILURE, "'=' not found"); 194 if (p > argv[i] && *(p - 1) == '+') { 195 *(p - 1) = '\0'; 196 do_merge = 1; 197 } else 198 do_merge = 0; 199 *p++ = '\0'; 200 f = field_by_name(argv[i]); 201 if ((f->flags & FLG_RDONLY) != 0) 202 errx(EXIT_FAILURE, "%s: read only", 203 argv[i]); 204 if (do_merge) { 205 if ((f->flags & FLG_MODIFY) == 0) 206 errx(EXIT_FAILURE, 207 "%s: can only be set", 208 argv[i]); 209 f->flags |= FLG_GET; 210 (*getval)(fd); 211 f->flags &= ~FLG_GET; 212 } 213 rd_field(f, p, do_merge); 214 f->flags |= FLG_SET; 215 (*putval)(fd); 216 f->flags &= ~FLG_SET; 217 } 218 } else { 219 for (i = 0; i < argc; i++) { 220 f = field_by_name(argv[i]); 221 if ((f->flags & FLG_WRONLY) != 0) 222 errx(EXIT_FAILURE, "%s: write only", 223 argv[i]); 224 f->flags |= FLG_GET; 225 } 226 (*getval)(fd); 227 for (i = 0; i < field_tab_len; i++) { 228 if (field_tab[i].flags & FLG_DISABLED) 229 errx(EXIT_FAILURE, 230 "%s: no kernel support", 231 field_tab[i].name); 232 if (field_tab[i].flags & FLG_GET) 233 pr_field(field_tab + i, sep); 234 } 235 } 236 } else { 237 close(fd); 238 usage(NULL); 239 } 240 241 close(fd); 242 243 return EXIT_SUCCESS; 244 } 245