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

unix.superglobalmegacorp.com

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