1/* $NetBSD: wsconsctl.c,v 1.17 2008/04/28 20:23:09 martin 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 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <sys/cdefs.h> 33#include <err.h> 34#include <fcntl.h> 35#include <string.h> 36#include <stdio.h> 37#include <stdlib.h> 38#include <unistd.h> 39 40#include "wsconsctl.h" 41 42#define PATH_KEYBOARD "/dev/wskbd" 43#define PATH_MOUSE "/dev/wsmouse" 44#define PATH_DISPLAY "/dev/ttyE0" 45 46extern struct field keyboard_field_tab[]; 47extern struct field mouse_field_tab[]; 48extern struct field display_field_tab[]; 49extern int keyboard_field_tab_len; 50extern int mouse_field_tab_len; 51extern int display_field_tab_len; 52 53static void usage(const char *) __dead; 54 55static void 56usage(const char *msg) 57{ 58 const char *progname = getprogname(); 59 60 if (msg != NULL) 61 (void)fprintf(stderr, "%s: %s\n\n", progname, msg); 62 63 (void)fprintf(stderr, 64 "Usage: %s [-kmd] [-f file] [-n] name ...\n" 65 " -or- %s [-kmd] [-f file] [-n] -w name=value ...\n" 66 " -or- %s [-kmd] [-f file] [-n] -w name+=value ...\n" 67 " -or- %s [-kmd] [-f file] [-n] -a\n", 68 progname, progname, progname, progname); 69 70 exit(EXIT_FAILURE); 71} 72 73int 74main(int argc, char **argv) 75{ 76 int i, ch, fd; 77 int aflag, dflag, kflag, mflag, wflag; 78 char *p; 79 const char *sep, *file; 80 struct field *f, *field_tab; 81 int do_merge, field_tab_len; 82 void (*getval)(int); 83 void (*putval)(int); 84 85 aflag = 0; 86 dflag = 0; 87 kflag = 0; 88 mflag = 0; 89 wflag = 0; 90 file = NULL; 91 sep = "="; 92 field_tab = NULL; 93 field_tab_len = 0; 94 getval = NULL; 95 putval = NULL; 96 97 while ((ch = getopt(argc, argv, "adf:kmnw")) != -1) { 98 switch(ch) { 99 case 'a': 100 aflag = 1; 101 break; 102 case 'd': 103 dflag = 1; 104 break; 105 case 'f': 106 file = optarg; 107 break; 108 case 'k': 109 kflag = 1; 110 break; 111 case 'm': 112 mflag = 1; 113 break; 114 case 'n': 115 sep = NULL; 116 break; 117 case 'w': 118 wflag = 1; 119 break; 120 case '?': 121 default: 122 usage(NULL); 123 } 124 } 125 126 argc -= optind; 127 argv += optind; 128 129 if (dflag + kflag + mflag == 0) 130 kflag = 1; 131 if (dflag + kflag + mflag > 1) 132 usage("only one of -k, -d or -m may be given"); 133 if (argc > 0 && aflag != 0) 134 usage("excess arguments after -a"); 135 if (aflag != 0 && wflag != 0) 136 usage("only one of -a or -w may be given"); 137 138 if (kflag) { 139 if (file == NULL) 140 file = PATH_KEYBOARD; 141 field_tab = keyboard_field_tab; 142 field_tab_len = keyboard_field_tab_len; 143 getval = keyboard_get_values; 144 putval = keyboard_put_values; 145 } else if (mflag) { 146 if (file == NULL) 147 file = PATH_MOUSE; 148 field_tab = mouse_field_tab; 149 field_tab_len = mouse_field_tab_len; 150 getval = mouse_get_values; 151 putval = mouse_put_values; 152 } else if (dflag) { 153 if (file == NULL) 154 file = PATH_DISPLAY; 155 field_tab = display_field_tab; 156 field_tab_len = display_field_tab_len; 157 getval = display_get_values; 158 putval = display_put_values; 159 } 160 161 field_setup(field_tab, field_tab_len); 162 163 fd = open(file, O_WRONLY); 164 if (fd < 0) 165 fd = open(file, O_RDONLY); 166 if (fd < 0) 167 err(EXIT_FAILURE, "%s", file); 168 169 if (aflag != 0) { 170 for (i = 0; i < field_tab_len; i++) 171 if ((field_tab[i].flags & (FLG_NOAUTO|FLG_WRONLY)) == 0) 172 field_tab[i].flags |= FLG_GET; 173 (*getval)(fd); 174 for (i = 0; i < field_tab_len; i++) 175 if (field_tab[i].flags & FLG_NOAUTO) 176 warnx("\"%s\" not shown with -a; use \"%s %s\"" 177 " to view.", 178 field_tab[i].name, 179 getprogname(), field_tab[i].name); 180 else if (field_tab[i].flags & FLG_GET && 181 !(field_tab[i].flags & FLG_DISABLED)) 182 pr_field(field_tab + i, sep); 183 } else if (argc > 0) { 184 if (wflag != 0) { 185 for (i = 0; i < argc; i++) { 186 p = strchr(argv[i], '='); 187 if (p == NULL) 188 errx(EXIT_FAILURE, "'=' not found"); 189 if (p > argv[i] && *(p - 1) == '+') { 190 *(p - 1) = '\0'; 191 do_merge = 1; 192 } else 193 do_merge = 0; 194 *p++ = '\0'; 195 f = field_by_name(argv[i]); 196 if ((f->flags & FLG_RDONLY) != 0) 197 errx(EXIT_FAILURE, "%s: read only", 198 argv[i]); 199 if (do_merge) { 200 if ((f->flags & FLG_MODIFY) == 0) 201 errx(EXIT_FAILURE, 202 "%s: can only be set", 203 argv[i]); 204 f->flags |= FLG_GET; 205 (*getval)(fd); 206 f->flags &= ~FLG_GET; 207 } 208 rd_field(f, p, do_merge); 209 f->flags |= FLG_SET; 210 (*putval)(fd); 211 f->flags &= ~FLG_SET; 212 } 213 } else { 214 for (i = 0; i < argc; i++) { 215 f = field_by_name(argv[i]); 216 if ((f->flags & FLG_WRONLY) != 0) 217 errx(EXIT_FAILURE, "%s: write only", 218 argv[i]); 219 f->flags |= FLG_GET; 220 } 221 (*getval)(fd); 222 for (i = 0; i < field_tab_len; i++) { 223 if (field_tab[i].flags & FLG_DISABLED) 224 errx(EXIT_FAILURE, 225 "%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 238 return EXIT_SUCCESS; 239} 240