1 /* $NetBSD: wsmuxctl.c,v 1.9 2004/10/30 15:55:28 dsl 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", 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 snprintf(buf, sizeof(buf), "%s%d", ctlpath, 99 devs.devices[i].idx); 100 rfd = open(buf, O_WRONLY, 0); 101 if (rfd < 0) 102 warn("%s", buf); 103 listdevs(rfd, rec, ind+2); 104 close(rfd); 105 } 106 } 107 } 108 109 int 110 main(int argc, char **argv) 111 { 112 char *wsdev, *dev; 113 int wsfd, list, c, add, rem, recursive; 114 struct wsmux_device mdev; 115 char buf[100]; 116 117 wsdev = NULL; 118 dev = NULL; 119 add = 0; 120 rem = 0; 121 list = 0; 122 recursive = 0; 123 124 while ((c = getopt(argc, argv, "a:f:lLr:")) != -1) { 125 switch (c) { 126 case 'a': 127 if (dev) 128 usage(); 129 dev = optarg; 130 add++; 131 break; 132 case 'r': 133 if (dev) 134 usage(); 135 dev = optarg; 136 rem++; 137 break; 138 case 'f': 139 wsdev = optarg; 140 break; 141 case 'L': 142 recursive++; 143 case 'l': 144 list++; 145 break; 146 case '?': 147 default: 148 usage(); 149 break; 150 } 151 } 152 argc -= optind; 153 argv += optind; 154 155 if (wsdev == NULL) 156 usage(); 157 158 wsfd = open(wsdev, O_WRONLY, 0); 159 if (wsfd < 0) { 160 if (isdigit((unsigned char)wsdev[0])) { 161 snprintf(buf, sizeof(buf), "%s%s", ctlpath, wsdev); 162 wsdev = buf; 163 wsfd = open(wsdev, O_WRONLY, 0); 164 } 165 if (wsfd < 0) 166 err(2, "%s", wsdev); 167 } 168 169 if (list) { 170 if (add || rem) 171 usage(); 172 listdevs(wsfd, recursive, 0); 173 exit(0); 174 } 175 176 if (add) { 177 parsedev(dev, &mdev); 178 if (ioctl(wsfd, WSMUXIO_ADD_DEVICE, &mdev) < 0) 179 err(1, "WSMUXIO_ADD_DEVICE"); 180 } 181 182 if (rem) { 183 parsedev(dev, &mdev); 184 if (ioctl(wsfd, WSMUXIO_REMOVE_DEVICE, &mdev) < 0) 185 err(1, "WSMUXIO_REMOVE_DEVICE"); 186 } 187 188 close(wsfd); 189 return (0); 190 } 191