132185Sminshall void 232185Sminshall tn3270_init() 332185Sminshall { 432185Sminshall #if defined(TN3270) 532185Sminshall Sent3270TerminalType = 0; 632185Sminshall Ifrontp = Ibackp = Ibuf; 732185Sminshall init_ctlr(); /* Initialize some things */ 832185Sminshall init_keyboard(); 932185Sminshall init_screen(); 1032185Sminshall init_system(); 1132185Sminshall #endif /* defined(TN3270) */ 1232185Sminshall } 1332185Sminshall 1432185Sminshall #if defined(TN3270) 1532185Sminshall 1632531Sminshall 1732531Sminshall static char Ibuf[8*BUFSIZ], *Ifrontp, *Ibackp; 1832531Sminshall 1932531Sminshall static char sb_terminal[] = { IAC, SB, 2032531Sminshall TELOPT_TTYPE, TELQUAL_IS, 2132531Sminshall 'I', 'B', 'M', '-', '3', '2', '7', '8', '-', '2', 2232531Sminshall IAC, SE }; 2332531Sminshall #define SBTERMMODEL 13 2432531Sminshall 2532531Sminshall static int 2632531Sminshall Sent3270TerminalType; /* Have we said we are a 3270? */ 2732531Sminshall 2832531Sminshall 29*32551Sminshall #if defined(unix) 30*32551Sminshall static 31*32551Sminshall settranscom(argc, argv) 32*32551Sminshall int argc; 33*32551Sminshall char *argv[]; 34*32551Sminshall { 35*32551Sminshall int i, len = 0; 36*32551Sminshall char *strcpy(), *strcat(); 37*32551Sminshall 38*32551Sminshall if (argc == 1 && transcom) { 39*32551Sminshall transcom = 0; 40*32551Sminshall } 41*32551Sminshall if (argc == 1) { 42*32551Sminshall return; 43*32551Sminshall } 44*32551Sminshall for (i = 1; i < argc; ++i) { 45*32551Sminshall len += 1 + strlen(argv[1]); 46*32551Sminshall } 47*32551Sminshall transcom = tline; 48*32551Sminshall (void) strcpy(transcom, argv[1]); 49*32551Sminshall for (i = 2; i < argc; ++i) { 50*32551Sminshall (void) strcat(transcom, " "); 51*32551Sminshall (void) strcat(transcom, argv[i]); 52*32551Sminshall } 53*32551Sminshall } 54*32551Sminshall #endif /* defined(unix) */ 55*32551Sminshall 5632185Sminshall /* 5732185Sminshall * DataToNetwork - queue up some data to go to network. If "done" is set, 5832185Sminshall * then when last byte is queued, we add on an IAC EOR sequence (so, 5932185Sminshall * don't call us with "done" until you want that done...) 6032185Sminshall * 6132185Sminshall * We actually do send all the data to the network buffer, since our 6232185Sminshall * only client needs for us to do that. 6332185Sminshall */ 6432185Sminshall 6532185Sminshall int 6632185Sminshall DataToNetwork(buffer, count, done) 6732185Sminshall register char *buffer; /* where the data is */ 6832185Sminshall register int count; /* how much to send */ 6932185Sminshall int done; /* is this the last of a logical block */ 7032185Sminshall { 7132185Sminshall register int c; 7232185Sminshall int origCount; 7332185Sminshall fd_set o; 7432185Sminshall 7532185Sminshall origCount = count; 7632185Sminshall FD_ZERO(&o); 7732185Sminshall 7832185Sminshall while (count) { 7932185Sminshall if ((netobuf+sizeof netobuf - nfrontp) < 6) { 8032185Sminshall netflush(); 8132185Sminshall while ((netobuf+sizeof netobuf - nfrontp) < 6) { 8232185Sminshall FD_SET(net, &o); 8332185Sminshall (void) select(net+1, (fd_set *) 0, &o, (fd_set *) 0, 8432185Sminshall (struct timeval *) 0); 8532185Sminshall netflush(); 8632185Sminshall } 8732185Sminshall } 8832185Sminshall c = *buffer++; 8932185Sminshall count--; 9032185Sminshall if (c == IAC) { 9132185Sminshall *nfrontp++ = IAC; 9232185Sminshall *nfrontp++ = IAC; 9332185Sminshall } else { 9432185Sminshall *nfrontp++ = c; 9532185Sminshall } 9632185Sminshall } 9732185Sminshall 9832185Sminshall if (done && !count) { 9932185Sminshall *nfrontp++ = IAC; 10032185Sminshall *nfrontp++ = EOR; 10132185Sminshall netflush(); /* try to move along as quickly as ... */ 10232185Sminshall } 10332185Sminshall return(origCount - count); 10432185Sminshall } 10532185Sminshall 10632185Sminshall 10732185Sminshall #if defined(unix) 10832185Sminshall static void 10932185Sminshall inputAvailable() 11032185Sminshall { 11132185Sminshall HaveInput = 1; 11232185Sminshall } 11332185Sminshall #endif /* defined(unix) */ 11432185Sminshall 11532185Sminshall void 11632185Sminshall outputPurge() 11732185Sminshall { 11832257Sminshall ttyflush(1); 11932185Sminshall } 12032185Sminshall 12132185Sminshall 12232185Sminshall /* 12332185Sminshall * The following routines are places where the various tn3270 12432185Sminshall * routines make calls into telnet.c. 12532185Sminshall */ 12632185Sminshall 12732185Sminshall /* TtyChars() - returns the number of characters in the TTY buffer */ 12832185Sminshall TtyChars() 12932185Sminshall { 13032185Sminshall return(tfrontp-tbackp); 13132185Sminshall } 13232185Sminshall 13332185Sminshall /* DataToTerminal - queue up some data to go to terminal. */ 13432185Sminshall 13532185Sminshall int 13632185Sminshall DataToTerminal(buffer, count) 13732185Sminshall register char *buffer; /* where the data is */ 13832185Sminshall register int count; /* how much to send */ 13932185Sminshall { 14032185Sminshall int origCount; 14132185Sminshall #if defined(unix) 14232185Sminshall fd_set o; 14332185Sminshall 14432185Sminshall FD_ZERO(&o); 14532185Sminshall #endif /* defined(unix) */ 14632185Sminshall origCount = count; 14732185Sminshall 14832185Sminshall while (count) { 14932185Sminshall if (tfrontp >= ttyobuf+sizeof ttyobuf) { 15032257Sminshall ttyflush(0); 15132185Sminshall while (tfrontp >= ttyobuf+sizeof ttyobuf) { 15232185Sminshall #if defined(unix) 15332185Sminshall FD_SET(tout, &o); 15432185Sminshall (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0, 15532185Sminshall (struct timeval *) 0); 15632185Sminshall #endif /* defined(unix) */ 15732257Sminshall ttyflush(0); 15832185Sminshall } 15932185Sminshall } 16032185Sminshall *tfrontp++ = *buffer++; 16132185Sminshall count--; 16232185Sminshall } 16332185Sminshall return(origCount - count); 16432185Sminshall } 16532185Sminshall 16632185Sminshall /* EmptyTerminal - called to make sure that the terminal buffer is empty. 16732185Sminshall * Note that we consider the buffer to run all the 16832185Sminshall * way to the kernel (thus the select). 16932185Sminshall */ 17032185Sminshall 17132185Sminshall void 17232185Sminshall EmptyTerminal() 17332185Sminshall { 17432185Sminshall #if defined(unix) 17532185Sminshall fd_set o; 17632185Sminshall 17732185Sminshall FD_ZERO(&o); 17832185Sminshall #endif /* defined(unix) */ 17932185Sminshall 18032185Sminshall if (tfrontp == tbackp) { 18132185Sminshall #if defined(unix) 18232185Sminshall FD_SET(tout, &o); 18332185Sminshall (void) select(tout+1, (int *) 0, &o, (int *) 0, 18432185Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 18532185Sminshall #endif /* defined(unix) */ 18632185Sminshall } else { 18732185Sminshall while (tfrontp != tbackp) { 18832257Sminshall ttyflush(0); 18932185Sminshall #if defined(unix) 19032185Sminshall FD_SET(tout, &o); 19132185Sminshall (void) select(tout+1, (int *) 0, &o, (int *) 0, 19232185Sminshall (struct timeval *) 0); /* wait for TTLOWAT */ 19332185Sminshall #endif /* defined(unix) */ 19432185Sminshall } 19532185Sminshall } 19632185Sminshall } 19732185Sminshall 19832185Sminshall 19932185Sminshall /* 20032185Sminshall * Push3270 - Try to send data along the 3270 output (to screen) direction. 20132185Sminshall */ 20232185Sminshall 20332185Sminshall static int 20432185Sminshall Push3270() 20532185Sminshall { 20632185Sminshall int save = scc; 20732185Sminshall 20832185Sminshall if (scc) { 20932185Sminshall if (Ifrontp+scc > Ibuf+sizeof Ibuf) { 21032185Sminshall if (Ibackp != Ibuf) { 21132185Sminshall memcpy(Ibuf, Ibackp, Ifrontp-Ibackp); 21232185Sminshall Ifrontp -= (Ibackp-Ibuf); 21332185Sminshall Ibackp = Ibuf; 21432185Sminshall } 21532185Sminshall } 21632185Sminshall if (Ifrontp+scc < Ibuf+sizeof Ibuf) { 21732185Sminshall telrcv(); 21832185Sminshall } 21932185Sminshall } 22032185Sminshall return save != scc; 22132185Sminshall } 22232185Sminshall 22332185Sminshall 22432185Sminshall /* 22532185Sminshall * Finish3270 - get the last dregs of 3270 data out to the terminal 22632185Sminshall * before quitting. 22732185Sminshall */ 22832185Sminshall 22932185Sminshall static void 23032185Sminshall Finish3270() 23132185Sminshall { 23232185Sminshall while (Push3270() || !DoTerminalOutput()) { 23332185Sminshall #if defined(unix) 23432185Sminshall HaveInput = 0; 23532185Sminshall #endif /* defined(unix) */ 23632185Sminshall ; 23732185Sminshall } 23832185Sminshall } 23932185Sminshall 24032185Sminshall 24132185Sminshall /* StringToTerminal - output a null terminated string to the terminal */ 24232185Sminshall 24332185Sminshall void 24432185Sminshall StringToTerminal(s) 24532185Sminshall char *s; 24632185Sminshall { 24732185Sminshall int count; 24832185Sminshall 24932185Sminshall count = strlen(s); 25032185Sminshall if (count) { 25132185Sminshall (void) DataToTerminal(s, count); /* we know it always goes... */ 25232185Sminshall } 25332185Sminshall } 25432185Sminshall 25532185Sminshall 25632185Sminshall #if ((!defined(NOT43)) || defined(PUTCHAR)) 25732185Sminshall /* _putchar - output a single character to the terminal. This name is so that 25832185Sminshall * curses(3x) can call us to send out data. 25932185Sminshall */ 26032185Sminshall 26132185Sminshall void 26232185Sminshall _putchar(c) 26332185Sminshall char c; 26432185Sminshall { 26532185Sminshall if (tfrontp >= ttyobuf+sizeof ttyobuf) { 26632185Sminshall (void) DataToTerminal(&c, 1); 26732185Sminshall } else { 26832185Sminshall *tfrontp++ = c; /* optimize if possible. */ 26932185Sminshall } 27032185Sminshall } 27132185Sminshall #endif /* ((!defined(NOT43)) || defined(PUTCHAR)) */ 27232185Sminshall 27332531Sminshall void 27432531Sminshall SetForExit() 27532531Sminshall { 27632531Sminshall setconnmode(); 27732531Sminshall if (In3270) { 27832531Sminshall Finish3270(); 27932531Sminshall } 28032531Sminshall setcommandmode(); 28132531Sminshall fflush(stdout); 28232531Sminshall fflush(stderr); 28332531Sminshall if (In3270) { 28432531Sminshall StopScreen(1); 28532531Sminshall } 28632531Sminshall setconnmode(); 28732531Sminshall setcommandmode(); 28832531Sminshall } 28932531Sminshall 29032531Sminshall void 29132531Sminshall Exit(returnCode) 29232531Sminshall int returnCode; 29332531Sminshall { 29432531Sminshall SetForExit(); 29532531Sminshall exit(returnCode); 29632531Sminshall } 29732531Sminshall 29832531Sminshall void 29932531Sminshall ExitString(string, returnCode) 30032531Sminshall char *string; 30132531Sminshall int returnCode; 30232531Sminshall { 30332531Sminshall SetForExit(); 30432531Sminshall fwrite(string, 1, strlen(string), stderr); 30532531Sminshall exit(returnCode); 30632531Sminshall } 30732531Sminshall 30832531Sminshall void 30932531Sminshall ExitPerror(string, returnCode) 31032531Sminshall char *string; 31132531Sminshall int returnCode; 31232531Sminshall { 31332531Sminshall SetForExit(); 31432531Sminshall perror(string); 31532531Sminshall exit(returnCode); 31632531Sminshall } 31732531Sminshall 31832531Sminshall void 31932531Sminshall SetIn3270() 32032531Sminshall { 32132531Sminshall if (Sent3270TerminalType && myopts[TELOPT_BINARY] 32232531Sminshall && hisopts[TELOPT_BINARY] && !donebinarytoggle) { 32332531Sminshall if (!In3270) { 32432531Sminshall In3270 = 1; 32532531Sminshall Init3270(); /* Initialize 3270 functions */ 32632531Sminshall /* initialize terminal key mapping */ 32732531Sminshall InitTerminal(); /* Start terminal going */ 32832531Sminshall setconnmode(); 32932531Sminshall } 33032531Sminshall } else { 33132531Sminshall if (In3270) { 33232531Sminshall StopScreen(1); 33332531Sminshall In3270 = 0; 33432531Sminshall Stop3270(); /* Tell 3270 we aren't here anymore */ 33532531Sminshall setconnmode(); 33632531Sminshall } 33732531Sminshall } 33832531Sminshall } 33932531Sminshall 34032531Sminshall /* 34132531Sminshall * tn3270_ttype() 34232531Sminshall * 34332531Sminshall * Send a response to a terminal type negotiation. 34432531Sminshall * 34532531Sminshall * Return '0' if no more responses to send; '1' if a response sent. 34632531Sminshall */ 34732531Sminshall 34832531Sminshall int 34932531Sminshall tn3270_ttype() 35032531Sminshall { 35132531Sminshall /* 35232531Sminshall * Try to send a 3270 type terminal name. Decide which one based 35332531Sminshall * on the format of our screen, and (in the future) color 35432531Sminshall * capaiblities. 35532531Sminshall */ 35632531Sminshall InitTerminal(); /* Sets MaxNumberColumns, MaxNumberLines */ 35732531Sminshall if ((MaxNumberLines >= 24) && (MaxNumberColumns >= 80)) { 35832531Sminshall Sent3270TerminalType = 1; 35932531Sminshall if ((MaxNumberLines >= 27) && (MaxNumberColumns >= 132)) { 36032531Sminshall MaxNumberLines = 27; 36132531Sminshall MaxNumberColumns = 132; 36232531Sminshall sb_terminal[SBTERMMODEL] = '5'; 36332531Sminshall } else if (MaxNumberLines >= 43) { 36432531Sminshall MaxNumberLines = 43; 36532531Sminshall MaxNumberColumns = 80; 36632531Sminshall sb_terminal[SBTERMMODEL] = '4'; 36732531Sminshall } else if (MaxNumberLines >= 32) { 36832531Sminshall MaxNumberLines = 32; 36932531Sminshall MaxNumberColumns = 80; 37032531Sminshall sb_terminal[SBTERMMODEL] = '3'; 37132531Sminshall } else { 37232531Sminshall MaxNumberLines = 24; 37332531Sminshall MaxNumberColumns = 80; 37432531Sminshall sb_terminal[SBTERMMODEL] = '2'; 37532531Sminshall } 37632531Sminshall NumberLines = 24; /* before we start out... */ 37732531Sminshall NumberColumns = 80; 37832531Sminshall ScreenSize = NumberLines*NumberColumns; 37932531Sminshall if ((MaxNumberLines*MaxNumberColumns) > MAXSCREENSIZE) { 38032531Sminshall ExitString("Programming error: MAXSCREENSIZE too small.\n", 38132531Sminshall 1); 38232531Sminshall /*NOTREACHED*/ 38332531Sminshall } 38432531Sminshall printsub(">", sb_terminal+2, sizeof sb_terminal-2); 38532531Sminshall ring_supply_data(&netoring, sb_terminal, sizeof sb_terminal); 38632531Sminshall return 1; 38732531Sminshall } else { 38832531Sminshall return 0; 38932531Sminshall } 39032531Sminshall } 39132185Sminshall #endif /* defined(TN3270) */ 392