Annotation of 43BSDReno/contrib/isode-beta/rosap/test/ssapinitiate.c, revision 1.1.1.1

1.1       root        1: /* ssapinitiate.c - SPM: initiator */
                      2: 
                      3: #ifndef        lint
                      4: static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapinitiate.c,v 7.1 89/11/27 10:30:40 mrose Exp $";
                      5: #endif
                      6: 
                      7: /* 
                      8:  * $Header: /f/osi/ssap/RCS/ssapinitiate.c,v 7.1 89/11/27 10:30:40 mrose Exp $
                      9:  *
                     10:  *
                     11:  * $Log:       ssapinitiate.c,v $
                     12:  * Revision 7.1  89/11/27  10:30:40  mrose
                     13:  * sync
                     14:  * 
                     15:  * Revision 7.0  89/11/23  22:25:27  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: /* LINTLIBRARY */
                     32: 
                     33: #include <stdio.h>
                     34: #include <signal.h>
                     35: #include "spkt.h"
                     36: #include "tailor.h"
                     37: 
                     38: /*    S-(ASYN-)CONNECT.REQUEST */
                     39: 
                     40: #define        dotoken(requires,shift,bit,type) \
                     41: { \
                     42:     if (requirements & requires) \
                     43:        switch (settings & (ST_MASK << shift)) { \
                     44:            case ST_INIT_VALUE << shift: \
                     45:            case ST_RESP_VALUE << shift: \
                     46:            case ST_CALL_VALUE << shift: \
                     47:                break; \
                     48:  \
                     49:            default: \
                     50:                return ssaplose (si, SC_PARAMETER, NULLCP, \
                     51:                        "improper choice of %s token setting", type); \
                     52:        } \
                     53: }
                     54: 
                     55: /*  */
                     56: 
                     57: int    SAsynConnRequest (ref, calling, called, requirements, settings, isn,
                     58:        data, cc, qos, sc, si, async)
                     59: struct SSAPref *ref;
                     60: struct SSAPaddr *calling,
                     61:                *called;
                     62: int    requirements,
                     63:        settings,
                     64:        cc,
                     65:        async;
                     66: long   isn;
                     67: char   *data;
                     68: struct QOStype *qos;
                     69: struct SSAPconnect *sc;
                     70: struct SSAPindication *si;
                     71: {
                     72:     SBV     smask;
                     73:     int     result;
                     74: 
                     75:     isodetailor (NULLCP, 0);
                     76: 
                     77:     missingP (ref);
                     78:     refmuchP (ref);
                     79:     if (ref -> sr_vlen)
                     80:        return ssaplose (si, SC_PARAMETER, NULLCP, "bad format for reference");
                     81: #ifdef notdef
                     82:     missingP (calling);
                     83: #endif
                     84:     missingP (called);
                     85: 
                     86:     if (requirements & ~SR_MYREQUIRE)
                     87:        return ssaplose (si, SC_PARAMETER, NULLCP,
                     88:                "requirements settings not supported");
                     89:     if ((requirements & SR_EXCEPTIONS)
                     90:            && !(requirements & SR_HALFDUPLEX))
                     91:        return ssaplose (si, SC_PARAMETER, NULLCP,
                     92:                "exception service requires half-duplex service");
                     93: 
                     94:     dotokens ();
                     95: 
                     96:     if (requirements & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC)) {
                     97:        if (!(requirements & SR_ACTIVITY) || isn != SERIAL_NONE)
                     98:            if (SERIAL_MIN > isn || isn > SERIAL_MAX + 1)
                     99:                return ssaplose (si, SC_PARAMETER, NULLCP,
                    100:                        "bad choice for initial serial number");
                    101:     }
                    102:     else
                    103:        if (isn != SERIAL_NONE)
                    104:            return ssaplose (si, SC_PARAMETER, NULLCP,
                    105:                    "initial serial number invalid given requirements");
                    106: 
                    107:     if (data == NULL)
                    108:        cc = 0;
                    109:     else
                    110:        if (cc > CONNECT_MAX)
                    111:            return ssaplose (si, SC_PARAMETER, NULLCP,
                    112:                             "too much initial user data, %d octets", cc);
                    113: 
                    114: #ifdef notdef
                    115:     missingP (qos);
                    116: #endif
                    117:     missingP (sc);
                    118:     missingP (si);
                    119: 
                    120:     smask = sigioblock ();
                    121: 
                    122:     result = SConnRequestAux (ref, calling, called, requirements, settings,
                    123:            isn, data, cc, qos, sc, si, async);
                    124: 
                    125:     (void) sigiomask (smask);
                    126: 
                    127:     return result;
                    128: }
                    129: 
                    130: #undef dotoken
                    131: 
                    132: /*  */
                    133: 
                    134: static int  SConnRequestAux (ref, calling, called, requirements, settings, isn,
                    135:            data, cc, qos, sc, si, async)
                    136: struct SSAPref *ref;
                    137: struct SSAPaddr *calling,
                    138:                *called;
                    139: int    requirements,
                    140:        settings,
                    141:        cc,
                    142:        async;
                    143: long   isn;
                    144: char   *data;
                    145: struct QOStype *qos;
                    146: struct SSAPconnect *sc;
                    147: struct SSAPindication *si;
                    148: {
                    149:     int     result;
                    150:     register struct ssapkt *s;
                    151:     register struct ssapblk *sb;
                    152:     struct TSAPconnect  tcs;
                    153:     register struct TSAPconnect *tc = &tcs;
                    154:     struct TSAPdisconnect   tds;
                    155:     register struct TSAPdisconnect *td = &tds;
                    156: 
                    157:     if ((sb = newsblk ()) == NULL)
                    158:        return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
                    159:     if (!async || qos == NULLQOS || qos -> qos_maxtime <= 0)
                    160:        sb -> sb_maxtime = NOTOK;
                    161:     else
                    162:        sb -> sb_maxtime = qos -> qos_maxtime;
                    163: 
                    164:     if ((s = newspkt (SPDU_CN)) == NULL) {
                    165:        (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
                    166:        goto out1;
                    167:     }
                    168: 
                    169:     if (called -> sa_selectlen > 0) {
                    170:        if (calling == NULLSA) {
                    171:            static struct SSAPaddr sas;
                    172: 
                    173:            calling = &sas;
                    174:            bzero ((char *) calling, sizeof *calling);
                    175:        }
                    176: 
                    177:        if (calling -> sa_selectlen == 0) {
                    178:            calling -> sa_port =
                    179:                            htons ((u_short) (0x8000 | (getpid () & 0x7fff)));
                    180:            calling -> sa_selectlen = sizeof calling -> sa_port;
                    181:        }
                    182:     }
                    183: 
                    184:     if (calling) {
                    185:        if (calling -> sa_selectlen > 0) {
                    186:            s -> s_mask |= SMASK_CN_CALLING;
                    187:            bcopy (calling -> sa_selector, s -> s_calling,
                    188:                s -> s_callinglen = calling -> sa_selectlen);
                    189:        }
                    190:        sb -> sb_initiating = *calling; /* struct copy */
                    191:     }
                    192: 
                    193:     if (called -> sa_selectlen > 0) {
                    194:        s -> s_mask |= SMASK_CN_CALLED;
                    195:        bcopy (called -> sa_selector, s -> s_called,
                    196:                s -> s_calledlen = called -> sa_selectlen);
                    197:     }
                    198:     sb -> sb_responding = *called;     /* struct copy */
                    199: 
                    200:     sb -> sb_requirements = requirements;
                    201:     sb -> sb_settings = settings;
                    202: 
                    203:     if ((result = TAsynConnRequest (calling ? &calling -> sa_addr : NULLTA,
                    204:                &called -> sa_addr,
                    205:                (qos ? qos -> qos_extended : 0)
                    206:                        || ((requirements & SR_EXPEDITED) ? 1 : 0),
                    207:                NULLCP, 0, qos, tc, td, async)) == NOTOK) {
                    208:        (void) ts2sslose (si, "TAsynConnRequest", td);
                    209: 
                    210:        bzero ((char *) sc, sizeof *sc);
                    211:        sc -> sc_sd = NOTOK;
                    212:        sc -> sc_result = si -> si_abort.sa_reason;
                    213: 
                    214:        result = DONE;
                    215:        goto out2;
                    216:     }
                    217: 
                    218:     sb -> sb_fd = tc -> tc_sd;
                    219:     if (qos && qos -> qos_sversion < 0) {
                    220:        sb -> sb_version = SB_VRSN1;
                    221:        sb -> sb_vrsnmask = SB_ALLVRSNS;
                    222:     }
                    223:     else
                    224:        sb -> sb_vrsnmask = 1 << (sb -> sb_version =
                    225:                                    (cc > SS_SIZE
                    226:                                           || (qos && qos -> qos_sversion > 1))
                    227:                                       ? SB_VRSN2 : SB_VRSN1);
                    228: 
                    229:     s -> s_mask |= SMASK_CN_REF | SMASK_CN_OPT | SMASK_CN_VRSN;
                    230:     s -> s_cn_reference = *ref;        /* struct copy */
                    231:     s -> s_options = CR_OPT_NULL;
                    232:     s -> s_cn_version = sb -> sb_vrsnmask;
                    233: 
                    234:     if (isn != SERIAL_NONE) {
                    235:        s -> s_mask |= SMASK_CN_ISN;
                    236:        s -> s_isn = isn;
                    237:     }
                    238: 
                    239:     if (cc > 0) {              /* XXX: user musn't touch! */
                    240:        s -> s_mask |= SMASK_UDATA_PGI;
                    241:        s -> s_udata = data, s -> s_ulen = cc;
                    242:     }
                    243:     else
                    244:        s -> s_udata = NULL, s -> s_ulen = 0;
                    245: 
                    246:     sb -> sb_retry = s;
                    247:     if (async) {
                    248:        switch (result) {
                    249:        case CONNECTING_1:
                    250:        case CONNECTING_2:
                    251:            sc -> sc_sd = sb -> sb_fd;
                    252:            return result;
                    253:        }
                    254:     }
                    255:     if ((result = SAsynRetryAux (sb, tc, sc, si)) == DONE && !async)
                    256:        result = OK;
                    257:     return result;
                    258: 
                    259: out2: ;
                    260:     freespkt (s);
                    261: out1: ;
                    262:     freesblk (sb);
                    263: 
                    264:     return result;
                    265: }
                    266: 
                    267: /*    S-ASYN-RETRY.REQUEST (pseudo) */
                    268: 
                    269: int    SAsynRetryRequest (sd, sc, si)
                    270: int    sd;
                    271: struct SSAPconnect *sc;
                    272: struct SSAPindication *si;
                    273: {
                    274:     SBV     smask;
                    275:     int     result;
                    276:     register struct ssapblk *sb;
                    277:     struct TSAPconnect  tcs;
                    278:     register struct TSAPconnect *tc = &tcs;
                    279:     struct TSAPdisconnect   tds;
                    280:     register struct TSAPdisconnect *td = &tds;
                    281: 
                    282:     missingP (sc);
                    283:     missingP (si);
                    284: 
                    285:     smask = sigioblock ();
                    286: 
                    287:     if ((sb = findsblk (sd)) == NULL) {
                    288:        (void) sigiomask (smask);
                    289:        return ssaplose (si, SC_PARAMETER, NULLCP,
                    290:                "invalid session descriptor");
                    291:     }
                    292:     if (sb -> sb_flags & SB_CONN) {
                    293:        (void) sigiomask (smask);
                    294:        return ssaplose (si, SC_OPERATION, NULLCP,
                    295:                "session descriptor connected");
                    296:     }
                    297: 
                    298:     switch (result = TAsynRetryRequest (sb -> sb_fd, tc, td)) {
                    299:        case NOTOK: 
                    300:            (void) ts2sslose (si, "TAsynRetryRequest", td);
                    301:            sb -> sb_fd = NOTOK;
                    302: 
                    303:            bzero ((char *) sc, sizeof *sc);
                    304:            sc -> sc_sd = NOTOK;
                    305:            sc -> sc_result = si -> si_abort.sa_reason;
                    306: 
                    307:            result = DONE;
                    308:            freesblk (sb);
                    309:            break;
                    310: 
                    311:        case CONNECTING_1:
                    312:        case CONNECTING_2:
                    313:            break;
                    314: 
                    315:        case DONE: 
                    316:            result = SAsynRetryAux (sb, tc, sc, si);
                    317:            break;
                    318:     }
                    319: 
                    320:     (void) sigiomask (smask);
                    321: 
                    322:     return result;
                    323: }
                    324: 
                    325: /*    S-ASYN-NEXT.REQUEST (pseudo) */
                    326: 
                    327: int    SAsynNextRequest (sd, sc, si)
                    328: int    sd;
                    329: struct SSAPconnect *sc;
                    330: struct SSAPindication *si;
                    331: {
                    332:     SBV     smask;
                    333:     int     result;
                    334:     register struct ssapblk *sb;
                    335:     struct TSAPconnect  tcs;
                    336:     register struct TSAPconnect *tc = &tcs;
                    337:     struct TSAPdisconnect   tds;
                    338:     register struct TSAPdisconnect *td = &tds;
                    339: 
                    340:     missingP (sc);
                    341:     missingP (si);
                    342: 
                    343:     smask = sigioblock ();
                    344: 
                    345:     if ((sb = findsblk (sd)) == NULL) {
                    346:        (void) sigiomask (smask);
                    347:        return ssaplose (si, SC_PARAMETER, NULLCP,
                    348:                "invalid session descriptor");
                    349:     }
                    350:     if (sb -> sb_flags & SB_CONN) {
                    351:        (void) sigiomask (smask);
                    352:        return ssaplose (si, SC_OPERATION, NULLCP,
                    353:                "session descriptor connected");
                    354:     }
                    355: 
                    356:     switch (result = TAsynNextRequest (sb -> sb_fd, tc, td)) {
                    357:        case NOTOK: 
                    358:            (void) ts2sslose (si, "TAsynRetryRequest", td);
                    359:            sb -> sb_fd = NOTOK;
                    360: 
                    361:            bzero ((char *) sc, sizeof *sc);
                    362:            sc -> sc_sd = NOTOK;
                    363:            sc -> sc_result = si -> si_abort.sa_reason;
                    364: 
                    365:            result = DONE;
                    366:            freesblk (sb);
                    367:            break;
                    368: 
                    369:        case CONNECTING_1:
                    370:        case CONNECTING_2:
                    371:            break;
                    372: 
                    373:        case DONE: 
                    374:            result = SAsynRetryAux (sb, tc, sc, si);
                    375:            break;
                    376:     }
                    377: 
                    378:     (void) sigiomask (smask);
                    379: 
                    380:     return result;
                    381: }
                    382: 
                    383: /*  */
                    384: 
                    385: #define        dotoken(requires,shift,bit,type) \
                    386: { \
                    387:     if (sb -> sb_requirements & requires) { \
                    388:        switch (sb -> sb_settings & (ST_MASK << shift)) { \
                    389:            case ST_CALL_VALUE << shift: \
                    390:                if (!(s -> s_mask & SMASK_CN_SET)) \
                    391:                    s -> s_settings = ST_INIT_VALUE << shift; \
                    392:                switch (s -> s_settings & (ST_MASK << shift)) { \
                    393:                    case ST_INIT_VALUE << shift: \
                    394:                    default: \
                    395:                        sb -> sb_owned |= bit; \
                    396:                        sc -> sc_settings |= ST_INIT_VALUE << shift; \
                    397:                        break; \
                    398:  \
                    399:                    case ST_RESP_VALUE << shift: \
                    400:                        sc -> sc_settings |= ST_RESP_VALUE << shift; \
                    401:                        break; \
                    402:                } \
                    403:                break; \
                    404:  \
                    405:            case ST_INIT_VALUE << shift: \
                    406:                sb -> sb_owned |= bit; \
                    407:                sc -> sc_settings |= ST_INIT_VALUE << shift; \
                    408:                break; \
                    409:  \
                    410:            case ST_RESP_VALUE << shift: \
                    411:                sc -> sc_settings |= ST_RESP_VALUE << shift; \
                    412:                break; \
                    413:        } \
                    414:  \
                    415:        if ((s -> s_mask & SMASK_AC_TOKEN) && (s -> s_ac_token & bit)) \
                    416:            sc -> sc_please |= bit; \
                    417:     } \
                    418: }
                    419: 
                    420: /*  */
                    421: 
                    422: static int  SAsynRetryAux (sb, tc, sc, si)
                    423: register struct ssapblk *sb;
                    424: struct TSAPconnect *tc;
                    425: struct SSAPconnect *sc;
                    426: struct SSAPindication *si;
                    427: {
                    428:     int            len,
                    429:            result;
                    430:     register struct ssapkt *s;
                    431: 
                    432:     s = sb -> sb_retry;
                    433:     sb -> sb_retry = NULL;
                    434: 
                    435:     sb -> sb_responding.sa_addr = tc -> tc_responding; /* struct copy */
                    436:     if (tc -> tc_expedited)
                    437:        sb -> sb_flags |= SB_EXPD;
                    438:     else
                    439:        sb -> sb_requirements &= ~SR_EXPEDITED;
                    440:     if (sb -> sb_version < SB_VRSN2)           /* XXX */
                    441:        sb -> sb_tsdu_us = sb -> sb_tsdu_them =
                    442:                                            GET_TSDU_SIZE (tc -> tc_tsdusize);
                    443: 
                    444:     if (sb -> sb_tsdu_us || sb -> sb_tsdu_them) {
                    445:        s -> s_mask |= SMASK_CN_TSDU;
                    446:        s -> s_tsdu_resp = GET_TSDU_SIZE (sb -> sb_tsdu_us);
                    447:        s -> s_tsdu_init = GET_TSDU_SIZE (sb -> sb_tsdu_them);
                    448:     }
                    449: 
                    450:     s -> s_mask |= SMASK_CN_REQ;
                    451:     if ((s -> s_cn_require = sb -> sb_requirements) & SR_TOKENS) {
                    452:        s -> s_mask |= SMASK_CN_SET;
                    453:        s -> s_settings = sb -> sb_settings;
                    454:     }
                    455: 
                    456:     result = spkt2sd (s, sb -> sb_fd, 0, si);
                    457:     s -> s_mask &= ~SMASK_UDATA_PGI;
                    458:     s -> s_udata = NULL, s -> s_ulen = 0;
                    459: 
                    460:     freespkt (s);
                    461:     if (result == NOTOK)
                    462:        goto out1;
                    463: 
                    464:     if ((s = sb2spkt (sb, si, sb -> sb_maxtime, NULLTX)) == NULL) {
                    465:        if (si -> si_abort.sa_reason == SC_TIMER)
                    466:            (void) ssaplose (si, SC_CONGEST, NULLCP, "remote SPM timed-out");
                    467:        result = NOTOK;
                    468:        goto out2;
                    469:     }
                    470: 
                    471:     bzero ((char *) sc, sizeof *sc);
                    472:     switch (s -> s_code) {
                    473:        case SPDU_AC: 
                    474:            sc -> sc_sd = sb -> sb_fd;
                    475:            sc -> sc_result = SC_ACCEPT;
                    476:            if (s -> s_mask & SMASK_CN_REF)
                    477:                sc -> sc_connect = s -> s_cn_reference; /* struct copy */
                    478:            if (s -> s_mask & SMASK_CN_OPT)
                    479:                sb -> sb_options = s -> s_options;
                    480:            if (!(s -> s_mask & SMASK_CN_TSDU))
                    481:                s -> s_tsdu_init = s -> s_tsdu_resp = 0;
                    482:            if (s -> s_tsdu_init < sb -> sb_tsdu_us)
                    483:                sb -> sb_tsdu_us = s -> s_tsdu_init;
                    484:            if (s -> s_tsdu_resp < sb -> sb_tsdu_them)
                    485:                sb -> sb_tsdu_them = s -> s_tsdu_resp;
                    486:            if (BAD_TSDU_SIZE (sb -> sb_tsdu_us)) {
                    487:                result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
                    488:                        "perposterous TSDU size (%d) for initiator",
                    489:                        sb -> sb_tsdu_us);
                    490:                goto out2;
                    491:            }
                    492:            if (BAD_TSDU_SIZE (sb -> sb_tsdu_them)) {
                    493:                result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
                    494:                        "perposterous TSDU size (%d) for responder",
                    495:                        sb -> sb_tsdu_them);
                    496:                goto out2;
                    497:            }
                    498:            if (s -> s_mask & SMASK_CN_VRSN) {
                    499:                if (!(s -> s_cn_version & sb -> sb_vrsnmask)) {
                    500:                                                        /* not SC_VERSION */
                    501:                    result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
                    502:                     "version mismatch: expecting something in 0x%x, got 0x%x",
                    503:                                       sb -> sb_vrsnmask, s -> s_cn_version);
                    504:                    goto out2;
                    505:                }
                    506:                sb -> sb_vrsnmask &= s -> s_cn_version;
                    507:            }
                    508:            sb -> sb_version = (sb -> sb_vrsnmask & (1 << SB_VRSN2))
                    509:                                        ? SB_VRSN2 : SB_VRSN1;
                    510:            if (s -> s_mask & SMASK_CN_ISN)
                    511:                sc -> sc_isn = sb -> sb_V_A = sb -> sb_V_M = s -> s_isn;
                    512:            else
                    513:                sc -> sc_isn = SERIAL_NONE;
                    514:            if (!(s -> s_mask & SMASK_CN_REQ)) {
                    515:                s -> s_mask |= SMASK_CN_REQ;
                    516:                s -> s_cn_require = SR_DEFAULT;
                    517:            }
                    518:            switch (sb -> sb_requirements & (SR_HALFDUPLEX | SR_DUPLEX)) {
                    519:                case SR_HALFDUPLEX: 
                    520:                    if (s -> s_cn_require & SR_HALFDUPLEX)
                    521:                        break;
                    522:                    result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
                    523:                            "half-duplex negotiation failed");
                    524:                    goto out2;
                    525: 
                    526:                case SR_DUPLEX: 
                    527:                    if (s -> s_cn_require & SR_DUPLEX)
                    528:                        break;
                    529:                    result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
                    530:                            "full-duplex negotiation failed");
                    531:                    goto out2;
                    532: 
                    533:                default: 
                    534:                    break;
                    535:            }
                    536: #ifdef notdef          /* screwy session protocol... */
                    537:            if (s -> s_cn_require & ~sb -> sb_requirements) {
                    538:                result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
                    539:                            "requirements negotiation failed");
                    540:                goto out2;
                    541:            }
                    542: #endif
                    543:            sb -> sb_requirements &= s -> s_cn_require;
                    544:            switch (sb -> sb_requirements & (SR_HALFDUPLEX | SR_DUPLEX)) {
                    545:                case SR_HALFDUPLEX: 
                    546:                case SR_DUPLEX: 
                    547:                    break;
                    548: 
                    549:                default: 
                    550:                    result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
                    551:                            "half/full-duplex negotiation failed");
                    552:                    goto out2;
                    553:            }
                    554:            if ((sb -> sb_requirements & SR_EXCEPTIONS)
                    555:                    && !(sb -> sb_requirements & SR_HALFDUPLEX)) {
                    556:                result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
                    557:                        "exception service requires half-duplex service");
                    558:                goto out2;
                    559:            }
                    560:            sc -> sc_requirements = sb -> sb_requirements;
                    561:            sc -> sc_settings = sc -> sc_please = 0;
                    562:            dotokens ();
                    563:            if (s -> s_mask & SMASK_CN_CALLED) {
                    564:                if ((len = s -> s_calledlen)
                    565:                        > sizeof sb -> sb_responding.sa_selector)
                    566:                    len = sizeof sb -> sb_responding.sa_selector;
                    567:                bcopy (s -> s_called, sb -> sb_responding.sa_selector,
                    568:                        sb -> sb_responding.sa_selectlen = len);
                    569:            }
                    570:            sc -> sc_responding = sb -> sb_responding;  /* struct copy */
                    571:            if ((sc -> sc_ssdusize = sb -> sb_tsdu_us - SSDU_MAGIC) < 0)
                    572:                sc -> sc_ssdusize = tc -> tc_tsdusize - SSDU_MAGIC;
                    573:            sc -> sc_qos = tc -> tc_qos;        /* struct copy */
                    574:            sc -> sc_qos.qos_sversion = sb -> sb_version + 1;
                    575:            sc -> sc_qos.qos_extended = (sb -> sb_flags & SB_EXPD) ? 1 : 0;
                    576:            copySPKTdata (s, sc);
                    577: 
                    578:            freespkt (s);
                    579:            sb -> sb_flags |= SB_CONN | SB_INIT;
                    580: 
                    581:            return DONE;
                    582: 
                    583:        case SPDU_RF:           /* ignore s -> s_rf_disconnect */
                    584:            sc -> sc_sd = NOTOK;
                    585:            sc -> sc_result = s -> s_rlen > 0 ? *s -> s_rdata
                    586:                : SC_NOTSPECIFIED;
                    587:            if (s -> s_mask & SMASK_RF_REF)
                    588:                sc -> sc_connect = s -> s_rf_reference; /* struct copy */
                    589:            if ((sc -> sc_result == SC_REJECTED)
                    590:                    && (s -> s_mask & SMASK_RF_REQ))
                    591:                sc -> sc_requirements = s -> s_rf_require;
                    592:            if ((s -> s_mask & SMASK_CN_CALLED)
                    593:                    && (sc -> sc_result & SC_BASE)) {
                    594:                if ((len = s -> s_calledlen)
                    595:                        > sizeof sb -> sb_responding.sa_selector)
                    596:                    len = sizeof sb -> sb_responding.sa_selector;
                    597:                bcopy (s -> s_called, sb -> sb_responding.sa_selector,
                    598:                        sb -> sb_responding.sa_selectlen = len);
                    599:            }
                    600:            sc -> sc_responding = sb -> sb_responding;  /* struct copy */
                    601:            sc -> sc_data = s -> s_rdata + 1, sc -> sc_cc = s -> s_rlen - 1;
                    602:            sc -> sc_realdata = s -> s_rdata, s -> s_rdata = NULL;
                    603:            si -> si_type = SI_ABORT;
                    604:            {
                    605:                register struct SSAPabort  *sa = &si -> si_abort;
                    606: 
                    607:                sa -> sa_peer = 0;
                    608:                sa -> sa_reason = sc -> sc_result;
                    609:                sa -> sa_info = sc -> sc_data, sa -> sa_cc = sc -> sc_cc;
                    610:                sa -> sa_realinfo = NULL;
                    611:            }
                    612:            result = DONE;
                    613:            break;
                    614: 
                    615:        case SPDU_AB: 
                    616:            sc -> sc_sd = NOTOK;
                    617:            sc -> sc_result = SC_ABORT;
                    618:            si -> si_type = SI_ABORT;
                    619:            {
                    620:                register struct SSAPabort  *sa = &si -> si_abort;
                    621: 
                    622:                if (!(sa -> sa_peer = (s -> s_ab_disconnect & AB_DISC_USER)
                    623:                            ? 1 : 0))
                    624:                    sa -> sa_reason = sc -> sc_result;
                    625:                sa -> sa_info = s -> s_udata, sa -> sa_cc = s -> s_ulen;
                    626:                sa -> sa_realinfo = s -> s_udata, s -> s_udata = NULL;
                    627:            }
                    628:            result = DONE;
                    629:            break;
                    630: 
                    631:        default: 
                    632:            result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
                    633:                    "session protocol mangled: expecting 0x%x, got 0x%x",
                    634:                    SPDU_AC, s -> s_code);
                    635:            break;
                    636:     }
                    637: 
                    638: out2: ;
                    639:     freespkt (s);
                    640: out1: ;
                    641:     freesblk (sb);
                    642: 
                    643:     return result;
                    644: }
                    645: 
                    646: #undef dotoken

unix.superglobalmegacorp.com

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