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