conscontrol.c revision 130676
1121982Sjhb/*- 2121982Sjhb * Copyright (c) 2001 Jonathan Lemon <jlemon@FreeBSD.org> 3121982Sjhb * All rights reserved. 4121982Sjhb * 5121982Sjhb * Redistribution and use in source and binary forms, with or without 6121982Sjhb * modification, are permitted provided that the following conditions 7121982Sjhb * are met: 8121982Sjhb * 1. Redistributions of source code must retain the above copyright 9121982Sjhb * notice, this list of conditions and the following disclaimer. 10121982Sjhb * 2. Redistributions in binary form must reproduce the above copyright 11121982Sjhb * notice, this list of conditions and the following disclaimer in the 12121982Sjhb * documentation and/or other materials provided with the distribution. 13121982Sjhb * 14121982Sjhb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15121982Sjhb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16121982Sjhb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17121982Sjhb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18121982Sjhb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19121982Sjhb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20121982Sjhb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21121982Sjhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22121982Sjhb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23121982Sjhb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24121982Sjhb * SUCH DAMAGE. 25121982Sjhb */ 26121982Sjhb 27121982Sjhb#include <sys/cdefs.h> 28121982Sjhb__FBSDID("$FreeBSD: head/sbin/conscontrol/conscontrol.c 130676 2004-06-18 06:33:44Z green $"); 29121982Sjhb 30121982Sjhb#include <sys/types.h> 31121982Sjhb#include <sys/sysctl.h> 32121982Sjhb#include <sys/ioctl.h> 33121982Sjhb#include <sys/ttycom.h> 34151979Sjhb 35151979Sjhb#include <err.h> 36151979Sjhb#include <errno.h> 37151979Sjhb#include <fcntl.h> 38151979Sjhb#include <stdio.h> 39151979Sjhb#include <stdlib.h> 40151979Sjhb#include <string.h> 41151979Sjhb#include <unistd.h> 42151979Sjhb 43151979Sjhb#define DEVDIR "/dev/" 44151979Sjhb 45151979Sjhbstatic void __dead2 46164265Sjhbusage(void) 47164265Sjhb{ 48164265Sjhb 49151979Sjhb (void)fprintf(stderr, "%s\n%s\n%s\n%s\n", 50187880Sjeff "usage: conscontrol [list]", 51164265Sjhb " conscontrol mute on | off", 52164265Sjhb " conscontrol add | delete console", 53121982Sjhb " conscontrol set console | unset"); 54151979Sjhb exit(1); 55164265Sjhb} 56164265Sjhb 57164265Sjhbstatic void 58164265Sjhbconsstatus(void) 59164265Sjhb{ 60151979Sjhb int mute; 61151979Sjhb size_t len; 62151979Sjhb char *buf, *p, *avail; 63151979Sjhb 64151979Sjhb len = sizeof(mute); 65151979Sjhb if (sysctlbyname("kern.consmute", &mute, &len, NULL, 0) == -1) 66163212Sjhb err(1, "kern.consmute retrieval failed"); 67163212Sjhb if (sysctlbyname("kern.console", NULL, &len, NULL, 0) == -1) 68151979Sjhb err(1, "kern.console estimate failed"); 69151979Sjhb if ((buf = malloc(len)) == NULL) 70151979Sjhb errx(1, "kern.console malloc failed"); 71121982Sjhb if (sysctlbyname("kern.console", buf, &len, NULL, 0) == -1) 72121982Sjhb err(1, "kern.console retrieval failed"); 73121982Sjhb if ((avail = strchr(buf, '/')) == NULL) 74121982Sjhb errx(1, "kern.console format not understood"); 75121982Sjhb p = avail; 76121982Sjhb *avail++ = '\0'; 77121982Sjhb if (p != buf) 78121982Sjhb *--p = '\0'; /* remove trailing ',' */ 79121982Sjhb p = avail + strlen(avail); 80121982Sjhb if (p != avail) 81121982Sjhb *--p = '\0'; /* remove trailing ',' */ 82121982Sjhb printf("Configured: %s\n", buf); 83121982Sjhb printf(" Available: %s\n", avail); 84121982Sjhb printf(" Muting: %s\n", mute ? "on" : "off"); 85121982Sjhb free(buf); 86133907Speter} 87121982Sjhb 88121982Sjhbstatic void 89169391Sjhbconsmute(const char *onoff) 90121982Sjhb{ 91121982Sjhb int mute; 92163219Sjhb size_t len; 93163219Sjhb 94129284Speter if (strcmp(onoff, "on") == 0) 95129284Speter mute = 1; 96156124Sjhb else if (strcmp(onoff, "off") == 0) 97163219Sjhb mute = 0; 98121982Sjhb else 99121982Sjhb usage(); 100133907Speter len = sizeof(mute); 101133907Speter if (sysctlbyname("kern.consmute", NULL, NULL, &mute, len) == -1) 102133907Speter err(1, "could not change console muting"); 103133907Speter} 104133907Speter 105133907Speter/* 106121982Sjhb * The name we supply to the sysctls should be an entry in /dev. If 107121982Sjhb * the user has specified the full pathname in /dev, DTRT. If he 108121982Sjhb * specifies a name in some other directory, it's an error. 109121982Sjhb */ 110121982Sjhb 111121982Sjhbstatic char* 112121982Sjhbstripdev(char *devnam) 113121982Sjhb{ 114151658Sjhb if (memcmp (devnam, DEVDIR, strlen(DEVDIR)) == 0) 115121982Sjhb return (&devnam[strlen(DEVDIR)]); /* remove /dev */ 116121982Sjhb else if (strchr (devnam, '/')) { 117121982Sjhb fprintf(stderr, "Not a device in /dev: %s\n", devnam); 118169391Sjhb return (NULL); /* end of string */ 119121982Sjhb } else 120121982Sjhb return (devnam); /* passed */ 121153241Sjhb} 122121982Sjhb 123188065Sjkoshystatic void 124188065Sjkoshyconsadd(char *devnam) 125188065Sjkoshy{ 126188065Sjkoshy size_t len; 127188065Sjkoshy 128188065Sjkoshy devnam = stripdev(devnam); 129188065Sjkoshy if (devnam == NULL) 130188065Sjkoshy return; 131188065Sjkoshy len = strlen(devnam); 132121982Sjhb if (sysctlbyname("kern.console", NULL, NULL, devnam, len) == -1) 133140555Speter err(1, "could not add %s as a console", devnam); 134121982Sjhb} 135163219Sjhb 136163219Sjhbstatic void 137163219Sjhbconsdel(char *devnam) 138129284Speter{ 139129284Speter char *buf; 140129284Speter size_t len; 141129284Speter 142129284Speter devnam = stripdev(devnam); 143156124Sjhb if (devnam == NULL) 144167273Sjhb return; 145156124Sjhb len = strlen(devnam) + sizeof("-"); 146166901Spiso if ((buf = malloc(len)) == NULL) 147166901Spiso errx(1, "malloc failed"); 148166901Spiso buf[0] = '-'; 149177181Sjhb strcpy(buf + 1, devnam); 150177181Sjhb if (sysctlbyname("kern.console", NULL, NULL, buf, len) == -1) 151177181Sjhb err(1, "could not remove %s as a console", devnam); 152129284Speter free(buf); 153129284Speter} 154153241Sjhb 155121982Sjhbstatic void 156163219Sjhbconsset(char *devnam) 157121982Sjhb{ 158121982Sjhb int ttyfd, flag = 1; 159121982Sjhb 160121982Sjhb ttyfd = open(devnam, O_RDONLY); 161140555Speter if (ttyfd == -1) 162169391Sjhb err(1, "opening %s", devnam); 163169391Sjhb if (ioctl(ttyfd, TIOCCONS, &flag) == -1) 164165127Sjhb err(1, "could not set %s as virtual console", devnam); 165169221Sjhb close(ttyfd); 166164265Sjhb} 167169391Sjhb 168164265Sjhbstatic void 169121982Sjhbconsunset(void) 170121982Sjhb{ 171121982Sjhb int ttyfd, flag = 0; 172121982Sjhb 173 ttyfd = open(DEVDIR "console", O_RDONLY); 174 if (ttyfd == -1) 175 err(1, "opening virtual console"); 176 if (ioctl(ttyfd, TIOCCONS, &flag) == -1) 177 err(1, "could not unset virtual console"); 178 close(ttyfd); 179} 180 181int 182main(int argc, char **argv) 183{ 184 185 if (getopt(argc, argv, "") != -1) 186 usage(); 187 argc -= optind; 188 argv += optind; 189 190 if (argc > 0 && strcmp(argv[0], "list") != 0) { 191 if (argc == 1 && strcmp(argv[0], "unset") == 0) 192 consunset(); 193 else if (argc != 2) 194 usage(); 195 else if (strcmp(argv[0], "mute") == 0) 196 consmute(argv[1]); 197 else if (strcmp(argv[0], "add") == 0) 198 consadd(argv[1]); 199 else if (strcmp(argv[0], "delete") == 0) 200 consdel(argv[1]); 201 else if (strcmp(argv[0], "set") == 0) 202 consset(argv[1]); 203 else 204 usage(); 205 } 206 consstatus(); 207 exit(0); 208} 209