Annotation of 43BSDTahoe/ucb/telnet/Source/tn3270.c, revision 1.1.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.