ttyflags.c revision 1.19 1 1.19 mrg /* $NetBSD: ttyflags.c,v 1.19 2014/05/04 20:43:30 mrg Exp $ */
2 1.4 cgd
3 1.1 cgd /*
4 1.1 cgd * Copyright (c) 1994 Christopher G. Demetriou
5 1.1 cgd * All rights reserved.
6 1.12 cgd *
7 1.1 cgd * Redistribution and use in source and binary forms, with or without
8 1.1 cgd * modification, are permitted provided that the following conditions
9 1.1 cgd * are met:
10 1.1 cgd * 1. Redistributions of source code must retain the above copyright
11 1.1 cgd * notice, this list of conditions and the following disclaimer.
12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 cgd * notice, this list of conditions and the following disclaimer in the
14 1.1 cgd * documentation and/or other materials provided with the distribution.
15 1.1 cgd * 3. All advertising materials mentioning features or use of this software
16 1.1 cgd * must display the following acknowledgement:
17 1.12 cgd * This product includes software developed for the
18 1.13 grant * NetBSD Project. See http://www.NetBSD.org/ for
19 1.12 cgd * information about NetBSD.
20 1.1 cgd * 4. The name of the author may not be used to endorse or promote products
21 1.12 cgd * derived from this software without specific prior written permission.
22 1.12 cgd *
23 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 1.1 cgd * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 1.1 cgd * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 1.1 cgd * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 1.1 cgd * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 1.1 cgd * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 1.1 cgd * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 1.1 cgd * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 1.1 cgd * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 1.1 cgd * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 1.12 cgd *
34 1.12 cgd * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
35 1.1 cgd */
36 1.1 cgd
37 1.9 lukem #include <sys/cdefs.h>
38 1.1 cgd #ifndef lint
39 1.17 lukem __COPYRIGHT("@(#) Copyright (c) 1994\
40 1.17 lukem Christopher G. Demetriou. All rights reserved.");
41 1.1 cgd #endif /* not lint */
42 1.1 cgd
43 1.1 cgd #ifndef lint
44 1.19 mrg __RCSID("$NetBSD: ttyflags.c,v 1.19 2014/05/04 20:43:30 mrg Exp $");
45 1.1 cgd #endif /* not lint */
46 1.1 cgd
47 1.1 cgd #include <sys/types.h>
48 1.1 cgd #include <sys/ioctl.h>
49 1.1 cgd
50 1.1 cgd #include <err.h>
51 1.1 cgd #include <errno.h>
52 1.1 cgd #include <fcntl.h>
53 1.1 cgd #include <limits.h>
54 1.1 cgd #include <paths.h>
55 1.1 cgd #include <stdio.h>
56 1.1 cgd #include <stdlib.h>
57 1.8 cgd #include <string.h>
58 1.1 cgd #include <ttyent.h>
59 1.1 cgd #include <unistd.h>
60 1.1 cgd
61 1.18 joerg static int change_all(void);
62 1.18 joerg static int change_ttyflags(struct ttyent *);
63 1.18 joerg static int change_ttys(char **);
64 1.18 joerg __dead static void usage(void);
65 1.1 cgd
66 1.18 joerg static int nflag, vflag;
67 1.1 cgd
68 1.1 cgd /*
69 1.1 cgd * Ttyflags sets the device-specific tty flags, based on the contents
70 1.1 cgd * of /etc/ttys. It can either set all of the ttys' flags, or set
71 1.1 cgd * the flags of the ttys specified on the command line.
72 1.1 cgd */
73 1.1 cgd int
74 1.15 xtraeme main(int argc, char *argv[])
75 1.1 cgd {
76 1.1 cgd int aflag, ch, rval;
77 1.1 cgd
78 1.1 cgd aflag = nflag = vflag = 0;
79 1.9 lukem while ((ch = getopt(argc, argv, "anv")) != -1)
80 1.1 cgd switch (ch) {
81 1.1 cgd case 'a':
82 1.1 cgd aflag = 1;
83 1.1 cgd break;
84 1.1 cgd case 'n': /* undocumented */
85 1.1 cgd nflag = 1;
86 1.1 cgd break;
87 1.1 cgd case 'v':
88 1.1 cgd vflag = 1;
89 1.1 cgd break;
90 1.1 cgd case '?':
91 1.1 cgd default:
92 1.1 cgd usage();
93 1.1 cgd }
94 1.1 cgd argc -= optind;
95 1.1 cgd argv += optind;
96 1.1 cgd
97 1.1 cgd if (aflag && argc != 0)
98 1.1 cgd usage();
99 1.1 cgd
100 1.1 cgd rval = 0;
101 1.1 cgd
102 1.1 cgd if (setttyent() == 0)
103 1.1 cgd err(1, "setttyent");
104 1.1 cgd
105 1.1 cgd if (aflag)
106 1.1 cgd rval = change_all();
107 1.1 cgd else
108 1.1 cgd rval = change_ttys(argv);
109 1.1 cgd
110 1.1 cgd if (endttyent() == 0)
111 1.1 cgd warn("endttyent");
112 1.1 cgd
113 1.1 cgd exit(rval);
114 1.1 cgd }
115 1.1 cgd
116 1.1 cgd /*
117 1.1 cgd * Change all /etc/ttys entries' flags.
118 1.1 cgd */
119 1.18 joerg static int
120 1.15 xtraeme change_all(void)
121 1.1 cgd {
122 1.1 cgd struct ttyent *tep;
123 1.1 cgd int rval;
124 1.1 cgd
125 1.1 cgd rval = 0;
126 1.1 cgd for (tep = getttyent(); tep != NULL; tep = getttyent())
127 1.1 cgd if (change_ttyflags(tep))
128 1.1 cgd rval = 1;
129 1.1 cgd return (rval);
130 1.1 cgd }
131 1.1 cgd
132 1.1 cgd /*
133 1.1 cgd * Change the specified ttys' flags.
134 1.1 cgd */
135 1.18 joerg static int
136 1.15 xtraeme change_ttys(char **ttylist)
137 1.1 cgd {
138 1.1 cgd struct ttyent *tep;
139 1.1 cgd int rval;
140 1.1 cgd
141 1.1 cgd rval = 0;
142 1.1 cgd for (; *ttylist != NULL; ttylist++) {
143 1.1 cgd tep = getttynam(*ttylist);
144 1.1 cgd if (tep == NULL) {
145 1.1 cgd warnx("couldn't find an entry in %s for \"%s\"",
146 1.1 cgd _PATH_TTYS, *ttylist);
147 1.1 cgd rval = 1;
148 1.1 cgd continue;
149 1.1 cgd }
150 1.1 cgd
151 1.1 cgd if (change_ttyflags(tep))
152 1.1 cgd rval = 1;
153 1.1 cgd }
154 1.1 cgd return (rval);
155 1.1 cgd }
156 1.1 cgd
157 1.7 christos
158 1.1 cgd /*
159 1.7 christos * Actually do the work; find out what the new flags value should be,
160 1.1 cgd * open the device, and change the flags.
161 1.1 cgd */
162 1.18 joerg static int
163 1.15 xtraeme change_ttyflags(struct ttyent *tep)
164 1.1 cgd {
165 1.7 christos int fd, flags, rval, st, sep;
166 1.1 cgd char path[PATH_MAX];
167 1.7 christos char strflags[256];
168 1.1 cgd
169 1.1 cgd st = tep->ty_status;
170 1.7 christos sep = flags = rval = 0;
171 1.7 christos strflags[0] = '\0';
172 1.1 cgd
173 1.7 christos
174 1.1 cgd /* Convert ttyent.h flags into ioctl flags. */
175 1.7 christos if (st & TTY_LOCAL) {
176 1.1 cgd flags |= TIOCFLAG_CLOCAL;
177 1.14 itojun (void)strlcat(strflags, "local", sizeof(strflags));
178 1.7 christos sep++;
179 1.7 christos }
180 1.7 christos if (st & TTY_RTSCTS) {
181 1.1 cgd flags |= TIOCFLAG_CRTSCTS;
182 1.7 christos if (sep++)
183 1.14 itojun (void)strlcat(strflags, "|", sizeof(strflags));
184 1.14 itojun (void)strlcat(strflags, "rtscts", sizeof(strflags));
185 1.10 scottr }
186 1.10 scottr if (st & TTY_DTRCTS) {
187 1.10 scottr flags |= TIOCFLAG_CDTRCTS;
188 1.10 scottr if (sep++)
189 1.14 itojun (void)strlcat(strflags, "|", sizeof(strflags));
190 1.14 itojun (void)strlcat(strflags, "dtrcts", sizeof(strflags));
191 1.7 christos }
192 1.7 christos if (st & TTY_SOFTCAR) {
193 1.1 cgd flags |= TIOCFLAG_SOFTCAR;
194 1.7 christos if (sep++)
195 1.14 itojun (void)strlcat(strflags, "|", sizeof(strflags));
196 1.14 itojun (void)strlcat(strflags, "softcar", sizeof(strflags));
197 1.7 christos }
198 1.7 christos if (st & TTY_MDMBUF) {
199 1.1 cgd flags |= TIOCFLAG_MDMBUF;
200 1.7 christos if (sep++)
201 1.14 itojun (void)strlcat(strflags, "|", sizeof(strflags));
202 1.14 itojun (void)strlcat(strflags, "mdmbuf", sizeof(strflags));
203 1.7 christos }
204 1.7 christos
205 1.7 christos if (strflags[0] == '\0')
206 1.14 itojun (void)strlcpy(strflags, "none", sizeof(strflags));
207 1.1 cgd
208 1.1 cgd /* Find the full device path name. */
209 1.1 cgd (void)snprintf(path, sizeof path, "%s%s", _PATH_DEV, tep->ty_name);
210 1.1 cgd
211 1.1 cgd if (vflag)
212 1.7 christos warnx("setting flags on %s to %s", path, strflags);
213 1.1 cgd if (nflag)
214 1.1 cgd return (0);
215 1.1 cgd
216 1.1 cgd /* Open the device NON-BLOCKING, set the flags, and close it. */
217 1.19 mrg if ((fd = open(path, O_RDWR | O_NONBLOCK, 0)) == -1) {
218 1.6 cgd if (!(errno == ENXIO ||
219 1.6 cgd (errno == ENOENT && (st & TTY_ON) == 0)))
220 1.2 cgd rval = 1;
221 1.2 cgd if (rval || vflag)
222 1.2 cgd warn("open %s", path);
223 1.2 cgd return (rval);
224 1.1 cgd }
225 1.2 cgd if (ioctl(fd, TIOCSFLAGS, &flags) == -1)
226 1.2 cgd if (errno != ENOTTY || vflag) {
227 1.2 cgd warn("TIOCSFLAGS on %s", path);
228 1.2 cgd rval = (errno != ENOTTY);
229 1.2 cgd }
230 1.1 cgd if (close(fd) == -1) {
231 1.1 cgd warn("close %s", path);
232 1.1 cgd return (1);
233 1.1 cgd }
234 1.1 cgd return (rval);
235 1.1 cgd }
236 1.1 cgd
237 1.1 cgd /*
238 1.1 cgd * Print usage information when a bogus set of arguments is given.
239 1.1 cgd */
240 1.18 joerg static void
241 1.15 xtraeme usage(void)
242 1.1 cgd {
243 1.1 cgd (void)fprintf(stderr, "usage: ttyflags [-v] [-a | tty ... ]\n");
244 1.1 cgd exit(1);
245 1.1 cgd }
246