Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sbin/conscontrol/conscontrol.c
39475 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2001 Jonathan Lemon <[email protected]>
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*/
28
29
#include <sys/types.h>
30
#include <sys/sysctl.h>
31
#include <sys/ioctl.h>
32
#include <sys/ttycom.h>
33
34
#include <err.h>
35
#include <errno.h>
36
#include <fcntl.h>
37
#include <stdio.h>
38
#include <stdlib.h>
39
#include <string.h>
40
#include <unistd.h>
41
42
#define DEVDIR "/dev/"
43
44
static void __dead2
45
usage(void)
46
{
47
48
(void)fprintf(stderr, "%s\n%s\n%s\n%s\n",
49
"usage: conscontrol [list]",
50
" conscontrol mute on | off",
51
" conscontrol add | delete console",
52
" conscontrol set | unset console");
53
exit(1);
54
}
55
56
static void
57
consstatus(void)
58
{
59
int mute;
60
size_t len;
61
char *buf, *p, *avail;
62
63
len = sizeof(mute);
64
if (sysctlbyname("kern.consmute", &mute, &len, NULL, 0) == -1)
65
err(1, "kern.consmute retrieval failed");
66
if (sysctlbyname("kern.console", NULL, &len, NULL, 0) == -1)
67
err(1, "kern.console estimate failed");
68
if ((buf = malloc(len)) == NULL)
69
errx(1, "kern.console malloc failed");
70
if (sysctlbyname("kern.console", buf, &len, NULL, 0) == -1)
71
err(1, "kern.console retrieval failed");
72
if ((avail = strchr(buf, '/')) == NULL)
73
errx(1, "kern.console format not understood");
74
p = avail;
75
*avail++ = '\0';
76
if (p != buf)
77
*--p = '\0'; /* remove trailing ',' */
78
p = avail + strlen(avail);
79
if (p != avail)
80
*--p = '\0'; /* remove trailing ',' */
81
printf("Configured: %s\n", buf);
82
printf(" Available: %s\n", avail);
83
printf(" Muting: %s\n", mute ? "on" : "off");
84
free(buf);
85
}
86
87
static void
88
consmute(const char *onoff)
89
{
90
int mute;
91
size_t len;
92
93
if (strcmp(onoff, "on") == 0)
94
mute = 1;
95
else if (strcmp(onoff, "off") == 0)
96
mute = 0;
97
else
98
usage();
99
len = sizeof(mute);
100
if (sysctlbyname("kern.consmute", NULL, NULL, &mute, len) == -1)
101
err(1, "could not change console muting");
102
}
103
104
/*
105
* The name we supply to the sysctls should be an entry in /dev. If
106
* the user has specified the full pathname in /dev, DTRT. If he
107
* specifies a name in some other directory, it's an error.
108
*/
109
110
static char*
111
stripdev(char *devnam)
112
{
113
if (memcmp (devnam, DEVDIR, strlen(DEVDIR)) == 0)
114
return (&devnam[strlen(DEVDIR)]); /* remove /dev */
115
else if (strchr (devnam, '/')) {
116
fprintf(stderr, "Not a device in /dev: %s\n", devnam);
117
return (NULL); /* end of string */
118
} else
119
return (devnam); /* passed */
120
}
121
122
static void
123
consadd(char *devnam)
124
{
125
size_t len;
126
127
devnam = stripdev(devnam);
128
if (devnam == NULL)
129
return;
130
len = strlen(devnam);
131
if (sysctlbyname("kern.console", NULL, NULL, devnam, len) == -1)
132
err(1, "could not add %s as a console", devnam);
133
}
134
135
static void
136
consdel(char *devnam)
137
{
138
char *buf;
139
size_t len;
140
141
devnam = stripdev(devnam);
142
if (devnam == NULL)
143
return;
144
len = strlen(devnam) + sizeof("-");
145
if ((buf = malloc(len)) == NULL)
146
errx(1, "malloc failed");
147
buf[0] = '-';
148
strcpy(buf + 1, devnam);
149
if (sysctlbyname("kern.console", NULL, NULL, buf, len) == -1)
150
err(1, "could not remove %s as a console", devnam);
151
free(buf);
152
}
153
154
static void
155
consset(char *devnam, int flag)
156
{
157
int ttyfd;
158
159
ttyfd = open(devnam, O_RDONLY);
160
if (ttyfd == -1)
161
err(1, "opening %s", devnam);
162
if (ioctl(ttyfd, TIOCCONS, &flag) == -1)
163
err(1, "could not %s %s as virtual console",
164
flag ? "set" : "unset", devnam);
165
close(ttyfd);
166
}
167
168
int
169
main(int argc, char **argv)
170
{
171
172
if (getopt(argc, argv, "") != -1)
173
usage();
174
argc -= optind;
175
argv += optind;
176
177
if (argc > 0 && strcmp(argv[0], "list") != 0) {
178
if (argc != 2)
179
usage();
180
else if (strcmp(argv[0], "mute") == 0)
181
consmute(argv[1]);
182
else if (strcmp(argv[0], "add") == 0)
183
consadd(argv[1]);
184
else if (strcmp(argv[0], "delete") == 0)
185
consdel(argv[1]);
186
else if (strcmp(argv[0], "set") == 0)
187
consset(argv[1], 1);
188
else if (strcmp(argv[0], "unset") == 0)
189
consset(argv[1], 0);
190
else
191
usage();
192
}
193
consstatus();
194
exit(0);
195
}
196
197