xref: /netbsd-src/sbin/ttyflags/ttyflags.c (revision 424f4c982d1e95077a47e7e3c337da3c635ccf19)
1*424f4c98Smrg /* $NetBSD: ttyflags.c,v 1.19 2014/05/04 20:43:30 mrg Exp $ */
20114e805Scgd 
330783705Scgd /*
430783705Scgd  * Copyright (c) 1994 Christopher G. Demetriou
530783705Scgd  * All rights reserved.
630783705Scgd  *
730783705Scgd  * Redistribution and use in source and binary forms, with or without
830783705Scgd  * modification, are permitted provided that the following conditions
930783705Scgd  * are met:
1030783705Scgd  * 1. Redistributions of source code must retain the above copyright
1130783705Scgd  *    notice, this list of conditions and the following disclaimer.
1230783705Scgd  * 2. Redistributions in binary form must reproduce the above copyright
1330783705Scgd  *    notice, this list of conditions and the following disclaimer in the
1430783705Scgd  *    documentation and/or other materials provided with the distribution.
1530783705Scgd  * 3. All advertising materials mentioning features or use of this software
1630783705Scgd  *    must display the following acknowledgement:
17db755e7cScgd  *          This product includes software developed for the
18c39c2e62Sgrant  *          NetBSD Project.  See http://www.NetBSD.org/ for
19db755e7cScgd  *          information about NetBSD.
2030783705Scgd  * 4. The name of the author may not be used to endorse or promote products
21db755e7cScgd  *    derived from this software without specific prior written permission.
2230783705Scgd  *
2330783705Scgd  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2430783705Scgd  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2530783705Scgd  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2630783705Scgd  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2730783705Scgd  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2830783705Scgd  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2930783705Scgd  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3030783705Scgd  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3130783705Scgd  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3230783705Scgd  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33db755e7cScgd  *
34db755e7cScgd  * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
3530783705Scgd  */
3630783705Scgd 
372e61b867Slukem #include <sys/cdefs.h>
3830783705Scgd #ifndef lint
396543a91fSlukem __COPYRIGHT("@(#) Copyright (c) 1994\
406543a91fSlukem  Christopher G. Demetriou.  All rights reserved.");
4130783705Scgd #endif /* not lint */
4230783705Scgd 
4330783705Scgd #ifndef lint
44*424f4c98Smrg __RCSID("$NetBSD: ttyflags.c,v 1.19 2014/05/04 20:43:30 mrg Exp $");
4530783705Scgd #endif /* not lint */
4630783705Scgd 
4730783705Scgd #include <sys/types.h>
4830783705Scgd #include <sys/ioctl.h>
4930783705Scgd 
5030783705Scgd #include <err.h>
5130783705Scgd #include <errno.h>
5230783705Scgd #include <fcntl.h>
5330783705Scgd #include <limits.h>
5430783705Scgd #include <paths.h>
5530783705Scgd #include <stdio.h>
5630783705Scgd #include <stdlib.h>
57c32e2614Scgd #include <string.h>
5830783705Scgd #include <ttyent.h>
5930783705Scgd #include <unistd.h>
6030783705Scgd 
61b7935600Sjoerg static int change_all(void);
62b7935600Sjoerg static int change_ttyflags(struct ttyent *);
63b7935600Sjoerg static int change_ttys(char **);
64b7935600Sjoerg __dead static void usage(void);
6530783705Scgd 
66b7935600Sjoerg static int nflag, vflag;
6730783705Scgd 
6830783705Scgd /*
6930783705Scgd  * Ttyflags sets the device-specific tty flags, based on the contents
7030783705Scgd  * of /etc/ttys.  It can either set all of the ttys' flags, or set
7130783705Scgd  * the flags of the ttys specified on the command line.
7230783705Scgd  */
7330783705Scgd int
main(int argc,char * argv[])74d9f85c21Sxtraeme main(int argc, char *argv[])
7530783705Scgd {
7630783705Scgd 	int aflag, ch, rval;
7730783705Scgd 
7830783705Scgd 	aflag = nflag = vflag = 0;
792e61b867Slukem 	while ((ch = getopt(argc, argv, "anv")) != -1)
8030783705Scgd 		switch (ch) {
8130783705Scgd 		case 'a':
8230783705Scgd 			aflag = 1;
8330783705Scgd 			break;
8430783705Scgd 		case 'n':		/* undocumented */
8530783705Scgd 			nflag = 1;
8630783705Scgd 			break;
8730783705Scgd 		case 'v':
8830783705Scgd 			vflag = 1;
8930783705Scgd 			break;
9030783705Scgd 		case '?':
9130783705Scgd 		default:
9230783705Scgd 			usage();
9330783705Scgd 		}
9430783705Scgd 	argc -= optind;
9530783705Scgd 	argv += optind;
9630783705Scgd 
9730783705Scgd 	if (aflag && argc != 0)
9830783705Scgd 		usage();
9930783705Scgd 
10030783705Scgd 	rval = 0;
10130783705Scgd 
10230783705Scgd 	if (setttyent() == 0)
10330783705Scgd 		err(1, "setttyent");
10430783705Scgd 
10530783705Scgd 	if (aflag)
10630783705Scgd 		rval = change_all();
10730783705Scgd 	else
10830783705Scgd 		rval = change_ttys(argv);
10930783705Scgd 
11030783705Scgd 	if (endttyent() == 0)
11130783705Scgd 		warn("endttyent");
11230783705Scgd 
11330783705Scgd 	exit(rval);
11430783705Scgd }
11530783705Scgd 
11630783705Scgd /*
11730783705Scgd  * Change all /etc/ttys entries' flags.
11830783705Scgd  */
119b7935600Sjoerg static int
change_all(void)120d9f85c21Sxtraeme change_all(void)
12130783705Scgd {
12230783705Scgd 	struct ttyent *tep;
12330783705Scgd 	int rval;
12430783705Scgd 
12530783705Scgd 	rval = 0;
12630783705Scgd 	for (tep = getttyent(); tep != NULL; tep = getttyent())
12730783705Scgd 		if (change_ttyflags(tep))
12830783705Scgd 			rval = 1;
12930783705Scgd 	return (rval);
13030783705Scgd }
13130783705Scgd 
13230783705Scgd /*
13330783705Scgd  * Change the specified ttys' flags.
13430783705Scgd  */
135b7935600Sjoerg static int
change_ttys(char ** ttylist)136d9f85c21Sxtraeme change_ttys(char **ttylist)
13730783705Scgd {
13830783705Scgd 	struct ttyent *tep;
13930783705Scgd 	int rval;
14030783705Scgd 
14130783705Scgd 	rval = 0;
14230783705Scgd 	for (; *ttylist != NULL; ttylist++) {
14330783705Scgd 		tep = getttynam(*ttylist);
14430783705Scgd 		if (tep == NULL) {
14530783705Scgd 			warnx("couldn't find an entry in %s for \"%s\"",
14630783705Scgd 			    _PATH_TTYS, *ttylist);
14730783705Scgd 			rval = 1;
14830783705Scgd 			continue;
14930783705Scgd 		}
15030783705Scgd 
15130783705Scgd 		if (change_ttyflags(tep))
15230783705Scgd 			rval = 1;
15330783705Scgd 	}
15430783705Scgd 	return (rval);
15530783705Scgd }
15630783705Scgd 
157e759e917Schristos 
15830783705Scgd /*
159e759e917Schristos  * Actually do the work; find out what the new flags value should be,
16030783705Scgd  * open the device, and change the flags.
16130783705Scgd  */
162b7935600Sjoerg static int
change_ttyflags(struct ttyent * tep)163d9f85c21Sxtraeme change_ttyflags(struct ttyent *tep)
16430783705Scgd {
165e759e917Schristos 	int fd, flags, rval, st, sep;
16630783705Scgd 	char path[PATH_MAX];
167e759e917Schristos 	char strflags[256];
16830783705Scgd 
16930783705Scgd 	st = tep->ty_status;
170e759e917Schristos 	sep = flags = rval = 0;
171e759e917Schristos 	strflags[0] = '\0';
172e759e917Schristos 
17330783705Scgd 
17430783705Scgd 	/* Convert ttyent.h flags into ioctl flags. */
175e759e917Schristos 	if (st & TTY_LOCAL) {
17630783705Scgd 		flags |= TIOCFLAG_CLOCAL;
177ca9297afSitojun 		(void)strlcat(strflags, "local", sizeof(strflags));
178e759e917Schristos 		sep++;
179e759e917Schristos 	}
180e759e917Schristos 	if (st & TTY_RTSCTS) {
18130783705Scgd 		flags |= TIOCFLAG_CRTSCTS;
182e759e917Schristos 		if (sep++)
183ca9297afSitojun 			(void)strlcat(strflags, "|", sizeof(strflags));
184ca9297afSitojun 		(void)strlcat(strflags, "rtscts", sizeof(strflags));
185e759e917Schristos 	}
18694cf4332Sscottr 	if (st & TTY_DTRCTS) {
18794cf4332Sscottr 		flags |= TIOCFLAG_CDTRCTS;
18894cf4332Sscottr 		if (sep++)
189ca9297afSitojun 			(void)strlcat(strflags, "|", sizeof(strflags));
190ca9297afSitojun 		(void)strlcat(strflags, "dtrcts", sizeof(strflags));
19194cf4332Sscottr 	}
192e759e917Schristos 	if (st & TTY_SOFTCAR) {
19330783705Scgd 		flags |= TIOCFLAG_SOFTCAR;
194e759e917Schristos 		if (sep++)
195ca9297afSitojun 			(void)strlcat(strflags, "|", sizeof(strflags));
196ca9297afSitojun 		(void)strlcat(strflags, "softcar", sizeof(strflags));
197e759e917Schristos 	}
198e759e917Schristos 	if (st & TTY_MDMBUF) {
19930783705Scgd 		flags |= TIOCFLAG_MDMBUF;
200e759e917Schristos 		if (sep++)
201ca9297afSitojun 			(void)strlcat(strflags, "|", sizeof(strflags));
202ca9297afSitojun 		(void)strlcat(strflags, "mdmbuf", sizeof(strflags));
203e759e917Schristos 	}
204e759e917Schristos 
205e759e917Schristos 	if (strflags[0] == '\0')
206ca9297afSitojun 		(void)strlcpy(strflags, "none", sizeof(strflags));
20730783705Scgd 
20830783705Scgd 	/* Find the full device path name. */
20930783705Scgd 	(void)snprintf(path, sizeof path, "%s%s", _PATH_DEV, tep->ty_name);
21030783705Scgd 
21130783705Scgd 	if (vflag)
212e759e917Schristos 		warnx("setting flags on %s to %s", path, strflags);
21330783705Scgd 	if (nflag)
21430783705Scgd 		return (0);
21530783705Scgd 
21630783705Scgd 	/* Open the device NON-BLOCKING, set the flags, and close it. */
217*424f4c98Smrg 	if ((fd = open(path, O_RDWR | O_NONBLOCK, 0)) == -1) {
218f091151dScgd 		if (!(errno == ENXIO ||
219f091151dScgd 		      (errno == ENOENT && (st & TTY_ON) == 0)))
22030783705Scgd 			rval = 1;
221d4c11604Scgd 		if (rval || vflag)
222d4c11604Scgd 			warn("open %s", path);
223d4c11604Scgd 		return (rval);
224d4c11604Scgd 	}
225d4c11604Scgd 	if (ioctl(fd, TIOCSFLAGS, &flags) == -1)
226d4c11604Scgd 		if (errno != ENOTTY || vflag) {
227d4c11604Scgd 			warn("TIOCSFLAGS on %s", path);
228d4c11604Scgd 			rval = (errno != ENOTTY);
22930783705Scgd 		}
23030783705Scgd 	if (close(fd) == -1) {
23130783705Scgd 		warn("close %s", path);
23230783705Scgd 		return (1);
23330783705Scgd 	}
23430783705Scgd 	return (rval);
23530783705Scgd }
23630783705Scgd 
23730783705Scgd /*
23830783705Scgd  * Print usage information when a bogus set of arguments is given.
23930783705Scgd  */
240b7935600Sjoerg static void
usage(void)241d9f85c21Sxtraeme usage(void)
24230783705Scgd {
24330783705Scgd 	(void)fprintf(stderr, "usage: ttyflags [-v] [-a | tty ... ]\n");
24430783705Scgd 	exit(1);
24530783705Scgd }
246