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