source: trunk/minix/commands/zmodem/rbsb.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 8.8 KB
Line 
1/*
2 *
3 * Rev 05-05-1988
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
8 *
9 * V7/BSD HACKERS: SEE NOTES UNDER mode(2) !!!
10 *
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.
13 */
14
15#ifdef V7
16#include <sys/types.h>
17#include <sys/stat.h>
18#include <sgtty.h>
19#define OS "V7/BSD"
20#ifdef LLITOUT
21long Locmode; /* Saved "local mode" for 4.x BSD "new driver" */
22long Locbit = LLITOUT; /* Bit SUPPOSED to disable output translations */
23#include <strings.h>
24#endif
25#endif
26
27#ifdef POSIX
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <termios.h>
31#define OS "POSIX"
32#endif
33
34#ifndef OS
35#ifndef USG
36#define USG
37#endif
38#endif
39
40#ifdef USG
41#include <sys/types.h>
42#include <sys/stat.h>
43#include <termio.h>
44#include <sys/ioctl.h>
45#define OS "SYS III/V"
46#define MODE2OK
47#include <string.h>
48#endif
49
50#include "zmodem.h"
51
52_PROTOTYPE(static unsigned getspeed , (int code ));
53
54#if HOWMANY > 255
55Howmany must be 255 or less
56#endif
57
58/*
59 * return 1 iff stdout and stderr are different devices
60 * indicating this program operating with a modem on a
61 * different line
62 */
63int Fromcu; /* Were called from cu or yam */
64
65void from_cu()
66{
67 struct stat a, b;
68
69 fstat(1, &a); fstat(2, &b);
70 Fromcu = a.st_rdev != b.st_rdev;
71 return;
72}
73
74void cucheck()
75{
76 if (Fromcu)
77 fprintf(stderr,"Please read the manual page BUGS chapter!\r\n");
78}
79
80
81struct {
82 unsigned baudr;
83 int speedcode;
84} speeds[] = {
85 110, B110,
86 300, B300,
87#ifdef B600
88 600, B600,
89#endif
90 1200, B1200,
91 2400, B2400,
92 4800, B4800,
93 9600, B9600,
94#ifdef EXTA
95 19200, EXTA,
96 38400, EXTB,
97#endif
98 0,
99};
100
101int Twostop; /* Use two stop bits */
102
103
104#ifndef READCHECK
105#ifdef FIONREAD
106#define READCHECK
107/*
108 * Return non 0 iff something to read from io descriptor f
109 */
110int rdchk(f)
111{
112 static long lf;
113
114 ioctl(f, FIONREAD, &lf);
115 return ((int) lf);
116}
117#endif
118#ifdef SV
119#define READCHECK
120#include <fcntl.h>
121
122char checked = '\0' ;
123/*
124 * Nonblocking I/O is a bit different in System V, Release 2
125 */
126int rdchk(f)
127{
128 int lf, savestat;
129
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) ;
134 return(lf) ;
135}
136#endif
137#endif
138
139
140static unsigned
141getspeed(code)
142int code;
143{
144 register n;
145
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 */
150}
151
152
153
154#ifdef POSIX
155struct termios oldtty, tty;
156#else
157#ifdef ICANON
158struct termio oldtty, tty;
159#else
160struct sgttyb oldtty, tty;
161struct tchars oldtch, tch;
162#endif
163#endif
164
165int iofd = 0; /* File descriptor for ioctls & reads */
166
167/*
168 * mode(n)
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
173 */
174int mode(n)
175int n;
176{
177 static did0 = FALSE;
178
179 vfile("mode:%d", n);
180 switch(n) {
181#ifdef POSIX
182 case 2: /* Un-raw mode used by sz, sb when -g detected */
183 if(!did0)
184 (void) tcgetattr(iofd, &oldtty);
185 tty = oldtty;
186
187 tty.c_iflag = BRKINT|IXON;
188
189 tty.c_oflag = 0; /* Transparent output */
190
191 tty.c_cflag &= ~PARENB; /* Disable parity */
192 tty.c_cflag |= CS8; /* Set character size = 8 */
193 if (Twostop)
194 tty.c_cflag |= CSTOPB; /* Set two stop bits */
195
196
197 tty.c_lflag = ISIG;
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 */
202
203 (void) tcsetattr(iofd, TCSANOW, &tty);
204 did0 = TRUE;
205 return OK;
206 case 1:
207 case 3:
208 if(!did0)
209 (void) tcgetattr(iofd, &oldtty);
210 tty = oldtty;
211
212 tty.c_iflag = n==3 ? (IGNBRK|IXOFF) : IGNBRK;
213
214 /* No echo, crlf mapping, INTR, QUIT, delays, no erase/kill */
215 tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
216
217 tty.c_oflag = 0; /* Transparent output */
218
219 tty.c_cflag &= ~PARENB; /* Same baud rate, disable parity */
220 tty.c_cflag |= CS8; /* Set character size = 8 */
221 if (Twostop)
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);
226 did0 = TRUE;
227 Baudrate = cfgetospeed(&tty);
228 return OK;
229#endif
230#ifdef USG
231 case 2: /* Un-raw mode used by sz, sb when -g detected */
232 if(!did0)
233 (void) ioctl(iofd, TCGETA, &oldtty);
234 tty = oldtty;
235
236 tty.c_iflag = BRKINT|IXON;
237
238 tty.c_oflag = 0; /* Transparent output */
239
240 tty.c_cflag &= ~PARENB; /* Disable parity */
241 tty.c_cflag |= CS8; /* Set character size = 8 */
242 if (Twostop)
243 tty.c_cflag |= CSTOPB; /* Set two stop bits */
244
245
246#ifdef READCHECK
247 tty.c_lflag = Zmodem ? 0 : ISIG;
248 tty.c_cc[VINTR] = Zmodem ? -1:030; /* Interrupt char */
249#else
250 tty.c_lflag = ISIG;
251 tty.c_cc[VINTR] = Zmodem ? 03:030; /* Interrupt char */
252#endif
253 tty.c_cc[VQUIT] = -1; /* Quit char */
254#ifdef NFGVMIN
255 tty.c_cc[VMIN] = 1;
256#else
257 tty.c_cc[VMIN] = 3; /* This many chars satisfies reads */
258#endif
259 tty.c_cc[VTIME] = 1; /* or in this many tenths of seconds */
260
261 (void) ioctl(iofd, TCSETAW, &tty);
262 did0 = TRUE;
263 return OK;
264 case 1:
265 case 3:
266 if(!did0)
267 (void) ioctl(iofd, TCGETA, &oldtty);
268 tty = oldtty;
269
270 tty.c_iflag = n==3 ? (IGNBRK|IXOFF) : IGNBRK;
271
272 /* No echo, crlf mapping, INTR, QUIT, delays, no erase/kill */
273 tty.c_lflag &= ~(ECHO | ICANON | ISIG);
274
275 tty.c_oflag = 0; /* Transparent output */
276
277 tty.c_cflag &= ~PARENB; /* Same baud rate, disable parity */
278 tty.c_cflag |= CS8; /* Set character size = 8 */
279 if (Twostop)
280 tty.c_cflag |= CSTOPB; /* Set two stop bits */
281#ifdef NFGVMIN
282 tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */
283#else
284 tty.c_cc[VMIN] = HOWMANY; /* This many chars satisfies reads */
285#endif
286 tty.c_cc[VTIME] = 1; /* or in this many tenths of seconds */
287 (void) ioctl(iofd, TCSETAW, &tty);
288 did0 = TRUE;
289 Baudrate = getspeed(tty.c_cflag & CBAUD);
290 return OK;
291#endif
292#ifdef V7
293 /*
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.
299 */
300 case 2: /* Un-raw mode used by sz, sb when -g detected */
301 if(!did0) {
302#ifdef TIOCEXCL
303 ioctl(iofd, TIOCEXCL, 0);
304#endif
305 ioctl(iofd, TIOCGETP, &oldtty);
306 ioctl(iofd, TIOCGETC, (struct sgttyb *) &oldtch);
307#ifdef LLITOUT
308 ioctl(iofd, TIOCLGET, &Locmode);
309#endif
310 }
311 tty = oldtty;
312 tch = oldtch;
313#ifdef READCHECK
314 tch.t_intrc = Zmodem ? -1:030; /* Interrupt char */
315#else
316 tch.t_intrc = Zmodem ? 03:030; /* Interrupt char */
317#endif
318#ifdef ODDP
319 tty.sg_flags |= ODDP;
320#endif
321#ifdef EVENP
322 tty.sg_flags |= EVENP;
323#endif
324#ifdef CBREAK
325 tty.sg_flags |= CBREAK;
326#endif
327#ifdef ALLDELAY
328 tty.sg_flags &= ~ALLDELAY;
329#endif
330#ifdef CRMOD
331 tty.sg_flags &= ~CRMOD;
332#endif
333#ifdef ECHO
334 tty.sg_flags &= ~ECHO;
335#endif
336#ifdef LCASE
337 tty.sg_flags &= ~LCASE;
338#endif
339
340 ioctl(iofd, TIOCSETP, &tty);
341 ioctl(iofd, TIOCSETC, (struct sgttyb *) &tch);
342#ifdef LLITOUT
343 ioctl(iofd, TIOCLBIS, &Locbit);
344#endif
345 bibi(99); /* un-raw doesn't work w/o lit out */
346 did0 = TRUE;
347 return OK;
348 case 1:
349 case 3:
350 if(!did0) {
351#ifdef TIOCEXCL
352 ioctl(iofd, TIOCEXCL, 0);
353#endif
354 ioctl(iofd, TIOCGETP, &oldtty);
355 ioctl(iofd, TIOCGETC, (struct sgttyb *) &oldtch);
356#ifdef LLITOUT
357 ioctl(iofd, TIOCLGET, &Locmode);
358#endif
359 }
360 tty = oldtty;
361 tty.sg_flags |= RAW;
362 tty.sg_flags &= ~ECHO;
363 ioctl(iofd, TIOCSETP, &tty);
364 did0 = TRUE;
365 Baudrate = getspeed(tty.sg_ospeed);
366 return OK;
367#endif
368 case 0:
369 if(!did0)
370 return ERROR;
371#ifdef POSIX
372 /* Wait for output to drain, flush input queue, restore
373 * modes and restart output.
374 */
375 (void) tcsetattr(iofd, TCSAFLUSH, &oldtty);
376 (void) tcflow(iofd, TCOON);
377#endif
378#ifdef USG
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 */
383#endif
384#ifdef V7
385 ioctl(iofd, TIOCSETP, &oldtty);
386 ioctl(iofd, TIOCSETC, (struct sgttyb *) &oldtch);
387#ifdef TIOCNXCL
388 ioctl(iofd, TIOCNXCL, 0);
389#endif
390#ifdef LLITOUT
391 ioctl(iofd, TIOCLSET, &Locmode);
392#endif
393#endif
394
395 return OK;
396 default:
397 return ERROR;
398 }
399}
400
401void sendbrk()
402{
403#ifdef POSIX
404 tcsendbreak(iofd, 1);
405#endif
406#ifdef V7
407#ifdef TIOCSBRK
408#define CANBREAK
409 sleep(1);
410 ioctl(iofd, TIOCSBRK, 0);
411 sleep(1);
412 ioctl(iofd, TIOCCBRK, 0);
413#endif
414#endif
415#ifdef USG
416#define CANBREAK
417 ioctl(iofd, TCSBRK, 0);
418#endif
419}
420
421/* End of rbsb.c */
Note: See TracBrowser for help on using the repository browser.