Annotation of 43BSDReno/usr.bin/telnet/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 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.