Annotation of 43BSDTahoe/ucb/tn3270/ctlr/outbound.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[] = "@(#)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.