Annotation of 43BSDReno/usr.bin/telnet/tn3270.c, revision 1.1

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) */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.