|
|
1.1 root 1: /*
2: * Copyright (c) 1988 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that the above copyright notice and this paragraph are
7: * duplicated in all such forms and that any documentation,
8: * advertising materials, and other materials related to such
9: * distribution and use acknowledge that the software was developed
10: * by the University of California, Berkeley. The name of the
11: * University may not be used to endorse or promote products derived
12: * from this software without specific prior written permission.
13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16: */
17:
18: #ifndef lint
19: static char sccsid[] = "@(#)hack.tty.c 5.2 (Berkeley) 7/22/88";
20: #endif /* not lint */
21:
22: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
23: /* hack.tty.c - version 1.0.3 */
24: /* With thanks to the people who sent code for SYSV - hpscdi!jon,
25: arnold@ucsf-cgl, wcs@bo95b, cbcephus!pds and others. */
26:
27: #include "hack.h"
28: #include <stdio.h>
29:
30: /*
31: * The distinctions here are not BSD - rest but rather USG - rest, as
32: * BSD still has the old sgttyb structure, but SYSV has termio. Thus:
33: */
34: #ifdef BSD
35: #define V7
36: #else
37: #define USG
38: #endif BSD
39:
40: /*
41: * Some systems may have getchar() return EOF for various reasons, and
42: * we should not quit before seeing at least NR_OF_EOFS consecutive EOFs.
43: */
44: #ifndef BSD
45: #define NR_OF_EOFS 20
46: #endif BSD
47:
48:
49: #ifdef USG
50:
51: #include <termio.h>
52: #define termstruct termio
53: #define kill_sym c_cc[VKILL]
54: #define erase_sym c_cc[VERASE]
55: #define EXTABS TAB3
56: #define tabflgs c_oflag
57: #define echoflgs c_lflag
58: #define cbrkflgs c_lflag
59: #define CBRKMASK ICANON
60: #define CBRKON ! /* reverse condition */
61: #define OSPEED(x) ((x).c_cflag & CBAUD)
62: #define GTTY(x) (ioctl(0, TCGETA, x))
63: #define STTY(x) (ioctl(0, TCSETA, x)) /* TCSETAF? TCSETAW? */
64:
65: #else /* V7 */
66:
67: #include <sgtty.h>
68: #define termstruct sgttyb
69: #define kill_sym sg_kill
70: #define erase_sym sg_erase
71: #define EXTABS XTABS
72: #define tabflgs sg_flags
73: #define echoflgs sg_flags
74: #define cbrkflgs sg_flags
75: #define CBRKMASK CBREAK
76: #define CBRKON /* empty */
77: #define OSPEED(x) (x).sg_ospeed
78: #define GTTY(x) (gtty(0, x))
79: #define STTY(x) (stty(0, x))
80:
81: #endif USG
82:
83: extern short ospeed;
84: static char erase_char, kill_char;
85: static boolean settty_needed = FALSE;
86: struct termstruct inittyb, curttyb;
87:
88: /*
89: * Get initial state of terminal, set ospeed (for termcap routines)
90: * and switch off tab expansion if necessary.
91: * Called by startup() in termcap.c and after returning from ! or ^Z
92: */
93: gettty(){
94: if(GTTY(&inittyb) < 0)
95: perror("Hack (gettty)");
96: curttyb = inittyb;
97: ospeed = OSPEED(inittyb);
98: erase_char = inittyb.erase_sym;
99: kill_char = inittyb.kill_sym;
100: getioctls();
101:
102: /* do not expand tabs - they might be needed inside a cm sequence */
103: if(curttyb.tabflgs & EXTABS) {
104: curttyb.tabflgs &= ~EXTABS;
105: setctty();
106: }
107: settty_needed = TRUE;
108: }
109:
110: /* reset terminal to original state */
111: settty(s) char *s; {
112: clear_screen();
113: end_screen();
114: if(s) printf(s);
115: (void) fflush(stdout);
116: if(STTY(&inittyb) < 0)
117: perror("Hack (settty)");
118: flags.echo = (inittyb.echoflgs & ECHO) ? ON : OFF;
119: flags.cbreak = (CBRKON(inittyb.cbrkflgs & CBRKMASK)) ? ON : OFF;
120: setioctls();
121: }
122:
123: setctty(){
124: if(STTY(&curttyb) < 0)
125: perror("Hack (setctty)");
126: }
127:
128:
129: setftty(){
130: register int ef = 0; /* desired value of flags & ECHO */
131: register int cf = CBRKON(CBRKMASK); /* desired value of flags & CBREAK */
132: register int change = 0;
133: flags.cbreak = ON;
134: flags.echo = OFF;
135: /* Should use (ECHO|CRMOD) here instead of ECHO */
136: if((curttyb.echoflgs & ECHO) != ef){
137: curttyb.echoflgs &= ~ECHO;
138: /* curttyb.echoflgs |= ef; */
139: change++;
140: }
141: if((curttyb.cbrkflgs & CBRKMASK) != cf){
142: curttyb.cbrkflgs &= ~CBRKMASK;
143: curttyb.cbrkflgs |= cf;
144: #ifdef USG
145: /* be satisfied with one character; no timeout */
146: curttyb.c_cc[VMIN] = 1; /* was VEOF */
147: curttyb.c_cc[VTIME] = 0; /* was VEOL */
148: #endif USG
149: change++;
150: }
151: if(change){
152: setctty();
153: }
154: start_screen();
155: }
156:
157:
158: /* fatal error */
159: /*VARARGS1*/
160: error(s,x,y) char *s; {
161: if(settty_needed)
162: settty((char *) 0);
163: printf(s,x,y);
164: putchar('\n');
165: exit(1);
166: }
167:
168: /*
169: * Read a line closed with '\n' into the array char bufp[BUFSZ].
170: * (The '\n' is not stored. The string is closed with a '\0'.)
171: * Reading can be interrupted by an escape ('\033') - now the
172: * resulting string is "\033".
173: */
174: getlin(bufp)
175: register char *bufp;
176: {
177: register char *obufp = bufp;
178: register int c;
179:
180: flags.toplin = 2; /* nonempty, no --More-- required */
181: for(;;) {
182: (void) fflush(stdout);
183: if((c = getchar()) == EOF) {
184: *bufp = 0;
185: return;
186: }
187: if(c == '\033') {
188: *obufp = c;
189: obufp[1] = 0;
190: return;
191: }
192: if(c == erase_char || c == '\b') {
193: if(bufp != obufp) {
194: bufp--;
195: putstr("\b \b"); /* putsym converts \b */
196: } else bell();
197: } else if(c == '\n') {
198: *bufp = 0;
199: return;
200: } else if(' ' <= c && c < '\177') {
201: /* avoid isprint() - some people don't have it
202: ' ' is not always a printing char */
203: *bufp = c;
204: bufp[1] = 0;
205: putstr(bufp);
206: if(bufp-obufp < BUFSZ-1 && bufp-obufp < COLNO)
207: bufp++;
208: } else if(c == kill_char || c == '\177') { /* Robert Viduya */
209: /* this test last - @ might be the kill_char */
210: while(bufp != obufp) {
211: bufp--;
212: putstr("\b \b");
213: }
214: } else
215: bell();
216: }
217: }
218:
219: getret() {
220: cgetret("");
221: }
222:
223: cgetret(s)
224: register char *s;
225: {
226: putsym('\n');
227: if(flags.standout)
228: standoutbeg();
229: putstr("Hit ");
230: putstr(flags.cbreak ? "space" : "return");
231: putstr(" to continue: ");
232: if(flags.standout)
233: standoutend();
234: xwaitforspace(s);
235: }
236:
237: char morc; /* tell the outside world what char he used */
238:
239: xwaitforspace(s)
240: register char *s; /* chars allowed besides space or return */
241: {
242: register int c;
243:
244: morc = 0;
245:
246: while((c = readchar()) != '\n') {
247: if(flags.cbreak) {
248: if(c == ' ') break;
249: if(s && index(s,c)) {
250: morc = c;
251: break;
252: }
253: bell();
254: }
255: }
256: }
257:
258: char *
259: parse()
260: {
261: static char inputline[COLNO];
262: register foo;
263:
264: flags.move = 1;
265: if(!Invisible) curs_on_u(); else home();
266: while((foo = readchar()) >= '0' && foo <= '9')
267: multi = 10*multi+foo-'0';
268: if(multi) {
269: multi--;
270: save_cm = inputline;
271: }
272: inputline[0] = foo;
273: inputline[1] = 0;
274: if(foo == 'f' || foo == 'F'){
275: inputline[1] = getchar();
276: #ifdef QUEST
277: if(inputline[1] == foo) inputline[2] = getchar(); else
278: #endif QUEST
279: inputline[2] = 0;
280: }
281: if(foo == 'm' || foo == 'M'){
282: inputline[1] = getchar();
283: inputline[2] = 0;
284: }
285: clrlin();
286: return(inputline);
287: }
288:
289: char
290: readchar() {
291: register int sym;
292:
293: (void) fflush(stdout);
294: if((sym = getchar()) == EOF)
295: #ifdef NR_OF_EOFS
296: { /*
297: * Some SYSV systems seem to return EOFs for various reasons
298: * (?like when one hits break or for interrupted systemcalls?),
299: * and we must see several before we quit.
300: */
301: register int cnt = NR_OF_EOFS;
302: while (cnt--) {
303: clearerr(stdin); /* omit if clearerr is undefined */
304: if((sym = getchar()) != EOF) goto noteof;
305: }
306: end_of_input();
307: noteof: ;
308: }
309: #else
310: end_of_input();
311: #endif NR_OF_EOFS
312: if(flags.toplin == 1)
313: flags.toplin = 2;
314: return((char) sym);
315: }
316:
317: end_of_input()
318: {
319: settty("End of input?\n");
320: clearlocks();
321: exit(0);
322: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.