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*49847Sbostic static char sccsid[] = "@(#)stty.c 5.24 (Berkeley) 05/22/91"; 1647843Sbostic #endif /* not lint */ 1719907Sdist 1838674Smarc #include <sys/types.h> 1937609Sbostic #include <sys/ioctl.h> 2048945Sbostic #include <termios.h> 2148945Sbostic #include <fcntl.h> 2238674Smarc #include <errno.h> 2348945Sbostic #include <unistd.h> 2448945Sbostic #include <stdio.h> 2538674Smarc #include <ctype.h> 2648945Sbostic #include <stdlib.h> 2748945Sbostic #include <string.h> 2848945Sbostic #include "stty.h" 2948945Sbostic #include "extern.h" 301179Sbill 3148945Sbostic static void usage __P((void)); 3238674Smarc 3338674Smarc main(argc, argv) 3448945Sbostic int argc; 3548945Sbostic char **argv; 361179Sbill { 3738674Smarc extern char *optarg; 3848974Sbostic extern int opterr, optind; 3948945Sbostic extern struct cchar cchars1[], cchars2[]; 4048945Sbostic extern struct modes cmodes[], imodes[], lmodes[], omodes[]; 4148945Sbostic register struct modes *mp; 4248945Sbostic register struct cchar *cp; 4348945Sbostic struct winsize win; 4448945Sbostic struct termios t; 4548945Sbostic enum FMT fmt; 4648945Sbostic int ch, ctl, ldisc, tmp; 471179Sbill 4848945Sbostic ctl = STDIN_FILENO; 4948945Sbostic fmt = NOTSET; 5048974Sbostic opterr = 0; 5148945Sbostic while ((ch = getopt(argc, argv, "aef:g")) != EOF) 5248945Sbostic switch(ch) { 5348945Sbostic case 'a': /* undocumented: POSIX compatibility */ 5448945Sbostic fmt = POSIX; 5548945Sbostic break; 5648945Sbostic case 'e': 5748945Sbostic fmt = BSD; 5848945Sbostic break; 5948945Sbostic case 'f': 6048945Sbostic if ((ctl = open(optarg, O_RDONLY | O_NONBLOCK)) < 0) 6148945Sbostic err(optarg); 6248945Sbostic break; 6348945Sbostic case 'g': 6448945Sbostic fmt = GFLAG; 6548945Sbostic break; 6648945Sbostic case '?': 6748945Sbostic default: 6848945Sbostic goto args; 6948945Sbostic } 7048945Sbostic 7148945Sbostic args: argc -= optind; 7248945Sbostic argv += optind; 7348945Sbostic 7438674Smarc if (ioctl(ctl, TIOCGETD, &ldisc) < 0) 7548945Sbostic err("TIOCGETD: %s", strerror(errno)); 7638674Smarc if (tcgetattr(ctl, &t) < 0) 7748945Sbostic err("tcgetattr: %s", strerror(errno)); 7838674Smarc if (ioctl(ctl, TIOCGWINSZ, &win) < 0) 7948945Sbostic warn("TIOCGWINSZ: %s\n", strerror(errno)); 8038674Smarc 8148945Sbostic checkredirect(); /* conversion aid */ 8248945Sbostic 8348945Sbostic switch(fmt) { 8448945Sbostic case NOTSET: 8548945Sbostic if (*argv) 8648945Sbostic break; 8748945Sbostic /* FALLTHROUGH */ 8848945Sbostic case BSD: 8948945Sbostic case POSIX: 9048945Sbostic print(&t, &win, ldisc, fmt); 9148945Sbostic break; 9248945Sbostic case GFLAG: 9348945Sbostic gprint(&t, &win, ldisc); 9448945Sbostic break; 951179Sbill } 9638674Smarc 9748945Sbostic #define CHK(s) (**argv == s[0] && !strcmp(*argv, s)) 9848945Sbostic 9948945Sbostic for (; *argv; ++argv) { 10048945Sbostic if (CHK("-nl")) { 10148945Sbostic t.c_iflag |= ICRNL; 10248945Sbostic t.c_oflag |= ONLCR; 10348945Sbostic continue; 1041179Sbill } 10548945Sbostic if (CHK("all")) { 10648945Sbostic print(&t, &win, ldisc, BSD); 10748945Sbostic continue; 1081179Sbill } 10948945Sbostic if (CHK("-cbreak")) 11048945Sbostic goto reset; 11148945Sbostic if (CHK("cbreak")) { 11248945Sbostic t.c_iflag | BRKINT|IXON|IMAXBEL; 11348945Sbostic t.c_oflag |= OPOST; 11448945Sbostic t.c_lflag |= ISIG|IEXTEN; 11548945Sbostic t.c_lflag &= ~ICANON; 11648945Sbostic continue; 1171179Sbill } 11848945Sbostic if (CHK("cols")) { 11948945Sbostic if (!*++argv) 12048945Sbostic err("option requires an argument -- cols"); 12148945Sbostic goto columns; 1221179Sbill } 12348945Sbostic if (CHK("columns")) { 12448945Sbostic if (!*++argv) 12548945Sbostic err("option requires an argument -- columns"); 12648945Sbostic columns: win.ws_col = atoi(*argv); 12748945Sbostic continue; 1283797Sroot } 12948945Sbostic if (CHK("cooked")) 13048945Sbostic goto reset; 13148945Sbostic if (CHK("dec")) { 13238674Smarc t.c_cc[VERASE] = (u_char)0177; 13338674Smarc t.c_cc[VKILL] = CTRL('u'); 13438674Smarc t.c_cc[VINTR] = CTRL('c'); 13538674Smarc t.c_lflag &= ~ECHOPRT; 13638674Smarc t.c_lflag |= ECHOE|ECHOKE|ECHOCTL; 13738674Smarc t.c_iflag &= ~IXANY; 13848945Sbostic continue; 1391179Sbill } 14048945Sbostic if (CHK("everything")) { 14148945Sbostic print(&t, &win, ldisc, BSD); 14248945Sbostic continue; 14348945Sbostic } 14448945Sbostic if (CHK("-extproc")) { 14548945Sbostic tmp = 0; 14648945Sbostic ioctl(ctl, TIOCEXT, &tmp); 14748945Sbostic continue; 14848945Sbostic } 14948945Sbostic if (CHK("extrpc")) { 15048945Sbostic tmp = 1; 15148945Sbostic ioctl(ctl, TIOCEXT, &tmp); 15248945Sbostic continue; 15348945Sbostic } 15448945Sbostic if (CHK("ispeed")) { 15548945Sbostic if (!*++argv) 15648945Sbostic err("option requires an argument -- ispeed"); 15748945Sbostic cfsetispeed(&t, atoi(*argv)); 15848945Sbostic continue; 15948945Sbostic } 16048945Sbostic if (CHK("new")) 16148945Sbostic goto tty; 16248945Sbostic if (CHK("nl")) { 16348945Sbostic t.c_iflag &= ~ICRNL; 16448945Sbostic t.c_oflag &= ~ONLCR; 16548945Sbostic continue; 16648945Sbostic } 16748945Sbostic if (CHK("old")) 16848945Sbostic goto tty; 16948945Sbostic if (CHK("ospeed")) { 17048945Sbostic if (!*++argv) 17148945Sbostic err("option requires an argument -- ospeed"); 17248945Sbostic cfsetospeed(&t, atoi(*argv)); 17348945Sbostic continue; 17448945Sbostic } 17548945Sbostic if (CHK("-raw")) 17648945Sbostic goto reset; 17748945Sbostic if (CHK("raw")) { 17840169Skarels cfmakeraw(&t); 17940169Skarels t.c_cflag &= ~(CSIZE|PARENB); 18040169Skarels t.c_cflag |= CS8; 18148945Sbostic continue; 18240169Skarels } 18348945Sbostic if (CHK("rows")) { 18448945Sbostic if (!*++argv) 18548945Sbostic err("option requires an argument -- rows"); 18648945Sbostic win.ws_row = atoi(*argv); 18748945Sbostic continue; 18845029Smarc } 18948945Sbostic if (CHK("sane")) { 19048945Sbostic reset: t.c_cflag = TTYDEF_CFLAG | (t.c_cflag & CLOCAL); 19140169Skarels t.c_iflag = TTYDEF_IFLAG; 19240169Skarels t.c_iflag |= ICRNL; 19340169Skarels /* preserve user-preference flags in lflag */ 19440169Skarels #define LKEEP (ECHOKE|ECHOE|ECHOK|ECHOPRT|ECHOCTL|ALTWERASE|TOSTOP|NOFLSH) 19540169Skarels t.c_lflag = TTYDEF_LFLAG | (t.c_lflag & LKEEP); 19640169Skarels t.c_oflag = TTYDEF_OFLAG; 19748945Sbostic continue; 19840169Skarels } 19948945Sbostic if (CHK("size")) { 20048945Sbostic (void)printf("%d %d\n", win.ws_row, win.ws_col); 20148945Sbostic continue; 20218023Sbloom } 20348945Sbostic if (CHK("speed")) { 20448945Sbostic (void)printf("%d\n", cfgetospeed(&t)); 20548945Sbostic continue; 20638674Smarc } 20748945Sbostic if (CHK("tty")) { 20848945Sbostic tty: tmp = TTYDISC; 20948945Sbostic if (ioctl(0, TIOCSETD, &tmp) < 0) 21048945Sbostic err("TIOCSETD: %s", strerror(errno)); 21148945Sbostic continue; 21238674Smarc } 21348945Sbostic 21448945Sbostic for (mp = cmodes; mp->name; ++mp) 21548945Sbostic if (CHK(mp->name)) { 21648945Sbostic t.c_cflag &= ~mp->unset; 21748945Sbostic t.c_cflag |= mp->set; 21838674Smarc goto next; 2191179Sbill } 22048945Sbostic for (mp = imodes; mp->name; ++mp) 22148945Sbostic if (CHK(mp->name)) { 22248945Sbostic t.c_iflag &= ~mp->unset; 22348945Sbostic t.c_iflag |= mp->set; 22438674Smarc goto next; 22538674Smarc } 22648945Sbostic for (mp = lmodes; mp->name; ++mp) 22748945Sbostic if (CHK(mp->name)) { 22848945Sbostic t.c_lflag &= ~mp->unset; 22948945Sbostic t.c_lflag |= mp->set; 23038674Smarc goto next; 23138674Smarc } 23248945Sbostic for (mp = omodes; mp->name; ++mp) 23348945Sbostic if (CHK(mp->name)) { 23448945Sbostic t.c_oflag &= ~mp->unset; 23548945Sbostic t.c_oflag |= mp->set; 23638674Smarc goto next; 23738674Smarc } 23848945Sbostic for (cp = cchars1; cp->name; ++cp) { 23948945Sbostic if (!CHK(cp->name)) 24048945Sbostic continue; 24148945Sbostic goto ccfound; 2421179Sbill } 24348945Sbostic for (cp = cchars2; cp->name; ++cp) { 24448945Sbostic if (!CHK(cp->name)) 24548945Sbostic continue; 24648945Sbostic ccfound: if (!*++argv) 24748945Sbostic err("option requires an argument -- %s", 24848945Sbostic cp->name); 249*49847Sbostic if (CHK("undef") || CHK("<undef>")) 25048945Sbostic t.c_cc[cp->sub] = _POSIX_VDISABLE; 25148945Sbostic else if (**argv == '^') 25248945Sbostic t.c_cc[cp->sub] = 25348945Sbostic ((*argv)[1] == '?') ? 0177 : 25448945Sbostic ((*argv)[1] == '-') ? _POSIX_VDISABLE : 25548945Sbostic (*argv)[1] & 037; 25648945Sbostic else 25748945Sbostic t.c_cc[cp->sub] = **argv; 25848945Sbostic goto next; 25948945Sbostic } 26048945Sbostic 26138674Smarc if (isdigit(**argv)) { 26238674Smarc cfsetospeed(&t, atoi(*argv)); 26338674Smarc cfsetispeed(&t, atoi(*argv)); 26438674Smarc goto next; 26538674Smarc } 26648945Sbostic if (!strncmp(*argv, "gfmt1", sizeof("gfmt1") - 1)) { 26748945Sbostic gread(&t, *argv + sizeof("gfmt1") - 1); 26843323Smarc goto next; 26943323Smarc } 27048945Sbostic 27148945Sbostic err("illegal option -- %s", *argv); 27248945Sbostic next: continue; 2731179Sbill } 27448945Sbostic 27538674Smarc if (tcsetattr(ctl, 0, &t) < 0) 27648945Sbostic err("tcsetattr: %s", strerror(errno)); 27738674Smarc if (ioctl(ctl, TIOCSWINSZ, &win) < 0) 27848945Sbostic warn("TIOCSWINSZ: %s", strerror(errno)); 27938674Smarc exit(0); 2801179Sbill } 2811179Sbill 28248945Sbostic static void 28348945Sbostic usage() 28443323Smarc { 28548945Sbostic (void)fprintf(stderr, "usage: stty: [-eg] [-f file] [options]\n"); 28638674Smarc exit(1); 28738674Smarc } 288