1*32148Sminshall #include <arpa/telnet.h> 2*32148Sminshall 3*32148Sminshall #include "externs.h" 4*32148Sminshall #include "types.h" 5*32148Sminshall 6*32148Sminshall char ttyobuf[2*BUFSIZ], *tfrontp, *tbackp; 7*32148Sminshall 8*32148Sminshall char 9*32148Sminshall termEofChar, 10*32148Sminshall termEraseChar, 11*32148Sminshall termFlushChar, 12*32148Sminshall termIntChar, 13*32148Sminshall termKillChar, 14*32148Sminshall termLiteralNextChar, 15*32148Sminshall termQuitChar; 16*32148Sminshall 17*32148Sminshall /* 18*32148Sminshall * initialize the terminal data structures. 19*32148Sminshall */ 20*32148Sminshall 21*32148Sminshall init_terminal() 22*32148Sminshall { 23*32148Sminshall tfrontp = tbackp = ttyobuf; 24*32148Sminshall autoflush = TerminalAutoFlush(); 25*32148Sminshall } 26*32148Sminshall 27*32148Sminshall 28*32148Sminshall /* 29*32148Sminshall * Send as much data as possible to the terminal. 30*32148Sminshall * 31*32148Sminshall * The return value indicates whether we did any 32*32148Sminshall * useful work. 33*32148Sminshall */ 34*32148Sminshall 35*32148Sminshall 36*32148Sminshall int 37*32148Sminshall ttyflush() 38*32148Sminshall { 39*32148Sminshall int n; 40*32148Sminshall 41*32148Sminshall if ((n = tfrontp - tbackp) > 0) { 42*32148Sminshall if (!(SYNCHing||flushout)) { 43*32148Sminshall n = TerminalWrite(tout, tbackp, n); 44*32148Sminshall } else { 45*32148Sminshall TerminalFlushOutput(); 46*32148Sminshall /* we leave 'n' alone! */ 47*32148Sminshall } 48*32148Sminshall } 49*32148Sminshall if (n >= 0) { 50*32148Sminshall tbackp += n; 51*32148Sminshall if (tbackp == tfrontp) { 52*32148Sminshall tbackp = tfrontp = ttyobuf; 53*32148Sminshall } 54*32148Sminshall } 55*32148Sminshall return n > 0; 56*32148Sminshall } 57*32148Sminshall 58*32148Sminshall #if defined(TN3270) 59*32148Sminshall 60*32148Sminshall #if defined(unix) 61*32148Sminshall static void 62*32148Sminshall inputAvailable() 63*32148Sminshall { 64*32148Sminshall HaveInput = 1; 65*32148Sminshall } 66*32148Sminshall #endif /* defined(unix) */ 67*32148Sminshall 68*32148Sminshall void 69*32148Sminshall outputPurge() 70*32148Sminshall { 71*32148Sminshall int tmp = flushout; 72*32148Sminshall 73*32148Sminshall flushout = 1; 74*32148Sminshall 75*32148Sminshall ttyflush(); 76*32148Sminshall 77*32148Sminshall flushout = tmp; 78*32148Sminshall } 79*32148Sminshall 80*32148Sminshall #endif /* defined(TN3270) */ 81*32148Sminshall 82*32148Sminshall #if defined(unix) 83*32148Sminshall /* 84*32148Sminshall * Various signal handling routines. 85*32148Sminshall */ 86*32148Sminshall 87*32148Sminshall void 88*32148Sminshall deadpeer() 89*32148Sminshall { 90*32148Sminshall setcommandmode(); 91*32148Sminshall longjmp(peerdied, -1); 92*32148Sminshall } 93*32148Sminshall 94*32148Sminshall void 95*32148Sminshall intr() 96*32148Sminshall { 97*32148Sminshall if (localchars) { 98*32148Sminshall intp(); 99*32148Sminshall return; 100*32148Sminshall } 101*32148Sminshall setcommandmode(); 102*32148Sminshall longjmp(toplevel, -1); 103*32148Sminshall } 104*32148Sminshall 105*32148Sminshall void 106*32148Sminshall intr2() 107*32148Sminshall { 108*32148Sminshall if (localchars) { 109*32148Sminshall sendbrk(); 110*32148Sminshall return; 111*32148Sminshall } 112*32148Sminshall } 113*32148Sminshall 114*32148Sminshall void 115*32148Sminshall doescape() 116*32148Sminshall { 117*32148Sminshall command(0); 118*32148Sminshall } 119*32148Sminshall #endif /* defined(unix) */ 120*32148Sminshall 121*32148Sminshall /* 122*32148Sminshall * These routines decides on what the mode should be (based on the values 123*32148Sminshall * of various global variables). 124*32148Sminshall */ 125*32148Sminshall 126*32148Sminshall 127*32148Sminshall int 128*32148Sminshall getconnmode() 129*32148Sminshall { 130*32148Sminshall static char newmode[16] = 131*32148Sminshall { 4, 5, 3, 3, 2, 2, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6 }; 132*32148Sminshall int modeindex = 0; 133*32148Sminshall 134*32148Sminshall if (dontlecho && (clocks.echotoggle > clocks.modenegotiated)) { 135*32148Sminshall modeindex += 1; 136*32148Sminshall } 137*32148Sminshall if (hisopts[TELOPT_ECHO]) { 138*32148Sminshall modeindex += 2; 139*32148Sminshall } 140*32148Sminshall if (hisopts[TELOPT_SGA]) { 141*32148Sminshall modeindex += 4; 142*32148Sminshall } 143*32148Sminshall if (In3270) { 144*32148Sminshall modeindex += 8; 145*32148Sminshall } 146*32148Sminshall return newmode[modeindex]; 147*32148Sminshall } 148*32148Sminshall 149*32148Sminshall void 150*32148Sminshall setconnmode() 151*32148Sminshall { 152*32148Sminshall TerminalNewMode(tin, tout, getconnmode()); 153*32148Sminshall } 154*32148Sminshall 155*32148Sminshall 156*32148Sminshall void 157*32148Sminshall setcommandmode() 158*32148Sminshall { 159*32148Sminshall TerminalNewMode(tin, tout, 0); 160*32148Sminshall } 161*32148Sminshall 162*32148Sminshall #if defined(TN3270) 163*32148Sminshall 164*32148Sminshall /* 165*32148Sminshall * The following routines are places where the various tn3270 166*32148Sminshall * routines make calls into telnet.c. 167*32148Sminshall */ 168*32148Sminshall 169*32148Sminshall /* TtyChars() - returns the number of characters in the TTY buffer */ 170*32148Sminshall TtyChars() 171*32148Sminshall { 172*32148Sminshall return(tfrontp-tbackp); 173*32148Sminshall } 174*32148Sminshall 175*32148Sminshall /* 176*32148Sminshall * DataToNetwork - queue up some data to go to network. If "done" is set, 177*32148Sminshall * then when last byte is queued, we add on an IAC EOR sequence (so, 178*32148Sminshall * don't call us with "done" until you want that done...) 179*32148Sminshall * 180*32148Sminshall * We actually do send all the data to the network buffer, since our 181*32148Sminshall * only client needs for us to do that. 182*32148Sminshall */ 183*32148Sminshall 184*32148Sminshall int 185*32148Sminshall DataToNetwork(buffer, count, done) 186*32148Sminshall register char *buffer; /* where the data is */ 187*32148Sminshall register int count; /* how much to send */ 188*32148Sminshall int done; /* is this the last of a logical block */ 189*32148Sminshall { 190*32148Sminshall register int c; 191*32148Sminshall int origCount; 192*32148Sminshall fd_set o; 193*32148Sminshall 194*32148Sminshall origCount = count; 195*32148Sminshall FD_ZERO(&o); 196*32148Sminshall 197*32148Sminshall while (count) { 198*32148Sminshall if ((netobuf+sizeof netobuf - nfrontp) < 6) { 199*32148Sminshall netflush(); 200*32148Sminshall while ((netobuf+sizeof netobuf - nfrontp) < 6) { 201*32148Sminshall FD_SET(net, &o); 202*32148Sminshall (void) select(net+1, (fd_set *) 0, &o, (fd_set *) 0, 203*32148Sminshall (struct timeval *) 0); 204*32148Sminshall netflush(); 205*32148Sminshall } 206*32148Sminshall } 207*32148Sminshall c = *buffer++; 208*32148Sminshall count--; 209*32148Sminshall if (c == IAC) { 210*32148Sminshall *nfrontp++ = IAC; 211*32148Sminshall *nfrontp++ = IAC; 212*32148Sminshall } else { 213*32148Sminshall *nfrontp++ = c; 214*32148Sminshall } 215*32148Sminshall } 216*32148Sminshall 217*32148Sminshall if (done && !count) { 218*32148Sminshall *nfrontp++ = IAC; 219*32148Sminshall *nfrontp++ = EOR; 220*32148Sminshall netflush(); /* try to move along as quickly as ... */ 221*32148Sminshall } 222*32148Sminshall return(origCount - count); 223*32148Sminshall } 224*32148Sminshall 225*32148Sminshall /* DataToTerminal - queue up some data to go to terminal. */ 226*32148Sminshall 227*32148Sminshall int 228*32148Sminshall DataToTerminal(buffer, count) 229*32148Sminshall register char *buffer; /* where the data is */ 230*32148Sminshall register int count; /* how much to send */ 231*32148Sminshall { 232*32148Sminshall int origCount; 233*32148Sminshall #if defined(unix) 234*32148Sminshall fd_set o; 235*32148Sminshall 236*32148Sminshall FD_ZERO(&o); 237*32148Sminshall #endif /* defined(unix) */ 238*32148Sminshall origCount = count; 239*32148Sminshall 240*32148Sminshall while (count) { 241*32148Sminshall if (tfrontp >= ttyobuf+sizeof ttyobuf) { 242*32148Sminshall ttyflush(); 243*32148Sminshall while (tfrontp >= ttyobuf+sizeof ttyobuf) { 244*32148Sminshall #if defined(unix) 245*32148Sminshall FD_SET(tout, &o); 246*32148Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 247*32148Sminshall (struct timeval *) 0); 248*32148Sminshall #endif /* defined(unix) */ 249*32148Sminshall ttyflush(); 250*32148Sminshall } 251*32148Sminshall } 252*32148Sminshall *tfrontp++ = *buffer++; 253*32148Sminshall count--; 254*32148Sminshall } 255*32148Sminshall return(origCount - count); 256*32148Sminshall } 257*32148Sminshall 258*32148Sminshall /* EmptyTerminal - called to make sure that the terminal buffer is empty. 259*32148Sminshall * Note that we consider the buffer to run all the 260*32148Sminshall * way to the kernel (thus the select). 261*32148Sminshall */ 262*32148Sminshall 263*32148Sminshall void 264*32148Sminshall EmptyTerminal() 265*32148Sminshall { 266*32148Sminshall #if defined(unix) 267*32148Sminshall fd_set o; 268*32148Sminshall 269*32148Sminshall FD_ZERO(&o); 270*32148Sminshall #endif /* defined(unix) */ 271*32148Sminshall 272*32148Sminshall if (tfrontp == tbackp) { 273*32148Sminshall #if defined(unix) 274*32148Sminshall FD_SET(tout, &o); 275*32148Sminshall (void) select(tout+1, (int *) 0, &o, (int *) 0, 276*32148Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 277*32148Sminshall #endif /* defined(unix) */ 278*32148Sminshall } else { 279*32148Sminshall while (tfrontp != tbackp) { 280*32148Sminshall ttyflush(); 281*32148Sminshall #if defined(unix) 282*32148Sminshall FD_SET(tout, &o); 283*32148Sminshall (void) select(tout+1, (int *) 0, &o, (int *) 0, 284*32148Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 285*32148Sminshall #endif /* defined(unix) */ 286*32148Sminshall } 287*32148Sminshall } 288*32148Sminshall } 289*32148Sminshall 290*32148Sminshall 291*32148Sminshall /* 292*32148Sminshall * Push3270 - Try to send data along the 3270 output (to screen) direction. 293*32148Sminshall */ 294*32148Sminshall 295*32148Sminshall static int 296*32148Sminshall Push3270() 297*32148Sminshall { 298*32148Sminshall int save = scc; 299*32148Sminshall 300*32148Sminshall if (scc) { 301*32148Sminshall if (Ifrontp+scc > Ibuf+sizeof Ibuf) { 302*32148Sminshall if (Ibackp != Ibuf) { 303*32148Sminshall memcpy(Ibuf, Ibackp, Ifrontp-Ibackp); 304*32148Sminshall Ifrontp -= (Ibackp-Ibuf); 305*32148Sminshall Ibackp = Ibuf; 306*32148Sminshall } 307*32148Sminshall } 308*32148Sminshall if (Ifrontp+scc < Ibuf+sizeof Ibuf) { 309*32148Sminshall telrcv(); 310*32148Sminshall } 311*32148Sminshall } 312*32148Sminshall return save != scc; 313*32148Sminshall } 314*32148Sminshall 315*32148Sminshall 316*32148Sminshall /* 317*32148Sminshall * Finish3270 - get the last dregs of 3270 data out to the terminal 318*32148Sminshall * before quitting. 319*32148Sminshall */ 320*32148Sminshall 321*32148Sminshall static void 322*32148Sminshall Finish3270() 323*32148Sminshall { 324*32148Sminshall while (Push3270() || !DoTerminalOutput()) { 325*32148Sminshall #if defined(unix) 326*32148Sminshall HaveInput = 0; 327*32148Sminshall #endif /* defined(unix) */ 328*32148Sminshall ; 329*32148Sminshall } 330*32148Sminshall } 331*32148Sminshall 332*32148Sminshall 333*32148Sminshall /* StringToTerminal - output a null terminated string to the terminal */ 334*32148Sminshall 335*32148Sminshall void 336*32148Sminshall StringToTerminal(s) 337*32148Sminshall char *s; 338*32148Sminshall { 339*32148Sminshall int count; 340*32148Sminshall 341*32148Sminshall count = strlen(s); 342*32148Sminshall if (count) { 343*32148Sminshall (void) DataToTerminal(s, count); /* we know it always goes... */ 344*32148Sminshall } 345*32148Sminshall } 346*32148Sminshall 347*32148Sminshall 348*32148Sminshall #if ((!defined(NOT43)) || defined(PUTCHAR)) 349*32148Sminshall /* _putchar - output a single character to the terminal. This name is so that 350*32148Sminshall * curses(3x) can call us to send out data. 351*32148Sminshall */ 352*32148Sminshall 353*32148Sminshall void 354*32148Sminshall _putchar(c) 355*32148Sminshall char c; 356*32148Sminshall { 357*32148Sminshall if (tfrontp >= ttyobuf+sizeof ttyobuf) { 358*32148Sminshall (void) DataToTerminal(&c, 1); 359*32148Sminshall } else { 360*32148Sminshall *tfrontp++ = c; /* optimize if possible. */ 361*32148Sminshall } 362*32148Sminshall } 363*32148Sminshall #endif /* ((!defined(NOT43)) || defined(PUTCHAR)) */ 364*32148Sminshall #endif /* defined(TN3270) */ 365