4 * This file contains Unix specific code for setting terminal modes,
5 * very little is specific to ZMODEM or YMODEM per se (that code is in
6 * sz.c and rz.c). The CRC-16 routines used by XMODEM, YMODEM, and ZMODEM
7 * are also in this file, a fast table driven macro version
9 * V7/BSD HACKERS: SEE NOTES UNDER mode(2) !!!
11 * This file is #included so the main file can set parameters such as HOWMANY.
12 * See the main files (rz.c/sz.c) for compile instructions.
16 #include <sys/types.h>
21 long Locmode
; /* Saved "local mode" for 4.x BSD "new driver" */
22 long Locbit
= LLITOUT
; /* Bit SUPPOSED to disable output translations */
28 #include <sys/types.h>
41 #include <sys/types.h>
44 #include <sys/ioctl.h>
45 #define OS "SYS III/V"
52 static unsigned getspeed(int code
);
55 Howmany must be
255 or less
59 * return 1 iff stdout and stderr are different devices
60 * indicating this program operating with a modem on a
63 int Fromcu
; /* Were called from cu or yam */
69 fstat(1, &a
); fstat(2, &b
);
70 Fromcu
= a
.st_rdev
!= b
.st_rdev
;
77 fprintf(stderr
,"Please read the manual page BUGS chapter!\r\n");
101 int Twostop
; /* Use two stop bits */
108 * Return non 0 iff something to read from io descriptor f
114 ioctl(f
, FIONREAD
, &lf
);
122 char checked
= '\0' ;
124 * Nonblocking I/O is a bit different in System V, Release 2
130 savestat
= fcntl(f
, F_GETFL
) ;
131 fcntl(f
, F_SETFL
, savestat
| O_NDELAY
) ;
132 lf
= read(f
, &checked
, 1) ;
133 fcntl(f
, F_SETFL
, savestat
) ;
146 for (n
=0; speeds
[n
].baudr
; ++n
)
147 if (speeds
[n
].speedcode
== code
)
148 return speeds
[n
].baudr
;
149 return 38400; /* Assume fifo if ioctl failed */
155 struct termios oldtty
, tty
;
158 struct termio oldtty
, tty
;
160 struct sgttyb oldtty
, tty
;
161 struct tchars oldtch
, tch
;
165 int iofd
= 0; /* File descriptor for ioctls & reads */
169 * 3: save old tty stat, set raw mode with flow control
170 * 2: set XON/XOFF for sb/sz with ZMODEM or YMODEM-g
171 * 1: save old tty stat, set raw mode
172 * 0: restore original tty mode
182 case 2: /* Un-raw mode used by sz, sb when -g detected */
184 (void) tcgetattr(iofd
, &oldtty
);
187 tty
.c_iflag
= BRKINT
|IXON
;
189 tty
.c_oflag
= 0; /* Transparent output */
191 tty
.c_cflag
&= ~PARENB
; /* Disable parity */
192 tty
.c_cflag
|= CS8
; /* Set character size = 8 */
194 tty
.c_cflag
|= CSTOPB
; /* Set two stop bits */
198 tty
.c_cc
[VINTR
] = Zmodem
? 03:030; /* Interrupt char */
199 tty
.c_cc
[VQUIT
] = -1; /* Quit char */
200 tty
.c_cc
[VMIN
] = 3; /* This many chars satisfies reads */
201 tty
.c_cc
[VTIME
] = 1; /* or in this many tenths of seconds */
203 (void) tcsetattr(iofd
, TCSANOW
, &tty
);
209 (void) tcgetattr(iofd
, &oldtty
);
212 tty
.c_iflag
= n
==3 ? (IGNBRK
|IXOFF
) : IGNBRK
;
214 /* No echo, crlf mapping, INTR, QUIT, delays, no erase/kill */
215 tty
.c_lflag
&= ~(ECHO
| ECHONL
| ICANON
| ISIG
| IEXTEN
);
217 tty
.c_oflag
= 0; /* Transparent output */
219 tty
.c_cflag
&= ~PARENB
; /* Same baud rate, disable parity */
220 tty
.c_cflag
|= CS8
; /* Set character size = 8 */
222 tty
.c_cflag
|= CSTOPB
; /* Set two stop bits */
223 tty
.c_cc
[VMIN
] = HOWMANY
; /* This many chars satisfies reads */
224 tty
.c_cc
[VTIME
] = 1; /* or in this many tenths of seconds */
225 (void) tcsetattr(iofd
, TCSANOW
, &tty
);
227 Baudrate
= cfgetospeed(&tty
);
231 case 2: /* Un-raw mode used by sz, sb when -g detected */
233 (void) ioctl(iofd
, TCGETA
, &oldtty
);
236 tty
.c_iflag
= BRKINT
|IXON
;
238 tty
.c_oflag
= 0; /* Transparent output */
240 tty
.c_cflag
&= ~PARENB
; /* Disable parity */
241 tty
.c_cflag
|= CS8
; /* Set character size = 8 */
243 tty
.c_cflag
|= CSTOPB
; /* Set two stop bits */
247 tty
.c_lflag
= Zmodem
? 0 : ISIG
;
248 tty
.c_cc
[VINTR
] = Zmodem
? -1:030; /* Interrupt char */
251 tty
.c_cc
[VINTR
] = Zmodem
? 03:030; /* Interrupt char */
253 tty
.c_cc
[VQUIT
] = -1; /* Quit char */
257 tty
.c_cc
[VMIN
] = 3; /* This many chars satisfies reads */
259 tty
.c_cc
[VTIME
] = 1; /* or in this many tenths of seconds */
261 (void) ioctl(iofd
, TCSETAW
, &tty
);
267 (void) ioctl(iofd
, TCGETA
, &oldtty
);
270 tty
.c_iflag
= n
==3 ? (IGNBRK
|IXOFF
) : IGNBRK
;
272 /* No echo, crlf mapping, INTR, QUIT, delays, no erase/kill */
273 tty
.c_lflag
&= ~(ECHO
| ICANON
| ISIG
);
275 tty
.c_oflag
= 0; /* Transparent output */
277 tty
.c_cflag
&= ~PARENB
; /* Same baud rate, disable parity */
278 tty
.c_cflag
|= CS8
; /* Set character size = 8 */
280 tty
.c_cflag
|= CSTOPB
; /* Set two stop bits */
282 tty
.c_cc
[VMIN
] = 1; /* This many chars satisfies reads */
284 tty
.c_cc
[VMIN
] = HOWMANY
; /* This many chars satisfies reads */
286 tty
.c_cc
[VTIME
] = 1; /* or in this many tenths of seconds */
287 (void) ioctl(iofd
, TCSETAW
, &tty
);
289 Baudrate
= getspeed(tty
.c_cflag
& CBAUD
);
294 * NOTE: this should transmit all 8 bits and at the same time
295 * respond to XOFF/XON flow control. If no FIONREAD or other
296 * READCHECK alternative, also must respond to INTRRUPT char
297 * This doesn't work with V7. It should work with LLITOUT,
298 * but LLITOUT was broken on the machine I tried it on.
300 case 2: /* Un-raw mode used by sz, sb when -g detected */
303 ioctl(iofd
, TIOCEXCL
, 0);
305 ioctl(iofd
, TIOCGETP
, &oldtty
);
306 ioctl(iofd
, TIOCGETC
, (struct sgttyb
*) &oldtch
);
308 ioctl(iofd
, TIOCLGET
, &Locmode
);
314 tch
.t_intrc
= Zmodem
? -1:030; /* Interrupt char */
316 tch
.t_intrc
= Zmodem
? 03:030; /* Interrupt char */
319 tty
.sg_flags
|= ODDP
;
322 tty
.sg_flags
|= EVENP
;
325 tty
.sg_flags
|= CBREAK
;
328 tty
.sg_flags
&= ~ALLDELAY
;
331 tty
.sg_flags
&= ~CRMOD
;
334 tty
.sg_flags
&= ~ECHO
;
337 tty
.sg_flags
&= ~LCASE
;
340 ioctl(iofd
, TIOCSETP
, &tty
);
341 ioctl(iofd
, TIOCSETC
, (struct sgttyb
*) &tch
);
343 ioctl(iofd
, TIOCLBIS
, &Locbit
);
345 bibi(99); /* un-raw doesn't work w/o lit out */
352 ioctl(iofd
, TIOCEXCL
, 0);
354 ioctl(iofd
, TIOCGETP
, &oldtty
);
355 ioctl(iofd
, TIOCGETC
, (struct sgttyb
*) &oldtch
);
357 ioctl(iofd
, TIOCLGET
, &Locmode
);
362 tty
.sg_flags
&= ~ECHO
;
363 ioctl(iofd
, TIOCSETP
, &tty
);
365 Baudrate
= getspeed(tty
.sg_ospeed
);
372 /* Wait for output to drain, flush input queue, restore
373 * modes and restart output.
375 (void) tcsetattr(iofd
, TCSAFLUSH
, &oldtty
);
376 (void) tcflow(iofd
, TCOON
);
379 (void) ioctl(iofd
, TCSBRK
, 1); /* Wait for output to drain */
380 (void) ioctl(iofd
, TCFLSH
, 1); /* Flush input queue */
381 (void) ioctl(iofd
, TCSETAW
, &oldtty
); /* Restore modes */
382 (void) ioctl(iofd
, TCXONC
,1); /* Restart output */
385 ioctl(iofd
, TIOCSETP
, &oldtty
);
386 ioctl(iofd
, TIOCSETC
, (struct sgttyb
*) &oldtch
);
388 ioctl(iofd
, TIOCNXCL
, 0);
391 ioctl(iofd
, TIOCLSET
, &Locmode
);
404 tcsendbreak(iofd
, 1);
410 ioctl(iofd
, TIOCSBRK
, 0);
412 ioctl(iofd
, TIOCCBRK
, 0);
417 ioctl(iofd
, TCSBRK
, 0);