Annotation of 43BSDReno/contrib/isode-beta/support/isoc.c, revision 1.1.1.1

1.1       root        1: /* isoc.c - "minimal" ISODE client for testing */
                      2: 
                      3: #ifndef        lint
                      4: static char *rcsid = "$Header: /f/osi/support/RCS/isoc.c,v 7.1 89/12/07 21:19:51 mrose Exp $";
                      5: #endif
                      6: 
                      7: /* 
                      8:  * $Header: /f/osi/support/RCS/isoc.c,v 7.1 89/12/07 21:19:51 mrose Exp $
                      9:  *
                     10:  *
                     11:  * $Log:       isoc.c,v $
                     12:  * Revision 7.1  89/12/07  21:19:51  mrose
                     13:  * stuff
                     14:  * 
                     15:  * Revision 7.0  89/11/23  22:27:15  mrose
                     16:  * Release 6.0
                     17:  * 
                     18:  */
                     19: 
                     20: /*
                     21:  *                               NOTICE
                     22:  *
                     23:  *    Acquisition, use, and distribution of this module and related
                     24:  *    materials are subject to the restrictions of a license agreement.
                     25:  *    Consult the Preface in the User's Manual for the full terms of
                     26:  *    this agreement.
                     27:  *
                     28:  */
                     29: 
                     30: 
                     31: #include <stdio.h>
                     32: #include <varargs.h>
                     33: #include "rosap.h"
                     34: #include "rtsap.h"
                     35: #include "acsap.h"
                     36: #include "psap2.h"
                     37: #include "ssap.h"
                     38: #include "tsap.h"
                     39: #ifdef TCP
                     40: #include "internet.h"
                     41: #ifdef BSD42
                     42: #include <sys/ioctl.h>
                     43: #endif
                     44: #ifdef SVR3
                     45: #include <fcntl.h>
                     46: #endif
                     47: #endif
                     48: #include "isoservent.h"
                     49: #include "tailor.h"
                     50: #include <sys/stat.h>
                     51: 
                     52: #undef TIMER
                     53: #undef TMS
                     54: #ifdef BSD42
                     55: #define        TIMER
                     56: #endif
                     57: #ifdef SYS5
                     58: #define        TIMER
                     59: #ifndef        HPUX
                     60: #include <sys/times.h>
                     61: #define        TMS
                     62: #endif
                     63: #endif
                     64: 
                     65: #if    !defined (TCP) || defined (FIONBIO) || defined (SVR3)
                     66: #define        ASYNC
                     67: #endif
                     68: 
                     69: /*    DATA */
                     70: 
                     71: #define        ISN(req) \
                     72:     (req & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY)) \
                     73:        ? (long) ((getpid () % (SERIAL_MAX - SERIAL_MIN + 1)) + SERIAL_MIN) \
                     74:        : SERIAL_NONE
                     75: 
                     76: static enum { echo, sink, XXX } mode = XXX;
                     77: 
                     78: static int   testing_queued_writes = 0;
                     79: 
                     80: static char *isacs = NULL;
                     81: static int   isrts = 0;
                     82: 
                     83: static int   status = 0;
                     84: 
                     85: static char *myname = "isoc";
                     86: 
                     87: 
                     88: void   adios (), advise ();
                     89: void   ts_adios (), ts_advise ();
                     90: void   ss_adios (), ss_advise ();
                     91: void   ps_adios (), ps_advise ();
                     92: void   acs_adios (), acs_advise ();
                     93: void   rts_adios (), rts_advise ();
                     94: void   ros_adios (), ros_advise ();
                     95: 
                     96: 
                     97: long   lseek ();
                     98: 
                     99: /*    MAIN */
                    100: 
                    101: #define        chkacs()        if (isacs) \
                    102:                            adios (NULLCP, "no association control for %s", \
                    103:                                        argv[2])
                    104: 
                    105: /* ARGSUSED */
                    106: 
                    107: main (argc, argv, envp)
                    108: int     argc;
                    109: char  **argv,
                    110:       **envp;
                    111: {
                    112:     register struct isoservent *is;
                    113: 
                    114:     if (myname = rindex (argv[0], '/'))
                    115:        myname++;
                    116:     if (myname == NULL || *myname == NULL)
                    117:        myname = argv[0];
                    118: 
                    119:     isodetailor (myname, 1);
                    120: 
                    121:     if (argc != 4)
                    122:        adios (NULLCP, "usage: %s host provider entity", myname);
                    123: 
                    124: #ifdef TCP
                    125:     if (strcmp (argv[2], "raw") == 0) {
                    126:        raw_main (argv[3], argv[1]);
                    127:        exit (0);
                    128:     }
                    129: #endif
                    130: 
                    131:     if (index (argv[3], '/')) {
                    132:        mode = strcmp (isacs = argv[3], "isode/sink") ? echo : sink;
                    133:     }
                    134:     else {
                    135:        if ((is = getisoserventbyname (argv[3], argv[2])) == NULL)
                    136:            adios (NULLCP, "%s/%s: unknown provider/entity pair",
                    137:                    argv[2], argv[3]);
                    138: 
                    139:        mode = strcmp (is -> is_entity, "sink") ? echo : sink;
                    140:     }
                    141: 
                    142:     if (strcmp (argv[2], "tsap") == 0) {
                    143:        chkacs ();
                    144:        ts_main (is, argv[1]);
                    145:     }
                    146:     else
                    147:        if (strcmp (argv[2], "ssap") == 0) {
                    148:            chkacs ();
                    149:            ss_main (is, argv[1]);
                    150:        }
                    151:        else
                    152:            if (strcmp (argv[2], "psap") == 0)
                    153:                ps_main (is, argv[1]);
                    154:            else
                    155:                if (strcmp (argv[2], "rtsap") == 0) {
                    156:                    isrts = 1;
                    157:                    rts_main (is, argv[1]);
                    158:                }
                    159:                else
                    160:                    if (strcmp (argv[2], "rosap") == 0)
                    161:                        ros_main (is, argv[1]);
                    162:                    else
                    163:                        adios (NULLCP, "unknown provider: \"%s\"", argv[2]);
                    164: 
                    165:     exit (status);             /* NOTREACHED */
                    166: }
                    167: 
                    168: /*    RAW */
                    169: 
                    170: #ifdef TCP
                    171: static int  raw_main (service, addr)
                    172: char   *service,
                    173:        *addr;
                    174: {
                    175:     int     sd,
                    176:             cc,
                    177:             i,
                    178:             j;
                    179:     char   *cp,
                    180:            *dp;
                    181:     register struct hostent *hp;
                    182:     register struct servent *sp;
                    183:     struct sockaddr_in  in_socket;
                    184:     register struct sockaddr_in *isock = &in_socket;
                    185:     struct stat st;
                    186: 
                    187:     if (strcmp (service, "sink"))
                    188:        adios (NULLCP, "only sink on raw tcp is supported");
                    189:     if ((sp = getservbyname (service, "tcp")) == NULL)
                    190:        adios (NULLCP, "%s/%s: unknown service", "tcp", service);
                    191:     if ((hp = gethostbystring (addr)) == NULL)
                    192:        adios (NULLCP, "%s: unknown host", addr);
                    193: 
                    194:     bzero ((char *) isock, sizeof *isock);
                    195:     isock -> sin_family = hp -> h_addrtype;
                    196:     isock -> sin_port = sp -> s_port;
                    197:     inaddr_copy (hp, isock);
                    198: 
                    199:     if ((sd = start_tcp_client ((struct sockaddr_in *) 0, 0)) == NOTOK)
                    200:        adios ("socket", "unable to start");
                    201:     fprintf (stderr, "%s... ", hp -> h_name);
                    202:     (void) fflush (stderr);
                    203:     if (join_tcp_server (sd, isock) == NOTOK) {
                    204:        fprintf (stderr, "failed\n");
                    205:        adios ("socket", "unable to connect");
                    206:     }
                    207:     fprintf (stderr, "connected\n");
                    208: 
                    209:     if (fstat (fileno (stdin), &st) == NOTOK
                    210:            || (st.st_mode & S_IFMT) != S_IFREG
                    211:            || (cc = st.st_size) == 0)
                    212:        adios (NULLCP, "standard input not a regular file");
                    213:     (void) lseek (fileno (stdin), 0L, 0);
                    214: 
                    215:     if ((cp = malloc ((unsigned) cc)) == NULL)
                    216:        adios (NULLCP, "no memory");
                    217:     for (dp = cp, j = cc; j > 0; dp += i, j -= i)
                    218:        switch (i = read (fileno (stdin), dp, j)) {
                    219:            case NOTOK: 
                    220:                adios ("on stdin", "read failed");
                    221: 
                    222:            case OK: 
                    223:                adios (NULLCP, "premature end-of-file");
                    224: 
                    225:            default: 
                    226:                break;
                    227:        }
                    228: 
                    229: #ifdef TIMER
                    230:     timer (0);
                    231: #endif
                    232:     if (write_tcp_socket (sd, cp, cc) != cc)
                    233:        adios ("writing", "error");
                    234:     (void) close_tcp_socket (sd);
                    235: #ifdef TIMER
                    236:     timer (cc);
                    237: #endif
                    238: }
                    239: #endif
                    240: 
                    241: /*    TSAP */
                    242: 
                    243: static int  ts_main (is, addr)
                    244: struct isoservent *is;
                    245: char   *addr;
                    246: {
                    247:     int     sd,
                    248:            cc,
                    249:            i,
                    250:            j,
                    251:            expedited,
                    252:            expd;
                    253:     char   *cp,
                    254:           *dp,
                    255:            buffer[BUFSIZ];
                    256:     struct  TSAPaddr *ta;
                    257:     struct TSAPconnect  tcs;
                    258:     register struct TSAPconnect *tc = &tcs;
                    259:     struct TSAPdisconnect   tds;
                    260:     register struct TSAPdisconnect *td = &tds;
                    261:     struct stat st;
                    262: 
                    263:     if ((ta = is2taddr (addr, NULLCP, is)) == NULL)
                    264:        adios (NULLCP, "address translation failed");
                    265: 
                    266:     fprintf (stderr, "%s... ", addr);
                    267:     (void) fflush (stderr);
                    268: #ifndef        ASYNC
                    269:     if (TConnRequest (NULLTA, ta, 1, NULLCP, 0, NULLQOS, tc, td) == NOTOK) {
                    270:        fprintf (stderr, "failed\n");
                    271:        ts_adios (td, "T-CONNECT.REQUEST");
                    272:     }
                    273:     sd = tc -> tc_sd;
                    274: #else
                    275:     if ((i = TAsynConnRequest (NULLTA, ta, 1, NULLCP, 0, NULLQOS, tc, td, 1))
                    276:            == NOTOK) {
                    277:        fprintf (stderr, "failed\n");
                    278:        ts_adios (td, "T-(ASYN-)CONNECT.REQUEST");
                    279:     }
                    280:     sd = tc -> tc_sd, cc = 0;
                    281:     while (i == CONNECTING_1 || i == CONNECTING_2) {
                    282:        int     nfds;
                    283:        fd_set  mask,
                    284:               *rmask,
                    285:               *wmask;
                    286: 
                    287:        nfds = 0;
                    288:        FD_ZERO (&mask);
                    289:        if (TSelectMask (sd, &mask, &nfds, td) == NOTOK) {
                    290:            fprintf (stderr, "failed\n");
                    291:            ts_adios (td, "T-(ASYN-)CONNECT.REQUEST(TSelectMask)");
                    292:        }
                    293:        rmask = (i == CONNECTING_2) ? &mask : NULLFD;
                    294:        wmask = (i == CONNECTING_2) ? NULLFD : &mask;
                    295: 
                    296:        fprintf (stderr, ".");
                    297:        (void) fflush (stderr);
                    298:        if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) {
                    299:            fprintf (stderr, "failed\n");
                    300:            adios ("failed", "select");
                    301:        }
                    302: 
                    303:        if ((rmask && FD_ISSET (sd, rmask) == 0)
                    304:                || (wmask && FD_ISSET (sd, wmask) == 0))
                    305:            continue;
                    306:            
                    307:        if ((i = TAsynRetryRequest (sd, tc, td)) == NOTOK) {
                    308:            fprintf (stderr, "failed\n");
                    309:            ts_adios (td, "T-ASYN-RETRY.REQUEST");
                    310:        }
                    311:     }
                    312: #endif
                    313:     fprintf (stderr, "connected\n");
                    314: 
                    315: 
                    316:     if (getenv ("TEST_QUEUED_WRITES")) {
                    317:        if (TSetQueuesOK (tc -> tc_sd, 1, td) == NOTOK)
                    318:            ts_adios (td, "T-SET-QUEUES-OK");
                    319: 
                    320:        tsap_log -> ll_events |= LLOG_EXCEPTIONS;
                    321:        tsap_log -> ll_file = "-";
                    322:        (void) ll_close (tsap_log);
                    323: 
                    324:        testing_queued_writes = 1;
                    325:     }
                    326: 
                    327:     expd = tc -> tc_expedited;
                    328: #ifdef DEBUG
                    329:     {
                    330:        advise (NULLCP, "responding TSAP address: %s",
                    331:                taddr2str (&tc -> tc_responding));
                    332: 
                    333:        if (tc -> tc_cc > 0)
                    334:            advise (NULLCP, "greetings: %d octets", tc -> tc_cc);
                    335:     }
                    336: #endif
                    337: 
                    338:     if (fstat (fileno (stdin), &st) != NOTOK
                    339:            && (st.st_mode & S_IFMT) == S_IFREG
                    340:            && (cc = st.st_size) != 0) {
                    341:        (void) lseek (fileno (stdin), 0L, 0);
                    342: 
                    343:        if ((cp = malloc ((unsigned) cc)) == NULL)
                    344:            adios (NULLCP, "no memory");
                    345:        for (dp = cp, j = cc; j > 0; dp += i, j -= i)
                    346:            switch (i = read (fileno (stdin), dp, j)) {
                    347:                case NOTOK:
                    348:                    adios ("on stdin", "read failed");
                    349: 
                    350:                case OK:
                    351:                    adios (NULLCP, "premature end-of-file");
                    352:                    
                    353:                default:
                    354:                    break;
                    355:            }
                    356:        for (i = 10; i > 0; i--) {
                    357: #ifdef TIMER
                    358:            timer (0);
                    359: #endif
                    360:            ts_datarequest (sd, cp, cc, 0);
                    361: #ifdef TIMER
                    362:            timer (cc);
                    363: #endif
                    364:        }
                    365:        free (cp);
                    366:     }
                    367:     else
                    368:        for (expedited = 0;
                    369:                fgets (buffer, sizeof buffer, stdin);
                    370:                expedited = !expedited) {
                    371:            if ((cc = strlen (buffer) + 1) > TX_SIZE && expedited)
                    372:                expedited = 0;
                    373: 
                    374:            ts_datarequest (sd, buffer, cc, expd ? expedited : 0);
                    375:        }
                    376: 
                    377:     if (TDiscRequest (sd, NULLCP, 0, td) == NOTOK)
                    378:        ts_adios (td, "T-DISCONNECT.REQUEST");
                    379: }
                    380: 
                    381: /*  */
                    382: 
                    383: static int  ts_datarequest (sd, data, cc, expedited)
                    384: int    sd;
                    385: char   *data;
                    386: int    cc,
                    387:        expedited;
                    388: {
                    389:     struct TSAPdata txs;
                    390:     register struct TSAPdata   *tx = &txs;
                    391:     struct TSAPdisconnect   tds;
                    392:     register struct TSAPdisconnect *td = &tds;
                    393: 
                    394:     if ((expedited ? TExpdRequest (sd, data, cc, td)
                    395:                : TDataRequest (sd, data, cc, td)) == NOTOK)
                    396:        if (expedited)
                    397:            ts_adios (td, "T-EXPEDITED-DATA.REQUEST");
                    398:        else
                    399:            ts_adios (td, "T-DATA.REQUEST");
                    400: 
                    401:     if (mode == echo) {
                    402:        if (testing_queued_writes) {
                    403:            int     vecp;
                    404:            char   *vec[4];
                    405:            fd_set  rfds;
                    406: 
                    407:            FD_ZERO (&rfds);
                    408:            FD_SET (sd, &rfds);
                    409:            if (TNetAccept (&vecp, vec, sd + 1, &rfds, NULLFD, NULLFD, NOTOK,
                    410:                            td) == NOTOK)
                    411:                ts_adios (td, "T-NET-ACCEPT");
                    412:        }
                    413: 
                    414:        if (TReadRequest (sd, tx, NOTOK, td) == NOTOK)
                    415:            ts_adios (td, "T-READ.REQUEST");
                    416:        if (cc != tx -> tx_cc) {
                    417:            advise (NULLCP, "length mismatch, orig=%d echo=%d",
                    418:                    cc, tx -> tx_cc);
                    419:            status++;
                    420:        }
                    421:        else
                    422:            if (qcmp (data, &tx -> tx_qbuf, cc))
                    423:                status++;
                    424:        TXFREE (tx)
                    425:     }
                    426: }
                    427: 
                    428: /*  */
                    429: 
                    430: static void  ts_adios (td, event)
                    431: register struct TSAPdisconnect *td;
                    432: char   *event;
                    433: {
                    434:     ts_advise (td, event);
                    435: 
                    436:     _exit (1);
                    437: }
                    438: 
                    439: 
                    440: static void  ts_advise (td, event)
                    441: register struct TSAPdisconnect *td;
                    442: char   *event;
                    443: {
                    444:     char    data[BUFSIZ];
                    445: 
                    446:     if (td -> td_cc > 0) {
                    447:        (void) sprintf (data, "[%s] %*.*s",
                    448:                TErrString (td -> td_reason),
                    449:                td -> td_cc, td -> td_cc, td -> td_data);
                    450:     }
                    451:     else
                    452:        (void) sprintf (data, "[%s]", TErrString (td -> td_reason));
                    453: 
                    454:     advise (NULLCP, "%s: %s", event, data);
                    455: }
                    456: 
                    457: /*    SSAP */
                    458: 
                    459: static int requirements = SR_HALFDUPLEX | SR_DUPLEX | SR_EXPEDITED
                    460:                | SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY
                    461:                | SR_NEGOTIATED | SR_CAPABILITY | SR_EXCEPTIONS | SR_TYPEDATA;
                    462: 
                    463: static int owned = 0;
                    464: static int avail = 0;
                    465: 
                    466: static long ssn;
                    467: 
                    468: static int nmodes;
                    469: static int datamodes[4];
                    470: 
                    471: static char userdata[1024];
                    472: 
                    473: /*  */
                    474: 
                    475: static int  ss_main (is, addr)
                    476: struct isoservent *is;
                    477: char   *addr;
                    478: {
                    479:     int     sd,
                    480:            cc,
                    481:            i,
                    482:            j,
                    483:            k,
                    484:            l,
                    485:            tokens;
                    486:     char   *cp,
                    487:           *dp,
                    488:            buffer[BUFSIZ];
                    489:     struct SSAPactid    ids;
                    490:     register struct SSAPactid  *id = &ids;
                    491:     register struct SSAPaddr *sz;
                    492:     struct SSAPref  sfs;
                    493:     register struct SSAPref *sf;
                    494:     struct SSAPconnect  scs;
                    495:     register struct SSAPconnect *sc = &scs;
                    496:     struct SSAPrelease  srs;
                    497:     register struct SSAPrelease *sr = &srs;
                    498:     struct SSAPindication   sis;
                    499:     register struct SSAPindication *si = &sis;
                    500:     register struct SSAPabort  *sa = &si -> si_abort;
                    501:     struct stat st;
                    502: 
                    503:     bzero (userdata, sizeof userdata);
                    504: 
                    505:     if ((sz = is2saddr (addr, NULLCP, is)) == NULL)
                    506:        adios (NULLCP, "address translation failed");
                    507:     if ((sf = addr2ref (SLocalHostName ())) == NULL) {
                    508:        sf = &sfs;
                    509:        (void) bzero ((char *) sf, sizeof *sf);
                    510:     }
                    511: 
                    512:     tokens = 0;
                    513: #define dotoken(requires,shift,bit,type) \
                    514: { \
                    515:     if (requirements & requires) \
                    516:        tokens |= ST_CALL_VALUE << shift; \
                    517: }
                    518:     dotokens ();
                    519: #undef dotoken
                    520: 
                    521:     fprintf (stderr, "%s... ", addr);
                    522:     (void) fflush (stderr);
                    523: #ifndef        ASYNC
                    524:     if (SConnRequest (sf, NULLSA, sz, requirements, tokens, ISN (requirements),
                    525:            userdata, sizeof userdata /*SS_SIZE*/, NULLQOS, sc, si) == NOTOK) {
                    526:        fprintf (stderr, "failed\n");
                    527:        ss_adios (sa, "S-CONNECT.REQUEST");
                    528:     }
                    529:     sd = sc -> sc_sd;
                    530: #else
                    531:     if ((i = SAsynConnRequest (sf, NULLSA, sz, requirements, tokens,
                    532:            ISN (requirements), userdata, sizeof userdata /*SS_SIZE*/, NULLQOS,
                    533:            sc, si, 1))
                    534:          == NOTOK) {
                    535:        fprintf (stderr, "failed\n");
                    536:        ss_adios (sa, "S-(ASYN-)CONNECT.REQUEST");
                    537:     }
                    538:     sd = sc -> sc_sd, cc = 0;
                    539:     while (i == CONNECTING_1 || i == CONNECTING_2) {
                    540:        int     nfds;
                    541:        fd_set  mask,
                    542:               *rmask,
                    543:               *wmask;
                    544: 
                    545:        nfds = 0;
                    546:        FD_ZERO (&mask);
                    547:        if (SSelectMask (sd, &mask, &nfds, si) == NOTOK) {
                    548:            fprintf (stderr, "failed\n");
                    549:            ss_adios (sa, "S-(ASYN-)CONNECT.REQUEST(SSelectMask)");
                    550:        }
                    551:        rmask = (i == CONNECTING_2) ? &mask : NULLFD;
                    552:        wmask = (i == CONNECTING_2) ? NULLFD : &mask;
                    553: 
                    554:        fprintf (stderr, ".");
                    555:        if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) {
                    556:            fprintf (stderr, "failed\n");
                    557:            adios ("failed", "select");
                    558:        }
                    559: 
                    560:        if ((rmask && FD_ISSET (sd, rmask) == 0)
                    561:                || (wmask && FD_ISSET (sd, wmask) == 0))
                    562:            continue;
                    563:            
                    564:        if ((i = SAsynRetryRequest (sd, sc, si)) == NOTOK) {
                    565:            fprintf (stderr, "failed\n");
                    566:            ss_adios (sa, "S-ASYN-RETRY.REQUEST");
                    567:        }
                    568:     }
                    569: #endif
                    570: 
                    571:     if (sc -> sc_result != SC_ACCEPT) {
                    572:        fprintf (stderr, "failed\n");
                    573:        if (sc -> sc_cc > 0)
                    574:            adios (NULLCP, "connection rejected: [%s] %*.*s",
                    575:                        SErrString (sc -> sc_result),
                    576:                        sc -> sc_cc, sc -> sc_cc, sc -> sc_data);
                    577:        else
                    578:            adios (NULLCP, "connection rejected: [%s]",
                    579:                        SErrString (sc -> sc_result));
                    580:     }
                    581:     fprintf (stderr, "connected\n");
                    582: 
                    583: #ifdef DEBUG
                    584:     {
                    585:        advise (NULLCP, "responding SSAP address: %s",
                    586:                saddr2str (&sc -> sc_responding));
                    587: 
                    588:        if (sc -> sc_cc > 0)
                    589:            advise (NULLCP, "greetings: %d octets", sc -> sc_cc);
                    590:     }
                    591: #endif
                    592:     requirements = sc -> sc_requirements;
                    593:     nmodes = 0;
                    594:     datamodes[nmodes++] = SX_NORMAL;
                    595:     if (requirements & SR_EXPEDITED)
                    596:        datamodes[nmodes++] = SX_EXPEDITED;
                    597:     if ((requirements & SR_CAPABILITY) && (requirements & SR_ACTIVITY))
                    598:        datamodes[nmodes++] = SX_CAPDIND;
                    599:     if (requirements & SR_TYPEDATA)
                    600:        datamodes[nmodes++] = SX_TYPED;
                    601: 
                    602: #define dotoken(requires,shift,bit,type) \
                    603: { \
                    604:     if (requirements & requires) \
                    605:        switch (sc -> sc_settings & (ST_MASK << shift)) { \
                    606:            case ST_CALL_VALUE: \
                    607:                adios (NULLCP, "%s token: choice", type); \
                    608:  \
                    609:            case ST_INIT_VALUE: \
                    610:                owned |= bit, avail |= bit; \
                    611:                break; \
                    612:  \
                    613:            case ST_RESP_VALUE: \
                    614:                avail |= bit; \
                    615:                break; \
                    616:  \
                    617:            default: \
                    618:                adios (NULLCP, "%s token: reserved", type); \
                    619:        } \
                    620: }
                    621:        dotokens ();
                    622: #undef dotoken
                    623: 
                    624:     if (requirements & SR_ACTIVITY) {
                    625:        (void) strcpy (id -> sd_data, mode == echo ? "echo" : "sink");
                    626:        id -> sd_len = strlen (id -> sd_data);
                    627:        if (SActStartRequest (sd, id, userdata, SV_SIZE, si) == NOTOK)
                    628:            ss_adios (sa, "S-ACTIVITY-START.REQUEST");
                    629:     }
                    630: 
                    631:     if (fstat (fileno (stdin), &st) != NOTOK
                    632:            && (st.st_mode & S_IFMT) == S_IFREG
                    633:            && (cc = st.st_size) != 0) {
                    634:        (void) lseek (fileno (stdin), 0L, 0);
                    635: 
                    636:        if ((cp = malloc ((unsigned) cc)) == NULL)
                    637:            adios (NULLCP, "no memory");
                    638:        for (dp = cp, j = cc; j > 0; dp += i, j -= i)
                    639:            switch (i = read (fileno (stdin), dp, j)) {
                    640:                case NOTOK:
                    641:                    adios ("on stdin", "read failed");
                    642: 
                    643:                case OK:
                    644:                    adios (NULLCP, "premature end-of-file");
                    645:                    
                    646:                default:
                    647:                    break;
                    648:            }
                    649:        for (i = 10; i > 0; i--) {
                    650: #ifdef TIMER
                    651:            timer (0);
                    652: #endif
                    653:            ss_datarequest (sd, cp, cc, SX_NORMAL, 0);
                    654: #ifdef TIMER
                    655:            timer (cc);
                    656: #endif
                    657:        }
                    658:        free (cp);
                    659:     }
                    660:     else {
                    661:        for (j = l = 0; fgets (buffer, sizeof buffer, stdin); ) {
                    662:            k = j >= nmodes ? SX_EXPEDITED : datamodes[j++ % nmodes];
                    663:            if ((cc = strlen (buffer) + 1) > SX_EXSIZE && k == SX_EXPEDITED) {
                    664:                if ((k = datamodes[j++ % nmodes]) == SX_EXPEDITED)
                    665:                    k = datamodes[j++ % nmodes];
                    666:            }
                    667: 
                    668:            switch (k) {
                    669:                case SX_CAPDIND:
                    670:                    if (!(requirements & SR_RESYNC) || l++ & 0x01) {
                    671:                        ss_waitfor (sd, ST_ACT_TOKEN);
                    672:                        if (l & 0x03) {
                    673:                            if (SActIntrRequest (sd, SP_SEQUENCE, si)
                    674:                                    == NOTOK)
                    675:                                ss_adios (sa, "S-ACTIVITY-INTERRUPT.REQUEST");
                    676:                        }
                    677:                        else {
                    678:                            if (SActDiscRequest (sd, SP_SEQUENCE, si)
                    679:                                    == NOTOK)
                    680:                                ss_adios (sa, "S-ACTIVITY-DISCARD.REQUEST");
                    681:                        }
                    682:                        ss_waitfor (sd, -1);
                    683:                        goto push_data;
                    684:                    }
                    685:                    if (!(requirements & SR_RESYNC))
                    686:                        break;
                    687:                    tokens = 0;
                    688: #define dotoken(requires,shift,bit,type) \
                    689: { \
                    690:                    if (requirements & requires) \
                    691:                        tokens |= ST_CALL_VALUE << shift; \
                    692: }
                    693:                    dotokens ();
                    694: #undef dotoken
                    695:                    if (SReSyncRequest (sd, SYNC_SET, ssn - 1, tokens,
                    696:                                userdata, SN_SIZE, si) == NOTOK)
                    697:                        ss_adios (sa, "S-RESYNCHRONIZE.REQUEST");
                    698:                    ss_waitfor (sd, -1);
                    699:                    break;
                    700: 
                    701:                case SX_EXPEDITED:
                    702:                    if (j >= nmodes)
                    703:                        j = j % nmodes;/* fall... */
                    704:                    if (!(requirements & SR_EXPEDITED))
                    705:                        k = SX_NORMAL;  /* fall... */
                    706:                default:
                    707: push_data: ;
                    708:                    ss_datarequest (sd, buffer, cc, k, 1);
                    709:                    if (k == SX_CAPDIND
                    710:                            && SActResumeRequest (sd, id, id, 
                    711:                                    (long) (getpid () % (SERIAL_MAX - SERIAL_MIN + 1))
                    712:                                    + SERIAL_MIN, sf, userdata, SV_SIZE, si)
                    713:                                  == NOTOK)
                    714:                        ss_adios (sa, "S-ACTIVITY-RESUME.REQUEST");
                    715:                    break;
                    716:            }
                    717:        }
                    718: 
                    719:        if (requirements & SR_EXCEPTIONS) {
                    720:            if (owned & ST_DAT_TOKEN)
                    721:                if (SGTokenRequest (sd, ST_DAT_TOKEN, si) == NOTOK)
                    722:                    ss_adios (sa, "S-TOKEN-GIVE.REQUEST");
                    723:                else
                    724:                    owned &= ~ST_DAT_TOKEN;
                    725:            if (SUReportRequest (sd, SP_NOREASON, userdata, SP_SIZE, si)
                    726:                    == NOTOK)
                    727:                ss_adios (sa, "S-U-EXCEPTION-REPORT.REQUEST");
                    728:            ss_waitfor (sd, -1);
                    729:        }    
                    730:     }
                    731: 
                    732:     if ((requirements & SR_MAJORSYNC) && !(requirements & SR_ACTIVITY)) {
                    733:        if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si) == NOTOK)
                    734:            switch (sa -> sa_reason) {
                    735:                case SC_OPERATION:
                    736:                    ss_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN
                    737:                            | ST_MAJ_TOKEN);
                    738:                    if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si)
                    739:                            == OK)
                    740:                        break;  /* else fall */
                    741: 
                    742:                default:
                    743:                    ss_adios (sa, "S-MAJOR-SYNC.REQUEST");
                    744:            }
                    745: 
                    746:        ss_waitfor (sd, -1);
                    747:     }
                    748: 
                    749:     if (requirements & SR_ACTIVITY) {
                    750:        if (SActEndRequest (sd, &ssn, userdata, SV_SIZE, si) == NOTOK)
                    751:            switch (sa -> sa_reason) {
                    752:                case SC_OPERATION:
                    753:                    ss_waitfor (sd, avail);
                    754:                    if (SActEndRequest (sd, &ssn, userdata, SV_SIZE, si) == OK)
                    755:                        break;  /* else fall */
                    756: 
                    757:                default:
                    758:                    ss_adios (sa, "S-ACTIVITY-END.REQUEST");
                    759:            }
                    760: 
                    761:        ss_waitfor (sd, -1);
                    762:                
                    763:        if (SGControlRequest (sd, si) == NOTOK)
                    764:            switch (sa -> sa_reason) {
                    765:                case SC_OPERATION:
                    766:                    ss_waitfor (sd, avail);
                    767:                    if (SGControlRequest (sd, si) == OK)
                    768:                        break;  /* else fall */
                    769: 
                    770:                default:
                    771:                    ss_adios (sa, "S-CONTROL-GIVE.REQUEST");
                    772:            }
                    773: 
                    774:        owned = 0;
                    775: 
                    776:        ss_waitfor (sd, -1);
                    777:     }
                    778: 
                    779:     if (SRelRequest (sd, userdata, SF_SIZE, NOTOK, sr, si) == NOTOK)
                    780:        switch (sa -> sa_reason) {
                    781:            case SC_OPERATION: 
                    782:            case SC_WAITING: 
                    783:                ss_waitfor (sd, avail);
                    784:                if (SRelRequest (sd, userdata, SF_SIZE, NOTOK, sr, si) == OK)
                    785:                    break;      /* else fall */
                    786: 
                    787:            default: 
                    788:                ss_adios (sa, "S-RELEASE.REQUEST");
                    789:        }
                    790: 
                    791:        if (!sr -> sr_affirmative) {
                    792:            (void) SUAbortRequest (sd, NULLCP, 0, si);
                    793: 
                    794:            if (sr -> sr_cc > 0)
                    795:                adios (NULLCP, "release rejected by peer: %*.*s",
                    796:                        sr -> sr_cc, sr -> sr_cc, sr -> sr_data);
                    797:            else
                    798:                adios (NULLCP, "release rejected by peer");
                    799:        }
                    800:        SRFREE (sr);
                    801: }
                    802: 
                    803: /*  */
                    804: 
                    805: static int ss_datarequest (sd, data, cc, dm, sync)
                    806: int    sd;
                    807: char   *data;
                    808: int    cc,
                    809:        dm,
                    810:        sync;
                    811: {
                    812:     int     result;
                    813:     struct SSAPdata sxs;
                    814:     register struct SSAPdata   *sx = &sxs;
                    815:     struct SSAPindication   sis;
                    816:     register struct SSAPindication *si = &sis;
                    817:     register struct SSAPabort  *sa = &si -> si_abort;
                    818: 
                    819:     switch (dm) {
                    820:        default: 
                    821:            if (SDataRequest (sd, data, cc, si) == NOTOK)
                    822:                switch (sa -> sa_reason) {
                    823:                    case SC_OPERATION: 
                    824:                        ss_waitfor (sd, ST_DAT_TOKEN);
                    825:                        if (SDataRequest (sd, data, cc, si) == OK)
                    826:                            break;/* else fall */
                    827: 
                    828:                    default: 
                    829:                        ss_adios (sa, "S-DATA.REQUEST");
                    830:                }
                    831:            break;
                    832: 
                    833:        case SX_EXPEDITED: 
                    834:            if (SExpdRequest (sd, data, cc, si) == NOTOK)
                    835:                ss_adios (sa, "S-EXPEDITED-DATA.REQUEST");
                    836:            break;
                    837: 
                    838:        case SX_CAPDIND: 
                    839:            if (SCapdRequest (sd, data, cc, si) == NOTOK)
                    840:                switch (sa -> sa_reason) {
                    841:                    case SC_OPERATION: 
                    842:                        ss_waitfor (sd, avail & ~ST_RLS_TOKEN);
                    843:                        if (SCapdRequest (sd, data, cc, si) == OK)
                    844:                            break;/* else fall */
                    845: 
                    846:                    default: 
                    847:                        ss_adios (sa, "S-CAPABILITY-DATA.REQUEST");
                    848:                }
                    849:            break;
                    850: 
                    851:        case SX_TYPED: 
                    852:            if (STypedRequest (sd, data, cc, si) == NOTOK)
                    853:                ss_adios (sa, "S-TYPED-DATA.REQUEST");
                    854:            break;
                    855:     }
                    856: 
                    857:     if (mode == echo || dm == SX_CAPDIND)
                    858:        for (;;) {
                    859:            switch (result = SReadRequest (sd, sx, NOTOK, si)) {
                    860:                case NOTOK: 
                    861:                    ss_adios (sa, "S-READ.REQUEST");
                    862: 
                    863:                case OK: 
                    864:                    if ((dm != SX_CAPDIND ? dm : SX_CAPDCNF)
                    865:                            != sx -> sx_type) {
                    866:                        advise (NULLCP,
                    867:                                "data indication type mismatch, orig=%d echo=%d",
                    868:                                dm, sx -> sx_type);
                    869:                        status++;
                    870:                    }
                    871:                    if (cc != sx -> sx_cc) {
                    872:                        advise (NULLCP, "length mismatch, orig=%d echo=%d",
                    873:                                cc, sx -> sx_cc);
                    874:                        status++;
                    875:                    }
                    876:                    else
                    877:                        if (qcmp (data, &sx -> sx_qbuf, cc))
                    878:                            status++;
                    879:                    SXFREE (sx)
                    880:                    break;
                    881: 
                    882:                case DONE: 
                    883:                    ss_event (sd, si);
                    884:                    continue;
                    885: 
                    886:                default: 
                    887:                    adios (NULLCP, "unknown return from SReadRequest=%d",
                    888:                            result);
                    889:            }
                    890:            break;
                    891:        }
                    892: 
                    893:     if (sync &&
                    894:            (requirements & SR_MINORSYNC) && !(requirements & SR_ACTIVITY)) {
                    895:        if (SMinSyncRequest (sd, SYNC_CONFIRM, &ssn, userdata, SN_SIZE, si)
                    896:                == NOTOK)
                    897:            switch (sa -> sa_reason) {
                    898:                case SC_OPERATION: 
                    899:                    ss_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN);
                    900:                    if (SMinSyncRequest (sd, SYNC_CONFIRM, &ssn, userdata,
                    901:                            SN_SIZE, si) == OK)
                    902:                        break;  /* else fall */
                    903: 
                    904:                default: 
                    905:                    ss_adios (sa, "S-MINOR-SYNC.REQUEST");
                    906:            }
                    907: 
                    908:        ss_waitfor (sd, -1);
                    909:     }
                    910:     else
                    911:        if (sync
                    912:                && (requirements & SR_ACTIVITY)
                    913:                && (requirements & SR_MAJORSYNC)
                    914:                && dm == SX_NORMAL) {
                    915:            if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si) == NOTOK)
                    916:                switch (sa -> sa_reason) {
                    917:                    case SC_OPERATION: 
                    918:                        ss_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN
                    919:                                | ST_MAJ_TOKEN);
                    920:                        if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si)
                    921:                                == OK)
                    922:                            break;/* else fall */
                    923: 
                    924:                    default: 
                    925:                        ss_adios (sa, "S-MAJOR-SYNC.REQUEST");
                    926:                }
                    927: 
                    928:            ss_waitfor (sd, -1);
                    929:        }
                    930: }
                    931: 
                    932: /*  */
                    933: 
                    934: static int  ss_waitfor (sd, want)
                    935: int    sd,
                    936:        want;
                    937: {
                    938:     int     result,
                    939:            tokens;
                    940:     char    buffer[BUFSIZ];
                    941:     struct SSAPdata sxs;
                    942:     register struct SSAPdata   *sx = &sxs;
                    943:     struct SSAPindication   sis;
                    944:     register struct SSAPindication *si = &sis;
                    945:     register struct SSAPabort  *sa = &si -> si_abort;
                    946: 
                    947:     for (;;) {
                    948:        if (want == -1) {
                    949:            want = avail;
                    950:            goto read_it;
                    951:        }
                    952: 
                    953:        tokens = 0;
                    954: #define dotoken(requires,shift,bit,type) \
                    955: { \
                    956:        if ((want & bit) && !(owned & bit)) \
                    957:            tokens |= bit; \
                    958: }
                    959:        dotokens ();
                    960: #undef dotoken
                    961:        if (tokens == 0)
                    962:            return;
                    963: 
                    964:        if (SPTokenRequest (sd, tokens, userdata, ST_SIZE, si) == NOTOK)
                    965:            ss_adios (sa, "S-TOKEN-PLEASE.REQUEST");
                    966: 
                    967: read_it: ;
                    968:        switch (result = SReadRequest (sd, sx, NOTOK, si)) {
                    969:            case NOTOK: 
                    970:                ss_adios (sa, "S-READ.REQUEST");
                    971: 
                    972:            case OK: 
                    973:                (void) strcpy (buffer, "protocol screw-up");
                    974:                if (SUAbortRequest (sd, buffer, strlen (buffer) + 1, si) == NOTOK)
                    975:                    ss_adios (sa, "S-U-ABORT.REQUEST");
                    976:                adios (NULLCP, "%s, data indication type=0x%x",
                    977:                        buffer, sx -> sx_type);
                    978: 
                    979:            case DONE: 
                    980:                ss_event (sd, si);
                    981:                break;
                    982: 
                    983:            default: 
                    984:                adios (NULLCP, "unknown return from SReadRequest=%d",
                    985:                        result);
                    986:        }
                    987:     }
                    988: }
                    989: 
                    990: /*  */
                    991: 
                    992: static ss_event (sd, si)
                    993: int    sd;
                    994: register struct SSAPindication *si;
                    995: {
                    996:     register struct SSAPabort  *sa = &si -> si_abort;
                    997:     register struct SSAPactivity *sv = &si -> si_activity;
                    998:     register struct SSAPfinish *sf = &si -> si_finish;
                    999:     register struct SSAPreport *sp = &si -> si_report;
                   1000:     register struct SSAPsync   *sn = &si -> si_sync;
                   1001:     register struct SSAPtoken  *st = &si -> si_token;
                   1002: 
                   1003:     switch (si -> si_type) {
                   1004:        case SI_TOKEN: 
                   1005:            switch (st -> st_type) {
                   1006:                case ST_GIVE: 
                   1007:                case ST_CONTROL: 
                   1008:                    owned = st -> st_owned;
                   1009:                    break;
                   1010: 
                   1011:                case ST_PLEASE: 
                   1012:                    if (SGTokenRequest (sd,
                   1013:                                (int) st -> st_tokens, si)
                   1014:                            == NOTOK)
                   1015:                        ss_adios (sa, "S-TOKEN-GIVE.REQUEST");
                   1016:                    else
                   1017:                        owned &= ~st -> st_tokens;
                   1018:                    break;
                   1019: 
                   1020:                default: 
                   1021:                    adios (NULLCP,
                   1022:                            "unknown token indication type=0x%x, %d bytes",
                   1023:                            st -> st_type, st -> st_cc);
                   1024:            }
                   1025:            STFREE (st);
                   1026:            break;
                   1027: 
                   1028:        case SI_SYNC: 
                   1029:            switch (sn -> sn_type) {
                   1030:                case SN_MAJORIND: 
                   1031:                    adios (NULLCP, "majorsync indication %d, %d bytes",
                   1032:                            sn -> sn_ssn, sn -> sn_cc);
                   1033:                    break;
                   1034: 
                   1035:                case SN_MAJORCNF: 
                   1036:                    break;
                   1037: 
                   1038:                case SN_MINORIND: 
                   1039:                    adios (NULLCP, "minorsync indication %d%s, %d bytes",
                   1040:                            sn -> sn_ssn, sn -> sn_options == SYNC_CONFIRM
                   1041:                            ? " (wants confirmation)" : NULLCP, sn -> sn_cc);
                   1042:                    break;
                   1043: 
                   1044:                case SN_MINORCNF: 
                   1045:                    break;
                   1046: 
                   1047:                case SN_RESETIND: 
                   1048: #define        dotoken(requires,shift,bit,type) \
                   1049: { \
                   1050:                    if (requirements & requires) \
                   1051:                        switch (sn -> sn_settings & (ST_MASK << shift)) { \
                   1052:                            case ST_CALL_VALUE << shift: \
                   1053:                                sn -> sn_settings &= ~(ST_MASK << shift); \
                   1054:                                sn -> sn_settings |= ST_RESP_VALUE << shift; \
                   1055:                            case ST_RESP_VALUE << shift: \
                   1056:                                owned &= ~bit; \
                   1057:                                break; \
                   1058:  \
                   1059:                            case ST_INIT_VALUE << shift: \
                   1060:                                owned |= bit; \
                   1061:                                break; \
                   1062:  \
                   1063:                            default: \
                   1064:                                adios (NULLCP, "%s token: reserved", type); \
                   1065:                                break; \
                   1066:                        } \
                   1067: }
                   1068:                    dotokens ();
                   1069: #undef dotoken
                   1070:                    if (SReSyncResponse (sd, sn -> sn_ssn, sn -> sn_settings,
                   1071:                                userdata, SN_SIZE, si) == NOTOK)
                   1072:                        ss_adios (sa, "S-RESYNCHRONIZE.RESPONSE");
                   1073:                    break;
                   1074: 
                   1075:                case SN_RESETCNF: 
                   1076:                    break;
                   1077: 
                   1078:                default: 
                   1079:                    adios (NULLCP,
                   1080:                            "unknown sync indication=0x%x, ssn=%d, %d bytes",
                   1081:                            sn -> sn_type, sn -> sn_ssn, sn -> sn_cc);
                   1082:            }
                   1083:            SNFREE (sn);
                   1084:            break;
                   1085: 
                   1086:        case SI_ACTIVITY: 
                   1087:            switch (sv -> sv_type) {
                   1088:                case SV_START: 
                   1089:                    adios (NULLCP,
                   1090:                            "activity start indication: %*.*s, %d bytes",
                   1091:                            sv -> sv_id.sd_len, sv -> sv_id.sd_len,
                   1092:                            sv -> sv_id.sd_data, sv -> sv_cc);
                   1093: 
                   1094:                case SV_RESUME: 
                   1095:                    adios (NULLCP, 
                   1096:                            "activity resume indication: id=%*.*s oid=%*.*s connect=%s ssn=%d, %d bytes",
                   1097:                            sv -> sv_id.sd_len, sv -> sv_id.sd_len,
                   1098:                            sv -> sv_id.sd_data, sv -> sv_oid.sd_len,
                   1099:                            sv -> sv_oid.sd_len, sv -> sv_oid.sd_data,
                   1100:                            sprintref (&sv -> sv_connect), sv -> sv_ssn,
                   1101:                            sv -> sv_cc);
                   1102: 
                   1103:                case SV_INTRIND: 
                   1104:                    adios (NULLCP,
                   1105:                            "activity interrupt indication %d, %d bytes",
                   1106:                            sv -> sv_reason, sv -> sv_cc);
                   1107: 
                   1108:                case SV_INTRCNF: 
                   1109:                    break;
                   1110: 
                   1111:                case SV_DISCIND: 
                   1112:                    adios (NULLCP,
                   1113:                            "activity discard indication %d, %d bytes",
                   1114:                            sv -> sv_reason, sv -> sv_cc);
                   1115: 
                   1116:                case SV_DISCCNF: 
                   1117:                    break;
                   1118: 
                   1119:                case SV_ENDIND: 
                   1120:                    adios (NULLCP, "activity end indication %d, %d bytes",
                   1121:                            sv -> sv_ssn, sv -> sv_cc);
                   1122: 
                   1123:                case SV_ENDCNF: 
                   1124:                    break;
                   1125: 
                   1126:                default: 
                   1127:                    adios (NULLCP,
                   1128:                            "unknown activity indication=0x%x, %d bytes",
                   1129:                            sv -> sv_type, sv -> sv_cc);
                   1130:            }
                   1131:            SVFREE (sv);
                   1132:            break;
                   1133: 
                   1134:        case SI_REPORT: 
                   1135:            if (requirements & SR_DAT_EXISTS) {
                   1136:                if (SGTokenRequest (sd, ST_DAT_TOKEN, si) == NOTOK)
                   1137:                    ss_adios (sa, "S-TOKEN-GIVE.REQUEST (to clear exception)");
                   1138:                else
                   1139:                    owned &= ~ST_DAT_TOKEN;
                   1140:            }
                   1141:            else
                   1142:                if (SUAbortRequest (sd, NULLCP, 0, si) == NOTOK)
                   1143:                    ss_adios (sa, "S-U-ABORT.REQUEST");
                   1144:                else
                   1145:                    adios (NULLCP, "aborted");
                   1146:            SPFREE (sp);
                   1147:            break;
                   1148: 
                   1149:        case SI_FINISH: 
                   1150:            if (SRelResponse (sd, SC_REJECTED, NULLCP, 0, si) == NOTOK)
                   1151:                ss_adios (sa, "S-RELEASE.RESPONSE");
                   1152:            SFFREE (sf);
                   1153:            break;
                   1154: 
                   1155:        default: 
                   1156:            adios (NULLCP, "unknown indication type=0x%x",
                   1157:                    si -> si_type);
                   1158:     }
                   1159: }
                   1160: 
                   1161: /*  */
                   1162: 
                   1163: static void  ss_adios (sa, event)
                   1164: register struct SSAPabort *sa;
                   1165: char   *event;
                   1166: {
                   1167:     ss_advise (sa, event);
                   1168: 
                   1169:     _exit (1);
                   1170: }
                   1171: 
                   1172: 
                   1173: static void  ss_advise (sa, event)
                   1174: register struct SSAPabort *sa;
                   1175: char   *event;
                   1176: {
                   1177:     char    buffer[BUFSIZ];
                   1178: 
                   1179:     if (sa -> sa_cc > 0)
                   1180:        (void) sprintf (buffer, "[%s] %*.*s",
                   1181:                SErrString (sa -> sa_reason),
                   1182:                sa -> sa_cc, sa -> sa_cc, sa -> sa_data);
                   1183:     else
                   1184:        (void) sprintf (buffer, "[%s]", SErrString (sa -> sa_reason));
                   1185: 
                   1186:     advise (NULLCP, "%s: %s%s", event, buffer,
                   1187:            sa -> sa_peer ? " (peer initiated)" : "");
                   1188: 
                   1189:     SAFREE (sa);
                   1190: }
                   1191: 
                   1192: /*    PSAP */
                   1193: 
                   1194: static int prequirements = 0;
                   1195: #define        srequirements requirements
                   1196: 
                   1197: static int nctxs;
                   1198: static int datactxs[NPCTX];
                   1199: 
                   1200: /*  */
                   1201: 
                   1202: static int  ps_main (is, addr)
                   1203: struct isoservent *is;
                   1204: char   *addr;
                   1205: {
                   1206:     int     sd,
                   1207:            cc,
                   1208:            i,
                   1209:            j,
                   1210:            k,
                   1211:            l,
                   1212:            m,
                   1213:            tokens;
                   1214:     char   *cp,
                   1215:           *dp,
                   1216:            buffer[BUFSIZ];
                   1217:     register struct PSAPaddr   *pz;
                   1218:     struct SSAPactid    ids;
                   1219:     register struct SSAPactid  *id = &ids;
                   1220:     struct SSAPref  sfs;
                   1221:     register struct SSAPref *sf;
                   1222:     struct PSAPconnect  pcs;
                   1223:     register struct PSAPconnect *pc = &pcs;
                   1224:     struct PSAPctxlist pls;
                   1225:     register struct PSAPctxlist *pl = &pls;
                   1226:     struct PSAPrelease  prs;
                   1227:     register struct PSAPrelease *pr = &prs;
                   1228:     struct PSAPindication   pis;
                   1229:     register struct PSAPindication *pi = &pis;
                   1230:     register struct PSAPabort  *pa = &pi -> pi_abort;
                   1231:     struct AcSAPconnect  accs;
                   1232:     register struct AcSAPconnect *acc = &accs;
                   1233:     struct AcSAPrelease acrs;
                   1234:     register struct AcSAPrelease *acr = &acrs;
                   1235:     struct AcSAPindication   acis;
                   1236:     register struct AcSAPindication *aci = &acis;
                   1237:     register struct AcSAPabort  *aca = &aci -> aci_abort;
                   1238:     register PE            pe;
                   1239:     PE     udata[NPDATA];
                   1240:     AEI            aei;
                   1241:     OID            oid,
                   1242:            ode;
                   1243:     struct stat st;
                   1244: 
                   1245:     if (isacs) {
                   1246:        if ((aei = str2aei (addr, isacs)) == NULLAEI)
                   1247:            adios (NULLCP, "%s-%s: unknown application-entity", addr, isacs);
                   1248:        if ((pz = aei2addr (aei)) == NULLPA)
                   1249:            adios (NULLCP, "address translation failed");
                   1250: 
                   1251:        cp = mode == echo ? "isode echo pci" : "isode sink pci";
                   1252:        if ((ode = ode2oid (cp)) == NULLOID)
                   1253:            adios (NULLCP, "%s: unknown object descriptor", cp);
                   1254:        ode = oid_cpy (ode);
                   1255:     }
                   1256:     else
                   1257:        if ((pz = is2paddr (addr, NULLCP, is)) == NULL)
                   1258:            adios (NULLCP, "address translation failed");
                   1259:     if ((sf = addr2ref (PLocalHostName ())) == NULL) {
                   1260:        sf = &sfs;
                   1261:        (void) bzero ((char *) sf, sizeof *sf);
                   1262:     }
                   1263: 
                   1264:     tokens = 0;
                   1265: #define dotoken(requires,shift,bit,type) \
                   1266: { \
                   1267:     if (srequirements & requires) \
                   1268:        tokens |= ST_CALL_VALUE << shift; \
                   1269: }
                   1270:     dotokens ();
                   1271: #undef dotoken
                   1272: 
                   1273:     for (i = (pl -> pc_nctx = NPCTX - (isacs ? 1 : 0)) - 1; i >= 0; i--) {
                   1274:        pl -> pc_ctx[i].pc_id = i * 2 + 1;
                   1275:        if ((oid = ode2oid ("iso asn.1 abstract syntax")) == NULLOID)
                   1276:            adios (NULLCP, "iso asn.1 abstract syntax: unknown");
                   1277:        pl -> pc_ctx[i].pc_asn = oid_cpy (oid);
                   1278:        pl -> pc_ctx[i].pc_atn = NULLOID;
                   1279:     }
                   1280: 
                   1281:     for (i = 0; i < NPDATA; i++) {
                   1282:        if ((pe = int2prim (i)) == NULLPE)
                   1283:            adios (NULLCP, "unable to allocate hello");
                   1284:        pe -> pe_context = (i % pl -> pc_nctx) * 2 + 1;
                   1285:        udata[i] = pe;
                   1286:     }
                   1287: 
                   1288:     fprintf (stderr, "%s... ", addr);
                   1289:     (void) fflush (stderr);
                   1290:     if (isacs) {
                   1291: #ifndef        ASYNC
                   1292:        if (AcAssocRequest (ode, NULLAEI, aei, NULLPA, pz, pl, ode,
                   1293:                prequirements, srequirements, ISN (srequirements), tokens, sf,
                   1294:                udata, NACDATA, NULLQOS, acc, aci)
                   1295:                == NOTOK) {
                   1296:            fprintf (stderr, "failed\n");
                   1297:            acs_adios (aca, "A-ASSOCIATE.REQUEST");
                   1298:        }
                   1299:        sd = acc -> acc_sd;
                   1300: #else
                   1301:        if ((i = AcAsynAssocRequest (ode, NULLAEI, aei, NULLPA, pz, pl, ode,
                   1302:                prequirements, srequirements, ISN (srequirements), tokens, sf,
                   1303:                udata, NACDATA, NULLQOS, acc, aci, 1)) == NOTOK) {
                   1304:            fprintf (stderr, "failed\n");
                   1305:            acs_adios (aca, "A-(ASYN-)ASSOCIATE.REQUEST");
                   1306:        }
                   1307:        sd = acc -> acc_sd, cc = 0;
                   1308:        while (i == CONNECTING_1 || i == CONNECTING_2) {
                   1309:            int     nfds;
                   1310:            fd_set  mask,
                   1311:                   *rmask,
                   1312:                   *wmask;
                   1313: 
                   1314:            nfds = 0;
                   1315:            FD_ZERO (&mask);
                   1316:            if (PSelectMask (sd, &mask, &nfds, pi) == NOTOK) {
                   1317:                fprintf (stderr, "failed\n");
                   1318:                acs_adios (aca, "A-(ASYN-)ASSOCIATE.REQUEST(PSelectMask)");
                   1319:            }
                   1320:            rmask = (i == CONNECTING_2) ? &mask : NULLFD;
                   1321:            wmask = (i == CONNECTING_2) ? NULLFD : &mask;
                   1322: 
                   1323:            fprintf (stderr, ".");
                   1324:            if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) {
                   1325:                fprintf (stderr, "failed\n");
                   1326:                adios ("failed", "select");
                   1327:            }
                   1328: 
                   1329:            if ((rmask && FD_ISSET (sd, rmask) == 0)
                   1330:                    || (wmask && FD_ISSET (sd, wmask) == 0))
                   1331:                continue;
                   1332:            
                   1333:            if ((i = AcAsynRetryRequest (sd, acc, aci)) == NOTOK) {
                   1334:                fprintf (stderr, "failed\n");
                   1335:                acs_adios (aca, "A-ASYN-RETRY.REQUEST");
                   1336:            }
                   1337:        }
                   1338: #endif
                   1339: 
                   1340:        if (acc -> acc_result != ACS_ACCEPT) {
                   1341:            fprintf (stderr, "failed\n");
                   1342:            adios (NULLCP, "connection rejected: [%s], %d elements",
                   1343:                    AcErrString (acc -> acc_result), acc -> acc_ninfo);
                   1344:        }
                   1345:     }
                   1346:     else {
                   1347: #ifndef        ASYNC
                   1348:        if (PConnRequest (NULLPA, pz, pl, NULLOID, prequirements,
                   1349:                srequirements, srequirements
                   1350:                    & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY)
                   1351:                ? (long) (getpid () % (SERIAL_MAX - SERIAL_MIN + 1)) + SERIAL_MIN
                   1352:                : SERIAL_NONE, tokens, sf, udata, NPDATA, NULLQOS, pc, pi) == NOTOK) {
                   1353:            fprintf (stderr, "failed\n");
                   1354:            ps_adios (pa, "P-CONNECT.REQUEST");
                   1355:        }
                   1356:        sd = pc -> pc_sd;
                   1357: #else
                   1358:        if ((i = PAsynConnRequest (NULLPA, pz, pl, NULLOID, prequirements,
                   1359:                srequirements, ISN (srequirements), tokens, sf, udata, NPDATA,
                   1360:                NULLQOS, pc, pi, 1)) == NOTOK) {
                   1361:            fprintf (stderr, "failed\n");
                   1362:            ps_adios (pa, "P-CONNECT.REQUEST");
                   1363:        }
                   1364:        sd = pc -> pc_sd, cc = 0;
                   1365:        while (i == CONNECTING_1 || i == CONNECTING_2) {
                   1366:            int     nfds;
                   1367:            fd_set  mask,
                   1368:                   *rmask,
                   1369:                   *wmask;
                   1370: 
                   1371:            nfds = 0;
                   1372:            FD_ZERO (&mask);
                   1373:            if (PSelectMask (sd, &mask, &nfds, pi) == NOTOK) {
                   1374:                fprintf (stderr, "failed\n");
                   1375:                ps_adios (pa, "P-CONNECT.REQUEST(PSelectMask)");
                   1376:            }
                   1377:            rmask = (i == CONNECTING_2) ? &mask : NULLFD;
                   1378:            wmask = (i == CONNECTING_2) ? NULLFD : &mask;
                   1379: 
                   1380:            fprintf (stderr, ".");
                   1381:            if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) {
                   1382:                fprintf (stderr, "failed\n");
                   1383:                adios ("failed", "select");
                   1384:            }
                   1385: 
                   1386:            if ((rmask && FD_ISSET (sd, rmask) == 0)
                   1387:                    || (wmask && FD_ISSET (sd, wmask) == 0))
                   1388:                continue;
                   1389: 
                   1390:            if ((i = PAsynRetryRequest (sd, pc, pi)) == NOTOK) {
                   1391:                fprintf (stderr, "failed\n");
                   1392:                ps_adios (pa, "P-ASYN-RETRY.REQUEST");
                   1393:            }
                   1394:        }
                   1395: #endif
                   1396: 
                   1397:        if (pc -> pc_result != PC_ACCEPT) {
                   1398:            fprintf (stderr, "failed\n");
                   1399:            adios (NULLCP, "connection rejected: [%s], %d elements",
                   1400:                    PErrString (pc -> pc_result), pc -> pc_ninfo);
                   1401:        }
                   1402:     }
                   1403:     fprintf (stderr, "connected\n");
                   1404: 
                   1405:     if (isacs) {
                   1406:        pc = &acc -> acc_connect;
                   1407: 
                   1408: #ifdef DEBUG
                   1409:        {
                   1410:            advise (NULLCP, "context: %s", oid2ode (acc -> acc_context));
                   1411: 
                   1412:            advise (NULLCP,
                   1413:                    "responding AE title: %s, responding PSAP address: %s",
                   1414:                    sprintaei (&acc -> acc_respondtitle),
                   1415:                    paddr2str (&pc -> pc_responding, NULLNA));
                   1416: 
                   1417:            advise (NULLCP, "greetings: %d elements", acc -> acc_ninfo);
                   1418: 
                   1419:            pl = &pc -> pc_ctxlist;
                   1420:            for (i = 0; i < pl -> pc_nctx; i++)
                   1421:                advise (NULLCP, "ctx %d: 0x%x 0x%x %d",
                   1422:                        pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
                   1423:                        pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
                   1424:            advise (NULLCP, "default %d", pc -> pc_defctxresult);
                   1425:            advise (NULLCP, "p/s requirements 0x%x/0x%x",
                   1426:                    pc -> pc_prequirements, pc -> pc_srequirements);
                   1427:        }
                   1428: #endif
                   1429: 
                   1430:        pl = &pc -> pc_ctxlist;
                   1431: 
                   1432:        if (mode == echo) {
                   1433:            if (acc -> acc_ninfo != NACDATA)
                   1434:                adios (NULLCP, "expecting %d hellos, got %d elements",
                   1435:                        NACDATA, acc -> acc_ninfo);
                   1436:            for (i = 0; i < NACDATA; i++) {
                   1437:                if ((pe = acc -> acc_info[i]) == NULLPE)
                   1438:                    adios (NULLCP, "hello %d: NULL", i);
                   1439:                if ((j = prim2num (pe)) == NOTOK
                   1440:                        && pe -> pe_errno != PE_ERR_NONE)
                   1441:                    adios (NULLCP, "hello %d: %s", i,
                   1442:                            pe_error (pe -> pe_errno));
                   1443:                if (j != i)
                   1444:                    adios (NULLCP, "hello %d: value %d", i, j);
                   1445:                if (pe -> pe_context != udata[i] -> pe_context)
                   1446:                    adios (NULLCP, "hello %d: context of %d instead of %d",
                   1447:                        i, pe -> pe_context, udata[i] -> pe_context);
                   1448:            }
                   1449:        }
                   1450: 
                   1451:        goto do_release;
                   1452:     }
                   1453:     else {
                   1454: #ifdef DEBUG
                   1455:        {
                   1456:            advise (NULLCP, "responding PSAP address: %s",
                   1457:                    paddr2str (&pc -> pc_responding, NULLNA));
                   1458: 
                   1459:            advise (NULLCP, "greetings: %d elements", pc -> pc_ninfo);
                   1460: 
                   1461:            pl = &pc -> pc_ctxlist;
                   1462:            for (i = 0; i < pl -> pc_nctx; i++)
                   1463:                advise (NULLCP, "ctx %d: 0x%x 0x%x %d",
                   1464:                        pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
                   1465:                        pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
                   1466:            advise (NULLCP, "default %d", pc -> pc_defctxresult);
                   1467:            advise (NULLCP, "p/s requirements 0x%x/0x%x",
                   1468:                    pc -> pc_prequirements, pc -> pc_srequirements);
                   1469:        }
                   1470: #endif
                   1471: 
                   1472:        if (mode == echo) {
                   1473:            if (pc -> pc_ninfo != NPDATA)
                   1474:                adios (NULLCP, "expecting %d hellos, got %d elements",
                   1475:                        NPDATA, pc -> pc_ninfo);
                   1476:            for (i = 0; i < NPDATA; i++) {
                   1477:                if ((pe = pc -> pc_info[i]) == NULLPE)
                   1478:                    adios (NULLCP, "hello %d: NULL", i);
                   1479:                if ((j = prim2num (pe)) == NOTOK
                   1480:                        && pe -> pe_errno != PE_ERR_NONE)
                   1481:                    adios (NULLCP, "hello %d: %s", i,
                   1482:                            pe_error (pe -> pe_errno));
                   1483:                if (j != i)
                   1484:                    adios (NULLCP, "hello %d: value %d", i, j);
                   1485:                if (pe -> pe_context != udata[i] -> pe_context)
                   1486:                    adios (NULLCP, "hello %d: context of %d instead of %d",
                   1487:                        i, pe -> pe_context, udata[i] -> pe_context);
                   1488:            }
                   1489:        }
                   1490:     }
                   1491: 
                   1492:     nctxs = 0;
                   1493:     pl = &pc -> pc_ctxlist;
                   1494:     for (i = 0; i < pl -> pc_nctx; i++)
                   1495:        if (pl -> pc_ctx[i].pc_result == PC_ACCEPT)
                   1496:                datactxs[nctxs++] = pl -> pc_ctx[i].pc_id;
                   1497: 
                   1498:     srequirements = pc -> pc_srequirements;
                   1499:     nmodes = 0;
                   1500:     datamodes[nmodes++] = SX_NORMAL;
                   1501:     if (srequirements & SR_EXPEDITED)
                   1502:        datamodes[nmodes++] = SX_EXPEDITED;
                   1503:     if ((srequirements & SR_CAPABILITY) && (srequirements & SR_ACTIVITY))
                   1504:        datamodes[nmodes++] = SX_CAPDIND;
                   1505:     if (srequirements & SR_TYPEDATA)
                   1506:        datamodes[nmodes++] = SX_TYPED;
                   1507: 
                   1508: #define dotoken(requires,shift,bit,type) \
                   1509: { \
                   1510:     if (srequirements & requires) \
                   1511:        switch (pc -> pc_settings & (ST_MASK << shift)) { \
                   1512:            case ST_CALL_VALUE: \
                   1513:                adios (NULLCP, "%s token: choice", type); \
                   1514:  \
                   1515:            case ST_INIT_VALUE: \
                   1516:                owned |= bit, avail |= bit; \
                   1517:                break; \
                   1518:  \
                   1519:            case ST_RESP_VALUE: \
                   1520:                avail |= bit; \
                   1521:                break; \
                   1522:  \
                   1523:            default: \
                   1524:                adios (NULLCP, "%s token: reserved", type); \
                   1525:        } \
                   1526: }
                   1527:        dotokens ();
                   1528: #undef dotoken
                   1529: 
                   1530:     if (isacs)
                   1531:        ACCFREE (acc)
                   1532:     else
                   1533:        PCFREE (pc);
                   1534: 
                   1535:     if (srequirements & SR_ACTIVITY) {
                   1536:        (void) strcpy (id -> sd_data, mode == echo ? "echo" : "sink");
                   1537:        id -> sd_len = strlen (id -> sd_data);
                   1538:        if (PActStartRequest (sd, id, udata, NPDATA, pi) == NOTOK)
                   1539:            ps_adios (pa, "P-ACTIVITY-START.REQUEST");
                   1540:     }
                   1541: 
                   1542:     if (fstat (fileno (stdin), &st) != NOTOK
                   1543:            && (st.st_mode & S_IFMT) == S_IFREG
                   1544:            && (cc = st.st_size) != 0) {
                   1545:        (void) lseek (fileno (stdin), 0L, 0);
                   1546: 
                   1547:        if ((cp = malloc ((unsigned) cc)) == NULL)
                   1548:            adios (NULLCP, "no memory");
                   1549:        for (dp = cp, j = cc; j > 0; dp += i, j -= i)
                   1550:            switch (i = read (fileno (stdin), dp, j)) {
                   1551:                case NOTOK:
                   1552:                    adios ("on stdin", "read failed");
                   1553: 
                   1554:                case OK:
                   1555:                    adios (NULLCP, "premature end-of-file");
                   1556:                    
                   1557:                default:
                   1558:                    break;
                   1559:            }
                   1560:        if ((pe = oct2prim (cp, cc)) == NULLPE)
                   1561:            adios (NULLCP, "unable to allocate PSDU");
                   1562:        free (cp);
                   1563:        if (nctxs)
                   1564:            pe -> pe_context = datactxs[0];
                   1565:        for (i = 10; i > 0; i--) {
                   1566: #ifdef TIMER
                   1567:            timer (0);
                   1568: #endif
                   1569:            ps_datarequest (sd, pe, SX_NORMAL, 0);
                   1570: #ifdef TIMER
                   1571:            timer (cc);
                   1572: #endif
                   1573:        }
                   1574:        pe_free (pe);
                   1575:     }
                   1576:     else {
                   1577:        for (j = l = m = 0; fgets (buffer, sizeof buffer, stdin); ) {
                   1578:            k = j >= nmodes ? SX_EXPEDITED : datamodes[j++ % nmodes];
                   1579:            if ((cc = strlen (buffer) + 1) > SX_EXSIZE - 7
                   1580:                    && k == SX_EXPEDITED) {
                   1581:                if ((k = datamodes[j++ % nmodes]) == SX_EXPEDITED)
                   1582:                    k = datamodes[j++ % nmodes];
                   1583:            }
                   1584: 
                   1585:            switch (k) {
                   1586:                case SX_CAPDIND:
                   1587:                    if (!(requirements & SR_RESYNC) || l++ & 0x01) {
                   1588:                        ps_waitfor (sd, ST_ACT_TOKEN);
                   1589:                        if (l & 0x03) {
                   1590:                            if (PActIntrRequest (sd, SP_SEQUENCE, pi)
                   1591:                                    == NOTOK)
                   1592:                                ps_adios (pa, "P-ACTIVITY-INTERRUPT.REQUEST");
                   1593:                        }
                   1594:                        else {
                   1595:                            if (PActDiscRequest (sd, SP_SEQUENCE, pi)
                   1596:                                    == NOTOK)
                   1597:                                ps_adios (pa, "P-ACTIVITY-DISCARD.REQUEST");
                   1598:                        }
                   1599:                        ps_waitfor (sd, -1);
                   1600:                        goto push_data;
                   1601:                    }
                   1602:                    tokens = 0;
                   1603: #define dotoken(requires,shift,bit,type) \
                   1604: { \
                   1605:                    if (requirements & requires) \
                   1606:                        tokens |= ST_CALL_VALUE << shift; \
                   1607: }
                   1608:                    dotokens ();
                   1609: #undef dotoken
                   1610:                    if (PReSyncRequest (sd, SYNC_SET, ssn - 1, tokens,
                   1611:                                udata, NPDATA, pi) == NOTOK)
                   1612:                        ps_adios (pa, "P-RESYNCHRONIZE.REQUEST");
                   1613:                    ps_waitfor (sd, -1);
                   1614:                    break;
                   1615: 
                   1616:                case SX_EXPEDITED:
                   1617:                    if (j >= nmodes)
                   1618:                        j = j % nmodes;
                   1619:                    if (!(srequirements & SR_EXPEDITED))
                   1620:                        k = SX_NORMAL;  /* fall... */
                   1621:                default:
                   1622: push_data: ;
                   1623:                    if ((pe = oct2prim (buffer, cc)) == NULLPE)
                   1624:                        adios (NULLCP, "unable to allocate PSDU");
                   1625:                    if (nctxs && k != SX_EXPEDITED)
                   1626:                        pe -> pe_context = datactxs[m++ % nctxs];
                   1627:                    ps_datarequest (sd, pe, k, 1);
                   1628:                    pe_free (pe);
                   1629:                    if (k == SX_CAPDIND
                   1630:                            && PActResumeRequest (sd, id, id, 
                   1631:                                    (long) (getpid () % (SERIAL_MAX - SERIAL_MIN + 1))
                   1632:                                    + SERIAL_MIN, sf, udata, NPDATA, pi)
                   1633:                                    == NOTOK)
                   1634:                        ps_adios (pa, "P-ACTIVITY-RESUME.REQUEST");
                   1635:                    break;
                   1636:            }
                   1637:        }
                   1638: 
                   1639:        if (requirements & SR_EXCEPTIONS) {
                   1640:            if (owned & ST_DAT_TOKEN)
                   1641:                if (PGTokenRequest (sd, ST_DAT_TOKEN, pi) == NOTOK)
                   1642:                    ps_adios (pa, "P-TOKEN-GIVE.REQUEST");
                   1643:                else
                   1644:                    owned &= ~ST_DAT_TOKEN;
                   1645:            if (PUReportRequest (sd, SP_NOREASON, udata, NPDATA, pi) == NOTOK)
                   1646:                ps_adios (pa, "P-U-EXCEPTION-REPORT.REQUEST");
                   1647:            ps_waitfor (sd, -1);
                   1648:        }    
                   1649:     }
                   1650: 
                   1651:     if ((requirements & SR_MAJORSYNC) && !(requirements & SR_ACTIVITY)) {
                   1652:        if (PMajSyncRequest (sd, &ssn, udata, NPDATA, pi) == NOTOK)
                   1653:            switch (pa -> pa_reason) {
                   1654:                case PC_OPERATION:
                   1655:                    ps_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN
                   1656:                            | ST_MAJ_TOKEN);
                   1657:                    if (PMajSyncRequest (sd, &ssn, udata, NPDATA, pi) == OK)
                   1658:                        break;  /* else fall */
                   1659: 
                   1660:                default:
                   1661:                    ps_adios (pa, "P-MAJOR-SYNC.REQUEST");
                   1662:            }
                   1663: 
                   1664:        ps_waitfor (sd, -1);
                   1665:     }
                   1666: 
                   1667:     if (requirements & SR_ACTIVITY) {
                   1668:        if (PActEndRequest (sd, &ssn, udata, NPDATA, pi) == NOTOK)
                   1669:            switch (pa -> pa_reason) {
                   1670:                case PC_OPERATION:
                   1671:                    ps_waitfor (sd, avail);
                   1672:                    if (PActEndRequest (sd, &ssn, udata, NPDATA, pi) == OK)
                   1673:                        break;  /* else fall */
                   1674: 
                   1675:                default:
                   1676:                    ps_adios (pa, "P-ACTIVITY-END.REQUEST");
                   1677:            }
                   1678: 
                   1679:        ps_waitfor (sd, -1);
                   1680:                
                   1681:        if (PGControlRequest (sd, pi) == NOTOK)
                   1682:            switch (pa -> pa_reason) {
                   1683:                case PC_OPERATION:
                   1684:                    ps_waitfor (sd, avail);
                   1685:                    if (PGControlRequest (sd, pi) == OK)
                   1686:                        break;  /* else fall */
                   1687: 
                   1688:                default:
                   1689:                    ps_adios (pa, "P-CONTROL-GIVE.REQUEST");
                   1690:            }
                   1691: 
                   1692:        owned = 0;
                   1693: 
                   1694:        ps_waitfor (sd, -1);
                   1695:     }
                   1696: 
                   1697: do_release: ;
                   1698:     if (isacs) {
                   1699:        if (AcRelRequest (sd, ACF_NORMAL, udata, NACDATA, NOTOK, acr, aci)
                   1700:                == NOTOK)
                   1701:            switch (aca -> aca_reason) {
                   1702:                case ACS_OPERATION:
                   1703:                    ps_waitfor (sd, avail);
                   1704:                    if (AcRelRequest (sd, ACF_NORMAL, udata, NACDATA, NOTOK,
                   1705:                                      acr, aci) == OK)
                   1706:                        break;  /* else fall */
                   1707: 
                   1708:                default:
                   1709:                    acs_adios (aca, "A-RELEASE.REQUEST");
                   1710:        }
                   1711: 
                   1712:        if (!acr -> acr_affirmative) {
                   1713:            (void) AcUAbortRequest (sd, NULLPEP, 0, aci);
                   1714:            adios (NULLCP, "release rejected by peer: %d, %d elements",
                   1715:                        acr -> acr_reason, acr -> acr_ninfo);
                   1716:        }
                   1717: 
                   1718: #ifdef DEBUG
                   1719:        advise (NULLCP, "A-RELEASE.CONFIRMATION: %d, %d elements",
                   1720:                acr -> acr_reason, acr -> acr_ninfo);
                   1721: #endif         
                   1722:        ACRFREE (acr);
                   1723:     }
                   1724:     else {
                   1725:        if (PRelRequest (sd, udata, NPDATA, NOTOK, pr, pi) == NOTOK)
                   1726:            switch (pa -> pa_reason) {
                   1727:                case PC_OPERATION: 
                   1728:                case PC_WAITING: 
                   1729:                    ps_waitfor (sd, avail);
                   1730:                    if (PRelRequest (sd, udata, NPDATA, NOTOK, pr, pi) == OK)
                   1731:                        break;  /* else fall */
                   1732: 
                   1733:                default: 
                   1734:                    ps_adios (pa, "P-RELEASE.REQUEST");
                   1735:            }
                   1736: 
                   1737:        if (!pr -> pr_affirmative) {
                   1738:            (void) PUAbortRequest (sd, NULLPEP, 0, pi);
                   1739:            adios (NULLCP, "release rejected by peer: %d elements",
                   1740:                    pr -> pr_ninfo);
                   1741:        }
                   1742:        PRFREE (pr);
                   1743:     }
                   1744: 
                   1745:     for (i = 0; i < NPDATA; i++)
                   1746:        pe_free (udata[i]);
                   1747: }
                   1748: 
                   1749: /*  */
                   1750: 
                   1751: static int ps_datarequest (sd, pe, dm, sync)
                   1752: int    sd;
                   1753: PE     pe;
                   1754: int    dm,
                   1755:        sync;
                   1756: {
                   1757:     int     result;
                   1758:     struct PSAPdata pxs;
                   1759:     register struct PSAPdata   *px = &pxs;
                   1760:     struct PSAPindication   pis;
                   1761:     register struct PSAPindication *pi = &pis;
                   1762:     register struct PSAPabort  *pa = &pi -> pi_abort;
                   1763: 
                   1764:     switch (dm) {
                   1765:        default: 
                   1766:            if (PDataRequest (sd, &pe, 1, pi) == NOTOK)
                   1767:                switch (pa -> pa_reason) {
                   1768:                    case PC_OPERATION: 
                   1769:                        ps_waitfor (sd, ST_DAT_TOKEN);
                   1770:                        if (PDataRequest (sd, &pe, 1, pi) == OK)
                   1771:                            break;/* else fall */
                   1772: 
                   1773:                    default: 
                   1774:                        ps_adios (pa, "P-DATA.REQUEST");
                   1775:                }
                   1776:            break;
                   1777: 
                   1778:        case SX_EXPEDITED: 
                   1779:            if (PExpdRequest (sd, &pe, 1, pi) == NOTOK)
                   1780:                ps_adios (pa, "P-EXPEDITED-DATA.REQUEST");
                   1781:            break;
                   1782: 
                   1783:        case SX_CAPDIND: 
                   1784:            if (PCapdRequest (sd, &pe, 1, pi) == NOTOK)
                   1785:                switch (pa -> pa_reason) {
                   1786:                    case PC_OPERATION: 
                   1787:                        ps_waitfor (sd, avail & ~ST_RLS_TOKEN);
                   1788:                        if (PCapdRequest (sd, &pe, 1, pi) == OK)
                   1789:                            break;/* else fall */
                   1790: 
                   1791:                    default: 
                   1792:                        ps_adios (pa, "P-CAPABILITY-DATA.REQUEST");
                   1793:                }
                   1794:            break;
                   1795: 
                   1796:        case SX_TYPED: 
                   1797:            if (PTypedRequest (sd, &pe, 1, pi) == NOTOK)
                   1798:                ps_adios (pa, "P-TYPED-DATA.REQUEST");
                   1799:            break;
                   1800:     }
                   1801: 
                   1802:     if (mode == echo || dm == SX_CAPDIND)
                   1803:        for (;;) {
                   1804:            switch (result = PReadRequest (sd, px, NOTOK, pi)) {
                   1805:                case NOTOK: 
                   1806:                    ps_adios (pa, "P-READ.REQUEST");
                   1807: 
                   1808:                case OK: 
                   1809:                    if ((dm != SX_CAPDIND ? dm : SX_CAPDCNF)
                   1810:                            != px -> px_type) {
                   1811:                        advise (NULLCP,
                   1812:                                "data indication type mismatch, orig=%d echo=%d",
                   1813:                                dm, px -> px_type);
                   1814:                        status++;
                   1815:                    }
                   1816:                    if (px -> px_ninfo != 1) {
                   1817:                        advise (NULLCP, "length mismatch, orig=%d echo=%d",
                   1818:                                1, px -> px_ninfo);
                   1819:                        status++;
                   1820:                    }
                   1821:                    if (pe -> pe_context != (*px -> px_info) -> pe_context) {
                   1822:                        advise (NULLCP, "context mismatch, orig=%d echo=%d",
                   1823:                                pe -> pe_context,
                   1824:                                (*px -> px_info) -> pe_context);
                   1825:                        status++;
                   1826:                    }
                   1827:                    if (pe_cmp (pe, *px -> px_info)) {
                   1828:                        advise (NULLCP, "data mismatch");
                   1829:                        status++;
                   1830:                    }
                   1831:                    PXFREE (px)
                   1832:                    break;
                   1833: 
                   1834:                case DONE: 
                   1835:                    ps_event (sd, pi);
                   1836:                    continue;
                   1837: 
                   1838:                default: 
                   1839:                    adios (NULLCP, "unknown return from PReadRequest=%d",
                   1840:                            result);
                   1841:            }
                   1842:            break;
                   1843:        }
                   1844: 
                   1845:     if (sync &&
                   1846:            (srequirements & SR_MINORSYNC) && !(srequirements & SR_ACTIVITY)) {
                   1847:        if (PMinSyncRequest (sd, SYNC_CONFIRM, &ssn, NULLPEP, 0, pi) == NOTOK)
                   1848:            switch (pa -> pa_reason) {
                   1849:                case PC_OPERATION: 
                   1850:                    ps_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN);
                   1851:                    if (PMinSyncRequest (sd, SYNC_CONFIRM, &ssn, NULLPEP, 0,
                   1852:                            pi) == OK)
                   1853:                        break;  /* else fall */
                   1854: 
                   1855:                default: 
                   1856:                    ps_adios (pa, "P-MINOR-SYNC.REQUEST");
                   1857:            }
                   1858: 
                   1859:        ps_waitfor (sd, -1);
                   1860:     }
                   1861:     else
                   1862:        if (sync
                   1863:                && (srequirements & SR_ACTIVITY)
                   1864:                && (srequirements & SR_MAJORSYNC)
                   1865:                && dm == SX_NORMAL) {
                   1866:            if (PMajSyncRequest (sd, &ssn, NULLPEP, 0, pi) == NOTOK)
                   1867:                switch (pa -> pa_reason) {
                   1868:                    case PC_OPERATION: 
                   1869:                        ps_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN
                   1870:                                | ST_MAJ_TOKEN);
                   1871:                        if (PMajSyncRequest (sd, &ssn, NULLPEP, 0, pi) == OK)
                   1872:                            break;/* else fall */
                   1873: 
                   1874:                    default: 
                   1875:                        ps_adios (pa, "P-MAJOR-SYNC.REQUEST");
                   1876:                }
                   1877: 
                   1878:            ps_waitfor (sd, -1);
                   1879:        }
                   1880: }
                   1881: 
                   1882: /*  */
                   1883: 
                   1884: static int  ps_waitfor (sd, want)
                   1885: int    sd,
                   1886:        want;
                   1887: {
                   1888:     int     result,
                   1889:            tokens;
                   1890:     struct PSAPdata pxs;
                   1891:     register struct PSAPdata   *px = &pxs;
                   1892:     struct PSAPindication   pis;
                   1893:     register struct PSAPindication *pi = &pis;
                   1894:     register struct PSAPabort  *pa = &pi -> pi_abort;
                   1895: 
                   1896:     for (;;) {
                   1897:        if (want == -1) {
                   1898:            want = avail;
                   1899:            goto read_it;
                   1900:        }
                   1901: 
                   1902:        tokens = 0;
                   1903: #define dotoken(requires,shift,bit,type) \
                   1904: { \
                   1905:        if ((want & bit) && !(owned & bit)) \
                   1906:            tokens |= bit; \
                   1907: }
                   1908:        dotokens ();
                   1909: #undef dotoken
                   1910:        if (tokens == 0)
                   1911:            return;
                   1912: 
                   1913:        if (PPTokenRequest (sd, tokens, NULLPEP, 0, pi) == NOTOK)
                   1914:            ps_adios (pa, "P-TOKEN-PLEASE.REQUEST");
                   1915: 
                   1916: read_it: ;
                   1917:        switch (result = PReadRequest (sd, px, NOTOK, pi)) {
                   1918:            case NOTOK: 
                   1919:                ps_adios (pa, "P-READ.REQUEST");
                   1920: 
                   1921:            case OK: 
                   1922:                ps_abort (sd, "protocol screw-up");
                   1923: 
                   1924:            case DONE: 
                   1925:                ps_event (sd, pi);
                   1926:                break;
                   1927: 
                   1928:            default: 
                   1929:                adios (NULLCP, "unknown return from PReadRequest=%d",
                   1930:                        result);
                   1931:        }
                   1932:     }
                   1933: }
                   1934: 
                   1935: /*  */
                   1936: 
                   1937: static ps_event (sd, pi)
                   1938: int    sd;
                   1939: register struct PSAPindication *pi;
                   1940: {
                   1941:     register struct PSAPabort  *pa = &pi -> pi_abort;
                   1942:     register struct PSAPactivity  *pv = &pi -> pi_activity;
                   1943:     register struct PSAPfinish  *pf = &pi -> pi_finish;
                   1944:     register struct PSAPreport  *pp = &pi -> pi_report;
                   1945:     register struct PSAPsync   *pn = &pi -> pi_sync;
                   1946:     register struct PSAPtoken  *pt = &pi -> pi_token;
                   1947:     struct AcSAPindication  acis;
                   1948:     register struct AcSAPindication *aci = &acis;
                   1949:     register struct AcSAPabort *aca = &aci -> aci_abort;
                   1950:     register struct AcSAPfinish *acf = &aci -> aci_finish;
                   1951: 
                   1952:     switch (pi -> pi_type) {
                   1953:        case PI_TOKEN: 
                   1954:            switch (pt -> pt_type) {
                   1955:                case ST_GIVE: 
                   1956:                case ST_CONTROL: 
                   1957:                    owned = pt -> pt_owned;
                   1958:                    break;
                   1959: 
                   1960:                case ST_PLEASE: 
                   1961:                    if (PGTokenRequest (sd,
                   1962:                                (int) pt -> pt_tokens, pi)
                   1963:                            == NOTOK)
                   1964:                        ps_adios (pa, "P-TOKEN-GIVE.REQUEST");
                   1965:                    else
                   1966:                        owned &= ~pt -> pt_tokens;
                   1967:                    break;
                   1968: 
                   1969:                default: 
                   1970:                    adios (NULLCP,
                   1971:                            "unknown token indication type=0x%x",
                   1972:                            pt -> pt_type);
                   1973:            }
                   1974:            PTFREE (pt);
                   1975:            break;
                   1976: 
                   1977:        case PI_SYNC: 
                   1978:            switch (pn -> pn_type) {
                   1979:                case SN_MAJORIND: 
                   1980:                    adios (NULLCP, "majorsync indication %d",
                   1981:                            pn -> pn_ssn);
                   1982:                    break;
                   1983: 
                   1984:                case SN_MAJORCNF: 
                   1985:                    break;
                   1986: 
                   1987:                case SN_MINORIND: 
                   1988:                    adios (NULLCP, "minorsync indication %d%s",
                   1989:                            pn -> pn_ssn, pn -> pn_options == SYNC_CONFIRM
                   1990:                            ? " (wants confirmation)" : NULLCP);
                   1991:                    break;
                   1992: 
                   1993:                case SN_MINORCNF: 
                   1994:                    break;
                   1995: 
                   1996:                case SN_RESETIND: 
                   1997: #define        dotoken(requires,shift,bit,type) \
                   1998: { \
                   1999:                    if (srequirements & requires) \
                   2000:                        switch (pn -> pn_settings & (ST_MASK << shift)) { \
                   2001:                            case ST_CALL_VALUE << shift: \
                   2002:                                pn -> pn_settings &= ~(ST_MASK << shift); \
                   2003:                                pn -> pn_settings |= ST_RESP_VALUE << shift; \
                   2004:                            case ST_RESP_VALUE << shift: \
                   2005:                                owned &= ~bit; \
                   2006:                                break; \
                   2007:  \
                   2008:                            case ST_INIT_VALUE << shift: \
                   2009:                                owned |= bit; \
                   2010:                                break; \
                   2011:  \
                   2012:                            default: \
                   2013:                                adios (NULLCP, "%s token: reserved", type); \
                   2014:                                break; \
                   2015:                        } \
                   2016: }
                   2017:                    dotokens ();
                   2018: #undef dotoken
                   2019:                    if (PReSyncResponse (sd, pn -> pn_ssn, pn -> pn_settings,
                   2020:                                NULLPEP, 0, pi) == NOTOK)
                   2021:                        ps_adios (pa, "P-RESYNCHRONIZE.RESPONSE");
                   2022:                    break;
                   2023: 
                   2024:                case SN_RESETCNF: 
                   2025:                    break;
                   2026: 
                   2027:                default: 
                   2028:                    adios (NULLCP, "unknown sync indication=0x%x, ssn=%d",
                   2029:                            pn -> pn_type, pn -> pn_ssn);
                   2030:            }
                   2031:            PNFREE (pn);
                   2032:            break;
                   2033: 
                   2034:        case PI_ACTIVITY: 
                   2035:            switch (pv -> pv_type) {
                   2036:                case SV_START: 
                   2037:                    adios (NULLCP, "activity start indication: %*.*s",
                   2038:                            pv -> pv_id.sd_len, pv -> pv_id.sd_len,
                   2039:                            pv -> pv_id.sd_data);
                   2040: 
                   2041:                case SV_RESUME: 
                   2042:                    adios (NULLCP, 
                   2043:                            "activity resume indication: id=%*.*s oid=%*.*s connect=%s ssn=%d",
                   2044:                            pv -> pv_id.sd_len, pv -> pv_id.sd_len,
                   2045:                            pv -> pv_id.sd_data, pv -> pv_oid.sd_len,
                   2046:                            pv -> pv_oid.sd_len, pv -> pv_oid.sd_data,
                   2047:                            sprintref (&pv -> pv_connect), pv -> pv_ssn);
                   2048: 
                   2049:                case SV_INTRIND: 
                   2050:                    adios (NULLCP, "activity interrupt indication %d",
                   2051:                            pv -> pv_reason);
                   2052: 
                   2053:                case SV_INTRCNF: 
                   2054:                    break;
                   2055: 
                   2056:                case SV_DISCIND: 
                   2057:                    adios (NULLCP, "activity discard indication %d",
                   2058:                            pv -> pv_reason);
                   2059: 
                   2060:                case SV_DISCCNF: 
                   2061:                    break;
                   2062: 
                   2063:                case SV_ENDIND: 
                   2064:                    adios (NULLCP, "activity end indication %d",
                   2065:                            pv -> pv_ssn);
                   2066: 
                   2067:                case SV_ENDCNF: 
                   2068:                    break;
                   2069: 
                   2070:                default: 
                   2071:                    adios (NULLCP, "unknown activity indication=0x%x",
                   2072:                            pv -> pv_type);
                   2073:            }
                   2074:            PVFREE (pv);
                   2075:            break;
                   2076: 
                   2077:        case PI_REPORT: 
                   2078:            advise (NULLCP, "%s report %d",
                   2079:                    pp -> pp_peer ? "user" : "provider", pp -> pp_reason);
                   2080:            if (srequirements & SR_DAT_EXISTS) {
                   2081:                if (PGTokenRequest (sd, ST_DAT_TOKEN, pi) == NOTOK)
                   2082:                    ps_adios (pa, "P-TOKEN-GIVE.REQUEST (to clear exception)");
                   2083:                else
                   2084:                    owned &= ~ST_DAT_TOKEN;
                   2085:            }
                   2086:            else
                   2087:                ps_abort (sd, "aborted");
                   2088:            PPFREE (pp);
                   2089:            break;
                   2090: 
                   2091:        case PI_FINISH: 
                   2092:            if (isacs) {
                   2093:                if (AcFINISHser (sd, pf, aci) == NOTOK)
                   2094:                    acs_adios (aca, "AcFINISHser");
                   2095: #ifdef DEBUG
                   2096:                advise (NULLCP, "A-RELEASE.INDICATION %d, %d elements",
                   2097:                        acf -> acf_reason, acf -> acf_ninfo);
                   2098:                if (AcRelResponse (sd, ACS_USER_NOREASON, ACR_NOTFINISHED,
                   2099:                                NULLPEP, 0, aci) == NOTOK)
                   2100:                    acs_adios (aca, "A-RELEASE.RESPONSE");
                   2101: #endif
                   2102: 
                   2103:                ACFFREE (acf);
                   2104:            }
                   2105:            else {
                   2106:                if (PRelResponse (sd, PC_REJECTED, NULLPEP, 0, pi) == NOTOK)
                   2107:                    ps_adios (pa, "P-RELEASE.RESPONSE");
                   2108: 
                   2109:                PFFREE (pf);
                   2110:            }
                   2111:            break;
                   2112: 
                   2113:        default: 
                   2114:            adios (NULLCP, "unknown indication type=0x%x", pi -> pi_type);
                   2115:     }
                   2116: }
                   2117: 
                   2118: /*  */
                   2119: 
                   2120: static  ps_abort (sd, reason)
                   2121: int     sd;
                   2122: char   *reason;
                   2123: {
                   2124:     struct PSAPindication   pis;
                   2125:     register struct PSAPindication *pi = &pis;
                   2126:     register struct PSAPabort  *pa = &pi -> pi_abort;
                   2127:     struct AcSAPindication  acis;
                   2128:     register struct AcSAPindication *aci = &acis;
                   2129:     register struct AcSAPabort *aca = &aci -> aci_abort;
                   2130: 
                   2131:     if (isacs) {
                   2132:        if (AcUAbortRequest (sd, NULLPEP, 0, aci) == NOTOK)
                   2133:            acs_adios (aca, "A-U-ABORT.REQUEST");
                   2134:     }
                   2135:     else {
                   2136:        if (PUAbortRequest (sd, NULLPEP, 0, pi) == NOTOK)
                   2137:            ps_adios (pa, "P-U-ABORT.REQUEST");
                   2138:     }
                   2139: 
                   2140:     adios (NULLCP, "%s", reason);
                   2141: }
                   2142: 
                   2143: /*  */
                   2144: 
                   2145: static void  ps_adios (pa, event)
                   2146: register struct PSAPabort *pa;
                   2147: char   *event;
                   2148: {
                   2149:     ps_advise (pa, event);
                   2150: 
                   2151:     _exit (1);
                   2152: }
                   2153: 
                   2154: 
                   2155: static void  ps_advise (pa, event)
                   2156: register struct PSAPabort *pa;
                   2157: char   *event;
                   2158: {
                   2159:     char    buffer[BUFSIZ];
                   2160: 
                   2161:     if (pa -> pa_cc > 0)
                   2162:        (void) sprintf (buffer, "[%s] %*.*s",
                   2163:                PErrString (pa -> pa_reason),
                   2164:                pa -> pa_cc, pa -> pa_cc, pa -> pa_data);
                   2165:     else
                   2166:        (void) sprintf (buffer, "[%s]", PErrString (pa -> pa_reason));
                   2167: 
                   2168:     advise (NULLCP, "%s: %s%s", event, buffer,
                   2169:            pa -> pa_peer ? " (peer initiated)" : "");
                   2170: }
                   2171: 
                   2172: /*    AcSAP */
                   2173: 
                   2174: static void  acs_adios (aca, event)
                   2175: register struct AcSAPabort *aca;
                   2176: char   *event;
                   2177: {
                   2178:     acs_advise (aca, event);
                   2179: 
                   2180:     _exit (1);
                   2181: }
                   2182: 
                   2183: 
                   2184: static void  acs_advise (aca, event)
                   2185: register struct AcSAPabort *aca;
                   2186: char   *event;
                   2187: {
                   2188:     char    buffer[BUFSIZ];
                   2189: 
                   2190:     if (aca -> aca_cc > 0)
                   2191:        (void) sprintf (buffer, "[%s] %*.*s",
                   2192:                AcErrString (aca -> aca_reason),
                   2193:                aca -> aca_cc, aca -> aca_cc, aca -> aca_data);
                   2194:     else
                   2195:        (void) sprintf (buffer, "[%s]", AcErrString (aca -> aca_reason));
                   2196: 
                   2197:        advise (NULLCP, "%s: %s (source %d)", event, buffer,
                   2198:                aca -> aca_source);
                   2199: }
                   2200: 
                   2201: /*    RtSAP */
                   2202: 
                   2203: static int turn = 0;
                   2204: 
                   2205: /*  */
                   2206: 
                   2207: static int  rts_main (is, addr)
                   2208: struct isoservent *is;
                   2209: char *addr;
                   2210: {
                   2211:     int     sd,
                   2212:             cc,
                   2213:             i,
                   2214:             j,
                   2215:            ros;
                   2216:     char   *cp,
                   2217:            *dp,
                   2218:             buffer[BUFSIZ];
                   2219:     register struct PSAPaddr   *pa;
                   2220:     struct PSAPctxlist pls;
                   2221:     register struct PSAPctxlist *pl = &pls;
                   2222:     struct AcSAPrelease acrs;
                   2223:     register struct AcSAPrelease *acr = &acrs;
                   2224:     struct RtSAPaddr    rtzs;
                   2225:     register struct RtSAPaddr  *rtz = &rtzs;
                   2226:     struct RtSAPconnect rtcs;
                   2227:     register struct RtSAPconnect   *rtc = &rtcs;
                   2228:     struct RtSAPindication  rtis;
                   2229:     register struct RtSAPindication *rti = &rtis;
                   2230:     register struct RtSAPabort   *rta = &rti -> rti_abort;
                   2231: #ifdef DEBUG
                   2232:     struct AcSAPconnect *acc= &rtc -> rtc_connect;
                   2233:     struct PSAPconnect *pc = &acc -> acc_connect;
                   2234: #endif
                   2235:     register PE            pe;
                   2236:     AEI            aei;
                   2237:     OID            oid,
                   2238:            ode;
                   2239:     struct stat st;
                   2240: 
                   2241:     if ((pe = int2prim (i = getpid ())) == NULLPE)
                   2242:        adios (NULLCP, "unable to allocate hello");
                   2243: 
                   2244:     turn = mode == sink;
                   2245: 
                   2246:     if (isacs) {
                   2247:        if (ros = strncmp (isacs, "isode/ros_", strlen ("isode/ros_")) == 0)
                   2248:            mode = strcmp (isacs, "isode/ros_sink") ? echo : sink;
                   2249:        else
                   2250:            mode = strcmp (isacs, "isode/rtse sink") ? echo : sink;
                   2251:        turn = mode == sink;
                   2252: 
                   2253:        if ((aei = str2aei (addr, isacs)) == NULLAEI)
                   2254:            adios (NULLCP, "%s-%s: unknown application-entity", addr, isacs);
                   2255:        if ((pa = aei2addr (aei)) == NULLPA)
                   2256:            adios (NULLCP, "address translation failed");
                   2257: 
                   2258:        cp = mode == echo ? "isode echo pci" : "isode sink pci";
                   2259:        if ((ode = ode2oid (cp)) == NULLOID)
                   2260:            adios (NULLCP, "%s: unknown object descriptor", cp);
                   2261:        ode = oid_cpy (ode);
                   2262: 
                   2263:        for (j = (pl -> pc_nctx = NPCTX - 2) - 1; j >= 0; j--) {
                   2264:            pl -> pc_ctx[j].pc_id = j * 2 + 1;
                   2265:            if ((oid = ode2oid ("iso asn.1 abstract syntax")) == NULLOID)
                   2266:                adios (NULLCP, "iso asn.1 abstract syntax: unknown");
                   2267:            pl -> pc_ctx[j].pc_asn = oid_cpy (oid);
                   2268:            pl -> pc_ctx[j].pc_atn = NULLOID;
                   2269:        }
                   2270: 
                   2271:        fprintf (stderr, "%s... ", addr);
                   2272:        (void) fflush (stderr);
                   2273:        if (RtOpenRequest (RTS_TWA, turn ? RTS_INITIATOR : RTS_RESPONDER,
                   2274:                    ode, NULLAEI, aei, NULLPA, pa, pl, ode, pe,
                   2275:                    NULLQOS, rtc, rti) == NOTOK) {
                   2276:            fprintf (stderr, "failed\n");
                   2277:            rts_adios (rta, "RT-OPEN.REQUEST");
                   2278:        }
                   2279:     }
                   2280:     else {
                   2281:        register struct SSAPaddr *sa;
                   2282: 
                   2283:        if (ros = strncmp (is -> is_entity, "ros_", strlen ("ros_")) == 0) {
                   2284:            mode = strcmp (is -> is_entity, "ros_sink") ? echo : sink;
                   2285:            turn = mode == sink;
                   2286:        }
                   2287: 
                   2288:        rtz -> rta_port = is -> is_port;        /* yikes! */
                   2289:        if ((is = getisoserventbyname ("rts", "ssap")) == NULL)
                   2290:            adios (NULLCP, "ssap/rts: unknown entity");
                   2291:        if ((sa = is2saddr (addr, NULLCP, is)) == NULLSA)
                   2292:            adios (NULLCP, "address translation failed");
                   2293:        rtz -> rta_addr = *sa;  /* struct copy */
                   2294: 
                   2295:        fprintf (stderr, "%s... ", addr);
                   2296:        (void) fflush (stderr);
                   2297:        if (RtBeginRequest (rtz, RTS_TWA, turn ? RTS_INITIATOR : RTS_RESPONDER,
                   2298:                    pe, rtc, rti) == NOTOK) {
                   2299:            fprintf (stderr, "failed\n");
                   2300:            rts_adios (rta, "RT-BEGIN.REQUEST");
                   2301:        }
                   2302:     }
                   2303: 
                   2304:     pe_free (pe);
                   2305: 
                   2306:     if (rtc -> rtc_result != RTS_ACCEPT) {
                   2307:        fprintf (stderr, "failed\n");
                   2308:        adios (NULLCP, "association rejected: [%s]",
                   2309:                RtErrString (rtc -> rtc_result));
                   2310:     }
                   2311:     fprintf (stderr, "connected\n");
                   2312: 
                   2313: #ifdef DEBUG
                   2314:     advise (NULLCP, "sent greetings of %d", i);
                   2315: #endif
                   2316: 
                   2317:     sd = rtc -> rtc_sd;
                   2318:     if (rtc -> rtc_data) {
                   2319:        if ((i = prim2num (rtc -> rtc_data)) == NOTOK
                   2320:                && rtc -> rtc_data -> pe_errno != PE_ERR_NONE)
                   2321:            adios (NULLCP, "error decoding hello: %s (%d)",
                   2322:                    pe_error (rtc -> rtc_data -> pe_errno), i);
                   2323: #ifdef DEBUG
                   2324:        advise (NULLCP, "received greetings of %d", i);
                   2325: #endif
                   2326:     }
                   2327: 
                   2328: #ifdef DEBUG
                   2329:     if (isacs) {
                   2330:            advise (NULLCP, "context: %s", oid2ode (acc -> acc_context));
                   2331: 
                   2332:            advise (NULLCP,
                   2333:                    "responding AE title: %s, responding PSAP address: %s",
                   2334:                    sprintaei (&acc -> acc_respondtitle),
                   2335:                    paddr2str (&pc -> pc_responding, NULLNA));
                   2336: 
                   2337:            advise (NULLCP, "greetings: %d elements", acc -> acc_ninfo);
                   2338: 
                   2339:            pl = &pc -> pc_ctxlist;
                   2340:            for (i = 0; i < pl -> pc_nctx; i++)
                   2341:                advise (NULLCP, "ctx %d: 0x%x 0x%x %d",
                   2342:                        pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
                   2343:                        pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
                   2344:            advise (NULLCP, "default %d", pc -> pc_defctxresult);
                   2345:            advise (NULLCP, "p/s requirements 0x%x/0x%x",
                   2346:                    pc -> pc_prequirements, pc -> pc_srequirements);
                   2347:        }
                   2348: #endif
                   2349: 
                   2350:     RTCFREE (rtc);
                   2351: 
                   2352:     if (ros) {
                   2353:        struct RoSAPindication rois;
                   2354:        register struct RoSAPpreject *rop = &rois.roi_preject;
                   2355: 
                   2356:        if (RoSetService (sd, RoRtService, &rois) == NOTOK)
                   2357:            ros_adios (rop, "set RO/PT fails");
                   2358: 
                   2359:        do_ros (sd);
                   2360:        return;
                   2361:     }
                   2362: 
                   2363:     if (fstat (fileno (stdin), &st) != NOTOK
                   2364:            && (st.st_mode & S_IFMT) == S_IFREG
                   2365:            && (cc = st.st_size) != 0) {
                   2366:        (void) lseek (fileno (stdin), 0L, 0);
                   2367: 
                   2368:        if ((cp = malloc ((unsigned) cc)) == NULL)
                   2369:            adios (NULLCP, "no memory");
                   2370:        for (dp = cp, j = cc; j > 0; dp += i, j -= i)
                   2371:            switch (i = read (fileno (stdin), dp, j)) {
                   2372:                case NOTOK: 
                   2373:                    adios ("on stdin", "read failed");
                   2374: 
                   2375:                case OK: 
                   2376:                    adios (NULLCP, "premature end-of-file");
                   2377: 
                   2378:                default: 
                   2379:                    break;
                   2380:            }
                   2381:        if ((pe = oct2prim (cp, cc)) == NULLPE)
                   2382:            adios (NULLCP, "unable to allocate APDU");
                   2383:        free (cp);
                   2384:        for (i = 10; i > 0; i--) {
                   2385: #ifdef TIMER
                   2386:            timer (0);
                   2387: #endif
                   2388:            rts_transferequest (sd, pe);
                   2389: #ifdef TIMER
                   2390:            timer (cc);
                   2391: #endif
                   2392:        }
                   2393:        pe_free (pe);
                   2394:     }
                   2395:     else
                   2396:        while (fgets (buffer, sizeof buffer, stdin)) {
                   2397:            if ((pe = oct2prim (buffer, strlen (buffer) + 1)) == NULLPE)
                   2398:                adios (NULLCP, "unable to allocate APDU");
                   2399:            rts_transferequest (sd, pe);
                   2400:            pe_free (pe);
                   2401:        }
                   2402: 
                   2403:     if (isacs) {
                   2404:        if ((pe = int2prim (i = getpid ())) == NULLPE)
                   2405:            adios (NULLCP, "unable to allocate hello");
                   2406: 
                   2407:        if (RtCloseRequest (sd, ACF_NORMAL, pe, acr, rti) == NOTOK)
                   2408:            switch (rta -> rta_reason) {
                   2409:                case RTS_OPERATION: 
                   2410:                case RTS_WAITING: 
                   2411:                    rts_waitfor (sd);
                   2412:                    if (RtCloseRequest (sd, ACF_NORMAL, pe, acr, rti)
                   2413:                            == OK)
                   2414:                        break;  /* else fall */
                   2415: 
                   2416:                default: 
                   2417:                    rts_adios (rta, "RT-CLOSE.REQUEST");
                   2418:            }
                   2419: 
                   2420:        if (!acr -> acr_affirmative) {
                   2421:            (void) RtUAbortRequest (sd, NULLPE, rti);
                   2422:            adios (NULLCP, "release rejected by peer: %d, %d elements",
                   2423:                        acr -> acr_reason, acr -> acr_ninfo);
                   2424:        }
                   2425: 
                   2426:        if (mode == echo) {
                   2427:            if (acr -> acr_ninfo != 1)
                   2428:                advise (NULLCP, "got %d elements returned on close",
                   2429:                            acr -> acr_ninfo);
                   2430:                if (pe_cmp (pe, acr -> acr_info[0])) {
                   2431:                    advise (NULLCP, "data mismatch");
                   2432:                    status++;
                   2433:                }
                   2434:        }
                   2435: 
                   2436:        ACRFREE (acr);
                   2437: 
                   2438:        pe_free (pe);
                   2439:     }
                   2440:     else
                   2441:        if (RtEndRequest (sd, rti) == NOTOK)
                   2442:            switch (rta -> rta_reason) {
                   2443:                case RTS_OPERATION: 
                   2444:                case RTS_WAITING: 
                   2445:                    rts_waitfor (sd);
                   2446:                    if (RtEndRequest (sd, rti) == OK)
                   2447:                        break;  /* else fall */
                   2448: 
                   2449:                default: 
                   2450:                    rts_adios (rta, "RT-END.REQUEST");
                   2451:            }
                   2452: }
                   2453: 
                   2454: /*  */
                   2455: 
                   2456: static int  rts_transferequest (sd, pe)
                   2457: int    sd;
                   2458: register PE    pe;
                   2459: {
                   2460:     int     result;
                   2461:     struct RtSAPindication  rtis;
                   2462:     register struct RtSAPindication *rti = &rtis;
                   2463:     register struct RtSAPabort *rta = &rti -> rti_abort;
                   2464:     register struct RtSAPtransfer  *rtt = &rti -> rti_transfer;
                   2465: 
                   2466:     if (RtTransferRequest (sd, pe, NOTOK, rti) == NOTOK)
                   2467:        switch (rta -> rta_reason) {
                   2468:            case RTS_OPERATION: 
                   2469:                rts_waitfor (sd);
                   2470:                if (RtTransferRequest (sd, pe, NOTOK, rti) == OK)
                   2471:                    break;      /* else fall */
                   2472: 
                   2473:            default: 
                   2474:                if (RTS_FATAL (rta -> rta_reason))
                   2475:                    rts_adios (rta, "RT-TRANSFER.REQUEST");
                   2476:                rts_advise (rta, "RT-TRANSFER.REQUEST");
                   2477:                return;
                   2478:        }
                   2479: 
                   2480:     if (mode == echo)
                   2481:        for (;;)
                   2482:            switch (result = RtWaitRequest (sd, NOTOK, rti)) {
                   2483:                case NOTOK: 
                   2484:                    rts_adios (rta, "RT-WAIT.REQUEST");
                   2485: 
                   2486:                case OK: 
                   2487:                    if (pe_cmp (pe, rtt -> rtt_data)) {
                   2488:                        advise (NULLCP, "data mismatch");
                   2489:                        status++;
                   2490:                    }
                   2491:                    RTTFREE (rtt);
                   2492:                    return;
                   2493: 
                   2494:                case DONE: 
                   2495:                    rts_event (sd, rti);
                   2496:                    break;
                   2497: 
                   2498:                default: 
                   2499:                    adios (NULLCP, "unknown return from RtWaitRequest=%d",
                   2500:                            result);
                   2501:            }
                   2502: }
                   2503: 
                   2504: /*  */
                   2505: 
                   2506: static int  rts_waitfor (sd)
                   2507: int    sd;
                   2508: {
                   2509:     int     result;
                   2510:     struct RtSAPindication  rtis;
                   2511:     register struct RtSAPindication *rti = &rtis;
                   2512:     register struct RtSAPabort *rta = &rti -> rti_abort;
                   2513:     static int  priority = 1;
                   2514: 
                   2515:     if (turn)
                   2516:        return;
                   2517: 
                   2518:     if (RtPTurnRequest (sd, priority++, rti) == NOTOK)
                   2519:        rts_adios (rta, "RT-TURN-PLEASE.REQUEST");
                   2520: 
                   2521:     while (!turn)
                   2522:        switch (result = RtWaitRequest (sd, NOTOK, rti)) {
                   2523:            case NOTOK: 
                   2524:                rts_adios (rta, "RT-WAIT.REQUEST");
                   2525: 
                   2526:            case OK: 
                   2527:                adios (NULLCP, "protocol screw-up");
                   2528: 
                   2529:            case DONE: 
                   2530:                rts_event (sd, rti);
                   2531:                break;
                   2532: 
                   2533:            default: 
                   2534:                adios (NULLCP, "unknown return from RtWaitRequest=%d",
                   2535:                        result);
                   2536:        }
                   2537: }
                   2538: 
                   2539: /*  */
                   2540: 
                   2541: static int  rts_event (sd, rti)
                   2542: int    sd;
                   2543: register struct RtSAPindication *rti;
                   2544: {
                   2545:     register struct RtSAPabort *rta = &rti -> rti_abort;
                   2546:     register struct RtSAPturn  *rtu = &rti -> rti_turn;
                   2547: 
                   2548:     switch (rti -> rti_type) {
                   2549:        case RTI_TURN: 
                   2550:            if (rtu -> rtu_please) {
                   2551:                if (RtGTurnRequest (sd, rti) == NOTOK)
                   2552:                    rts_adios (rta, "RT-TURN-GIVE.REQUEST");
                   2553:                turn = 0;
                   2554:            }
                   2555:            else
                   2556:                turn = 1;
                   2557:            break;
                   2558: 
                   2559:        case RTI_CLOSE: 
                   2560:            adios (NULLCP, "got RT-END.INDICATION");
                   2561: 
                   2562:        case RTI_FINISH:
                   2563:            adios (NULLCP, "got RT-CLOSE.INDICATION");
                   2564: 
                   2565:        default: 
                   2566:            adios (NULLCP, "unknown indication type=0x%x",
                   2567:                    rti -> rti_type);
                   2568:     }
                   2569: }
                   2570: 
                   2571: /*  */
                   2572: 
                   2573: static void  rts_adios (rta, event)
                   2574: register struct RtSAPabort *rta;
                   2575: char   *event;
                   2576: {
                   2577:     rts_advise (rta, event);
                   2578: 
                   2579:     _exit (1);
                   2580: }
                   2581: 
                   2582: 
                   2583: static void  rts_advise (rta, event)
                   2584: register struct RtSAPabort *rta;
                   2585: char   *event;
                   2586: {
                   2587:     char    buffer[BUFSIZ];
                   2588: 
                   2589:     if (rta -> rta_cc > 0)
                   2590:        (void) sprintf (buffer, "[%s] %*.*s", RtErrString (rta -> rta_reason),
                   2591:                rta -> rta_cc, rta -> rta_cc, rta -> rta_data);
                   2592:     else
                   2593:        (void) sprintf (buffer, "[%s]", RtErrString (rta -> rta_reason));
                   2594: 
                   2595:     advise (NULLCP, "%s: %s", event, buffer);
                   2596: }
                   2597: 
                   2598: /*    RoSAP */
                   2599: 
                   2600: static int  ros_main (is, addr)
                   2601: struct isoservent *is;
                   2602: char *addr;
                   2603: {
                   2604:     int     sd,
                   2605:             i;
                   2606:     char   *cp;
                   2607:     struct SSAPref  sfs;
                   2608:     register struct SSAPref *sf;
                   2609:     register struct PSAPaddr   *pa;
                   2610:     struct AcSAPconnect accs;
                   2611:     register struct AcSAPconnect   *acc = &accs;
                   2612:     struct AcSAPindication  acis;
                   2613:     register struct AcSAPindication *aci = &acis;
                   2614:     register struct AcSAPabort *aca = &aci -> aci_abort;
                   2615:     struct RoSAPaddr    roas;
                   2616:     register struct RoSAPaddr  *roa = &roas;
                   2617:     struct RoSAPconnect rocs;
                   2618:     register struct RoSAPconnect   *roc = &rocs;
                   2619:     struct RoSAPindication  rois;
                   2620:     register struct RoSAPindication *roi = &rois;
                   2621:     register struct RoSAPpreject   *rop = &roi -> roi_preject;
                   2622: #ifdef DEBUG
                   2623:     struct PSAPconnect *pc = &acc -> acc_connect;
                   2624: #endif
                   2625:     struct PSAPctxlist pls;
                   2626:     register struct PSAPctxlist *pl = &pls;
                   2627:     AEI            aei;
                   2628:     OID     oid,
                   2629:            ode;
                   2630:     register PE            pe;
                   2631: 
                   2632:     if (isacs) {
                   2633:        if ((aei = str2aei (addr, isacs)) == NULLAEI)
                   2634:            adios (NULLCP, "%s-%s: unknown application-entity", addr, isacs);
                   2635:        if ((pa = aei2addr (aei)) == NULLPA)
                   2636:            adios (NULLCP, "address translation failed");
                   2637: 
                   2638:        cp = mode == echo ? "isode echo pci" : "isode sink pci";
                   2639:        if ((ode = ode2oid (cp)) == NULLOID)
                   2640:            adios (NULLCP, "%s: unknown object descriptor", cp);
                   2641:        ode = oid_cpy (ode);
                   2642: 
                   2643:        if ((sf = addr2ref (PLocalHostName ())) == NULL) {
                   2644:            sf = &sfs;
                   2645:            (void) bzero ((char *) sf, sizeof *sf);
                   2646:        }
                   2647:        pl -> pc_nctx = 1;
                   2648:        pl -> pc_ctx[0].pc_id = 1;
                   2649:        if ((oid = ode2oid ("iso asn.1 abstract syntax")) == NULLOID)
                   2650:            adios (NULLCP, "iso asn.1 abstract syntax: unknown");
                   2651:        pl -> pc_ctx[0].pc_asn = oid_cpy (oid);
                   2652:        pl -> pc_ctx[0].pc_atn = NULLOID;
                   2653: 
                   2654:        fprintf (stderr, "%s... ", addr);
                   2655:        (void) fflush (stderr);
                   2656:        if (AcAssocRequest (ode, NULLAEI, aei, NULLPA, pa, pl, ode,
                   2657:                    0, ROS_MYREQUIRE, SERIAL_NONE, 0, sf, NULLPEP, 0, NULLQOS,
                   2658:                    acc, aci)
                   2659:                == NOTOK)
                   2660:            acs_adios (aca, "A-ASSOCIATE.REQUEST");
                   2661: 
                   2662:        if (acc -> acc_result != ACS_ACCEPT) {
                   2663:            fprintf (stderr, "failed\n");
                   2664:            adios (NULLCP, "association rejected: [%s]",
                   2665:                    AcErrString (acc -> acc_result));
                   2666:        }
                   2667:        fprintf (stderr, "connected\n");
                   2668: 
                   2669:        sd = acc -> acc_sd;
                   2670: 
                   2671: #ifdef DEBUG
                   2672:        pa = &pc -> pc_responding;
                   2673:        {
                   2674:            advise (NULLCP, "context: %s", oid2ode (acc -> acc_context));
                   2675: 
                   2676:            advise (NULLCP,
                   2677:                    "responding AE title: %s, responding PSAP address: %s",
                   2678:                    sprintaei (&acc -> acc_respondtitle),
                   2679:                    paddr2str (&pc -> pc_responding, NULLNA));
                   2680: 
                   2681:            advise (NULLCP, "greetings: %d elements", acc -> acc_ninfo);
                   2682: 
                   2683:            pl = &pc -> pc_ctxlist;
                   2684:            for (i = 0; i < pl -> pc_nctx; i++)
                   2685:                advise (NULLCP, "ctx %d: 0x%x 0x%x %d",
                   2686:                        pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
                   2687:                        pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
                   2688:            advise (NULLCP, "default %d", pc -> pc_defctxresult);
                   2689:            advise (NULLCP, "p/s requirements 0x%x/0x%x",
                   2690:                    pc -> pc_prequirements, pc -> pc_srequirements);
                   2691:        }
                   2692: #endif
                   2693: 
                   2694:        ACCFREE (acc);
                   2695: 
                   2696:        if (RoSetService (sd, RoPService, roi) == NOTOK)
                   2697:            ros_adios (rop, "set RO/PT fails");
                   2698:     }
                   2699:     else {
                   2700:        register struct SSAPaddr *sa;
                   2701: 
                   2702:        roa -> roa_port = is -> is_port;        /* yikes! */
                   2703:        if ((is = getisoserventbyname ("ros", "ssap")) == NULL)
                   2704:            adios (NULLCP, "ssap/ros: unknown entity");
                   2705:        if ((sa = is2saddr (addr, NULLCP, is)) == NULLSA)
                   2706:            adios (NULLCP, "address translation failed");
                   2707:        roa -> roa_addr = *sa;  /* struct copy */
                   2708: 
                   2709:        if ((pe = int2prim (i = getpid ())) == NULLPE)
                   2710:            adios (NULLCP, "unable to allocate hello");
                   2711: 
                   2712:        fprintf (stderr, "%s... ", addr);
                   2713:        (void) fflush (stderr);
                   2714:        if (RoBeginRequest (roa, pe, roc, roi) == NOTOK) {
                   2715:            fprintf (stderr, "failed\n");
                   2716:            ros_adios (rop, "RO-BEGIN.REQUEST");
                   2717:        }
                   2718: 
                   2719:        pe_free (pe);
                   2720: 
                   2721:        if (roc -> roc_result != ROS_ACCEPT) {
                   2722:            fprintf (stderr, "failed\n");
                   2723:            adios (NULLCP, "association rejected: [%s]",
                   2724:                    RoErrString (roc -> roc_result));
                   2725:        }
                   2726:        fprintf (stderr, "connected\n");
                   2727: 
                   2728: #ifdef DEBUG
                   2729:        advise (NULLCP, "sent greetings of %d", i);
                   2730: #endif
                   2731: 
                   2732:        sd = roc -> roc_sd;
                   2733:        if (roc -> roc_data) {
                   2734:            if ((i = prim2num (roc -> roc_data)) == NOTOK
                   2735:                    && roc -> roc_data -> pe_errno != PE_ERR_NONE)
                   2736:                adios (NULLCP, "error decoding hello: %s (%d)",
                   2737:                        pe_error (roc -> roc_data -> pe_errno), i);
                   2738: #ifdef DEBUG
                   2739:            advise (NULLCP, "received greetings of %d", i);
                   2740: #endif
                   2741:        }
                   2742:        ROCFREE (roc);
                   2743:     }
                   2744: 
                   2745:     do_ros (sd);
                   2746: }
                   2747: 
                   2748: /*  */
                   2749: 
                   2750: static int  do_ros (sd)
                   2751: int    sd;
                   2752: {
                   2753:     int     cc,
                   2754:             i,
                   2755:             j;
                   2756:     char   *cp,
                   2757:            *dp,
                   2758:             buffer[BUFSIZ];
                   2759:     struct RoSAPindication  rois;
                   2760:     register struct RoSAPindication *roi = &rois;
                   2761:     register struct RoSAPpreject   *rop = &roi -> roi_preject;
                   2762:     struct AcSAPrelease acrs;
                   2763:     register struct AcSAPrelease *acr = &acrs;
                   2764:     register PE        pe;
                   2765:     struct stat st;
                   2766:     
                   2767:     if (fstat (fileno (stdin), &st) != NOTOK
                   2768:            && (st.st_mode & S_IFMT) == S_IFREG
                   2769:            && (cc = st.st_size) != 0) {
                   2770:        (void) lseek (fileno (stdin), 0L, 0);
                   2771: 
                   2772:        if ((cp = malloc ((unsigned) cc)) == NULL)
                   2773:            adios (NULLCP, "no memory");
                   2774:        for (dp = cp, j = cc; j > 0; dp += i, j -= i)
                   2775:            switch (i = read (fileno (stdin), dp, j)) {
                   2776:                case NOTOK: 
                   2777:                    adios ("on stdin", "read failed");
                   2778: 
                   2779:                case OK: 
                   2780:                    adios (NULLCP, "premature end-of-file");
                   2781: 
                   2782:                default: 
                   2783:                    break;
                   2784:            }
                   2785:        if ((pe = oct2prim (cp, cc)) == NULLPE)
                   2786:            adios (NULLCP, "unable to allocate invocation argument");
                   2787:        free (cp);
                   2788:        for (i = 10; i > 0; i--) {
                   2789: #ifdef TIMER
                   2790:            timer (0);
                   2791: #endif
                   2792:            ros_invokerequest (sd, pe);
                   2793: #ifdef TIMER
                   2794:            timer (cc);
                   2795: #endif
                   2796:        }
                   2797:        pe_free (pe);
                   2798:     }
                   2799:     else
                   2800:        while (fgets (buffer, sizeof buffer, stdin)) {
                   2801:            if ((pe = oct2prim (buffer, strlen (buffer) + 1)) == NULLPE)
                   2802:                adios (NULLCP, "unable to allocate invocation argument");
                   2803:            ros_invokerequest (sd, pe);
                   2804:            pe_free (pe);
                   2805:        }
                   2806: 
                   2807:     if (isrts) {
                   2808:        struct RtSAPindication  rtis;
                   2809:        register struct RtSAPindication *rti = &rtis;
                   2810:        register struct RtSAPabort *rta = &rti -> rti_abort;
                   2811: 
                   2812:        if (isacs) {
                   2813:            if (RtCloseRequest (sd, ACF_NORMAL, NULLPE, acr, rti) == NOTOK)
                   2814:                switch (rta -> rta_reason) {
                   2815:                    case RTS_OPERATION:
                   2816:                    case RTS_WAITING: 
                   2817:                        rts_waitfor (sd);
                   2818:                        if (RtCloseRequest (sd, ACF_NORMAL, NULLPE, acr, rti)
                   2819:                                == OK)
                   2820:                            break;      /* else fall */
                   2821: 
                   2822:                    default:
                   2823:                        rts_adios (rta, "RT-CLOSE.REQUEST");
                   2824:                }
                   2825: 
                   2826:            if (!acr -> acr_affirmative) {
                   2827:                (void) RtUAbortRequest (sd, NULLPE, rti);
                   2828:                adios (NULLCP, "release rejected by peer: %d, %d elements",
                   2829:                            acr -> acr_reason, acr -> acr_ninfo);
                   2830:            }
                   2831:        }
                   2832:        else
                   2833:            if (RtEndRequest (sd, rti) == NOTOK)
                   2834:                switch (rta -> rta_reason) {
                   2835:                    case RTS_OPERATION: 
                   2836:                    case RTS_WAITING: 
                   2837:                        rts_waitfor (sd);
                   2838:                        if (RtEndRequest (sd, rti) == OK)
                   2839:                            break;      /* else fall */
                   2840: 
                   2841:                    default: 
                   2842:                        rts_adios (rta, "RT-END.REQUEST");
                   2843:                }
                   2844:     }
                   2845:     else
                   2846:        if (isacs) {
                   2847:            struct AcSAPindication  acis;
                   2848:            register struct AcSAPindication *aci = &acis;
                   2849:            register struct AcSAPabort *aca = &aci -> aci_abort;
                   2850: 
                   2851:            if (AcRelRequest (sd, ACF_NORMAL, NULLPEP, 0, NOTOK, acr, aci)
                   2852:                    == NOTOK)
                   2853:                acs_adios (aca, "A-RELEASE.REQUEST");
                   2854: 
                   2855:            if (!acr -> acr_affirmative) {
                   2856:                (void) AcUAbortRequest (sd, NULLPEP, 0, aci);
                   2857:                adios (NULLCP, "release rejected by peer: %d, %d elements",
                   2858:                            acr -> acr_reason, acr -> acr_ninfo);
                   2859:            }
                   2860:            ACRFREE (acr);
                   2861:        }
                   2862:        else
                   2863:            if (RoEndRequest (sd, ROS_NOPRIO, roi) == NOTOK)
                   2864:                ros_adios (rop, "RO-END.REQUEST");
                   2865: }
                   2866: 
                   2867: /*  */
                   2868: 
                   2869: static int  ros_invokerequest (sd, pe)
                   2870: int    sd;
                   2871: PE     pe;
                   2872: {
                   2873:     int     result;
                   2874:     struct RoSAPindication  rois;
                   2875:     register struct RoSAPindication *roi = &rois;
                   2876:     register struct RoSAPpreject   *rop = &roi -> roi_preject;
                   2877:     static int  id = 0;
                   2878:     static int  op = 0;
                   2879: 
                   2880:     switch (result = RoInvokeRequest (sd, op++, ROS_SYNC, pe, ++id, NULLIP,
                   2881:                ROS_NOPRIO, roi)) {
                   2882:        case NOTOK: 
                   2883:            if (ROS_FATAL (rop -> rop_reason))
                   2884:                ros_adios (rop, "RO-INVOKE.REQUEST");
                   2885:            ros_advise (rop, "RO-INVOKE.REQUEST");
                   2886:            break;
                   2887: 
                   2888:        case OK: 
                   2889:            switch (roi -> roi_type) {
                   2890:                case ROI_INVOKE: 
                   2891:                    adios (NULLCP, "got RO-INVOKE.INDICATION");
                   2892: 
                   2893:                case ROI_RESULT: 
                   2894:                    {
                   2895:                        register struct RoSAPresult *ror = &roi -> roi_result;
                   2896: 
                   2897:                        if (ror -> ror_id != id) {
                   2898:                            advise (NULLCP, "id mismatch (wanted %d, got %d)",
                   2899:                                    id, ror -> ror_id);
                   2900:                            status++;
                   2901:                            if (RoURejectRequest (sd, &ror -> ror_id,
                   2902:                                    ROS_RRP_UNRECOG, ROS_NOPRIO, roi) == NOTOK)
                   2903:                                ros_adios (rop, "RO-REJECT-U.REQUEST");
                   2904:                        }
                   2905:                        else
                   2906:                            if (mode == echo
                   2907:                                    && pe_cmp (pe, ror -> ror_result)) {
                   2908:                                advise (NULLCP, "data mismatch");
                   2909:                                status++;
                   2910:                            }
                   2911: 
                   2912:                        RORFREE (ror);
                   2913:                    }
                   2914:                    break;
                   2915: 
                   2916:                case ROI_ERROR: 
                   2917:                    {
                   2918:                        register struct RoSAPerror *roe = &roi -> roi_error;
                   2919: 
                   2920:                        if (roe -> roe_id != id) {
                   2921:                            advise (NULLCP, "id mismatch (wanted %d, got %d)",
                   2922:                                    id, roe -> roe_id);
                   2923:                            status++;
                   2924:                            if (RoURejectRequest (sd, &roe -> roe_id,
                   2925:                                    ROS_REP_UNRECOG, ROS_NOPRIO, roi) == NOTOK)
                   2926:                                ros_adios (rop, "RO-REJECT-U.REQUEST");
                   2927:                        }
                   2928:                        else
                   2929:                            if (mode == echo
                   2930:                                    && pe_cmp (pe, roe -> roe_param)) {
                   2931:                                advise (NULLCP, "data mismatch");
                   2932:                                status++;
                   2933:                            }
                   2934: 
                   2935:                        ROEFREE (roe);
                   2936:                    }
                   2937:                    break;
                   2938: 
                   2939:                case ROI_UREJECT: 
                   2940:                    {
                   2941:                        register struct RoSAPureject *rou = &roi -> roi_ureject;
                   2942: 
                   2943:                        if (rou -> rou_noid)
                   2944:                            advise (NULLCP, "RO-REJECT-U.INDICATION: %s",
                   2945:                                    RoErrString (rou -> rou_reason));
                   2946:                        else
                   2947:                            advise (NULLCP, "RO-REJECT-U.INDICATION: %s (id=%d)",
                   2948:                                    RoErrString (rou -> rou_reason),
                   2949:                                    rou -> rou_id);
                   2950:                        if (!rou -> rou_noid && rou -> rou_id != id) {
                   2951:                            advise (NULLCP, "id mismatch (wanted %d, got %d)",
                   2952:                                    id, rou -> rou_id);
                   2953:                            status++;
                   2954:                        }
                   2955:                    }
                   2956:                    break;
                   2957: 
                   2958:                default: 
                   2959:                    adios (NULLCP, "unknown indication type=%d",
                   2960:                            roi -> roi_type);
                   2961:            }
                   2962:            if (isrts)
                   2963:                turn = 0;
                   2964:            break;
                   2965: 
                   2966:        case DONE: 
                   2967:            adios (NULLCP, "got RO-END.INDICATION");
                   2968: 
                   2969:        default: 
                   2970:            adios (NULLCP, "unknown return from RoInvokeRequest=%d", result);
                   2971:     }
                   2972: }
                   2973: 
                   2974: 
                   2975: /*  */
                   2976: 
                   2977: static void  ros_adios (rop, event)
                   2978: register struct RoSAPpreject *rop;
                   2979: char   *event;
                   2980: {
                   2981:     ros_advise (rop, event);
                   2982: 
                   2983:     _exit (1);
                   2984: }
                   2985: 
                   2986: 
                   2987: static void  ros_advise (rop, event)
                   2988: register struct RoSAPpreject *rop;
                   2989: char   *event;
                   2990: {
                   2991:     char    buffer[BUFSIZ];
                   2992: 
                   2993:     if (rop -> rop_cc > 0)
                   2994:        (void) sprintf (buffer, "[%s] %*.*s", RoErrString (rop -> rop_reason),
                   2995:                rop -> rop_cc, rop -> rop_cc, rop -> rop_data);
                   2996:     else
                   2997:        (void) sprintf (buffer, "[%s]", RoErrString (rop -> rop_reason));
                   2998: 
                   2999:     advise (NULLCP, "%s: %s", event, buffer);
                   3000: }
                   3001: 
                   3002: /*    TIMER */
                   3003: 
                   3004: #ifdef TIMER
                   3005: 
                   3006: #ifndef        NBBY
                   3007: #define        NBBY    8
                   3008: #endif
                   3009: 
                   3010: 
                   3011: #ifndef        TMS
                   3012: static  timer (cc)
                   3013: int     cc;
                   3014: {
                   3015:     int     bytes;
                   3016:     long    ms;
                   3017:     float   bs;
                   3018:     struct timeval  stop,
                   3019:                     td;
                   3020:     static struct timeval   start;
                   3021: 
                   3022:     if (cc == 0) {
                   3023:        (void) gettimeofday (&start, (struct timezone *) 0);
                   3024:        return;
                   3025:     }
                   3026:     else
                   3027:        (void) gettimeofday (&stop, (struct timezone  *) 0);
                   3028: 
                   3029:     tvsub (&td, &stop, &start);
                   3030:     ms = (td.tv_sec * 1000) + (td.tv_usec / 1000);
                   3031:     bytes = mode == echo ? cc * 2 : cc;
                   3032:     bs = (((float) bytes * NBBY * 1000) / (float) (ms ? ms : 1)) / NBBY;
                   3033: 
                   3034:     advise (NULLCP, "%d bytes %s in %d.%02d seconds (%.2f Kbytes/s)",
                   3035:            cc, mode == echo ? "echoed" : "sunk",
                   3036:            td.tv_sec, td.tv_usec / 10000, bs / 1024);
                   3037: }
                   3038: 
                   3039: 
                   3040: static  tvsub (tdiff, t1, t0)
                   3041: register struct timeval *tdiff,
                   3042:                        *t1,
                   3043:                        *t0;
                   3044: {
                   3045: 
                   3046:     tdiff -> tv_sec = t1 -> tv_sec - t0 -> tv_sec;
                   3047:     tdiff -> tv_usec = t1 -> tv_usec - t0 -> tv_usec;
                   3048:     if (tdiff -> tv_usec < 0)
                   3049:        tdiff -> tv_sec--, tdiff -> tv_usec += 1000000;
                   3050: }
                   3051: #else
                   3052: long   times ();
                   3053: 
                   3054: 
                   3055: static timer (cc)
                   3056: int    cc;
                   3057: {
                   3058:     int            bytes;
                   3059:     long    ms;
                   3060:     float   bs;
                   3061:     long    stop,
                   3062:            td,
                   3063:            secs,
                   3064:            msecs;
                   3065:     struct tms tm;
                   3066:     static long start;
                   3067: 
                   3068:     if (cc == 0) {
                   3069:        start = times (&tm);
                   3070:        return;
                   3071:     }
                   3072:     else
                   3073:        stop = times (&tm);
                   3074: 
                   3075:     td = stop - start;
                   3076:     secs = td / 60, msecs = (td % 60) * 1000 / 60;
                   3077:     ms = (secs * 1000) +  msecs;
                   3078:     bytes = mode == echo ? cc * 2 : cc;
                   3079:     bs = (((float) bytes * NBBY * 1000) / (float) (ms ? ms : 1)) / NBBY;
                   3080:     
                   3081:     advise (NULLCP, "%d bytes %s in %d.%02d seconds (%.2f KBytes/s)",
                   3082:            cc, mode == echo ? "echoed" : "sunk",
                   3083:            secs, msecs / 10, bs / 1024);
                   3084: }
                   3085: #endif
                   3086: #endif
                   3087: 
                   3088: /*    QBUF */
                   3089: 
                   3090: static int  qcmp (b, qb, l)
                   3091: register char *b;
                   3092: register struct qbuf *qb;
                   3093: register int l;
                   3094: {
                   3095:     register struct qbuf   *qp;
                   3096: 
                   3097:     for (qp = qb -> qb_forw; qp != qb; qp = qp -> qb_forw) {
                   3098:        if ((l -= qp -> qb_len) < 0) {
                   3099:            advise (NULLCP, "length mismatch(1)");
                   3100:            return NOTOK;
                   3101:        }
                   3102: 
                   3103:        if (bcmp (b, qp -> qb_data, qp -> qb_len)) {
                   3104:            advise (NULLCP, "data mismatch");
                   3105:            return NOTOK;
                   3106:        }
                   3107: 
                   3108:        b += qp -> qb_len;
                   3109:     }
                   3110: 
                   3111:     if (l != 0) {
                   3112:        advise (NULLCP, "length mismatch(2)");
                   3113:        return NOTOK;
                   3114:     }
                   3115: 
                   3116:     return OK;
                   3117: }
                   3118: 
                   3119: /*    ERRORS */
                   3120: 
                   3121: #ifndef        lint
                   3122: void   _advise ();
                   3123: 
                   3124: 
                   3125: void   adios (va_alist)
                   3126: va_dcl
                   3127: {
                   3128:     va_list ap;
                   3129: 
                   3130:     va_start (ap);
                   3131: 
                   3132:     _advise (ap);
                   3133: 
                   3134:     va_end (ap);
                   3135: 
                   3136:     _exit (1);
                   3137: }
                   3138: #else
                   3139: /* VARARGS */
                   3140: 
                   3141: void   adios (what, fmt)
                   3142: char   *what,
                   3143:        *fmt;
                   3144: {
                   3145:     adios (what, fmt);
                   3146: }
                   3147: #endif
                   3148: 
                   3149: 
                   3150: #ifndef        lint
                   3151: void   advise (va_alist)
                   3152: va_dcl
                   3153: {
                   3154:     va_list ap;
                   3155: 
                   3156:     va_start (ap);
                   3157: 
                   3158:     _advise (ap);
                   3159: 
                   3160:     va_end (ap);
                   3161: }
                   3162: 
                   3163: 
                   3164: static void  _advise (ap)
                   3165: va_list        ap;
                   3166: {
                   3167:     char    buffer[BUFSIZ];
                   3168: 
                   3169:     asprintf (buffer, ap);
                   3170: 
                   3171:     (void) fflush (stdout);
                   3172: 
                   3173:     fprintf (stderr, "%s: ", myname);
                   3174:     (void) fputs (buffer, stderr);
                   3175:     (void) fputc ('\n', stderr);
                   3176: 
                   3177:     (void) fflush (stderr);
                   3178: }
                   3179: #else
                   3180: /* VARARGS */
                   3181: 
                   3182: void   advise (what, fmt)
                   3183: char   *what,
                   3184:        *fmt;
                   3185: {
                   3186:     advise (what, fmt);
                   3187: }
                   3188: #endif

unix.superglobalmegacorp.com

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