Annotation of 43BSDTahoe/ucb/telnet/Source/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
        !             6:  * provided that this notice is preserved and that due credit is given
        !             7:  * to the University of California at Berkeley. The name of the University
        !             8:  * may not be used to endorse or promote products derived from this
        !             9:  * software without specific prior written permission. This software
        !            10:  * is provided ``as is'' without express or implied warranty.
        !            11:  */
        !            12: 
        !            13: #ifndef lint
        !            14: static char sccsid[] = "@(#)tn3270.c   1.10 (Berkeley) 5/15/88";
        !            15: #endif /* not lint */
        !            16: 
        !            17: #include <sys/types.h>
        !            18: #include <arpa/telnet.h>
        !            19: 
        !            20: #include "general.h"
        !            21: 
        !            22: #include "defines.h"
        !            23: #include "ring.h"
        !            24: #include "externs.h"
        !            25: #include "fdset.h"
        !            26: 
        !            27: #if    defined(TN3270)
        !            28: 
        !            29: #include "../ctlr/screen.h"
        !            30: #include "../general/globals.h"
        !            31: 
        !            32: #if    defined(unix)
        !            33: char   tline[200];
        !            34: char   *transcom = 0;  /* transparent mode command (default: none) */
        !            35: #endif /* defined(unix) */
        !            36: 
        !            37: char   Ibuf[8*BUFSIZ], *Ifrontp, *Ibackp;
        !            38: 
        !            39: static char    sb_terminal[] = { IAC, SB,
        !            40:                        TELOPT_TTYPE, TELQUAL_IS,
        !            41:                        'I', 'B', 'M', '-', '3', '2', '7', '8', '-', '2',
        !            42:                        IAC, SE };
        !            43: #define        SBTERMMODEL     13
        !            44: 
        !            45: static int
        !            46:        Sent3270TerminalType;   /* Have we said we are a 3270? */
        !            47: 
        !            48: #endif /* defined(TN3270) */
        !            49: 
        !            50: 
        !            51: void
        !            52: init_3270()
        !            53: {
        !            54: #if    defined(TN3270)
        !            55:     Sent3270TerminalType = 0;
        !            56:     Ifrontp = Ibackp = Ibuf;
        !            57:     init_ctlr();               /* Initialize some things */
        !            58:     init_keyboard();
        !            59:     init_screen();
        !            60:     init_system();
        !            61: #endif /* defined(TN3270) */
        !            62: }
        !            63: 
        !            64: 
        !            65: #if    defined(TN3270)
        !            66: 
        !            67: /*
        !            68:  * DataToNetwork - queue up some data to go to network.  If "done" is set,
        !            69:  * then when last byte is queued, we add on an IAC EOR sequence (so,
        !            70:  * don't call us with "done" until you want that done...)
        !            71:  *
        !            72:  * We actually do send all the data to the network buffer, since our
        !            73:  * only client needs for us to do that.
        !            74:  */
        !            75: 
        !            76: int
        !            77: DataToNetwork(buffer, count, done)
        !            78: register char  *buffer;        /* where the data is */
        !            79: register int   count;          /* how much to send */
        !            80: int            done;           /* is this the last of a logical block */
        !            81: {
        !            82:     register int loop, c;
        !            83:     int origCount;
        !            84: 
        !            85:     origCount = count;
        !            86: 
        !            87:     while (count) {
        !            88:        /* If not enough room for EORs, IACs, etc., wait */
        !            89:        if (NETROOM() < 6) {
        !            90:            fd_set o;
        !            91: 
        !            92:            FD_ZERO(&o);
        !            93:            netflush();
        !            94:            while (NETROOM() < 6) {
        !            95:                FD_SET(net, &o);
        !            96:                (void) select(net+1, (fd_set *) 0, &o, (fd_set *) 0,
        !            97:                                                (struct timeval *) 0);
        !            98:                netflush();
        !            99:            }
        !           100:        }
        !           101:        c = ring_empty_count(&netoring);
        !           102:        if (c > count) {
        !           103:            c = count;
        !           104:        }
        !           105:        loop = c;
        !           106:        while (loop) {
        !           107:            if (((unsigned char)*buffer) == IAC) {
        !           108:                break;
        !           109:            }
        !           110:            buffer++;
        !           111:            loop--;
        !           112:        }
        !           113:        if ((c = c-loop)) {
        !           114:            ring_supply_data(&netoring, buffer-c, c);
        !           115:            count -= c;
        !           116:        }
        !           117:        if (loop) {
        !           118:            NET2ADD(IAC, IAC);
        !           119:            count--;
        !           120:            buffer++;
        !           121:        }
        !           122:     }
        !           123: 
        !           124:     if (done) {
        !           125:        NET2ADD(IAC, EOR);
        !           126:        netflush();             /* try to move along as quickly as ... */
        !           127:     }
        !           128:     return(origCount - count);
        !           129: }
        !           130: 
        !           131: 
        !           132: #if    defined(unix)
        !           133: void
        !           134: inputAvailable()
        !           135: {
        !           136:     HaveInput = 1;
        !           137: }
        !           138: #endif /* defined(unix) */
        !           139: 
        !           140: void
        !           141: outputPurge()
        !           142: {
        !           143:     ttyflush(1);
        !           144: }
        !           145: 
        !           146: 
        !           147: /*
        !           148:  * The following routines are places where the various tn3270
        !           149:  * routines make calls into telnet.c.
        !           150:  */
        !           151: 
        !           152: /*
        !           153:  * DataToTerminal - queue up some data to go to terminal.
        !           154:  *
        !           155:  * Note: there are people who call us and depend on our processing
        !           156:  * *all* the data at one time (thus the select).
        !           157:  */
        !           158: 
        !           159: int
        !           160: DataToTerminal(buffer, count)
        !           161: register char  *buffer;                /* where the data is */
        !           162: register int   count;                  /* how much to send */
        !           163: {
        !           164:     register int loop, c;
        !           165:     int origCount;
        !           166: 
        !           167:     origCount = count;
        !           168: 
        !           169:     while (count) {
        !           170:        if (TTYROOM() == 0) {
        !           171: #if    defined(unix)
        !           172:            fd_set o;
        !           173: 
        !           174:            FD_ZERO(&o);
        !           175: #endif /* defined(unix) */
        !           176:            ttyflush();
        !           177:            while (TTYROOM() == 0) {
        !           178: #if    defined(unix)
        !           179:                FD_SET(tout, &o);
        !           180:                (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
        !           181:                                                (struct timeval *) 0);
        !           182: #endif /* defined(unix) */
        !           183:                ttyflush();
        !           184:            }
        !           185:        }
        !           186:        c = TTYROOM();
        !           187:        if (c > count) {
        !           188:            c = count;
        !           189:        }
        !           190:        ring_supply_data(&ttyoring, buffer, c);
        !           191:        count -= c;
        !           192:        buffer += c;
        !           193:     }
        !           194:     return(origCount);
        !           195: }
        !           196: 
        !           197: /* EmptyTerminal - called to make sure that the terminal buffer is empty.
        !           198:  *                     Note that we consider the buffer to run all the
        !           199:  *                     way to the kernel (thus the select).
        !           200:  */
        !           201: 
        !           202: void
        !           203: EmptyTerminal()
        !           204: {
        !           205: #if    defined(unix)
        !           206:     fd_set     o;
        !           207: 
        !           208:     FD_ZERO(&o);
        !           209: #endif /* defined(unix) */
        !           210: 
        !           211:     if (TTYBYTES() == 0) {
        !           212: #if    defined(unix)
        !           213:        FD_SET(tout, &o);
        !           214:        (void) select(tout+1, (int *) 0, &o, (int *) 0,
        !           215:                        (struct timeval *) 0);  /* wait for TTLOWAT */
        !           216: #endif /* defined(unix) */
        !           217:     } else {
        !           218:        while (TTYBYTES()) {
        !           219:            ttyflush(0);
        !           220: #if    defined(unix)
        !           221:            FD_SET(tout, &o);
        !           222:            (void) select(tout+1, (int *) 0, &o, (int *) 0,
        !           223:                                (struct timeval *) 0);  /* wait for TTLOWAT */
        !           224: #endif /* defined(unix) */
        !           225:        }
        !           226:     }
        !           227: }
        !           228: 
        !           229: 
        !           230: /*
        !           231:  * Push3270 - Try to send data along the 3270 output (to screen) direction.
        !           232:  */
        !           233: 
        !           234: int
        !           235: Push3270()
        !           236: {
        !           237:     int save = ring_full_count(&netiring);
        !           238: 
        !           239:     if (save) {
        !           240:        if (Ifrontp+save > Ibuf+sizeof Ibuf) {
        !           241:            if (Ibackp != Ibuf) {
        !           242:                memcpy(Ibuf, Ibackp, Ifrontp-Ibackp);
        !           243:                Ifrontp -= (Ibackp-Ibuf);
        !           244:                Ibackp = Ibuf;
        !           245:            }
        !           246:        }
        !           247:        if (Ifrontp+save < Ibuf+sizeof Ibuf) {
        !           248:            telrcv();
        !           249:        }
        !           250:     }
        !           251:     return save != ring_full_count(&netiring);
        !           252: }
        !           253: 
        !           254: 
        !           255: /*
        !           256:  * Finish3270 - get the last dregs of 3270 data out to the terminal
        !           257:  *             before quitting.
        !           258:  */
        !           259: 
        !           260: void
        !           261: Finish3270()
        !           262: {
        !           263:     while (Push3270() || !DoTerminalOutput()) {
        !           264: #if    defined(unix)
        !           265:        HaveInput = 0;
        !           266: #endif /* defined(unix) */
        !           267:        ;
        !           268:     }
        !           269: }
        !           270: 
        !           271: 
        !           272: /* StringToTerminal - output a null terminated string to the terminal */
        !           273: 
        !           274: void
        !           275: StringToTerminal(s)
        !           276: char *s;
        !           277: {
        !           278:     int count;
        !           279: 
        !           280:     count = strlen(s);
        !           281:     if (count) {
        !           282:        (void) DataToTerminal(s, count);        /* we know it always goes... */
        !           283:     }
        !           284: }
        !           285: 
        !           286: 
        !           287: #if    ((!defined(NOT43)) || defined(PUTCHAR))
        !           288: /* _putchar - output a single character to the terminal.  This name is so that
        !           289:  *     curses(3x) can call us to send out data.
        !           290:  */
        !           291: 
        !           292: void
        !           293: _putchar(c)
        !           294: char c;
        !           295: {
        !           296:     if (TTYBYTES()) {
        !           297:        (void) DataToTerminal(&c, 1);
        !           298:     } else {
        !           299:        TTYADD(c);
        !           300:     }
        !           301: }
        !           302: #endif /* ((!defined(NOT43)) || defined(PUTCHAR)) */
        !           303: 
        !           304: void
        !           305: SetForExit()
        !           306: {
        !           307:     setconnmode();
        !           308:     if (In3270) {
        !           309:        Finish3270();
        !           310:     }
        !           311:     setcommandmode();
        !           312:     fflush(stdout);
        !           313:     fflush(stderr);
        !           314:     if (In3270) {
        !           315:        StopScreen(1);
        !           316:     }
        !           317:     setconnmode();
        !           318:     setcommandmode();
        !           319: }
        !           320: 
        !           321: void
        !           322: Exit(returnCode)
        !           323: int returnCode;
        !           324: {
        !           325:     SetForExit();
        !           326:     exit(returnCode);
        !           327: }
        !           328: 
        !           329: void
        !           330: ExitString(string, returnCode)
        !           331: char *string;
        !           332: int returnCode;
        !           333: {
        !           334:     SetForExit();
        !           335:     fwrite(string, 1, strlen(string), stderr);
        !           336:     exit(returnCode);
        !           337: }
        !           338: 
        !           339: void
        !           340: ExitPerror(string, returnCode)
        !           341: char *string;
        !           342: int returnCode;
        !           343: {
        !           344:     SetForExit();
        !           345:     perror(string);
        !           346:     exit(returnCode);
        !           347: }
        !           348: 
        !           349: void
        !           350: SetIn3270()
        !           351: {
        !           352:     if (Sent3270TerminalType && myopts[TELOPT_BINARY]
        !           353:                            && hisopts[TELOPT_BINARY] && !donebinarytoggle) {
        !           354:        if (!In3270) {
        !           355:            In3270 = 1;
        !           356:            Init3270();         /* Initialize 3270 functions */
        !           357:            /* initialize terminal key mapping */
        !           358:            InitTerminal();     /* Start terminal going */
        !           359:            setconnmode();
        !           360:        }
        !           361:     } else {
        !           362:        if (In3270) {
        !           363:            StopScreen(1);
        !           364:            In3270 = 0;
        !           365:            Stop3270();         /* Tell 3270 we aren't here anymore */
        !           366:            setconnmode();
        !           367:        }
        !           368:     }
        !           369: }
        !           370: 
        !           371: /*
        !           372:  * tn3270_ttype()
        !           373:  *
        !           374:  *     Send a response to a terminal type negotiation.
        !           375:  *
        !           376:  *     Return '0' if no more responses to send; '1' if a response sent.
        !           377:  */
        !           378: 
        !           379: int
        !           380: tn3270_ttype()
        !           381: {
        !           382:     /*
        !           383:      * Try to send a 3270 type terminal name.  Decide which one based
        !           384:      * on the format of our screen, and (in the future) color
        !           385:      * capaiblities.
        !           386:      */
        !           387:     InitTerminal();            /* Sets MaxNumberColumns, MaxNumberLines */
        !           388:     if ((MaxNumberLines >= 24) && (MaxNumberColumns >= 80)) {
        !           389:        Sent3270TerminalType = 1;
        !           390:        if ((MaxNumberLines >= 27) && (MaxNumberColumns >= 132)) {
        !           391:            MaxNumberLines = 27;
        !           392:            MaxNumberColumns = 132;
        !           393:            sb_terminal[SBTERMMODEL] = '5';
        !           394:        } else if (MaxNumberLines >= 43) {
        !           395:            MaxNumberLines = 43;
        !           396:            MaxNumberColumns = 80;
        !           397:            sb_terminal[SBTERMMODEL] = '4';
        !           398:        } else if (MaxNumberLines >= 32) {
        !           399:            MaxNumberLines = 32;
        !           400:            MaxNumberColumns = 80;
        !           401:            sb_terminal[SBTERMMODEL] = '3';
        !           402:        } else {
        !           403:            MaxNumberLines = 24;
        !           404:            MaxNumberColumns = 80;
        !           405:            sb_terminal[SBTERMMODEL] = '2';
        !           406:        }
        !           407:        NumberLines = 24;               /* before we start out... */
        !           408:        NumberColumns = 80;
        !           409:        ScreenSize = NumberLines*NumberColumns;
        !           410:        if ((MaxNumberLines*MaxNumberColumns) > MAXSCREENSIZE) {
        !           411:            ExitString("Programming error:  MAXSCREENSIZE too small.\n",
        !           412:                                                                1);
        !           413:            /*NOTREACHED*/
        !           414:        }
        !           415:        printsub(">", sb_terminal+2, sizeof sb_terminal-2);
        !           416:        ring_supply_data(&netoring, sb_terminal, sizeof sb_terminal);
        !           417:        return 1;
        !           418:     } else {
        !           419:        return 0;
        !           420:     }
        !           421: }
        !           422: 
        !           423: #if    defined(unix)
        !           424: settranscom(argc, argv)
        !           425:        int argc;
        !           426:        char *argv[];
        !           427: {
        !           428:        int i, len = 0;
        !           429: 
        !           430:        if (argc == 1 && transcom) {
        !           431:           transcom = 0;
        !           432:        }
        !           433:        if (argc == 1) {
        !           434:           return;
        !           435:        }
        !           436:        for (i = 1; i < argc; ++i) {
        !           437:            len += 1 + strlen(argv[1]);
        !           438:        }
        !           439:        transcom = tline;
        !           440:        (void) strcpy(transcom, argv[1]);
        !           441:        for (i = 2; i < argc; ++i) {
        !           442:            (void) strcat(transcom, " ");
        !           443:            (void) strcat(transcom, argv[i]);
        !           444:        }
        !           445: }
        !           446: #endif /* defined(unix) */
        !           447: 
        !           448: #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.