|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted provided ! 6: * that: (1) source distributions retain this entire copyright notice and ! 7: * comment, and (2) distributions including binaries display the following ! 8: * acknowledgement: ``This product includes software developed by the ! 9: * University of California, Berkeley and its contributors'' in the ! 10: * documentation or other materials provided with the distribution and in ! 11: * all advertising materials mentioning features or use of this software. ! 12: * Neither the name of the University nor the names of its contributors may ! 13: * be used to endorse or promote products derived from this software without ! 14: * specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)tn3270.c 1.21 (Berkeley) 6/28/90"; ! 22: #endif /* not lint */ ! 23: ! 24: #include <sys/types.h> ! 25: #include <arpa/telnet.h> ! 26: ! 27: #include "general.h" ! 28: ! 29: #include "defines.h" ! 30: #include "ring.h" ! 31: #include "externs.h" ! 32: #include "fdset.h" ! 33: ! 34: #if defined(TN3270) ! 35: ! 36: #include "../ctlr/screen.h" ! 37: #include "../general/globals.h" ! 38: ! 39: #include "../telextrn.h" ! 40: #include "../ctlr/externs.h" ! 41: ! 42: #if defined(unix) ! 43: int ! 44: HaveInput, /* There is input available to scan */ ! 45: cursesdata, /* Do we dump curses data? */ ! 46: sigiocount; /* Number of times we got a SIGIO */ ! 47: ! 48: char tline[200]; ! 49: char *transcom = 0; /* transparent mode command (default: none) */ ! 50: #endif /* defined(unix) */ ! 51: ! 52: char Ibuf[8*BUFSIZ], *Ifrontp, *Ibackp; ! 53: ! 54: static char sb_terminal[] = { IAC, SB, ! 55: TELOPT_TTYPE, TELQUAL_IS, ! 56: 'I', 'B', 'M', '-', '3', '2', '7', '8', '-', '2', ! 57: IAC, SE }; ! 58: #define SBTERMMODEL 13 ! 59: ! 60: static int ! 61: Sent3270TerminalType; /* Have we said we are a 3270? */ ! 62: ! 63: #endif /* defined(TN3270) */ ! 64: ! 65: ! 66: void ! 67: init_3270() ! 68: { ! 69: #if defined(TN3270) ! 70: #if defined(unix) ! 71: HaveInput = 0; ! 72: sigiocount = 0; ! 73: #endif /* defined(unix) */ ! 74: Sent3270TerminalType = 0; ! 75: Ifrontp = Ibackp = Ibuf; ! 76: init_ctlr(); /* Initialize some things */ ! 77: init_keyboard(); ! 78: init_screen(); ! 79: init_system(); ! 80: #endif /* defined(TN3270) */ ! 81: } ! 82: ! 83: ! 84: #if defined(TN3270) ! 85: ! 86: /* ! 87: * DataToNetwork - queue up some data to go to network. If "done" is set, ! 88: * then when last byte is queued, we add on an IAC EOR sequence (so, ! 89: * don't call us with "done" until you want that done...) ! 90: * ! 91: * We actually do send all the data to the network buffer, since our ! 92: * only client needs for us to do that. ! 93: */ ! 94: ! 95: int ! 96: DataToNetwork(buffer, count, done) ! 97: register char *buffer; /* where the data is */ ! 98: register int count; /* how much to send */ ! 99: int done; /* is this the last of a logical block */ ! 100: { ! 101: register int loop, c; ! 102: int origCount; ! 103: ! 104: origCount = count; ! 105: ! 106: while (count) { ! 107: /* If not enough room for EORs, IACs, etc., wait */ ! 108: if (NETROOM() < 6) { ! 109: fd_set o; ! 110: ! 111: FD_ZERO(&o); ! 112: netflush(); ! 113: while (NETROOM() < 6) { ! 114: FD_SET(net, &o); ! 115: (void) select(net+1, (fd_set *) 0, &o, (fd_set *) 0, ! 116: (struct timeval *) 0); ! 117: netflush(); ! 118: } ! 119: } ! 120: c = ring_empty_count(&netoring); ! 121: if (c > count) { ! 122: c = count; ! 123: } ! 124: loop = c; ! 125: while (loop) { ! 126: if (((unsigned char)*buffer) == IAC) { ! 127: break; ! 128: } ! 129: buffer++; ! 130: loop--; ! 131: } ! 132: if ((c = c-loop)) { ! 133: ring_supply_data(&netoring, buffer-c, c); ! 134: count -= c; ! 135: } ! 136: if (loop) { ! 137: NET2ADD(IAC, IAC); ! 138: count--; ! 139: buffer++; ! 140: } ! 141: } ! 142: ! 143: if (done) { ! 144: NET2ADD(IAC, EOR); ! 145: netflush(); /* try to move along as quickly as ... */ ! 146: } ! 147: return(origCount - count); ! 148: } ! 149: ! 150: ! 151: #if defined(unix) ! 152: void ! 153: inputAvailable() ! 154: { ! 155: HaveInput = 1; ! 156: sigiocount++; ! 157: } ! 158: #endif /* defined(unix) */ ! 159: ! 160: void ! 161: outputPurge() ! 162: { ! 163: (void) ttyflush(1); ! 164: } ! 165: ! 166: ! 167: /* ! 168: * The following routines are places where the various tn3270 ! 169: * routines make calls into telnet.c. ! 170: */ ! 171: ! 172: /* ! 173: * DataToTerminal - queue up some data to go to terminal. ! 174: * ! 175: * Note: there are people who call us and depend on our processing ! 176: * *all* the data at one time (thus the select). ! 177: */ ! 178: ! 179: int ! 180: DataToTerminal(buffer, count) ! 181: register char *buffer; /* where the data is */ ! 182: register int count; /* how much to send */ ! 183: { ! 184: register int c; ! 185: int origCount; ! 186: ! 187: origCount = count; ! 188: ! 189: while (count) { ! 190: if (TTYROOM() == 0) { ! 191: #if defined(unix) ! 192: fd_set o; ! 193: ! 194: FD_ZERO(&o); ! 195: #endif /* defined(unix) */ ! 196: (void) ttyflush(0); ! 197: while (TTYROOM() == 0) { ! 198: #if defined(unix) ! 199: FD_SET(tout, &o); ! 200: (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, ! 201: (struct timeval *) 0); ! 202: #endif /* defined(unix) */ ! 203: (void) ttyflush(0); ! 204: } ! 205: } ! 206: c = TTYROOM(); ! 207: if (c > count) { ! 208: c = count; ! 209: } ! 210: ring_supply_data(&ttyoring, buffer, c); ! 211: count -= c; ! 212: buffer += c; ! 213: } ! 214: return(origCount); ! 215: } ! 216: ! 217: ! 218: /* ! 219: * Push3270 - Try to send data along the 3270 output (to screen) direction. ! 220: */ ! 221: ! 222: int ! 223: Push3270() ! 224: { ! 225: int save = ring_full_count(&netiring); ! 226: ! 227: if (save) { ! 228: if (Ifrontp+save > Ibuf+sizeof Ibuf) { ! 229: if (Ibackp != Ibuf) { ! 230: memcpy(Ibuf, Ibackp, Ifrontp-Ibackp); ! 231: Ifrontp -= (Ibackp-Ibuf); ! 232: Ibackp = Ibuf; ! 233: } ! 234: } ! 235: if (Ifrontp+save < Ibuf+sizeof Ibuf) { ! 236: (void)telrcv(); ! 237: } ! 238: } ! 239: return save != ring_full_count(&netiring); ! 240: } ! 241: ! 242: ! 243: /* ! 244: * Finish3270 - get the last dregs of 3270 data out to the terminal ! 245: * before quitting. ! 246: */ ! 247: ! 248: void ! 249: Finish3270() ! 250: { ! 251: while (Push3270() || !DoTerminalOutput()) { ! 252: #if defined(unix) ! 253: HaveInput = 0; ! 254: #endif /* defined(unix) */ ! 255: ; ! 256: } ! 257: } ! 258: ! 259: ! 260: /* StringToTerminal - output a null terminated string to the terminal */ ! 261: ! 262: void ! 263: StringToTerminal(s) ! 264: char *s; ! 265: { ! 266: int count; ! 267: ! 268: count = strlen(s); ! 269: if (count) { ! 270: (void) DataToTerminal(s, count); /* we know it always goes... */ ! 271: } ! 272: } ! 273: ! 274: ! 275: #if ((!defined(NOT43)) || defined(PUTCHAR)) ! 276: /* _putchar - output a single character to the terminal. This name is so that ! 277: * curses(3x) can call us to send out data. ! 278: */ ! 279: ! 280: void ! 281: _putchar(c) ! 282: char c; ! 283: { ! 284: #if defined(sun) /* SunOS 4.0 bug */ ! 285: c &= 0x7f; ! 286: #endif /* defined(sun) */ ! 287: if (cursesdata) { ! 288: Dump('>', &c, 1); ! 289: } ! 290: if (!TTYROOM()) { ! 291: (void) DataToTerminal(&c, 1); ! 292: } else { ! 293: TTYADD(c); ! 294: } ! 295: } ! 296: #endif /* ((!defined(NOT43)) || defined(PUTCHAR)) */ ! 297: ! 298: void ! 299: SetIn3270() ! 300: { ! 301: if (Sent3270TerminalType && my_want_state_is_will(TELOPT_BINARY) ! 302: && my_want_state_is_do(TELOPT_BINARY) && !donebinarytoggle) { ! 303: if (!In3270) { ! 304: In3270 = 1; ! 305: Init3270(); /* Initialize 3270 functions */ ! 306: /* initialize terminal key mapping */ ! 307: InitTerminal(); /* Start terminal going */ ! 308: setconnmode(0); ! 309: } ! 310: } else { ! 311: if (In3270) { ! 312: StopScreen(1); ! 313: In3270 = 0; ! 314: Stop3270(); /* Tell 3270 we aren't here anymore */ ! 315: setconnmode(0); ! 316: } ! 317: } ! 318: } ! 319: ! 320: /* ! 321: * tn3270_ttype() ! 322: * ! 323: * Send a response to a terminal type negotiation. ! 324: * ! 325: * Return '0' if no more responses to send; '1' if a response sent. ! 326: */ ! 327: ! 328: int ! 329: tn3270_ttype() ! 330: { ! 331: /* ! 332: * Try to send a 3270 type terminal name. Decide which one based ! 333: * on the format of our screen, and (in the future) color ! 334: * capaiblities. ! 335: */ ! 336: InitTerminal(); /* Sets MaxNumberColumns, MaxNumberLines */ ! 337: if ((MaxNumberLines >= 24) && (MaxNumberColumns >= 80)) { ! 338: Sent3270TerminalType = 1; ! 339: if ((MaxNumberLines >= 27) && (MaxNumberColumns >= 132)) { ! 340: MaxNumberLines = 27; ! 341: MaxNumberColumns = 132; ! 342: sb_terminal[SBTERMMODEL] = '5'; ! 343: } else if (MaxNumberLines >= 43) { ! 344: MaxNumberLines = 43; ! 345: MaxNumberColumns = 80; ! 346: sb_terminal[SBTERMMODEL] = '4'; ! 347: } else if (MaxNumberLines >= 32) { ! 348: MaxNumberLines = 32; ! 349: MaxNumberColumns = 80; ! 350: sb_terminal[SBTERMMODEL] = '3'; ! 351: } else { ! 352: MaxNumberLines = 24; ! 353: MaxNumberColumns = 80; ! 354: sb_terminal[SBTERMMODEL] = '2'; ! 355: } ! 356: NumberLines = 24; /* before we start out... */ ! 357: NumberColumns = 80; ! 358: ScreenSize = NumberLines*NumberColumns; ! 359: if ((MaxNumberLines*MaxNumberColumns) > MAXSCREENSIZE) { ! 360: ExitString("Programming error: MAXSCREENSIZE too small.\n", ! 361: 1); ! 362: /*NOTREACHED*/ ! 363: } ! 364: printsub('>', sb_terminal+2, sizeof sb_terminal-2); ! 365: ring_supply_data(&netoring, sb_terminal, sizeof sb_terminal); ! 366: return 1; ! 367: } else { ! 368: return 0; ! 369: } ! 370: } ! 371: ! 372: #if defined(unix) ! 373: settranscom(argc, argv) ! 374: int argc; ! 375: char *argv[]; ! 376: { ! 377: int i; ! 378: ! 379: if (argc == 1 && transcom) { ! 380: transcom = 0; ! 381: } ! 382: if (argc == 1) { ! 383: return; ! 384: } ! 385: transcom = tline; ! 386: (void) strcpy(transcom, argv[1]); ! 387: for (i = 2; i < argc; ++i) { ! 388: (void) strcat(transcom, " "); ! 389: (void) strcat(transcom, argv[i]); ! 390: } ! 391: } ! 392: #endif /* defined(unix) */ ! 393: ! 394: #endif /* defined(TN3270) */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.