1/* $NetBSD: wsmuxctl.c,v 1.10 2008/04/28 20:24:17 martin 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 46static const char *ctlpath = "/dev/wsmuxctl"; 47 48static const char *devnames[] = { "?", "wsmouse", "wskbd", "wsmux" }; 49 50static void 51usage(void) 52{ 53 54 fprintf(stderr, "usage: %s [-a dev] -f wsmux [-l] [-L] [-r dev]\n", 55 getprogname()); 56 exit(1); 57} 58 59static void 60parsedev(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 77static void 78listdevs(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 101int 102main(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