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