1 /* 2 * The following routines try to encapsulate what is system dependent 3 * (at least between 4.x and dos) which is used in telnet.c. 4 */ 5 6 #if defined(unix) 7 8 #include <sys/ioctl.h> 9 #include <sys/time.h> 10 #include <signal.h> 11 12 #include "defines.h" 13 #include "externs.h" 14 #include "types.h" 15 16 int 17 HaveInput; /* There is input available to scan */ 18 19 #if defined(TN3270) 20 static char tline[200]; 21 char *transcom = 0; /* transparent mode command (default: none) */ 22 #endif /* defined(TN3270) */ 23 24 static struct tchars otc = { 0 }, ntc = { 0 }; 25 static struct ltchars oltc = { 0 }, nltc = { 0 }; 26 static struct sgttyb ottyb = { 0 }, nttyb = { 0 }; 27 28 29 TerminalWrite(fd, buf, n) 30 int fd; 31 char *buf; 32 int n; 33 { 34 return write(fd, buf, n); 35 } 36 37 TerminalRead(fd, buf, n) 38 int fd; 39 char *buf; 40 int n; 41 { 42 return read(fd, buf, n); 43 } 44 45 /* 46 * 47 */ 48 49 int 50 TerminalAutoFlush() /* unix */ 51 { 52 #if defined(LNOFLSH) 53 int flush; 54 55 ioctl(0, TIOCLGET, (char *)&flush); 56 return !(flush&LNOFLSH); /* if LNOFLSH, no autoflush */ 57 #else /* LNOFLSH */ 58 return 1; 59 #endif /* LNOFLSH */ 60 } 61 62 /* 63 * TerminalSpecialChars() 64 * 65 * Look at an input character to see if it is a special character 66 * and decide what to do. 67 * 68 * Output: 69 * 70 * 0 Don't add this character. 71 * 1 Do add this character 72 */ 73 74 int 75 TerminalSpecialChars(c) /* unix */ 76 int c; 77 { 78 void doflush(), intp(), sendbrk(); 79 80 if (c == ntc.t_intrc) { 81 intp(); 82 return 0; 83 } else if (c == ntc.t_quitc) { 84 sendbrk(); 85 return 0; 86 } else if (c == nltc.t_flushc) { 87 xmitAO(); /* Transmit Abort Output */ 88 return 0; 89 } else if (!MODE_LOCAL_CHARS(globalmode)) { 90 if (c == nttyb.sg_kill) { 91 xmitEL(); 92 return 0; 93 } else if (c == nttyb.sg_erase) { 94 xmitEC(); /* Transmit Erase Character */ 95 return 0; 96 } 97 } 98 return 1; 99 } 100 101 102 /* 103 * Flush output to the terminal 104 */ 105 106 void 107 TerminalFlushOutput() /* unix */ 108 { 109 (void) ioctl(fileno(stdout), TIOCFLUSH, (char *) 0); 110 } 111 112 void 113 TerminalSaveState() /* unix */ 114 { 115 ioctl(0, TIOCGETP, (char *)&ottyb); 116 ioctl(0, TIOCGETC, (char *)&otc); 117 ioctl(0, TIOCGLTC, (char *)&oltc); 118 119 ntc = otc; 120 nltc = oltc; 121 nttyb = ottyb; 122 } 123 124 void 125 TerminalRestoreState() /* unix */ 126 { 127 } 128 129 /* 130 * TerminalNewMode - set up terminal to a specific mode. 131 */ 132 133 134 void 135 TerminalNewMode(fd_in, fd_out, f) /* unix */ 136 int fd_in, fd_out; /* File descriptor */ 137 register int f; 138 { 139 static int prevmode = 0; 140 struct tchars *tc; 141 struct tchars tc3; 142 struct ltchars *ltc; 143 struct sgttyb sb; 144 int onoff; 145 int old; 146 struct tchars notc2; 147 struct ltchars noltc2; 148 static struct tchars notc = { -1, -1, -1, -1, -1, -1 }; 149 static struct ltchars noltc = { -1, -1, -1, -1, -1, -1 }; 150 151 globalmode = f; 152 if (prevmode == f) 153 return; 154 old = prevmode; 155 prevmode = f; 156 sb = nttyb; 157 158 switch (f) { 159 160 case 0: 161 onoff = 0; 162 tc = &otc; 163 ltc = &oltc; 164 break; 165 166 case 1: /* remote character processing, remote echo */ 167 case 2: /* remote character processing, local echo */ 168 case 6: /* 3270 mode - like 1, but with xon/xoff local */ 169 /* (might be nice to have "6" in telnet also...) */ 170 sb.sg_flags |= CBREAK; 171 if ((f == 1) || (f == 6)) { 172 sb.sg_flags &= ~(ECHO|CRMOD); 173 } else { 174 sb.sg_flags |= ECHO|CRMOD; 175 } 176 sb.sg_erase = sb.sg_kill = -1; 177 if (f == 6) { 178 tc = &tc3; 179 tc3 = notc; 180 /* get XON, XOFF characters */ 181 tc3.t_startc = otc.t_startc; 182 tc3.t_stopc = otc.t_stopc; 183 } else { 184 /* 185 * If user hasn't specified one way or the other, 186 * then default to not trapping signals. 187 */ 188 if (!donelclchars) { 189 localchars = 0; 190 } 191 if (localchars) { 192 notc2 = notc; 193 notc2.t_intrc = ntc.t_intrc; 194 notc2.t_quitc = ntc.t_quitc; 195 tc = ¬c2; 196 } else { 197 tc = ¬c; 198 } 199 } 200 ltc = &noltc; 201 onoff = 1; 202 break; 203 case 3: /* local character processing, remote echo */ 204 case 4: /* local character processing, local echo */ 205 case 5: /* local character processing, no echo */ 206 sb.sg_flags &= ~CBREAK; 207 sb.sg_flags |= CRMOD; 208 if (f == 4) 209 sb.sg_flags |= ECHO; 210 else 211 sb.sg_flags &= ~ECHO; 212 notc2 = ntc; 213 tc = ¬c2; 214 noltc2 = oltc; 215 ltc = &noltc2; 216 /* 217 * If user hasn't specified one way or the other, 218 * then default to trapping signals. 219 */ 220 if (!donelclchars) { 221 localchars = 1; 222 } 223 if (localchars) { 224 notc2.t_brkc = nltc.t_flushc; 225 noltc2.t_flushc = -1; 226 } else { 227 notc2.t_intrc = notc2.t_quitc = -1; 228 } 229 noltc2.t_suspc = escape; 230 noltc2.t_dsuspc = -1; 231 onoff = 1; 232 break; 233 234 default: 235 return; 236 } 237 ioctl(fd_in, TIOCSLTC, (char *)ltc); 238 ioctl(fd_in, TIOCSETC, (char *)tc); 239 ioctl(fd_in, TIOCSETP, (char *)&sb); 240 #if (!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR)) 241 ioctl(fd_in, FIONBIO, (char *)&onoff); 242 ioctl(fd_out, FIONBIO, (char *)&onoff); 243 #endif /* (!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR)) */ 244 #if defined(TN3270) 245 if (noasynch == 0) { 246 ioctl(fd_in, FIOASYNC, (char *)&onoff); 247 } 248 #endif /* defined(TN3270) */ 249 250 if (MODE_LINE(f)) { 251 void doescape(); 252 253 signal(SIGTSTP, doescape); 254 } else if (MODE_LINE(old)) { 255 signal(SIGTSTP, SIG_DFL); 256 sigsetmask(sigblock(0) & ~(1<<(SIGTSTP-1))); 257 } 258 } 259 260 261 int 262 NetClose(net) 263 int net; 264 { 265 return close(net); 266 } 267 268 269 void 270 NetNonblockingIO(fd, onoff) /* unix */ 271 int 272 fd, 273 onoff; 274 { 275 ioctl(fd, FIONBIO, (char *)&onoff); 276 } 277 278 void 279 NetSigIO(fd, onoff) /* unix */ 280 int 281 fd, 282 onoff; 283 { 284 ioctl(fd, FIOASYNC, (char *)&onoff); /* hear about input */ 285 } 286 287 void 288 NetSetPgrp(fd) /* unix */ 289 int fd; 290 { 291 int myPid; 292 293 myPid = getpid(); 294 #if defined(NOT43) 295 myPid = -myPid; 296 #endif /* defined(NOT43) */ 297 ioctl(fd, SIOCSPGRP, (char *)&myPid); /* set my pid */ 298 } 299 300 301 #endif /* defined(unix) */ 302