1: /* 2: * 3: * Rev 1997-3-28 4: * Remove use of alldelay and lcase tty flags - they're gone (at last). 5: * 6: * Rev 5-09-89 7: * This file contains Unix specific code for setting terminal modes, 8: * very little is specific to ZMODEM or YMODEM per se (that code is in 9: * sz.c and rz.c). The CRC-16 routines used by XMODEM, YMODEM, and ZMODEM 10: * are also in this file, a fast table driven macro version 11: * 12: * V7/BSD HACKERS: SEE NOTES UNDER mode(2) !!! 13: * 14: * This file is #included so the main file can set parameters such as HOWMANY. 15: * See the main files (rz.c/sz.c) for compile instructions. 16: */ 17: 18: #ifdef V7 19: #include <sys/types.h> 20: #include <sys/stat.h> 21: #define STAT 22: #include <sgtty.h> 23: #define OS "V7/BSD" 24: #define ROPMODE "r" 25: #ifdef LLITOUT 26: int Locmode; /* Saved "local mode" for 4.x BSD "new driver" */ 27: int Locbit = LLITOUT|LDECCTQ; /* Bit SUPPOSED to disable output 28: translations and only allow ^Q to 29: resume after ^S */ 30: #include <strings.h> 31: #endif 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: #define STAT 44: #include <termio.h> 45: #define OS "SYS III/V" 46: #define ROPMODE "r" 47: #define MODE2OK 48: #include <string.h> 49: #endif 50: 51: #if HOWMANY > 255 52: Howmany must be 255 or less 53: #endif 54: 55: /* 56: * return 1 iff stdout and stderr are different devices 57: * indicating this program operating with a modem on a 58: * different line 59: */ 60: int Fromcu; /* Were called from cu or yam */ 61: from_cu() 62: { 63: struct stat a, b; 64: 65: fstat(1, &a); fstat(2, &b); 66: Fromcu = a.st_rdev != b.st_rdev; 67: return; 68: } 69: cucheck() 70: { 71: if (Fromcu) 72: fprintf(stderr,"Please read the manual page BUGS chapter!\r\n"); 73: } 74: 75: 76: struct { 77: unsigned baudr; 78: int speedcode; 79: } speeds[] = { 80: 110, B110, 81: 300, B300, 82: 600, B600, 83: 1200, B1200, 84: 2400, B2400, 85: 4800, B4800, 86: 9600, B9600, 87: 19200, EXTA, 88: 38400, EXTB, 89: 0, 90: }; 91: 92: int Twostop; /* Use two stop bits */ 93: 94: 95: /* 96: * The following uses an external rdchk() routine if available, 97: * otherwise defines the function for BSD or fakes it for SYSV. 98: */ 99: 100: #ifndef READCHECK 101: #ifdef FIONREAD 102: #define READCHECK 103: /* 104: * Return non 0 iff something to read from io descriptor f 105: */ 106: rdchk(f) 107: { 108: static long lf; 109: 110: ioctl(f, FIONREAD, &lf); 111: return ((int) lf); 112: } 113: 114: #else /* FIONREAD */ 115: 116: #ifdef SV 117: #define READCHECK 118: #include <fcntl.h> 119: 120: int checked = 0; 121: /* 122: * Nonblocking I/O is a bit different in System V, Release 2 123: * Note: this rdchk vsn throws away a byte, OK for ZMODEM 124: * sender because protocol design anticipates this problem. 125: */ 126: #define EATSIT 127: rdchk(f) 128: { 129: int lf, savestat; 130: static char bchecked; 131: 132: savestat = fcntl(f, F_GETFL) ; 133: fcntl(f, F_SETFL, savestat | O_NDELAY) ; 134: lf = read(f, &bchecked, 1) ; 135: fcntl(f, F_SETFL, savestat) ; 136: checked = bchecked & 0377; /* force unsigned byte */ 137: return(lf) ; 138: } 139: #endif 140: #endif 141: #endif 142: 143: 144: static unsigned 145: getspeed(code) 146: { 147: register n; 148: 149: for (n=0; speeds[n].baudr; ++n) 150: if (speeds[n].speedcode == code) 151: return speeds[n].baudr; 152: return 38400; /* Assume fifo if ioctl failed */ 153: } 154: 155: 156: 157: #ifdef ICANON 158: struct termio oldtty, tty; 159: #else 160: struct sgttyb oldtty, tty; 161: struct tchars oldtch, tch; 162: #endif 163: 164: /* 165: * mode(n) 166: * 3: save old tty stat, set raw mode with flow control 167: * 2: set XON/XOFF for sb/sz with ZMODEM or YMODEM-g 168: * 1: save old tty stat, set raw mode 169: * 0: restore original tty mode 170: */ 171: mode(n) 172: { 173: static did0 = FALSE; 174: 175: vfile("mode:%d", n); 176: switch(n) { 177: #ifdef USG 178: case 2: /* Un-raw mode used by sz, sb when -g detected */ 179: if(!did0) 180: (void) ioctl(0, TCGETA, &oldtty); 181: tty = oldtty; 182: 183: tty.c_iflag = BRKINT|IXON; 184: 185: tty.c_oflag = 0; /* Transparent output */ 186: 187: tty.c_cflag &= ~PARENB; /* Disable parity */ 188: tty.c_cflag |= CS8; /* Set character size = 8 */ 189: if (Twostop) 190: tty.c_cflag |= CSTOPB; /* Set two stop bits */ 191: 192: 193: #ifdef READCHECK 194: tty.c_lflag = Zmodem ? 0 : ISIG; 195: tty.c_cc[VINTR] = Zmodem ? -1:030; /* Interrupt char */ 196: #else 197: tty.c_lflag = ISIG; 198: tty.c_cc[VINTR] = Zmodem ? 03:030; /* Interrupt char */ 199: #endif 200: tty.c_cc[VQUIT] = -1; /* Quit char */ 201: #ifdef NFGVMIN 202: tty.c_cc[VMIN] = 1; 203: #else 204: tty.c_cc[VMIN] = 3; /* This many chars satisfies reads */ 205: #endif 206: tty.c_cc[VTIME] = 1; /* or in this many tenths of seconds */ 207: 208: (void) ioctl(0, TCSETAW, &tty); 209: did0 = TRUE; 210: return OK; 211: case 1: 212: case 3: 213: if(!did0) 214: (void) ioctl(0, TCGETA, &oldtty); 215: tty = oldtty; 216: 217: tty.c_iflag = n==3 ? (IGNBRK|IXOFF) : IGNBRK; 218: 219: /* No echo, crlf mapping, INTR, QUIT, delays, no erase/kill */ 220: tty.c_lflag &= ~(ECHO | ICANON | ISIG); 221: 222: tty.c_oflag = 0; /* Transparent output */ 223: 224: tty.c_cflag &= ~PARENB; /* Same baud rate, disable parity */ 225: tty.c_cflag |= CS8; /* Set character size = 8 */ 226: if (Twostop) 227: tty.c_cflag |= CSTOPB; /* Set two stop bits */ 228: #ifdef NFGVMIN 229: tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */ 230: #else 231: tty.c_cc[VMIN] = HOWMANY; /* This many chars satisfies reads */ 232: #endif 233: tty.c_cc[VTIME] = 1; /* or in this many tenths of seconds */ 234: (void) ioctl(0, TCSETAW, &tty); 235: did0 = TRUE; 236: Effbaud = Baudrate = getspeed(tty.c_cflag & CBAUD); 237: return OK; 238: #endif 239: #ifdef V7 240: /* 241: * NOTE: this should transmit all 8 bits and at the same time 242: * respond to XOFF/XON flow control. If no FIONREAD or other 243: * rdchk() alternative, also must respond to INTRRUPT char 244: * This doesn't work with V7. It should work with LLITOUT, 245: * but LLITOUT was broken on the machine I tried it on. 246: */ 247: case 2: /* Un-raw mode used by sz, sb when -g detected */ 248: if(!did0) { 249: ioctl(0, TIOCEXCL, 0); 250: ioctl(0, TIOCGETP, &oldtty); 251: ioctl(0, TIOCGETC, &oldtch); 252: #ifdef LLITOUT 253: ioctl(0, TIOCLGET, &Locmode); 254: #endif 255: } 256: tty = oldtty; 257: tch = oldtch; 258: #ifdef READCHECK 259: tch.t_intrc = Zmodem ? -1:030; /* Interrupt char */ 260: #else 261: tch.t_intrc = Zmodem ? 03:030; /* Interrupt char */ 262: #endif 263: tty.sg_flags |= (ODDP|EVENP|CBREAK); 264: tty.sg_flags &= ~(CRMOD|ECHO); 265: ioctl(0, TIOCSETP, &tty); 266: ioctl(0, TIOCSETC, &tch); 267: #ifdef LLITOUT 268: ioctl(0, TIOCLBIS, &Locbit); 269: #endif 270: bibi(99); /* un-raw doesn't work w/o lit out */ 271: did0 = TRUE; 272: return OK; 273: case 1: 274: case 3: 275: if(!did0) { 276: ioctl(0, TIOCEXCL, 0); 277: ioctl(0, TIOCGETP, &oldtty); 278: ioctl(0, TIOCGETC, &oldtch); 279: #ifdef LLITOUT 280: ioctl(0, TIOCLGET, &Locmode); 281: #endif 282: } 283: tty = oldtty; 284: tty.sg_flags |= (RAW|TANDEM); 285: tty.sg_flags &= ~ECHO; 286: ioctl(0, TIOCSETP, &tty); 287: did0 = TRUE; 288: Effbaud = Baudrate = getspeed(tty.sg_ospeed); 289: return OK; 290: #endif 291: case 0: 292: if(!did0) 293: return ERROR; 294: #ifdef USG 295: (void) ioctl(0, TCSBRK, 1); /* Wait for output to drain */ 296: (void) ioctl(0, TCFLSH, 1); /* Flush input queue */ 297: (void) ioctl(0, TCSETAW, &oldtty); /* Restore modes */ 298: (void) ioctl(0, TCXONC,1); /* Restart output */ 299: #endif 300: #ifdef V7 301: ioctl(0, TIOCSETP, &oldtty); 302: ioctl(0, TIOCSETC, &oldtch); 303: ioctl(0, TIOCNXCL, 0); 304: #ifdef LLITOUT 305: ioctl(0, TIOCLSET, &Locmode); 306: #endif 307: #endif 308: 309: return OK; 310: default: 311: return ERROR; 312: } 313: } 314: 315: sendbrk() 316: { 317: #ifdef V7 318: #ifdef TIOCSBRK 319: #define CANBREAK 320: sleep(1); 321: ioctl(0, TIOCSBRK, 0); 322: sleep(1); 323: ioctl(0, TIOCCBRK, 0); 324: #endif 325: #endif 326: #ifdef USG 327: #define CANBREAK 328: ioctl(0, TCSBRK, 0); 329: #endif 330: } 331: 332: /* End of rbsb.c */