Annotation of 43BSDTahoe/ucb/tn3270/ctlr/outbound.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[] = "@(#)outbound.c 3.3 (Berkeley) 3/28/88";
        !            15: #endif /* not lint */
        !            16: 
        !            17: #include <stdio.h>
        !            18: 
        !            19: #include "../general/general.h"
        !            20: 
        !            21: #include "hostctlr.h"
        !            22: #include "oia.h"
        !            23: #include "screen.h"
        !            24: #include "../api/ebc_disp.h"
        !            25: 
        !            26: #include "../general/globals.h"
        !            27: #include "options.ext"
        !            28: #include "../telnet.ext"
        !            29: #include "inbound.ext"
        !            30: #include "outbound.ext"
        !            31: #include "../general/bsubs.ext"
        !            32: 
        !            33: #define SetHighestLowest(position) { \
        !            34:                                        if (position < Lowest) { \
        !            35:                                            Lowest = position; \
        !            36:                                        } \
        !            37:                                        if (position > Highest) { \
        !            38:                                            Highest = position; \
        !            39:                                        } \
        !            40:                                    }
        !            41: 
        !            42: 
        !            43: static int     LastWasTerminated = 1;  /* was "control" = 1 last time? */
        !            44: 
        !            45: /* some globals */
        !            46: 
        !            47: #if    !defined(PURE3274)
        !            48: int    OutputClock;            /* what time it is */
        !            49: int    TransparentClock;               /* time we were last in transparent */
        !            50: #endif /* !defined(PURE3274) */
        !            51: 
        !            52: char CIABuffer[64] = {
        !            53:     0x40, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
        !            54:     0xc8, 0xc9, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
        !            55:     0x50, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
        !            56:     0xd8, 0xd9, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
        !            57:     0x60, 0x61, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
        !            58:     0xe8, 0xe9, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
        !            59:     0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
        !            60:     0xf8, 0xf9, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
        !            61: };
        !            62: 
        !            63: static struct orders_def orders_def[] = ORDERS_DEF;
        !            64: 
        !            65: /*
        !            66:  * init_ctlr()
        !            67:  *
        !            68:  *     Initialize all data from the 'data' portion to their startup values.
        !            69:  */
        !            70: 
        !            71: void
        !            72: init_ctlr()
        !            73: {
        !            74:     LastWasTerminated = 1;
        !            75:     init_inbound();
        !            76:     init_oia();
        !            77: }
        !            78: 
        !            79: 
        !            80: FieldInc(position)
        !            81: register int   position;               /* Position in previous field */
        !            82: {
        !            83:     register ScreenImage *ptr;
        !            84: 
        !            85:     ptr = (ScreenImage *)memNSchr((char *)Host+position+1, ATTR_MASK,
        !            86:                        HighestScreen()-position, ATTR_MASK, sizeof Host[0]);
        !            87:     if (ptr == 0) {
        !            88:        ptr = (ScreenImage *)memNSchr((char *)Host+LowestScreen(), ATTR_MASK,
        !            89:                        position-LowestScreen(), ATTR_MASK, sizeof Host[0]);
        !            90:        if (ptr == 0) {
        !            91:            return LowestScreen();
        !            92:        }
        !            93:     }
        !            94:     return ptr-Host;
        !            95: }
        !            96: 
        !            97: FieldDec(position)
        !            98: int    position;
        !            99: {
        !           100:     register ScreenImage *ptr;
        !           101: 
        !           102:     ptr = (ScreenImage *)memNSchr((char *)(Host+position)-1, ATTR_MASK,
        !           103:                        position-LowestScreen(), ATTR_MASK, -sizeof Host[0]);
        !           104:     if (ptr == 0) {
        !           105:        ptr = (ScreenImage *)memNSchr((char *)Host+HighestScreen(), ATTR_MASK,
        !           106:                        HighestScreen()-position, ATTR_MASK, -sizeof Host[0]);
        !           107:        if (ptr == 0) {
        !           108:            return LowestScreen();
        !           109:        }
        !           110:     }
        !           111:     return ptr-Host;
        !           112: }
        !           113: 
        !           114: /* Clear3270 - called to clear the screen */
        !           115: 
        !           116: void
        !           117: Clear3270()
        !           118: {
        !           119:     ClearArray(Host);
        !           120:     DeleteAllFields();         /* get rid of all fields */
        !           121:     BufferAddress = SetBufferAddress(0,0);
        !           122:     CursorAddress = SetBufferAddress(0,0);
        !           123:     Lowest = LowestScreen();
        !           124:     Highest = HighestScreen();
        !           125: }
        !           126: 
        !           127: /* AddHost - called to add a character to the buffer.
        !           128:  *     We use a macro in this module, since we call it so
        !           129:  *     often from loops.
        !           130:  *
        !           131:  *     NOTE: It is a macro, so don't go around using AddHost(p, *c++), or
        !           132:  *     anything similar.  (I don't define any temporary variables, again
        !           133:  *     just for the speed.)
        !           134:  */
        !           135: void
        !           136: AddHost(position, character)
        !           137: int    position;
        !           138: char   character;
        !           139: {
        !           140: #   define     AddHostA(p,c)                                   \
        !           141:     {                                                          \
        !           142:        if (IsStartField(p)) {                                  \
        !           143:            DeleteField(p);                                     \
        !           144:            Highest = HighestScreen();                          \
        !           145:            Lowest = LowestScreen();                            \
        !           146:            SetHighestLowest(p);                                \
        !           147:        }                                                       \
        !           148:        SetHost(p, c);                                          \
        !           149:     }
        !           150: #   define     AddHost(p,c)                                    \
        !           151:     {                                                          \
        !           152:        if (c != GetHost(p)) {                                  \
        !           153:            SetHighestLowest(p);                                \
        !           154:        }                                                       \
        !           155:        AddHostA(p,c);                                          \
        !           156:     }  /* end of macro of AddHost */
        !           157: 
        !           158:     AddHost(position, character);
        !           159: }
        !           160: 
        !           161: /* returns the number of characters consumed */
        !           162: int
        !           163: DataFromNetwork(buffer, count, control)
        !           164: register unsigned char *buffer;                /* what the data is */
        !           165: register int   count;                          /* and how much there is */
        !           166: int    control;                                /* this buffer ended block? */
        !           167: {
        !           168:     int origCount;
        !           169:     register int c;
        !           170:     register int i;
        !           171:     static int Command;
        !           172:     static int Wcc;
        !           173: 
        !           174:     origCount = count;
        !           175: 
        !           176:     /*
        !           177:      * If this is the start of a new data stream, then look
        !           178:      * for an op-code and (possibly) a WCC.
        !           179:      */
        !           180:     if (LastWasTerminated) {
        !           181: 
        !           182:        if (count < 2) {
        !           183:            if (count == 0) {
        !           184:                ExitString(stderr, "Short count received from host!\n", 1);
        !           185:                return(count);
        !           186:            }
        !           187:            Command = buffer[0];
        !           188:            switch (Command) {          /* This had better be a read command */
        !           189:            case CMD_READ_MODIFIED:
        !           190:            case CMD_SNA_READ_MODIFIED:
        !           191:            case CMD_SNA_READ_MODIFIED_ALL:
        !           192:                SetOiaOnlineA(&OperatorInformationArea);
        !           193:                SetOiaModified();
        !           194:                DoReadModified(Command);
        !           195:                break;
        !           196:            case CMD_READ_BUFFER:
        !           197:            case CMD_SNA_READ_BUFFER:
        !           198:                SetOiaOnlineA(&OperatorInformationArea);
        !           199:                SetOiaModified();
        !           200:                DoReadBuffer();
        !           201:                break;
        !           202:            default:
        !           203:                {
        !           204:                    char buffer[100];
        !           205: 
        !           206:                    sprintf(buffer,
        !           207:                        "Unexpected read command code 0x%x received.\n",
        !           208:                                                                    Command);
        !           209:                    ExitString(stderr, buffer, 1);
        !           210:                    break;
        !           211:                }
        !           212:            }
        !           213:            return(1);                  /* We consumed everything */
        !           214:        }
        !           215:        Command = buffer[0];
        !           216:        Wcc = buffer[1];
        !           217:        if (Wcc & WCC_RESET_MDT) {
        !           218:            i = c = WhereAttrByte(LowestScreen());
        !           219:            do {
        !           220:                if (HasMdt(i)) {
        !           221:                    TurnOffMdt(i);
        !           222:                }
        !           223:                i = FieldInc(i);
        !           224:            } while (i != c);
        !           225:        }
        !           226: 
        !           227:        switch (Command) {
        !           228:        case CMD_ERASE_WRITE:
        !           229:        case CMD_ERASE_WRITE_ALTERNATE:
        !           230:        case CMD_SNA_ERASE_WRITE:
        !           231:        case CMD_SNA_ERASE_WRITE_ALTERNATE:
        !           232:            {
        !           233:                int newlines, newcolumns;
        !           234: 
        !           235:                SetOiaOnlineA(&OperatorInformationArea);
        !           236:                ResetOiaTWait(&OperatorInformationArea);
        !           237:                SetOiaModified();
        !           238:                if ((Command == CMD_ERASE_WRITE)
        !           239:                                || (Command == CMD_SNA_ERASE_WRITE)) {
        !           240:                    newlines = 24;
        !           241:                    newcolumns = 80;
        !           242:                } else {
        !           243:                    newlines = MaxNumberLines;
        !           244:                    newcolumns = MaxNumberColumns;
        !           245:                }
        !           246:                if ((newlines != NumberLines)
        !           247:                                || (newcolumns != NumberColumns)) {
        !           248:                        /*
        !           249:                         * The LocalClearScreen() is really for when we
        !           250:                         * are going from a larger screen to a smaller
        !           251:                         * screen, and we need to clear off the stuff
        !           252:                         * at the end of the lines, or the lines at
        !           253:                         * the end of the screen.
        !           254:                         */
        !           255:                    LocalClearScreen();
        !           256:                    NumberLines = newlines;
        !           257:                    NumberColumns = newcolumns;
        !           258:                    ScreenSize = NumberLines * NumberColumns;
        !           259:                }
        !           260:                Clear3270();
        !           261: #if    !defined(PURE3274)
        !           262:                if (TransparentClock == OutputClock) {
        !           263:                    TransStop();
        !           264:                }
        !           265: #endif /* !defined(PURE3274) */
        !           266:                break;
        !           267:            }
        !           268: 
        !           269:        case CMD_ERASE_ALL_UNPROTECTED:
        !           270:        case CMD_SNA_ERASE_ALL_UNPROTECTED:
        !           271:            SetOiaOnlineA(&OperatorInformationArea);
        !           272:            ResetOiaTWait(&OperatorInformationArea);
        !           273:            SetOiaModified();
        !           274:            CursorAddress = HighestScreen()+1;
        !           275:            for (i = LowestScreen(); i <= HighestScreen(); i = ScreenInc(i)) {
        !           276:                if (IsUnProtected(i)) {
        !           277:                    if (CursorAddress > i) {
        !           278:                        CursorAddress = i;
        !           279:                    }
        !           280:                    AddHost(i, '\0');
        !           281:                }
        !           282:                if (HasMdt(i)) {
        !           283:                    TurnOffMdt(i);
        !           284:                }
        !           285:            }
        !           286:            if (CursorAddress == HighestScreen()+1) {
        !           287:                CursorAddress = SetBufferAddress(0,0);
        !           288:            }
        !           289:            UnLocked = 1;
        !           290:            AidByte = 0;
        !           291:            ResetOiaSystemLocked(&OperatorInformationArea);
        !           292:            SetOiaModified();
        !           293:            TerminalIn();
        !           294:            break;
        !           295:        case CMD_WRITE:
        !           296:        case CMD_SNA_WRITE:
        !           297:            SetOiaOnlineA(&OperatorInformationArea);
        !           298:            ResetOiaTWait(&OperatorInformationArea);
        !           299:            SetOiaModified();
        !           300:            break;
        !           301:        default:
        !           302:            {
        !           303:                char buffer[100];
        !           304: 
        !           305:                sprintf(buffer,
        !           306:                        "Unexpected write command code 0x%x received.\n",
        !           307:                                                                Command);
        !           308:                ExitString(stderr, buffer, 1);
        !           309:                break;
        !           310:            }
        !           311:        }
        !           312: 
        !           313:        count -= 2;                     /* strip off command and wcc */
        !           314:        buffer += 2;
        !           315: 
        !           316:     } else {
        !           317: #if    !defined(PURE3274)
        !           318:        if (TransparentClock == OutputClock) {
        !           319:            TransOut(buffer, count, -1, control);
        !           320:            count = 0;
        !           321:        }
        !           322: #endif /* !defined(PURE3274) */
        !           323:     }
        !           324:     LastWasTerminated = 0;             /* then, reset at end... */
        !           325: 
        !           326:     while (count) {
        !           327:        count--;
        !           328:        c = *buffer++;
        !           329:        if (IsOrder(c)) {
        !           330:            /* handle an order */
        !           331:            switch (c) {
        !           332: #              define Ensure(x)        if (count < x) { \
        !           333:                                            if (!control) { \
        !           334:                                                return(origCount-(count+1)); \
        !           335:                                            } else { \
        !           336:                                                /* XXX - should not occur */ \
        !           337:                                                count = 0; \
        !           338:                                                break; \
        !           339:                                            } \
        !           340:                                        }
        !           341:            case ORDER_SF:
        !           342:                Ensure(1);
        !           343:                c = *buffer++;
        !           344:                count--;
        !           345:                if ( ! (IsStartField(BufferAddress) &&
        !           346:                                        FieldAttributes(BufferAddress) == c)) {
        !           347:                    SetHighestLowest(BufferAddress);
        !           348:                    NewField(BufferAddress,c);
        !           349:                }
        !           350:                BufferAddress = ScreenInc(BufferAddress);
        !           351:                break;
        !           352:            case ORDER_SBA:
        !           353:                Ensure(2);
        !           354:                i = buffer[0];
        !           355:                c = buffer[1];
        !           356: #if    !defined(PURE3274)
        !           357:                /* Check for transparent write */
        !           358:                if ((i == 0) && ((c == 0) || (c == 1) || (c == 5))) {
        !           359:                    TransparentClock = OutputClock+1;
        !           360:                    TransOut(buffer+2, count-2, c, control);
        !           361:                    buffer += count;
        !           362:                    count -= count;
        !           363:                    break;
        !           364:                }
        !           365: #endif /* !defined(PURE3274) */
        !           366:                BufferAddress = Addr3270(i, c);
        !           367:                buffer += 2;
        !           368:                count -= 2;
        !           369:                break;
        !           370:            case ORDER_IC:
        !           371:                CursorAddress = BufferAddress;
        !           372:                break;
        !           373:            /*
        !           374:             * XXX - PT is supposed to null fill the screen buffer
        !           375:             * under certain draconian conditions.
        !           376:             */
        !           377:            case ORDER_PT:
        !           378:                i = BufferAddress;
        !           379:                do {
        !           380:                    if (IsStartField(i)) {
        !           381:                        if (!IsProtected(ScreenInc(i))) {
        !           382:                            break;
        !           383:                        }
        !           384:                    }
        !           385:                    i = ScreenInc(i);
        !           386:                } while (i != HighestScreen());
        !           387:                BufferAddress = ScreenInc(i);
        !           388:                break;
        !           389:            case ORDER_RA:
        !           390:                Ensure(3);
        !           391:                i = Addr3270(buffer[0], buffer[1]);
        !           392:                c = buffer[2];
        !           393:                if (c == ORDER_GE) {
        !           394:                    Ensure(4);
        !           395:                    c = buffer[3];
        !           396:                    buffer += 4;
        !           397:                    count -= 4;
        !           398:                } else {
        !           399:                    buffer += 3;
        !           400:                    count -= 3;
        !           401:                }
        !           402:                do {
        !           403:                    AddHost(BufferAddress, ebc_disp[c]);
        !           404:                    BufferAddress = ScreenInc(BufferAddress);
        !           405:                } while (BufferAddress != i);
        !           406:                break;
        !           407:            case ORDER_EUA:    /* (from [here,there), ie: half open interval] */
        !           408:                Ensure(2);
        !           409:                /*
        !           410:                 * Compiler error - msc version 4.0:
        !           411:                 *                      "expression too complicated".
        !           412:                 */
        !           413:                i = WhereAttrByte(BufferAddress);
        !           414:                c = FieldAttributes(i);
        !           415:                i = Addr3270(buffer[0], buffer[1]);
        !           416:                do {
        !           417:                    if (IsStartField(BufferAddress)) {
        !           418:                        c = FieldAttributes(BufferAddress);
        !           419:                    } else if (!IsProtectedAttr(BufferAddress, c)) {
        !           420:                        AddHost(BufferAddress, 0);
        !           421:                    }
        !           422:                    BufferAddress = ScreenInc(BufferAddress);
        !           423:                } while (i != BufferAddress);
        !           424:                buffer += 2;
        !           425:                count -= 2;
        !           426:                break;
        !           427:            case ORDER_GE:
        !           428:                Ensure(2);
        !           429:                /* XXX Should do SOMETHING! */
        !           430:                buffer += 0;
        !           431:                count -= 0;             /* For now, just use this character */
        !           432:                break;
        !           433:            case ORDER_YALE:            /* special YALE defined order */
        !           434:                Ensure(2);      /* need at least two characters */
        !           435:                if (*buffer == 0x5b) {
        !           436:                    i = OptOrder(buffer+1, count-1, control);
        !           437:                    if (i == 0) {
        !           438:                        return(origCount-(count+1));    /* come here again */
        !           439:                    } else {
        !           440:                        buffer += 1 + i;
        !           441:                        count  -= (1 + i);
        !           442:                    }
        !           443:                }
        !           444:                break;
        !           445:            default:
        !           446:                {
        !           447:                    char buffer[100];
        !           448:                    static struct orders_def unk_order
        !           449:                                                = { 0, "??", "(unknown)" };
        !           450:                    struct orders_def *porder = &unk_order;
        !           451:                    int i;
        !           452: 
        !           453:                    for (i = 0; i <= highestof(orders_def); i++) {
        !           454:                        if (orders_def[i].code == c) {
        !           455:                            porder = &orders_def[i];
        !           456:                            break;
        !           457:                        }
        !           458:                    }
        !           459:                    sprintf(buffer,
        !           460:                        "Unsupported order '%s' (%s, 0x%x) received.\n",
        !           461:                        porder->long_name, porder->short_name, c);
        !           462:                    ExitString(stderr, buffer, 1);
        !           463:                    /*NOTREACHED*/
        !           464:                }
        !           465:            }
        !           466:            if (count < 0) {
        !           467:                count = 0;
        !           468:            }
        !           469:        } else {
        !           470:            /* Data comes in large clumps - take it all */
        !           471:            i = BufferAddress;
        !           472:            AddHostA(i, ebc_disp[c]);
        !           473:            SetHighestLowest(i);
        !           474:            i = ScreenInc(i);
        !           475:            c = *buffer;
        !           476:            while (count && !IsOrder(c)) {
        !           477:                AddHostA(i, ebc_disp[c]);
        !           478:                i = ScreenInc(i);
        !           479:                if (i == LowestScreen()) {
        !           480:                    SetHighestLowest(HighestScreen());
        !           481:                }
        !           482:                count--;
        !           483:                buffer++;
        !           484:                c = *buffer;
        !           485:            }
        !           486:            SetHighestLowest(i);
        !           487:            BufferAddress = i;
        !           488:        }
        !           489:     }
        !           490:     if (count == 0) {
        !           491:        if (control) {
        !           492: #if    !defined(PURE3274)
        !           493:            OutputClock++;              /* time rolls on */
        !           494: #endif /* !defined(PURE3274) */
        !           495:            if (Wcc & WCC_RESTORE) {
        !           496: #if    !defined(PURE3274)
        !           497:                if (TransparentClock != OutputClock) {
        !           498:                    AidByte = 0;
        !           499:                }
        !           500: #else  /* !defined(PURE3274) */
        !           501:                AidByte = 0;
        !           502: #endif /* !defined(PURE3274) */
        !           503:                UnLocked = 1;
        !           504:                ResetOiaSystemLocked(&OperatorInformationArea);
        !           505:                SetOiaModified();
        !           506:                SetPsModified();
        !           507:                TerminalIn();
        !           508:            }
        !           509:            if (Wcc & WCC_ALARM) {
        !           510:                RingBell(0);
        !           511:            }
        !           512:        }
        !           513:        LastWasTerminated = control;    /* state for next time */
        !           514:        return(origCount);
        !           515:     } else {
        !           516:        return(origCount-count);
        !           517:     }
        !           518: }
        !           519: 
        !           520: /*
        !           521:  * Init3270()
        !           522:  *
        !           523:  * Initialize any 3270 (controller) variables to an initial state
        !           524:  * in preparation for accepting a connection.
        !           525:  */
        !           526: 
        !           527: void
        !           528: Init3270()
        !           529: {
        !           530:     int i;
        !           531: 
        !           532:     OptInit();         /* initialize mappings */
        !           533: 
        !           534:     ClearArray(Host);
        !           535: 
        !           536:     ClearArray(Orders);
        !           537:     for (i = 0; i <= highestof(orders_def); i++) {
        !           538:        Orders[orders_def[i].code] = 1;
        !           539:     }
        !           540: 
        !           541:     DeleteAllFields();         /* Clear screen */
        !           542:     Lowest = HighestScreen()+1;
        !           543:     Highest = LowestScreen()-1;
        !           544:     CursorAddress = BufferAddress = SetBufferAddress(0,0);
        !           545:     UnLocked = 1;
        !           546: #if    !defined(PURE3274)
        !           547:     OutputClock = 1;
        !           548:     TransparentClock = -1;
        !           549: #endif /* !defined(PURE3274) */
        !           550:     SetOiaReady3274(&OperatorInformationArea);
        !           551: }
        !           552: 
        !           553: 
        !           554: void
        !           555: Stop3270()
        !           556: {
        !           557:     ResetOiaReady3274(&OperatorInformationArea);
        !           558: }

unix.superglobalmegacorp.com

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