Improve the process for GNU tools
[minix3.git] / minix / commands / zmodem / rbsb.c
blobc8f6fbcd0c990b87543b62605e1b71ebf4c6e48b
1 /*
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
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.
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
21 long Locmode; /* Saved "local mode" for 4.x BSD "new driver" */
22 long Locbit = LLITOUT; /* Bit SUPPOSED to disable output translations */
23 #include <strings.h>
24 #endif
25 #endif
27 #ifdef POSIX
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <termios.h>
31 #define OS "POSIX"
32 #endif
34 #ifndef OS
35 #ifndef USG
36 #define USG
37 #endif
38 #endif
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
50 #include "zmodem.h"
52 static unsigned getspeed(int code );
54 #if HOWMANY > 255
55 Howmany must be 255 or less
56 #endif
59 * return 1 iff stdout and stderr are different devices
60 * indicating this program operating with a modem on a
61 * different line
63 int Fromcu; /* Were called from cu or yam */
65 void from_cu()
67 struct stat a, b;
69 fstat(1, &a); fstat(2, &b);
70 Fromcu = a.st_rdev != b.st_rdev;
71 return;
74 void cucheck()
76 if (Fromcu)
77 fprintf(stderr,"Please read the manual page BUGS chapter!\r\n");
81 struct {
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},
101 int Twostop; /* Use two stop bits */
104 #ifndef READCHECK
105 #ifdef FIONREAD
106 #define READCHECK
108 * Return non 0 iff something to read from io descriptor f
110 int rdchk(int f)
112 static long lf;
114 ioctl(f, FIONREAD, &lf);
115 return ((int) lf);
117 #endif
118 #ifdef SV
119 #define READCHECK
120 #include <fcntl.h>
122 char checked = '\0' ;
124 * Nonblocking I/O is a bit different in System V, Release 2
126 int rdchk(f)
128 int lf, savestat;
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) ;
136 #endif
137 #endif
140 static unsigned
141 getspeed(int code)
143 register int n;
145 for (n=0; speeds[n].baudr; ++n)
146 if (speeds[n].speedcode == code)
147 return speeds[n].baudr;
148 return 38400; /* Assume fifo if ioctl failed */
153 #ifdef POSIX
154 struct termios oldtty, tty;
155 #else
156 #ifdef ICANON
157 struct termio oldtty, tty;
158 #else
159 struct sgttyb oldtty, tty;
160 struct tchars oldtch, tch;
161 #endif
162 #endif
164 int iofd = 0; /* File descriptor for ioctls & reads */
167 * mode(n)
168 * 3: save old tty stat, set raw mode with flow control
169 * 2: set XON/XOFF for sb/sz with ZMODEM or YMODEM-g
170 * 1: save old tty stat, set raw mode
171 * 0: restore original tty mode
173 int mode(n)
174 int n;
176 static int did0 = FALSE;
178 vfile("mode:%d", n);
179 switch(n) {
180 #ifdef POSIX
181 case 2: /* Un-raw mode used by sz, sb when -g detected */
182 if(!did0)
183 (void) tcgetattr(iofd, &oldtty);
184 tty = oldtty;
186 tty.c_iflag = BRKINT|IXON;
188 tty.c_oflag = 0; /* Transparent output */
190 tty.c_cflag &= ~PARENB; /* Disable parity */
191 tty.c_cflag |= CS8; /* Set character size = 8 */
192 if (Twostop)
193 tty.c_cflag |= CSTOPB; /* Set two stop bits */
196 tty.c_lflag = ISIG;
197 tty.c_cc[VINTR] = Zmodem ? 03:030; /* Interrupt char */
198 tty.c_cc[VQUIT] = -1; /* Quit char */
199 tty.c_cc[VMIN] = 3; /* This many chars satisfies reads */
200 tty.c_cc[VTIME] = 1; /* or in this many tenths of seconds */
202 (void) tcsetattr(iofd, TCSANOW, &tty);
203 did0 = TRUE;
204 return OK;
205 case 1:
206 case 3:
207 if(!did0)
208 (void) tcgetattr(iofd, &oldtty);
209 tty = oldtty;
211 tty.c_iflag = n==3 ? (IGNBRK|IXOFF) : IGNBRK;
213 /* No echo, crlf mapping, INTR, QUIT, delays, no erase/kill */
214 tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
216 tty.c_oflag = 0; /* Transparent output */
218 tty.c_cflag &= ~PARENB; /* Same baud rate, disable parity */
219 tty.c_cflag |= CS8; /* Set character size = 8 */
220 if (Twostop)
221 tty.c_cflag |= CSTOPB; /* Set two stop bits */
222 tty.c_cc[VMIN] = HOWMANY; /* This many chars satisfies reads */
223 tty.c_cc[VTIME] = 1; /* or in this many tenths of seconds */
224 (void) tcsetattr(iofd, TCSANOW, &tty);
225 did0 = TRUE;
226 Baudrate = cfgetospeed(&tty);
227 return OK;
228 #endif
229 #ifdef USG
230 case 2: /* Un-raw mode used by sz, sb when -g detected */
231 if(!did0)
232 (void) ioctl(iofd, TCGETA, &oldtty);
233 tty = oldtty;
235 tty.c_iflag = BRKINT|IXON;
237 tty.c_oflag = 0; /* Transparent output */
239 tty.c_cflag &= ~PARENB; /* Disable parity */
240 tty.c_cflag |= CS8; /* Set character size = 8 */
241 if (Twostop)
242 tty.c_cflag |= CSTOPB; /* Set two stop bits */
245 #ifdef READCHECK
246 tty.c_lflag = Zmodem ? 0 : ISIG;
247 tty.c_cc[VINTR] = Zmodem ? -1:030; /* Interrupt char */
248 #else
249 tty.c_lflag = ISIG;
250 tty.c_cc[VINTR] = Zmodem ? 03:030; /* Interrupt char */
251 #endif
252 tty.c_cc[VQUIT] = -1; /* Quit char */
253 #ifdef NFGVMIN
254 tty.c_cc[VMIN] = 1;
255 #else
256 tty.c_cc[VMIN] = 3; /* This many chars satisfies reads */
257 #endif
258 tty.c_cc[VTIME] = 1; /* or in this many tenths of seconds */
260 (void) ioctl(iofd, TCSETAW, &tty);
261 did0 = TRUE;
262 return OK;
263 case 1:
264 case 3:
265 if(!did0)
266 (void) ioctl(iofd, TCGETA, &oldtty);
267 tty = oldtty;
269 tty.c_iflag = n==3 ? (IGNBRK|IXOFF) : IGNBRK;
271 /* No echo, crlf mapping, INTR, QUIT, delays, no erase/kill */
272 tty.c_lflag &= ~(ECHO | ICANON | ISIG);
274 tty.c_oflag = 0; /* Transparent output */
276 tty.c_cflag &= ~PARENB; /* Same baud rate, disable parity */
277 tty.c_cflag |= CS8; /* Set character size = 8 */
278 if (Twostop)
279 tty.c_cflag |= CSTOPB; /* Set two stop bits */
280 #ifdef NFGVMIN
281 tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */
282 #else
283 tty.c_cc[VMIN] = HOWMANY; /* This many chars satisfies reads */
284 #endif
285 tty.c_cc[VTIME] = 1; /* or in this many tenths of seconds */
286 (void) ioctl(iofd, TCSETAW, &tty);
287 did0 = TRUE;
288 Baudrate = getspeed(tty.c_cflag & CBAUD);
289 return OK;
290 #endif
291 #ifdef V7
293 * NOTE: this should transmit all 8 bits and at the same time
294 * respond to XOFF/XON flow control. If no FIONREAD or other
295 * READCHECK alternative, also must respond to INTRRUPT char
296 * This doesn't work with V7. It should work with LLITOUT,
297 * but LLITOUT was broken on the machine I tried it on.
299 case 2: /* Un-raw mode used by sz, sb when -g detected */
300 if(!did0) {
301 #ifdef TIOCEXCL
302 ioctl(iofd, TIOCEXCL, 0);
303 #endif
304 ioctl(iofd, TIOCGETP, &oldtty);
305 ioctl(iofd, TIOCGETC, (struct sgttyb *) &oldtch);
306 #ifdef LLITOUT
307 ioctl(iofd, TIOCLGET, &Locmode);
308 #endif
310 tty = oldtty;
311 tch = oldtch;
312 #ifdef READCHECK
313 tch.t_intrc = Zmodem ? -1:030; /* Interrupt char */
314 #else
315 tch.t_intrc = Zmodem ? 03:030; /* Interrupt char */
316 #endif
317 #ifdef ODDP
318 tty.sg_flags |= ODDP;
319 #endif
320 #ifdef EVENP
321 tty.sg_flags |= EVENP;
322 #endif
323 #ifdef CBREAK
324 tty.sg_flags |= CBREAK;
325 #endif
326 #ifdef ALLDELAY
327 tty.sg_flags &= ~ALLDELAY;
328 #endif
329 #ifdef CRMOD
330 tty.sg_flags &= ~CRMOD;
331 #endif
332 #ifdef ECHO
333 tty.sg_flags &= ~ECHO;
334 #endif
335 #ifdef LCASE
336 tty.sg_flags &= ~LCASE;
337 #endif
339 ioctl(iofd, TIOCSETP, &tty);
340 ioctl(iofd, TIOCSETC, (struct sgttyb *) &tch);
341 #ifdef LLITOUT
342 ioctl(iofd, TIOCLBIS, &Locbit);
343 #endif
344 bibi(99); /* un-raw doesn't work w/o lit out */
345 did0 = TRUE;
346 return OK;
347 case 1:
348 case 3:
349 if(!did0) {
350 #ifdef TIOCEXCL
351 ioctl(iofd, TIOCEXCL, 0);
352 #endif
353 ioctl(iofd, TIOCGETP, &oldtty);
354 ioctl(iofd, TIOCGETC, (struct sgttyb *) &oldtch);
355 #ifdef LLITOUT
356 ioctl(iofd, TIOCLGET, &Locmode);
357 #endif
359 tty = oldtty;
360 tty.sg_flags |= RAW;
361 tty.sg_flags &= ~ECHO;
362 ioctl(iofd, TIOCSETP, &tty);
363 did0 = TRUE;
364 Baudrate = getspeed(tty.sg_ospeed);
365 return OK;
366 #endif
367 case 0:
368 if(!did0)
369 return ERROR;
370 #ifdef POSIX
371 /* Wait for output to drain, flush input queue, restore
372 * modes and restart output.
374 (void) tcsetattr(iofd, TCSAFLUSH, &oldtty);
375 (void) tcflow(iofd, TCOON);
376 #endif
377 #ifdef USG
378 (void) ioctl(iofd, TCSBRK, 1); /* Wait for output to drain */
379 (void) ioctl(iofd, TCFLSH, 1); /* Flush input queue */
380 (void) ioctl(iofd, TCSETAW, &oldtty); /* Restore modes */
381 (void) ioctl(iofd, TCXONC,1); /* Restart output */
382 #endif
383 #ifdef V7
384 ioctl(iofd, TIOCSETP, &oldtty);
385 ioctl(iofd, TIOCSETC, (struct sgttyb *) &oldtch);
386 #ifdef TIOCNXCL
387 ioctl(iofd, TIOCNXCL, 0);
388 #endif
389 #ifdef LLITOUT
390 ioctl(iofd, TIOCLSET, &Locmode);
391 #endif
392 #endif
394 return OK;
395 default:
396 return ERROR;
400 void sendbrk()
402 #ifdef POSIX
403 tcsendbreak(iofd, 1);
404 #endif
405 #ifdef V7
406 #ifdef TIOCSBRK
407 #define CANBREAK
408 sleep(1);
409 ioctl(iofd, TIOCSBRK, 0);
410 sleep(1);
411 ioctl(iofd, TIOCCBRK, 0);
412 #endif
413 #endif
414 #ifdef USG
415 #define CANBREAK
416 ioctl(iofd, TCSBRK, 0);
417 #endif
420 /* End of rbsb.c */