147843Sbostic /*- 248945Sbostic * Copyright (c) 1989, 1991 The Regents of the University of California. 347843Sbostic * All rights reserved. 447843Sbostic * 549269Sbostic * %sccs.include.redist.c% 619907Sdist */ 719907Sdist 813073Ssam #ifndef lint 919907Sdist char copyright[] = 1048945Sbostic "@(#) Copyright (c) 1989, 1991 The Regents of the University of California.\n\ 1119907Sdist All rights reserved.\n"; 1247843Sbostic #endif /* not lint */ 1319907Sdist 1419907Sdist #ifndef lint 15*50007Sbostic static char sccsid[] = "@(#)stty.c 5.27 (Berkeley) 06/05/91"; 1647843Sbostic #endif /* not lint */ 1719907Sdist 1838674Smarc #include <sys/types.h> 1948945Sbostic #include <fcntl.h> 2038674Smarc #include <errno.h> 2148945Sbostic #include <unistd.h> 2248945Sbostic #include <stdio.h> 2338674Smarc #include <ctype.h> 2448945Sbostic #include <stdlib.h> 2548945Sbostic #include <string.h> 2648945Sbostic #include "stty.h" 2748945Sbostic #include "extern.h" 281179Sbill 29*50007Sbostic static char usage[] = "usage: stty: [-eg] [-f file] [options]"; 3038674Smarc 3138674Smarc main(argc, argv) 3248945Sbostic int argc; 3348945Sbostic char **argv; 341179Sbill { 3548945Sbostic register struct modes *mp; 3648945Sbostic register struct cchar *cp; 37*50007Sbostic struct info i; 38*50007Sbostic struct key *kp; 3948945Sbostic enum FMT fmt; 40*50007Sbostic int ch; 411179Sbill 4248945Sbostic fmt = NOTSET; 43*50007Sbostic i.fd = STDIN_FILENO; 44*50007Sbostic 4548974Sbostic opterr = 0; 4649974Sbostic while (strspn(argv[optind], "-aefg") == strlen(argv[optind]) && 4749974Sbostic (ch = getopt(argc, argv, "aef:g")) != EOF) 4848945Sbostic switch(ch) { 4948945Sbostic case 'a': /* undocumented: POSIX compatibility */ 5048945Sbostic fmt = POSIX; 5148945Sbostic break; 5248945Sbostic case 'e': 5348945Sbostic fmt = BSD; 5448945Sbostic break; 5548945Sbostic case 'f': 56*50007Sbostic if ((i.fd = open(optarg, O_RDONLY | O_NONBLOCK)) < 0) 5749974Sbostic err("%s: %s", optarg, strerror(errno)); 5848945Sbostic break; 5948945Sbostic case 'g': 6048945Sbostic fmt = GFLAG; 6148945Sbostic break; 6248945Sbostic case '?': 6348945Sbostic default: 6448945Sbostic goto args; 6548945Sbostic } 6648945Sbostic 6748945Sbostic args: argc -= optind; 6848945Sbostic argv += optind; 6948945Sbostic 70*50007Sbostic if (ioctl(i.fd, TIOCGETD, &i.ldisc) < 0) 7148945Sbostic err("TIOCGETD: %s", strerror(errno)); 72*50007Sbostic if (tcgetattr(i.fd, &i.t) < 0) 7348945Sbostic err("tcgetattr: %s", strerror(errno)); 74*50007Sbostic if (ioctl(i.fd, TIOCGWINSZ, &i.win) < 0) 7548945Sbostic warn("TIOCGWINSZ: %s\n", strerror(errno)); 7638674Smarc 7748945Sbostic checkredirect(); /* conversion aid */ 7848945Sbostic 7948945Sbostic switch(fmt) { 8048945Sbostic case NOTSET: 8148945Sbostic if (*argv) 8248945Sbostic break; 8348945Sbostic /* FALLTHROUGH */ 8448945Sbostic case BSD: 8548945Sbostic case POSIX: 86*50007Sbostic print(&i.t, &i.win, i.ldisc, fmt); 8748945Sbostic break; 8848945Sbostic case GFLAG: 89*50007Sbostic gprint(&i.t, &i.win, i.ldisc); 9048945Sbostic break; 911179Sbill } 9238674Smarc 93*50007Sbostic for (i.set = i.wset = 0; *argv; ++argv) { 94*50007Sbostic i.off = **argv == '-'; 95*50007Sbostic if (kp = ksearch(i.off ? *argv + 1 : *argv)) { 96*50007Sbostic if (!(kp->flags & F_OFFOK) && i.off) 97*50007Sbostic err("illegal option -- %s\n%s", *argv, usage); 98*50007Sbostic if (kp->flags & F_NEEDARG && !(i.arg = *++argv)) 99*50007Sbostic err("option requires an argument -- %s\n%s", 100*50007Sbostic kp->name, usage); 101*50007Sbostic kp->f(&i); 10248945Sbostic continue; 1031179Sbill } 10448945Sbostic 105*50007Sbostic 106*50007Sbostic #define CHK(s) (**argv == s[0] && !strcmp(*argv, s)) 10748945Sbostic for (mp = cmodes; mp->name; ++mp) 10848945Sbostic if (CHK(mp->name)) { 109*50007Sbostic i.t.c_cflag &= ~mp->unset; 110*50007Sbostic i.t.c_cflag |= mp->set; 111*50007Sbostic i.set = 1; 11238674Smarc goto next; 1131179Sbill } 11448945Sbostic for (mp = imodes; mp->name; ++mp) 11548945Sbostic if (CHK(mp->name)) { 116*50007Sbostic i.t.c_iflag &= ~mp->unset; 117*50007Sbostic i.t.c_iflag |= mp->set; 118*50007Sbostic i.set = 1; 11938674Smarc goto next; 12038674Smarc } 12148945Sbostic for (mp = lmodes; mp->name; ++mp) 12248945Sbostic if (CHK(mp->name)) { 123*50007Sbostic i.t.c_lflag &= ~mp->unset; 124*50007Sbostic i.t.c_lflag |= mp->set; 125*50007Sbostic i.set = 1; 12638674Smarc goto next; 12738674Smarc } 12848945Sbostic for (mp = omodes; mp->name; ++mp) 12948945Sbostic if (CHK(mp->name)) { 130*50007Sbostic i.t.c_oflag &= ~mp->unset; 131*50007Sbostic i.t.c_oflag |= mp->set; 132*50007Sbostic i.set = 1; 13338674Smarc goto next; 13438674Smarc } 135*50007Sbostic 136*50007Sbostic for (cp = cchars1; cp->name; ++cp) 137*50007Sbostic if (CHK(cp->name)) 138*50007Sbostic goto ccfound; 13948945Sbostic for (cp = cchars2; cp->name; ++cp) { 14048945Sbostic if (!CHK(cp->name)) 14148945Sbostic continue; 14248945Sbostic ccfound: if (!*++argv) 143*50007Sbostic err("option requires an argument -- %s\n%s", 144*50007Sbostic cp->name, usage); 14549847Sbostic if (CHK("undef") || CHK("<undef>")) 146*50007Sbostic i.t.c_cc[cp->sub] = _POSIX_VDISABLE; 14748945Sbostic else if (**argv == '^') 148*50007Sbostic i.t.c_cc[cp->sub] = 14948945Sbostic ((*argv)[1] == '?') ? 0177 : 15048945Sbostic ((*argv)[1] == '-') ? _POSIX_VDISABLE : 15148945Sbostic (*argv)[1] & 037; 15248945Sbostic else 153*50007Sbostic i.t.c_cc[cp->sub] = **argv; 154*50007Sbostic i.set = 1; 155*50007Sbostic continue; 15648945Sbostic } 15748945Sbostic 15838674Smarc if (isdigit(**argv)) { 159*50007Sbostic cfsetospeed(&i.t, atoi(*argv)); 160*50007Sbostic cfsetispeed(&i.t, atoi(*argv)); 161*50007Sbostic continue; 16238674Smarc } 16348945Sbostic if (!strncmp(*argv, "gfmt1", sizeof("gfmt1") - 1)) { 164*50007Sbostic gread(&i.t, *argv + sizeof("gfmt1") - 1); 165*50007Sbostic continue; 16643323Smarc } 16748945Sbostic 168*50007Sbostic err("illegal option -- %s\n%s", *argv, usage); 16948945Sbostic next: continue; 1701179Sbill } 17148945Sbostic 172*50007Sbostic if (i.set && tcsetattr(i.fd, 0, &i.t) < 0) 17348945Sbostic err("tcsetattr: %s", strerror(errno)); 174*50007Sbostic if (i.wset && ioctl(i.fd, TIOCSWINSZ, &i.win) < 0) 17548945Sbostic warn("TIOCSWINSZ: %s", strerror(errno)); 17638674Smarc exit(0); 1771179Sbill } 178