1 /* $NetBSD: wsmuxctl.c,v 1.4 2001/10/24 18:31:16 augustss Exp $ */ 2 3 /* 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Author: Lennart Augustsson <augustss@carlstedt.se> 8 * Carlstedt Research & Technology 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 <stdio.h> 40 #include <stdlib.h> 41 #include <fcntl.h> 42 #include <unistd.h> 43 #include <ctype.h> 44 #include <sys/types.h> 45 #include <sys/ioctl.h> 46 #include <err.h> 47 #include <errno.h> 48 49 #include <dev/wscons/wsconsio.h> 50 51 static void usage(void); 52 int main(int, char**); 53 54 const char *ctlpath = "/dev/wsmuxctl"; 55 56 const char *devnames[] = { "?", "wsmouse", "wskbd", "wsmux" }; 57 58 static void 59 usage(void) 60 { 61 62 fprintf(stderr, "Usage: %s [-a dev] -f wsmux [-l] [-L] [-r dev]\n", 63 getprogname()); 64 exit(1); 65 } 66 67 static void 68 parsedev(const char *dev, struct wsmux_device *mdev) 69 { 70 if (sscanf(dev, "wsmouse%d", &mdev->idx) == 1) { 71 mdev->type = WSMUX_MOUSE; 72 return; 73 } 74 if (sscanf(dev, "wskbd%d", &mdev->idx) == 1) { 75 mdev->type = WSMUX_KBD; 76 return; 77 } 78 if (sscanf(dev, "wsmux%d", &mdev->idx) == 1) { 79 mdev->type = WSMUX_MUX; 80 return; 81 } 82 errx(1, "bad device: `%s', use wsmouse, wskdb, or wsmux\n", dev); 83 } 84 85 static void 86 listdevs(int fd, int rec, int ind) 87 { 88 int i, rfd; 89 char buf[100]; 90 struct wsmux_device_list devs; 91 92 if (ioctl(fd, WSMUXIO_LIST_DEVICES, &devs) < 0) 93 err(1, "WSMUXIO_LIST_DEVICES"); 94 for (i = 0; i < devs.ndevices; i++) { 95 printf("%*s%s%d\n", ind, "", devnames[devs.devices[i].type], 96 devs.devices[i].idx); 97 if (rec && devs.devices[i].type == WSMUX_MUX) { 98 sprintf(buf, "%s%d", ctlpath, devs.devices[i].idx); 99 rfd = open(buf, O_WRONLY, 0); 100 if (rfd < 0) 101 warn("%s", buf); 102 listdevs(rfd, rec, ind+2); 103 close(rfd); 104 } 105 } 106 } 107 108 int 109 main(int argc, char **argv) 110 { 111 char *wsdev, *dev; 112 int wsfd, list, c, add, rem, recursive; 113 struct wsmux_device mdev; 114 char buf[100]; 115 116 wsdev = NULL; 117 dev = NULL; 118 add = 0; 119 rem = 0; 120 list = 0; 121 recursive = 0; 122 123 while ((c = getopt(argc, argv, "a:f:lLr:")) != -1) { 124 switch (c) { 125 case 'a': 126 if (dev) 127 usage(); 128 dev = optarg; 129 add++; 130 break; 131 case 'r': 132 if (dev) 133 usage(); 134 dev = optarg; 135 rem++; 136 break; 137 case 'f': 138 wsdev = optarg; 139 break; 140 case 'L': 141 recursive++; 142 case 'l': 143 list++; 144 break; 145 case '?': 146 default: 147 usage(); 148 break; 149 } 150 } 151 argc -= optind; 152 argv += optind; 153 154 if (wsdev == NULL) 155 usage(); 156 157 wsfd = open(wsdev, O_WRONLY, 0); 158 if (wsfd < 0) { 159 if (isdigit(wsdev[0])) { 160 sprintf(buf, "%s%s", ctlpath, wsdev); 161 wsdev = buf; 162 wsfd = open(wsdev, O_WRONLY, 0); 163 if (wsfd < 0) 164 err(2, "%s", wsdev); 165 } 166 } 167 168 if (list) { 169 if (add || rem) 170 usage(); 171 listdevs(wsfd, recursive, 0); 172 exit(0); 173 } 174 175 if (add) { 176 parsedev(dev, &mdev); 177 if (ioctl(wsfd, WSMUXIO_ADD_DEVICE, &mdev) < 0) 178 err(1, "WSMUXIO_ADD_DEVICE"); 179 } 180 181 if (rem) { 182 parsedev(dev, &mdev); 183 if (ioctl(wsfd, WSMUXIO_REMOVE_DEVICE, &mdev) < 0) 184 err(1, "WSMUXIO_REMOVE_DEVICE"); 185 } 186 187 close(wsfd); 188 return (0); 189 } 190