[BACK]Return to tn3270.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / telnet

Annotation of src/usr.bin/telnet/tn3270.c, Revision 1.6

1.6     ! millert     1: /*     $OpenBSD: tn3270.c,v 1.5 2003/04/03 12:05:58 hin Exp $  */
1.2       niklas      2: /*     $NetBSD: tn3270.c,v 1.5 1996/02/28 21:04:18 thorpej Exp $       */
                      3:
1.1       deraadt     4: /*
                      5:  * Copyright (c) 1988, 1993
                      6:  *     The Regents of the University of California.  All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
1.6     ! millert    16:  * 3. Neither the name of the University nor the names of its contributors
1.1       deraadt    17:  *    may be used to endorse or promote products derived from this software
                     18:  *    without specific prior written permission.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     21:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     22:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     23:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     24:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     25:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     26:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     27:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     28:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     29:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     30:  * SUCH DAMAGE.
                     31:  */
                     32:
1.3       art        33: #include "telnet_locl.h"
1.1       deraadt    34:
                     35: #if    defined(TN3270)
                     36:
                     37: #include "../ctlr/screen.h"
                     38: #include "../general/globals.h"
                     39:
                     40: #include "../sys_curses/telextrn.h"
                     41: #include "../ctlr/externs.h"
                     42:
                     43: #if    defined(unix)
                     44: int
                     45:        HaveInput,              /* There is input available to scan */
                     46:        cursesdata,             /* Do we dump curses data? */
                     47:        sigiocount;             /* Number of times we got a SIGIO */
                     48:
                     49: char   tline[200];
                     50: char   *transcom = 0;  /* transparent mode command (default: none) */
                     51: #endif /* defined(unix) */
                     52:
                     53: char   Ibuf[8*BUFSIZ], *Ifrontp, *Ibackp;
                     54:
                     55: static char    sb_terminal[] = { IAC, SB,
                     56:                        TELOPT_TTYPE, TELQUAL_IS,
                     57:                        'I', 'B', 'M', '-', '3', '2', '7', '8', '-', '2',
                     58:                        IAC, SE };
                     59: #define        SBTERMMODEL     13
                     60:
                     61: static int
                     62:        Sent3270TerminalType;   /* Have we said we are a 3270? */
                     63:
                     64: #endif /* defined(TN3270) */
                     65:
                     66:
                     67:     void
                     68: init_3270()
                     69: {
                     70: #if    defined(TN3270)
                     71: #if    defined(unix)
                     72:     HaveInput = 0;
                     73:     sigiocount = 0;
                     74: #endif /* defined(unix) */
                     75:     Sent3270TerminalType = 0;
                     76:     Ifrontp = Ibackp = Ibuf;
                     77:     init_ctlr();               /* Initialize some things */
                     78:     init_keyboard();
                     79:     init_screen();
                     80:     init_system();
                     81: #endif /* defined(TN3270) */
                     82: }
                     83:
                     84: 
                     85: #if    defined(TN3270)
                     86:
                     87: /*
                     88:  * DataToNetwork - queue up some data to go to network.  If "done" is set,
                     89:  * then when last byte is queued, we add on an IAC EOR sequence (so,
                     90:  * don't call us with "done" until you want that done...)
                     91:  *
                     92:  * We actually do send all the data to the network buffer, since our
                     93:  * only client needs for us to do that.
                     94:  */
                     95:
                     96:     int
                     97: DataToNetwork(buffer, count, done)
1.4       mpech      98:     char *buffer;      /* where the data is */
                     99:     int  count;        /* how much to send */
1.1       deraadt   100:     int                  done;         /* is this the last of a logical block */
                    101: {
1.4       mpech     102:     int loop, c;
1.1       deraadt   103:     int origCount;
                    104:
                    105:     origCount = count;
                    106:
                    107:     while (count) {
                    108:        /* If not enough room for EORs, IACs, etc., wait */
                    109:        if (NETROOM() < 6) {
                    110:            fd_set o;
                    111:
                    112:            FD_ZERO(&o);
                    113:            netflush();
                    114:            while (NETROOM() < 6) {
                    115:                FD_SET(net, &o);
                    116:                (void) select(net+1, (fd_set *) 0, &o, (fd_set *) 0,
                    117:                                                (struct timeval *) 0);
                    118:                netflush();
                    119:            }
                    120:        }
                    121:        c = ring_empty_count(&netoring);
                    122:        if (c > count) {
                    123:            c = count;
                    124:        }
                    125:        loop = c;
                    126:        while (loop) {
                    127:            if (((unsigned char)*buffer) == IAC) {
                    128:                break;
                    129:            }
                    130:            buffer++;
                    131:            loop--;
                    132:        }
                    133:        if ((c = c-loop)) {
                    134:            ring_supply_data(&netoring, buffer-c, c);
                    135:            count -= c;
                    136:        }
                    137:        if (loop) {
                    138:            NET2ADD(IAC, IAC);
                    139:            count--;
                    140:            buffer++;
                    141:        }
                    142:     }
                    143:
                    144:     if (done) {
                    145:        NET2ADD(IAC, EOR);
                    146:        netflush();             /* try to move along as quickly as ... */
                    147:     }
                    148:     return(origCount - count);
                    149: }
                    150:
                    151:
                    152: #if    defined(unix)
                    153:     void
                    154: inputAvailable(signo)
                    155:        int signo;
                    156: {
                    157:     HaveInput = 1;
                    158:     sigiocount++;
                    159: }
                    160: #endif /* defined(unix) */
                    161:
                    162:     void
                    163: outputPurge()
                    164: {
                    165:     (void) ttyflush(1);
                    166: }
                    167:
                    168:
                    169: /*
                    170:  * The following routines are places where the various tn3270
                    171:  * routines make calls into telnet.c.
                    172:  */
                    173:
                    174: /*
                    175:  * DataToTerminal - queue up some data to go to terminal.
                    176:  *
                    177:  * Note: there are people who call us and depend on our processing
                    178:  * *all* the data at one time (thus the select).
                    179:  */
                    180:
                    181:     int
                    182: DataToTerminal(buffer, count)
1.4       mpech     183:     char       *buffer;                /* where the data is */
                    184:     int                count;                  /* how much to send */
1.1       deraadt   185: {
1.4       mpech     186:     int c;
1.1       deraadt   187:     int origCount;
                    188:
                    189:     origCount = count;
                    190:
                    191:     while (count) {
                    192:        if (TTYROOM() == 0) {
                    193: #if    defined(unix)
                    194:            fd_set o;
                    195:
                    196:            FD_ZERO(&o);
                    197: #endif /* defined(unix) */
                    198:            (void) ttyflush(0);
                    199:            while (TTYROOM() == 0) {
                    200: #if    defined(unix)
                    201:                FD_SET(tout, &o);
                    202:                (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
                    203:                                                (struct timeval *) 0);
                    204: #endif /* defined(unix) */
                    205:                (void) ttyflush(0);
                    206:            }
                    207:        }
                    208:        c = TTYROOM();
                    209:        if (c > count) {
                    210:            c = count;
                    211:        }
                    212:        ring_supply_data(&ttyoring, buffer, c);
                    213:        count -= c;
                    214:        buffer += c;
                    215:     }
                    216:     return(origCount);
                    217: }
                    218: 
                    219:
                    220: /*
                    221:  * Push3270 - Try to send data along the 3270 output (to screen) direction.
                    222:  */
                    223:
                    224:     int
                    225: Push3270()
                    226: {
                    227:     int save = ring_full_count(&netiring);
                    228:
                    229:     if (save) {
                    230:        if (Ifrontp+save > Ibuf+sizeof Ibuf) {
                    231:            if (Ibackp != Ibuf) {
1.2       niklas    232:                memmove(Ibuf, Ibackp, Ifrontp-Ibackp);
1.1       deraadt   233:                Ifrontp -= (Ibackp-Ibuf);
                    234:                Ibackp = Ibuf;
                    235:            }
                    236:        }
                    237:        if (Ifrontp+save < Ibuf+sizeof Ibuf) {
                    238:            (void)telrcv();
                    239:        }
                    240:     }
                    241:     return save != ring_full_count(&netiring);
                    242: }
                    243:
                    244:
                    245: /*
                    246:  * Finish3270 - get the last dregs of 3270 data out to the terminal
                    247:  *             before quitting.
                    248:  */
                    249:
                    250:     void
                    251: Finish3270()
                    252: {
                    253:     while (Push3270() || !DoTerminalOutput()) {
                    254: #if    defined(unix)
                    255:        HaveInput = 0;
                    256: #endif /* defined(unix) */
                    257:        ;
                    258:     }
                    259: }
                    260:
                    261:
                    262: /* StringToTerminal - output a null terminated string to the terminal */
                    263:
                    264:     void
                    265: StringToTerminal(s)
                    266:     char *s;
                    267: {
                    268:     int count;
                    269:
                    270:     count = strlen(s);
                    271:     if (count) {
                    272:        (void) DataToTerminal(s, count);        /* we know it always goes... */
                    273:     }
                    274: }
                    275:
                    276:
                    277: #if    ((!defined(NOT43)) || defined(PUTCHAR))
                    278: /* _putchar - output a single character to the terminal.  This name is so that
                    279:  *     curses(3x) can call us to send out data.
                    280:  */
                    281:
                    282:     void
                    283: _putchar(c)
                    284:     char c;
                    285: {
                    286: #if    defined(sun)            /* SunOS 4.0 bug */
                    287:     c &= 0x7f;
                    288: #endif /* defined(sun) */
                    289:     if (cursesdata) {
                    290:        Dump('>', &c, 1);
                    291:     }
                    292:     if (!TTYROOM()) {
                    293:        (void) DataToTerminal(&c, 1);
                    294:     } else {
                    295:        TTYADD(c);
                    296:     }
                    297: }
                    298: #endif /* ((!defined(NOT43)) || defined(PUTCHAR)) */
                    299:
                    300:     void
                    301: SetIn3270()
                    302: {
                    303:     if (Sent3270TerminalType && my_want_state_is_will(TELOPT_BINARY)
                    304:                && my_want_state_is_do(TELOPT_BINARY) && !donebinarytoggle) {
                    305:        if (!In3270) {
                    306:            In3270 = 1;
                    307:            Init3270();         /* Initialize 3270 functions */
                    308:            /* initialize terminal key mapping */
                    309:            InitTerminal();     /* Start terminal going */
                    310:            setconnmode(0);
                    311:        }
                    312:     } else {
                    313:        if (In3270) {
                    314:            StopScreen(1);
                    315:            In3270 = 0;
                    316:            Stop3270();         /* Tell 3270 we aren't here anymore */
                    317:            setconnmode(0);
                    318:        }
                    319:     }
                    320: }
                    321:
                    322: /*
                    323:  * tn3270_ttype()
                    324:  *
                    325:  *     Send a response to a terminal type negotiation.
                    326:  *
                    327:  *     Return '0' if no more responses to send; '1' if a response sent.
                    328:  */
                    329:
                    330:     int
                    331: tn3270_ttype()
                    332: {
                    333:     /*
                    334:      * Try to send a 3270 type terminal name.  Decide which one based
                    335:      * on the format of our screen, and (in the future) color
                    336:      * capaiblities.
                    337:      */
                    338:     InitTerminal();            /* Sets MaxNumberColumns, MaxNumberLines */
                    339:     if ((MaxNumberLines >= 24) && (MaxNumberColumns >= 80)) {
                    340:        Sent3270TerminalType = 1;
                    341:        if ((MaxNumberLines >= 27) && (MaxNumberColumns >= 132)) {
                    342:            MaxNumberLines = 27;
                    343:            MaxNumberColumns = 132;
                    344:            sb_terminal[SBTERMMODEL] = '5';
                    345:        } else if (MaxNumberLines >= 43) {
                    346:            MaxNumberLines = 43;
                    347:            MaxNumberColumns = 80;
                    348:            sb_terminal[SBTERMMODEL] = '4';
                    349:        } else if (MaxNumberLines >= 32) {
                    350:            MaxNumberLines = 32;
                    351:            MaxNumberColumns = 80;
                    352:            sb_terminal[SBTERMMODEL] = '3';
                    353:        } else {
                    354:            MaxNumberLines = 24;
                    355:            MaxNumberColumns = 80;
                    356:            sb_terminal[SBTERMMODEL] = '2';
                    357:        }
                    358:        NumberLines = 24;               /* before we start out... */
                    359:        NumberColumns = 80;
                    360:        ScreenSize = NumberLines*NumberColumns;
                    361:        if ((MaxNumberLines*MaxNumberColumns) > MAXSCREENSIZE) {
                    362:            ExitString("Programming error:  MAXSCREENSIZE too small.\n",
                    363:                                                                1);
                    364:            /*NOTREACHED*/
                    365:        }
                    366:        printsub('>', sb_terminal+2, sizeof sb_terminal-2);
                    367:        ring_supply_data(&netoring, sb_terminal, sizeof sb_terminal);
                    368:        return 1;
                    369:     } else {
                    370:        return 0;
                    371:     }
                    372: }
                    373:
                    374: #if    defined(unix)
                    375:        int
                    376: settranscom(argc, argv)
                    377:        int argc;
                    378:        char *argv[];
                    379: {
                    380:        int i;
                    381:
                    382:        if (argc == 1 && transcom) {
                    383:           transcom = 0;
                    384:        }
                    385:        if (argc == 1) {
                    386:           return 1;
                    387:        }
1.5       hin       388:        strlcpy(tline, argv[1], sizeof(tline));
1.1       deraadt   389:        for (i = 2; i < argc; ++i) {
1.5       hin       390:                strlcat(tline, " ", sizeof(tline));
                    391:                strlcat(tline, argv[i], sizeof(tline));
1.1       deraadt   392:        }
1.5       hin       393:        transcom = tline;
1.1       deraadt   394:        return 1;
                    395: }
                    396: #endif /* defined(unix) */
                    397:
                    398: #endif /* defined(TN3270) */