Annotation of 43BSDReno/contrib/isode-beta/psap2/psaprovider.c, revision 1.1.1.1

1.1       root        1: /* psaprovider.c - implement the presentation protocol */
                      2: 
                      3: #ifndef        lint
                      4: static char *rcsid = "$Header: /f/osi/psap2/RCS/psaprovider.c,v 7.3 90/07/01 21:05:11 mrose Exp $";
                      5: #endif
                      6: 
                      7: /* 
                      8:  * $Header: /f/osi/psap2/RCS/psaprovider.c,v 7.3 90/07/01 21:05:11 mrose Exp $
                      9:  *
                     10:  *
                     11:  * $Log:       psaprovider.c,v $
                     12:  * Revision 7.3  90/07/01  21:05:11  mrose
                     13:  * pepsy
                     14:  * 
                     15:  * Revision 7.2  90/03/23  17:27:48  mrose
                     16:  * update
                     17:  * 
                     18:  * Revision 7.1  89/11/24  16:22:20  mrose
                     19:  * sync
                     20:  * 
                     21:  * Revision 7.0  89/11/23  22:14:33  mrose
                     22:  * Release 6.0
                     23:  * 
                     24:  */
                     25: 
                     26: /*
                     27:  *                               NOTICE
                     28:  *
                     29:  *    Acquisition, use, and distribution of this module and related
                     30:  *    materials are subject to the restrictions of a license agreement.
                     31:  *    Consult the Preface in the User's Manual for the full terms of
                     32:  *    this agreement.
                     33:  *
                     34:  */
                     35: 
                     36: 
                     37: /* LINTLIBRARY */
                     38: 
                     39: #include <stdio.h>
                     40: #include <signal.h>
                     41: #include "PS-types.h"
                     42: #include "ppkt.h"
                     43: #include "tailor.h"
                     44: 
                     45: /*    DATA */
                     46: 
                     47: static int  once_only = 0;
                     48: static struct psapblk psapque;
                     49: static struct psapblk *PHead = &psapque;
                     50: 
                     51: 
                     52: struct pair preq_pairs[] = {
                     53:     PR_MANAGEMENT, bit_PS_Presentation__requirements_context__management,
                     54:     PR_RESTORATION, bit_PS_Presentation__requirements_restoration,
                     55:     0, 0
                     56: };
                     57: 
                     58: 
                     59: struct pair sreq_pairs[] = {
                     60:     SR_HALFDUPLEX, bit_PS_User__session__requirements_half__duplex,
                     61:     SR_DUPLEX, bit_PS_User__session__requirements_duplex,
                     62:     SR_EXPEDITED, bit_PS_User__session__requirements_expedited__data,
                     63:     SR_MINORSYNC, bit_PS_User__session__requirements_minor__synchronize,
                     64:     SR_MAJORSYNC, bit_PS_User__session__requirements_major__synchronize,
                     65:     SR_RESYNC, bit_PS_User__session__requirements_resynchronize,
                     66:     SR_ACTIVITY, bit_PS_User__session__requirements_activity__management,
                     67:     SR_NEGOTIATED, bit_PS_User__session__requirements_negotiated__release,
                     68:     SR_CAPABILITY, bit_PS_User__session__requirements_capability__data,
                     69:     SR_EXCEPTIONS, bit_PS_User__session__requirements_exceptions,
                     70:     SR_TYPEDATA, bit_PS_User__session__requirements_typed__data,
                     71:     0, 0
                     72: };
                     73: 
                     74: /*  */
                     75: 
                     76: #define        doABORT         ss2psabort
                     77: 
                     78: 
                     79: int    DATAser (), TOKENser (), SYNCser (), ACTIVITYser (), REPORTser (),
                     80:        FINISHser (), ABORTser ();
                     81: 
                     82: 
                     83: /*    P-[*-]DATA.REQUEST */
                     84: 
                     85: int    PDataRequest (sd, data, ndata, pi)
                     86: int    sd;
                     87: PE     *data;
                     88: int    ndata;
                     89: struct PSAPindication *pi;
                     90: {
                     91:     return PDataRequestAux (sd, data, ndata, pi, "user", SDataRequest,
                     92:                            "SDataRequest", "P-DATA user-data", PPDU_TD);
                     93: }
                     94: 
                     95: /*  */
                     96: 
                     97: int    PDataRequestAux (sd, data, ndata, pi, dtype, sfunc, stype, text, ppdu)
                     98: int    sd;
                     99: PE     *data;
                    100: int    ndata;
                    101: struct PSAPindication *pi;
                    102: char   *dtype,
                    103:        *stype,
                    104:        *text;
                    105: IFP    sfunc;
                    106: int    ppdu;
                    107: {
                    108:     SBV            smask;
                    109:     int     i,
                    110:            len,
                    111:            result;
                    112:     char   *base,
                    113:           *realbase;
                    114:     register struct psapblk *pb;
                    115:     struct SSAPindication   sis;
                    116:     register struct SSAPabort  *sa = &sis.si_abort;
                    117:     register PE           *d,
                    118:                    p;
                    119: 
                    120:     missingP (data);
                    121:     toomuchP (data, ndata, NPDATA, dtype);
                    122:     if (ndata <= 0)
                    123:        return psaplose (pi, PC_PARAMETER, NULLCP,
                    124:                    "illegal number of PDVs (%d)", ndata);
                    125:     missingP (pi);
                    126:     missingP (sfunc);
                    127:     missingP (stype);
                    128:     missingP (text);
                    129: 
                    130:     smask = sigioblock ();
                    131: 
                    132:     psapPsig (pb, sd);
                    133: 
                    134:     if (ppdu == PPDU_TE) {
                    135:        for (d = data, i = 0; i < ndata; i++)
                    136:            if ((p = *d++) && p -> pe_context != PE_DFLT_CTX) {
                    137:                (void) sigiomask (smask);
                    138:                return psaplose (pi, PC_OPERATION, NULLCP,
                    139:                        "defined context not permited with expedited service");
                    140:            }
                    141:     }
                    142:        
                    143:     if (ppdu == PPDU_TTD && !(pb -> pb_urequirements & SR_TYPEDATA)) {
                    144:        (void) sigiomask (smask);
                    145:        return psaplose (pi, PC_OPERATION, NULLCP,
                    146:                         "typed data service unavailable");
                    147:     }
                    148: 
                    149:     if ((result = info2ssdu (pb, pi, data, ndata, &realbase, &base, &len, text,
                    150:                            ppdu)) != OK)
                    151:        goto out2;
                    152: 
                    153:     if ((result = (*sfunc) (sd, base, len, &sis)) == NOTOK)
                    154:        if (SC_FATAL (sa -> sa_reason))
                    155:            (void) ss2pslose (pb, pi, stype, sa);
                    156:        else {
                    157:            (void) ss2pslose (NULLPB, pi, stype, sa);
                    158:            goto out1;
                    159:        }
                    160: 
                    161: out2: ;
                    162:     if (result == NOTOK)
                    163:        freepblk (pb);
                    164:     else
                    165:        if (result == DONE)
                    166:            result = NOTOK;
                    167: out1: ;
                    168:     if (realbase)
                    169:        free (realbase);
                    170:     else
                    171:        if (base)
                    172:            free (base);
                    173: 
                    174:     (void) sigiomask (smask);
                    175: 
                    176:     return result;
                    177: }
                    178: 
                    179: /*    P-READ.REQUEST (pseudo) */
                    180: 
                    181: int    PReadRequest (sd, px, secs, pi)
                    182: int    sd;
                    183: struct PSAPdata *px;
                    184: int    secs;
                    185: struct PSAPindication *pi;
                    186: {
                    187:     SBV            smask;
                    188:     int     result;
                    189:     register struct psapblk *pb;
                    190: 
                    191:     missingP (px);
                    192:     missingP (pi);
                    193: 
                    194:     smask = sigioblock ();
                    195: 
                    196:     psapPsig (pb, sd);
                    197: 
                    198:     result = PReadRequestAux (pb, px, secs, pi);
                    199: 
                    200:     (void) sigiomask (smask);
                    201: 
                    202:     return result;
                    203: }
                    204: 
                    205: /*  */
                    206: 
                    207: static int  PReadRequestAux (pb, px, secs, pi)
                    208: register struct psapblk *pb;
                    209: struct PSAPdata *px;
                    210: int    secs;
                    211: register struct PSAPindication *pi;
                    212: {
                    213:     int            result;
                    214:     struct SSAPdata sxs;
                    215:     register struct SSAPdata   *sx = &sxs;
                    216:     struct SSAPindication   sis;
                    217:     register struct SSAPindication *si = &sis;
                    218: 
                    219:     bzero ((char *) px, sizeof *px);
                    220:     bzero ((char *) pi, sizeof *pi);
                    221: 
                    222:     for (;;) {
                    223:        switch (result = SReadRequest (pb -> pb_fd, sx, secs, si)) {
                    224:            case NOTOK:
                    225:                return doABORT (pb, &si -> si_abort, pi);
                    226: 
                    227:            case OK:
                    228:                return doDATA (pb, sx, px, pi);
                    229: 
                    230:            case DONE:
                    231:                switch (si -> si_type) {
                    232:                    case SI_TOKEN:
                    233:                        return doTOKEN (pb, &si -> si_token, pi);
                    234: 
                    235:                    case SI_SYNC:
                    236:                        return doSYNC (pb, &si -> si_sync, pi);
                    237:                        
                    238:                    case SI_ACTIVITY:
                    239:                        return doACTIVITY (pb, &si -> si_activity, pi);
                    240: 
                    241:                    case SI_REPORT:
                    242:                        return doREPORT (pb, &si -> si_report, pi);
                    243: 
                    244:                    case SI_FINISH:
                    245:                        return doFINISH (pb, &si -> si_finish, pi);
                    246: 
                    247:                    default:
                    248:                        (void) ppktlose (pb, pi, PC_PROTOCOL, PPDU_NONE,
                    249:                                NULLCP,
                    250:                                "unknown indication (0x%x) from session",
                    251:                                si -> si_type);
                    252:                        break;
                    253:                }
                    254:                break;
                    255:                
                    256:            default:
                    257:                (void) ppktlose (pb, pi, PC_PROTOCOL, PPDU_NONE, NULLCP,
                    258:                        "unexpected return from SReadRequest=%d", result);
                    259:                break;
                    260:        }
                    261:        break;
                    262:     }
                    263: 
                    264:     freepblk (pb);
                    265:     return NOTOK;
                    266: }
                    267: 
                    268: /*  */
                    269: 
                    270: static int  doDATA (pb, sx, px, pi)
                    271: register struct psapblk *pb;
                    272: register struct SSAPdata *sx;
                    273: register struct PSAPdata  *px;
                    274: struct PSAPindication *pi;
                    275: {
                    276:     int     ppdu,
                    277:             result;
                    278:     char   *text;
                    279: 
                    280:     switch (px -> px_type = sx -> sx_type) {
                    281:        case SX_NORMAL: 
                    282:            ppdu = PPDU_TD;
                    283:            text = "P-DATA user-data";
                    284:            break;
                    285: 
                    286:        case SX_EXPEDITED: 
                    287:            ppdu = PPDU_TE;
                    288:            text = "P-EXPEDITED-DATA user-data";
                    289:            break;
                    290: 
                    291:        case SX_CAPDIND: 
                    292:            ppdu = PPDU_TC;
                    293:            goto capd;
                    294:        case SX_CAPDCNF: 
                    295:            ppdu = PPDU_TCC;
                    296: capd: ;
                    297:            text = "P-CAPABILITY-DATA user-data";
                    298:            break;
                    299: 
                    300:        case SX_TYPED: 
                    301:            ppdu = PPDU_TTD;
                    302:            text = "P-TYPED-DATA user-data";
                    303:            break;
                    304: 
                    305:        default: 
                    306:            result = ppktlose (pb, pi, PC_PROTOCOL, PPDU_NONE, NULLCP,
                    307:                    "unknown data indication type=0x%x, %d bytes",
                    308:                    sx -> sx_type, sx -> sx_cc);
                    309:            freepblk (pb);
                    310:            goto out;
                    311:     }
                    312: 
                    313:     result = qbuf2info (pb, pi, &sx -> sx_qbuf, sx -> sx_cc,
                    314:            px -> px_info, &px -> px_ninfo, text, ppdu);
                    315: 
                    316: out: ;
                    317:     if (result == NOTOK)
                    318:        SXFREE (sx);
                    319: 
                    320:     return result;
                    321: }
                    322: 
                    323: /*  */
                    324: 
                    325: static int  doTOKEN (pb, st, pi)
                    326: register struct psapblk *pb;
                    327: register struct SSAPtoken *st;
                    328: struct PSAPindication *pi;
                    329: {
                    330:     int            result;
                    331:     register struct PSAPtoken  *pt = &pi -> pi_token;
                    332: 
                    333:     pi -> pi_type = PI_TOKEN;
                    334: 
                    335:     pt -> pt_type = st -> st_type;
                    336:     pt -> pt_tokens = st -> st_tokens;
                    337:     pt -> pt_owned = pb -> pb_owned = st -> st_owned;
                    338: 
                    339:     result = ssdu2info (pb, pi, st -> st_data, st -> st_cc, pt -> pt_info,
                    340:                &pt -> pt_ninfo, "P-PLEASE-TOKEN user-data", PPDU_NONE);
                    341: 
                    342:     STFREE (st);
                    343: 
                    344:     return (result != NOTOK ? DONE : NOTOK);
                    345: }
                    346: 
                    347: /*  */
                    348: 
                    349: static int  doSYNC (pb, sn, pi)
                    350: register struct psapblk *pb;
                    351: register struct SSAPsync *sn;
                    352: struct PSAPindication *pi;
                    353: {
                    354:     int            result;
                    355:     register struct PSAPsync   *pn = &pi -> pi_sync;
                    356: 
                    357:     pi -> pi_type = PI_SYNC;
                    358: 
                    359:     pn -> pn_type = sn -> sn_type;
                    360:     pn -> pn_options = sn -> sn_options;
                    361:     pn -> pn_ssn = sn -> sn_ssn;
                    362:     pn -> pn_settings = sn -> sn_settings;
                    363: 
                    364:     result = ssdu2info (pb, pi, sn -> sn_data, sn -> sn_cc, pn -> pn_info,
                    365:                        &pn -> pn_ninfo, sn -> sn_type <= SN_MAJORCNF
                    366:                            ? "P-MAJOR-SYNC user-data"
                    367:                            : sn -> sn_type <= SN_MINORCNF
                    368:                                ? "P-MINOR-SYNC user-data"
                    369:                                : "P-RESYNCHRONIZE user-data",
                    370:                        sn -> sn_type == SN_RESETIND
                    371:                            ? PPDU_RS
                    372:                            : sn -> sn_type == SN_RESETCNF
                    373:                                ? PPDU_RSA
                    374:                                : PPDU_NONE);
                    375: 
                    376:     SNFREE (sn);
                    377: 
                    378:     return (result != NOTOK ? DONE : NOTOK);
                    379: }
                    380: 
                    381: /*  */
                    382: 
                    383: static int  doACTIVITY (pb, sv, pi)
                    384: register struct psapblk *pb;
                    385: register struct SSAPactivity *sv;
                    386: struct PSAPindication *pi;
                    387: {
                    388:     int            result;
                    389:     register struct PSAPactivity   *pv = &pi -> pi_activity;
                    390: 
                    391:     pi -> pi_type = PI_ACTIVITY;
                    392: 
                    393:     pv -> pv_type = sv -> sv_type;
                    394:     pv -> pv_id = sv -> sv_id;                 /* struct copy */
                    395:     pv -> pv_oid = sv -> sv_oid;               /* struct copy */
                    396:     pv -> pv_connect = sv -> sv_connect;       /* struct copy */
                    397:     pv -> pv_ssn = sv -> sv_ssn;
                    398:     pv -> pv_reason = sv -> sv_reason;
                    399: 
                    400:     result = ssdu2info (pb, pi, sv -> sv_data, sv -> sv_cc, pv -> pv_info,
                    401:                &pv -> pv_ninfo, sv -> sv_type <= SV_START
                    402:                        ? "P-ACTIVITY-START user-data"
                    403:                        : sv -> sv_type <= SV_RESUME
                    404:                        ? "P-ACTIVITY-RESUME user-data"
                    405:                        : "P-ACTIVITY-END user-data", PPDU_NONE);
                    406: 
                    407:     SVFREE (sv);
                    408: 
                    409:     return (result != NOTOK ? DONE : NOTOK);
                    410: }
                    411: 
                    412: /*  */
                    413: 
                    414: static int  doREPORT (pb, sp, pi)
                    415: register struct psapblk *pb;
                    416: register struct SSAPreport *sp;
                    417: struct PSAPindication *pi;
                    418: {
                    419:     int            result;
                    420:     register struct PSAPreport *pp = &pi -> pi_report;
                    421: 
                    422:     pi -> pi_type = PI_REPORT;
                    423: 
                    424:     pp -> pp_peer = sp -> sp_peer;
                    425:     pp -> pp_reason = sp -> sp_reason;
                    426: 
                    427:     result = ssdu2info (pb, pi, sp -> sp_data, sp -> sp_cc, pp -> pp_info,
                    428:                &pp -> pp_ninfo, "P-U-EXCEPTION-REPORT user-data", PPDU_NONE);
                    429: 
                    430:     SPFREE (sp);
                    431: 
                    432:     return (result != NOTOK ? DONE : NOTOK);
                    433: }
                    434: 
                    435: /*  */
                    436: 
                    437: static int  doFINISH (pb, sf, pi)
                    438: register struct psapblk *pb;
                    439: register struct SSAPfinish *sf;
                    440: struct PSAPindication *pi;
                    441: {
                    442:     int            result;
                    443:     register struct PSAPfinish *pf = &pi -> pi_finish;
                    444: 
                    445:     pi -> pi_type = PI_FINISH;
                    446: 
                    447:     result = ssdu2info (pb, pi, sf -> sf_data, sf -> sf_cc, pf -> pf_info,
                    448:                &pf -> pf_ninfo, "P-RELEASE user-data", PPDU_NONE);
                    449: 
                    450:     SFFREE (sf);
                    451: 
                    452:     if (result == NOTOK)
                    453:        return NOTOK;
                    454: 
                    455:     pb -> pb_flags |= PB_FINN;
                    456: 
                    457:     return DONE;
                    458: }
                    459: 
                    460: /*  */
                    461: 
                    462: int    ss2psabort (pb, sa, pi)
                    463: register struct psapblk *pb;
                    464: register struct SSAPabort *sa;
                    465: struct PSAPindication *pi;
                    466: {
                    467:     int            result,
                    468:            ppdu;
                    469:     register PE            pe;
                    470:     register struct PSAPabort *pa = &pi -> pi_abort;
                    471:     struct type_PS_Abort__type *pdu;
                    472:     register struct element_PS_3 *aru;
                    473:     register struct type_PS_ARP__PPDU *arp;
                    474:     register struct type_PS_User__data *info;
                    475: 
                    476:     pdu = NULL, pe = NULLPE;
                    477:     if (!sa -> sa_peer) {
                    478:        if (sa -> sa_reason == SC_TIMER)
                    479:            return psaplose (pi, PC_TIMER, NULLCP, NULLCP);
                    480: 
                    481:        (void) ss2pslose (pb, pi, NULLCP, sa);
                    482:        goto out;
                    483:     }
                    484: 
                    485:     if (sa -> sa_cc == 0) {
                    486:        (void) psaplose (pi, PC_ABORTED, NULLCP, NULLCP);
                    487:        goto out;
                    488:     }
                    489: 
                    490:     bzero ((char *) pi, sizeof *pi);
                    491:     pi -> pi_type = PI_ABORT;
                    492: 
                    493:     if ((pe = ssdu2pe (sa -> sa_info, sa -> sa_cc, NULLCP, &result))
                    494:            == NULLPE) {
                    495:        (void) psaplose (pi, result == PS_ERR_NMEM ? PC_CONGEST : PC_PROTOCOL,
                    496:                         NULLCP, "%s", ps_error (result));
                    497:        goto out;
                    498:     }
                    499: 
                    500:     if (decode_PS_Abort__type (pe, 1, NULLIP, NULLVP, &pdu) == NOTOK) {
                    501:        (void) psaplose (pi, PC_UNRECOGNIZED, NULLCP, "%s", PY_pepy);
                    502:        goto out;
                    503:     }
                    504: 
                    505:     PLOGP (psap2_log,PS_Abort__type, pe, "Abort-type", 1);
                    506: 
                    507:     switch (pdu -> offset) {
                    508:        default:
                    509:            pa -> pa_peer = 1;
                    510:            pa -> pa_reason = PC_ABORTED;
                    511:            info = NULL, ppdu = PPDU_NONE;
                    512:            break;
                    513: 
                    514:        case type_PS_Abort__type_normal__mode:
                    515:            aru = pdu -> un.normal__mode;
                    516:            pa -> pa_peer = 1;
                    517:            pa -> pa_reason = PC_ABORTED;
                    518:            info = aru -> user__data, ppdu = PPDU_ARU;
                    519:            break;
                    520: 
                    521:        case type_PS_Abort__type_provider__abort:
                    522:            if ((arp = pdu -> un.provider__abort) -> provider__reason) {
                    523:                if ((result = arp -> provider__reason -> parm) == 0)
                    524:                    result = PC_NOTSPECIFIED;
                    525:                else
                    526:                    result += PC_ABORT_BASE;
                    527:            }
                    528:            else
                    529:                result = PC_NOTSPECIFIED;
                    530: 
                    531:            (void) psaplose (pi, result, NULLCP, NULLCP);
                    532:            info = NULL, ppdu = PPDU_ARP;
                    533:            break;
                    534:     }
                    535: 
                    536:     (void) ppdu2info (pb, pi, info, pa -> pa_info, &pa -> pa_ninfo, ppdu);
                    537: 
                    538: out: ;
                    539:     SAFREE (sa);
                    540:     if (pe)
                    541:        pe_free (pe);
                    542:     if (pdu)
                    543:        free_PS_Abort__type (pdu);
                    544:     pb -> pb_fd = NOTOK;
                    545:     freepblk (pb);
                    546: 
                    547:     return NOTOK;
                    548: }
                    549: 
                    550: /*    define vectors for INDICATION events */
                    551: 
                    552: #define        e(i)    (data ? (i) : NULLIFP)
                    553: 
                    554: 
                    555: int    PSetIndications (sd, data, tokens, sync, activity, report, finish,
                    556:        abort, pi)
                    557: int    sd;
                    558: IFP    data,
                    559:        tokens,
                    560:        sync,
                    561:        activity,
                    562:        report,
                    563:        finish,
                    564:        abort;
                    565: struct PSAPindication *pi;
                    566: {
                    567:     SBV     smask;
                    568:     register struct psapblk *pb;
                    569:     struct SSAPindication   sis;
                    570:     register struct SSAPabort  *sa = &sis.si_abort;
                    571: 
                    572:     if (data || tokens || sync || activity || report || finish || abort) {
                    573:        missingP (data);
                    574:        missingP (tokens);
                    575:        missingP (sync);
                    576:        missingP (activity);
                    577:        missingP (report);
                    578:        missingP (finish);
                    579:        missingP (abort);
                    580:     }
                    581: 
                    582:     smask = sigioblock ();
                    583: 
                    584:     psapPsig (pb, sd);
                    585: 
                    586:     if (SSetIndications (pb -> pb_fd, e (DATAser), e (TOKENser),
                    587:                e (SYNCser), e (ACTIVITYser), e (REPORTser), e (FINISHser),
                    588:                e (ABORTser), &sis) == NOTOK)
                    589:        switch (sa -> sa_reason) {
                    590:            case SC_WAITING: 
                    591:                (void) sigiomask (smask);
                    592:                return psaplose (pi, PC_WAITING, NULLCP, NULLCP);
                    593: 
                    594:            default: 
                    595:                (void) ss2pslose (pb, pi, "SSetIndications", sa);
                    596:                freepblk (pb);
                    597:                (void) sigiomask (smask);
                    598:                return NOTOK;
                    599:        }
                    600: 
                    601:     if (pb -> pb_DataIndication = data)
                    602:        pb -> pb_flags |= PB_ASYN;
                    603:     else
                    604:        pb -> pb_flags &= ~PB_ASYN;
                    605:     pb -> pb_TokenIndication = tokens;
                    606:     pb -> pb_SyncIndication = sync;
                    607:     pb -> pb_ActivityIndication = activity;
                    608:     pb -> pb_ReportIndication = report;
                    609:     pb -> pb_ReleaseIndication = finish;
                    610:     pb -> pb_AbortIndication = abort;
                    611: 
                    612:     (void) sigiomask (smask);
                    613: 
                    614:     return OK;
                    615: }
                    616: 
                    617: #undef e
                    618: 
                    619: /*    SSAP interface */
                    620: 
                    621: int    ss2pslose (pb, pi, event, sa)
                    622: register struct psapblk *pb;
                    623: register struct PSAPindication *pi;
                    624: char   *event;
                    625: register struct SSAPabort *sa;
                    626: {
                    627:     int     reason;
                    628:     char   *cp,
                    629:             buffer[BUFSIZ];
                    630: 
                    631:     if (event && SC_FATAL (sa -> sa_reason))
                    632:        SLOG (psap2_log, LLOG_EXCEPTIONS, NULLCP,
                    633:              (sa -> sa_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event,
                    634:               SErrString (sa -> sa_reason), sa -> sa_cc, sa -> sa_cc,
                    635:               sa -> sa_data));
                    636: 
                    637:     cp = "";
                    638:     switch (sa -> sa_reason) {
                    639:        case SC_SSAPID: 
                    640:        case SC_SSUSER: 
                    641:        case SC_ADDRESS: 
                    642:            reason = PC_ADDRESS;
                    643:            break;
                    644: 
                    645:        case SC_REFUSED:
                    646:            reason = PC_REFUSED;
                    647:            break;
                    648: 
                    649:        case SC_CONGEST: 
                    650:            reason = PC_CONGEST;
                    651:            break;
                    652: 
                    653:        case SC_TRANSPORT:
                    654:        case SC_ABORT:
                    655:            reason = PC_SESSION;
                    656:            break;
                    657: 
                    658:        default: 
                    659:            reason = PC_SESSION;
                    660:            if (pb == NULLPB)
                    661:                switch (sa -> sa_reason) {
                    662:                    case SC_PARAMETER:
                    663:                        reason = PC_PARAMETER;
                    664:                        break;
                    665: 
                    666:                    case SC_OPERATION:
                    667:                        reason = PC_OPERATION;
                    668:                        break;
                    669: 
                    670:                    case SC_TIMER:
                    671:                        reason = PC_TIMER;
                    672:                        break;
                    673: 
                    674:                    case SC_WAITING:
                    675:                        reason = PC_WAITING;
                    676:                        break;
                    677:                }
                    678:            (void) sprintf (cp = buffer, " (%s at session)",
                    679:                        SErrString (sa -> sa_reason));
                    680:            break;
                    681:     }
                    682: 
                    683:     if (pb) {
                    684:        if (sa -> sa_cc > 0)
                    685:            return ppktlose (pb, pi, reason, PPDU_NONE, NULLCP, "%*.*s%s",
                    686:                    sa -> sa_cc, sa -> sa_cc, sa -> sa_data, cp);
                    687:        else
                    688:            return ppktlose (pb, pi, reason, PPDU_NONE, NULLCP, "%s",
                    689:                    *cp ? cp + 1 : cp);
                    690:     }
                    691:     else {
                    692:        if (sa -> sa_cc > 0)
                    693:            return psaplose (pi, reason, NULLCP, "%*.*s%s",
                    694:                    sa -> sa_cc, sa -> sa_cc, sa -> sa_data, cp);
                    695:        else
                    696:            return psaplose (pi, reason, NULLCP, "%s",
                    697:                    *cp ? cp + 1 : cp);
                    698:     }
                    699: }
                    700: 
                    701: /*  */
                    702: 
                    703: static int  DATAser (sd, sx)
                    704: int     sd;
                    705: register struct SSAPdata   *sx;
                    706: {
                    707:     IFP            abort;
                    708:     register struct psapblk *pb;
                    709:     struct PSAPindication   pis;
                    710:     register struct PSAPindication *pi = &pis;
                    711:     register struct PSAPdata   *px = &pi -> pi_data;
                    712: 
                    713:     if ((pb = findpblk (sd)) == NULL)
                    714:        return;
                    715: 
                    716:     bzero ((char *) px, sizeof *px);
                    717:     bzero ((char *) pi, sizeof *pi);
                    718:     abort = pb -> pb_AbortIndication;
                    719: 
                    720:     if (doDATA (pb, sx, px, pi) == NOTOK)
                    721:        (*abort) (sd, &pi -> pi_abort);
                    722:     else
                    723:        (*pb -> pb_DataIndication) (sd, px);
                    724: }
                    725: 
                    726: /*  */
                    727: 
                    728: static int  TOKENser (sd, st)
                    729: int     sd;
                    730: register struct SSAPtoken *st;
                    731: {
                    732:     IFP            abort;
                    733:     register struct psapblk *pb;
                    734:     struct PSAPindication   pis;
                    735:     register struct PSAPindication *pi = &pis;
                    736: 
                    737:     if ((pb = findpblk (sd)) == NULL)
                    738:        return;
                    739: 
                    740:     bzero ((char *) pi, sizeof *pi);
                    741:     abort = pb -> pb_AbortIndication;
                    742: 
                    743:     if  (doTOKEN (pb, st, pi) == NOTOK)
                    744:        (*abort) (sd, &pi -> pi_abort);
                    745:     else
                    746:        (*pb -> pb_TokenIndication) (sd, &pi -> pi_token);
                    747: }
                    748: 
                    749: /*  */
                    750: 
                    751: static int  SYNCser (sd, sn)
                    752: int     sd;
                    753: register struct SSAPsync   *sn;
                    754: {
                    755:     IFP            abort;
                    756:     register struct psapblk *pb;
                    757:     struct PSAPindication   pis;
                    758:     register struct PSAPindication *pi = &pis;
                    759: 
                    760:     if ((pb = findpblk (sd)) == NULL)
                    761:        return;
                    762: 
                    763:     bzero ((char *) pi, sizeof *pi);
                    764:     abort = pb -> pb_AbortIndication;
                    765: 
                    766:     if  (doSYNC (pb, sn, pi) == NOTOK)
                    767:        (*abort) (sd, &pi -> pi_abort);
                    768:     else
                    769:        (*pb -> pb_SyncIndication) (sd, &pi -> pi_sync);
                    770: }
                    771: 
                    772: /*  */
                    773: 
                    774: static int  ACTIVITYser (sd, sv)
                    775: int     sd;
                    776: register struct SSAPactivity   *sv;
                    777: {
                    778:     IFP            abort;
                    779:     register struct psapblk *pb;
                    780:     struct PSAPindication   pis;
                    781:     register struct PSAPindication *pi = &pis;
                    782: 
                    783:     if ((pb = findpblk (sd)) == NULL)
                    784:        return;
                    785: 
                    786:     bzero ((char *) pi, sizeof *pi);
                    787:     abort = pb -> pb_AbortIndication;
                    788: 
                    789:     if  (doACTIVITY (pb, sv, pi) == NOTOK)
                    790:        (*abort) (sd, &pi -> pi_abort);
                    791:     else
                    792:        (*pb -> pb_ActivityIndication) (sd, &pi -> pi_activity);
                    793: }
                    794: 
                    795: /*  */
                    796: 
                    797: static int  REPORTser (sd, sp)
                    798: int     sd;
                    799: register struct SSAPreport   *sp;
                    800: {
                    801:     IFP            abort;
                    802:     register struct psapblk *pb;
                    803:     struct PSAPindication   pis;
                    804:     register struct PSAPindication *pi = &pis;
                    805: 
                    806:     if ((pb = findpblk (sd)) == NULL)
                    807:        return;
                    808: 
                    809:     bzero ((char *) pi, sizeof *pi);
                    810:     abort = pb -> pb_AbortIndication;
                    811: 
                    812:     if  (doREPORT (pb, sp, pi) == NOTOK)
                    813:        (*abort) (sd, &pi -> pi_abort);
                    814:     else
                    815:        (*pb -> pb_ReportIndication) (sd, &pi -> pi_report);
                    816: }
                    817: 
                    818: /*  */
                    819: 
                    820: static int  FINISHser (sd, sf)
                    821: int     sd;
                    822: register struct SSAPfinish   *sf;
                    823: {
                    824:     IFP            abort;
                    825:     register struct psapblk *pb;
                    826:     struct PSAPindication   pis;
                    827:     register struct PSAPindication *pi = &pis;
                    828: 
                    829:     if ((pb = findpblk (sd)) == NULL)
                    830:        return;
                    831: 
                    832:     bzero ((char *) pi, sizeof *pi);
                    833:     abort = pb -> pb_AbortIndication;
                    834: 
                    835:     if  (doFINISH (pb, sf, pi) == NOTOK)
                    836:        (*abort) (sd, &pi -> pi_abort);
                    837:     else
                    838:        (*pb -> pb_ReleaseIndication) (sd, &pi -> pi_finish);
                    839: }
                    840: 
                    841: /*  */
                    842: 
                    843: static int  ABORTser (sd, sa)
                    844: int     sd;
                    845: register struct SSAPabort   *sa;
                    846: {
                    847:     IFP            abort;
                    848:     register struct psapblk *pb;
                    849:     struct PSAPindication   pis;
                    850:     register struct PSAPindication *pi = &pis;
                    851: 
                    852:     if ((pb = findpblk (sd)) == NULL)
                    853:        return;
                    854: 
                    855:     bzero ((char *) pi, sizeof *pi);
                    856:     abort = pb -> pb_AbortIndication;
                    857: 
                    858:     (void) doABORT (pb, sa, pi);
                    859:     (*abort) (sd, &pi -> pi_abort);
                    860: }
                    861: 
                    862: /*    INTERNAL */
                    863: 
                    864: struct psapblk  *newpblk () {
                    865:     register struct psapblk *pb;
                    866: 
                    867:     pb = (struct psapblk   *) calloc (1, sizeof *pb);
                    868:     if (pb == NULL)
                    869:        return NULL;
                    870: 
                    871:     pb -> pb_fd = NOTOK;
                    872: 
                    873:     if (once_only == 0) {
                    874:        PHead -> pb_forw = PHead -> pb_back = PHead;
                    875:        once_only++;
                    876:     }
                    877: 
                    878:     insque (pb, PHead -> pb_back);
                    879: 
                    880:     return pb;
                    881: }
                    882: 
                    883: 
                    884: int    freepblk (pb)
                    885: register struct psapblk *pb;
                    886: {
                    887:     register int    i;
                    888:     register struct PSAPcontext *qp;
                    889: 
                    890:     if (pb == NULL)
                    891:        return;
                    892: 
                    893:     if (pb -> pb_fd != NOTOK) {
                    894:        struct SSAPindication   sis;
                    895:        
                    896:        (void) SUAbortRequest (pb -> pb_fd, NULLCP, 0, &sis);
                    897:     }
                    898: 
                    899:     if (pb -> pb_realbase)
                    900:        free (pb -> pb_realbase);
                    901:     else
                    902:        if (pb -> pb_retry)
                    903:            free (pb -> pb_retry);
                    904: 
                    905:     for (qp = pb -> pb_contexts, i = pb -> pb_ncontext - 1;
                    906:            i >= 0;
                    907:            qp++, i--) {
                    908:        if (qp -> pc_asn)
                    909:            oid_free (qp -> pc_asn);
                    910:        if (qp -> pc_atn)
                    911:            oid_free (qp -> pc_atn);
                    912:     }
                    913:     if (pb -> pb_asn)
                    914:        oid_free (pb -> pb_asn);
                    915:     if (pb -> pb_atn)
                    916:        oid_free (pb -> pb_atn);
                    917: 
                    918:     if (pb -> pb_ber)
                    919:        oid_free (pb -> pb_ber);
                    920: 
                    921:     remque (pb);
                    922: 
                    923:     free ((char *) pb);
                    924: }
                    925: 
                    926: /*  */
                    927: 
                    928: struct psapblk   *findpblk (sd)
                    929: register int sd;
                    930: {
                    931:     register struct psapblk *pb;
                    932: 
                    933:     if (once_only == 0)
                    934:        return NULL;
                    935: 
                    936:     for (pb = PHead -> pb_forw; pb != PHead; pb = pb -> pb_forw)
                    937:        if (pb -> pb_fd == sd)
                    938:            return pb;
                    939: 
                    940:     return NULL;
                    941: }
                    942: 
                    943: /*  */
                    944: 
                    945: struct type_PS_User__data *info2ppdu (pb, pi, data, ndata, ppdu)
                    946: register struct psapblk *pb;
                    947: struct PSAPindication *pi;
                    948: PE     *data;
                    949: int    ndata,
                    950:        ppdu;
                    951: {
                    952:     register int    i,
                    953:                    j;
                    954:     register PE           *d,
                    955:                    pe;
                    956:     register struct qbuf *qb;
                    957:     register struct PSAPcontext *qp;
                    958:     OID            atn;
                    959:     struct type_PS_User__data *pdu;
                    960:     register struct type_PS_Simply__encoded__data *simple;
                    961:     register struct type_PS_Fully__encoded__data **complex,
                    962:                                                  *full;
                    963: 
                    964:     if ((pdu = (struct type_PS_User__data *) calloc (1, sizeof *pdu))
                    965:            == NULL) {
                    966: no_mem: ;
                    967:        (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory");
                    968:        goto out;
                    969:     }
                    970: 
                    971:     pdu -> offset = type_PS_User__data_simple;
                    972:     for (d = data, i = 0; i < ndata; i++) {
                    973:        if ((pe = *d++) == NULLPE) {
                    974:            (void) psaplose (pi, PC_PARAMETER, NULLCP,
                    975:                    "missing %d%s PDV in PSDU", i + 1,
                    976:                    i == 0 ? "st" : i == 1 ? "nd" : i == 2 ? "rd" : "th");
                    977:            goto out;
                    978:        }
                    979:        if (pb -> pb_ncontext > 0
                    980:                && pe -> pe_context == PE_DFLT_CTX) {
                    981:            if (ppdu != PPDU_TE) {
                    982:                (void) psaplose (pi, PC_PARAMETER, NULLCP,
                    983:                                 "default context not permitted");
                    984:                goto out;
                    985:            }
                    986:        }
                    987:        else
                    988:            if (ppdu == PPDU_CP
                    989:                     || (pb -> pb_ncontext > 1
                    990:                                && pe -> pe_context != PE_DFLT_CTX))
                    991:                pdu -> offset = type_PS_User__data_complex;
                    992:     }
                    993: 
                    994:     if (pdu -> offset == type_PS_User__data_simple) {
                    995:        if ((qb = (struct qbuf *) malloc (sizeof *qb)) == NULL)
                    996:            goto no_mem;
                    997:        simple = pdu -> un.simple = qb;
                    998:        qb -> qb_forw = qb -> qb_back = qb;
                    999:        qb -> qb_data = NULL, qb -> qb_len = 0;
                   1000: 
                   1001:        j = 0;
                   1002:        for (d = data, i = 0; i < ndata; i++)
                   1003:            j += ps_get_abs (*d++);
                   1004:        qb -> qb_len = j;
                   1005:        if ((qb = (struct qbuf *) malloc (sizeof *qb + ((unsigned)j))) == NULL)
                   1006:            goto no_mem;
                   1007:        qb -> qb_data = qb -> qb_base, qb -> qb_len = j;
                   1008:        insque (qb, simple -> qb_back);
                   1009:     }
                   1010:     else
                   1011:        complex = &pdu -> un.complex;
                   1012: 
                   1013:     for (d = data, i = 0; i < ndata; i++) {
                   1014:        pe = *d++;
                   1015:        switch (pe -> pe_context) {
                   1016:            case PE_DFLT_CTX:
                   1017:                atn = pb -> pb_atn;
                   1018:                break;
                   1019: 
                   1020:            default:
                   1021:                for (j = 0, qp = pb -> pb_contexts;
                   1022:                        j < pb -> pb_ncontext;
                   1023:                        j++, qp++)
                   1024:                    if (qp -> pc_id == pe -> pe_context)
                   1025:                        break;
                   1026:                if (j >= pb -> pb_ncontext) {
                   1027:                    (void) psaplose (pi, PC_PARAMETER, NULLCP,
                   1028:                                "context %d is undefined", pe -> pe_context);
                   1029:                    goto out;
                   1030:                }
                   1031:                if (qp -> pc_result != PC_ACCEPT) {
                   1032:                    (void) psaplose (pi, PC_PARAMETER, NULLCP,
                   1033:                                "context %d is unsupported", pe -> pe_context);
                   1034:                    goto out;
                   1035:                }
                   1036:                atn = qp -> pc_atn;
                   1037:                break;
                   1038:        }
                   1039: 
                   1040:        if (!atn_is_ber (pb, atn)) {
                   1041:            (void) psaplose (pi, PC_PARAMETER, NULLCP,
                   1042:                             "ATN not BER for context %d", pe -> pe_context);
                   1043:            goto out;
                   1044:        }
                   1045: 
                   1046:        if (pdu -> offset == type_PS_User__data_simple) {
                   1047:            if (info2qb (pe, qb, pi) == NULL)
                   1048:                goto out;
                   1049:        }
                   1050:        else {
                   1051:            register PE    *q;
                   1052: 
                   1053:            if ((full = (struct type_PS_Fully__encoded__data *)
                   1054:                            calloc (1, sizeof *full)) == NULL)
                   1055:                goto no_mem;
                   1056:            *complex = full;
                   1057:            complex = &full -> next;
                   1058:            if ((full -> PDV__list = (struct type_PS_PDV__list *)
                   1059:                                    calloc (1, sizeof *full -> PDV__list))
                   1060:                    == NULL)
                   1061:                goto no_mem;
                   1062:            full -> PDV__list -> identifier = pe -> pe_context;
                   1063:            if ((full -> PDV__list -> presentation__data__values =
                   1064:                     (struct choice_PS_0 *)
                   1065:                        calloc (1, sizeof (struct choice_PS_0))) == NULL)
                   1066:                goto no_mem;
                   1067: 
                   1068:            for (q = d, j = i + 1; j < ndata; q++, j++)
                   1069:                if ((*q) -> pe_context != pe -> pe_context)
                   1070:                    break;
                   1071:            q--, j--;
                   1072: 
                   1073:            if (i == j) {
                   1074:                full -> PDV__list -> presentation__data__values ->
                   1075:                    offset = choice_PS_0_single__ASN1__type;
                   1076:                (full -> PDV__list -> presentation__data__values ->
                   1077:                    un.single__ASN1__type = pe) -> pe_refcnt++;
                   1078:            }
                   1079:            else {
                   1080:                register struct qbuf *qb2;
                   1081: 
                   1082:                full -> PDV__list -> presentation__data__values ->
                   1083:                    offset = choice_PS_0_octet__aligned;
                   1084:                if ((qb2 = (struct qbuf *) malloc (sizeof *qb2)) == NULL)
                   1085:                    goto no_mem;
                   1086:                full -> PDV__list -> presentation__data__values ->
                   1087:                    un.octet__aligned = qb2;
                   1088:                qb2 -> qb_forw = qb2 -> qb_back = qb2;
                   1089:                qb2 -> qb_data = NULL, qb2 -> qb_len = 0;
                   1090:                for (d--, j++; i < j; i++) {
                   1091:                    if ((qb = info2qb (*d++, (struct qbuf *) NULL, pi))
                   1092:                            == NULL)
                   1093:                        goto out;
                   1094:                    qb2 -> qb_len += qb -> qb_len;
                   1095:                    insque (qb, qb2 -> qb_back);
                   1096:                }
                   1097:            }
                   1098:        }
                   1099:     }
                   1100: 
                   1101:     return pdu;
                   1102:     
                   1103: out: ;
                   1104:     if (pdu)
                   1105:        free_PS_User__data (pdu);
                   1106: 
                   1107:     return NULL;
                   1108: }
                   1109: 
                   1110: /*  */
                   1111: 
                   1112: int    ppdu2info (pb, pi, info, data, ndata, ppdu)
                   1113: register struct psapblk *pb;
                   1114: struct PSAPindication *pi;
                   1115: struct type_PS_User__data *info;
                   1116: PE     *data;
                   1117: int    *ndata,
                   1118:        ppdu;
                   1119: {
                   1120:     register int    i,
                   1121:                    j;
                   1122:     int            ctx,
                   1123:            result;
                   1124:     PE     pe;
                   1125:     register struct type_PS_Fully__encoded__data *full;
                   1126: 
                   1127:     *ndata = 0;
                   1128:     if (info == NULL)
                   1129:        return OK;
                   1130: 
                   1131:     i = 0;
                   1132:     switch (info -> offset) {
                   1133:        case type_PS_User__data_simple:
                   1134:            if (pb -> pb_ncontext < 1 || ppdu == PPDU_TE)
                   1135:                ctx = PE_DFLT_CTX;
                   1136:            else
                   1137:                if (pb -> pb_ncontext > 1)
                   1138:                    return ppktlose (pb, pi, PC_INVALID, ppdu, NULLCP,
                   1139:                                     "unexpected Simply-encoded-data");
                   1140:                else
                   1141:                    ctx = pb -> pb_contexts[0].pc_id;
                   1142:            while ((result = qb2info (info -> un.simple, &pe)) == PS_ERR_NONE){
                   1143:                if (i++ >= NPDATA) {
                   1144:                    pe_free (pe);
                   1145:                    return ppktlose (pb, pi, PC_CONGEST, ppdu, NULLCP,
                   1146:                                     "too much user information");
                   1147:                }
                   1148:                (*data++ = pe) -> pe_context = ctx;
                   1149:            }
                   1150:            if (result != PS_ERR_EOF)
                   1151:                return ppktlose (pb, pi, result != PS_ERR_NMEM ? PC_INVALID
                   1152:                                 : PC_CONGEST, ppdu, NULLCP, "%s",
                   1153:                                 ps_error (result));
                   1154:            break;
                   1155: 
                   1156:        case type_PS_User__data_complex:
                   1157:            for (full = info -> un.complex; full; full = full -> next) {
                   1158:                struct qbuf *qb;
                   1159:                register struct PSAPcontext *qp;
                   1160:                register struct type_PS_PDV__list *pdv = full -> PDV__list;
                   1161: 
                   1162:                ctx = pdv -> identifier;
                   1163:                for (j = 0, qp = pb -> pb_contexts;
                   1164:                         j < pb -> pb_ncontext;
                   1165:                         j++, qp++)
                   1166:                    if (qp -> pc_id == ctx)
                   1167:                        break;
                   1168:                if (j >= pb -> pb_ncontext)
                   1169:                    return ppktlose (pb, pi, PC_INVALID, ppdu, NULLCP,
                   1170:                                     "unexpected use of context %d", ctx);
                   1171:                switch (pdv -> presentation__data__values -> offset) {
                   1172:                    case choice_PS_0_single__ASN1__type:
                   1173:                        if (i++ >= NPDATA)
                   1174:                            return ppktlose (pb, pi, PC_CONGEST, ppdu, NULLCP,
                   1175:                                             "too much user information");
                   1176:                        pe = pdv -> presentation__data__values ->
                   1177:                                un.single__ASN1__type;
                   1178:                        pdv -> presentation__data__values ->
                   1179:                           un.single__ASN1__type = NULLPE;
                   1180:                        (*data++ = pe) -> pe_context = ctx;
                   1181:                        break;
                   1182: 
                   1183:                    case choice_PS_0_octet__aligned:
                   1184:                        qb = pdv -> presentation__data__values ->
                   1185:                            un.octet__aligned;
                   1186:                        while ((result = qb2info (qb, &pe)) == PS_ERR_NONE) {
                   1187:                            pe -> pe_context = ctx;
                   1188:                            if (i++ >= NPDATA) {
                   1189:                                pe_free (pe);
                   1190:                                return ppktlose (pb, pi, PC_CONGEST, ppdu,
                   1191:                                                 NULLCP,
                   1192:                                                 "too much user information");
                   1193:                            }
                   1194:                            (*data++ = pe) -> pe_context = ctx;
                   1195:                        }
                   1196:                        if (result != PS_ERR_EOF)
                   1197:                            return ppktlose (pb, pi, result != PS_ERR_NMEM
                   1198:                                             ? PC_INVALID : PC_CONGEST, ppdu,
                   1199:                                             NULLCP, "%s", ps_error (result));
                   1200:                        break;
                   1201: 
                   1202:                    default:
                   1203:                        return ppktlose (pb, pi, PC_INVALID, ppdu, NULLCP,
                   1204:                                         "not expecting non-BER encoding");
                   1205:                }
                   1206:            }
                   1207:            break;
                   1208:     }
                   1209:     *ndata = i;
                   1210: 
                   1211:     return OK;
                   1212: }
                   1213: 
                   1214: /*  */
                   1215: 
                   1216: #ifndef        DEBUG
                   1217: /* ARGSUSED */
                   1218: #endif
                   1219: 
                   1220: int    info2ssdu (pb, pi, data, ndata, realbase, base, len, text, ppdu)
                   1221: register struct psapblk *pb;
                   1222: struct PSAPindication *pi;
                   1223: PE     *data;
                   1224: int    ndata;
                   1225: char  **realbase,
                   1226:       **base;
                   1227: int    *len;
                   1228: char   *text;
                   1229: int    ppdu;
                   1230: {
                   1231:     int            result;
                   1232:     PE     pe;
                   1233:     struct type_PS_User__data *info;
                   1234: 
                   1235:     *realbase = *base = NULLCP, *len = 0;
                   1236:     if (data == NULLPEP || ndata <= 0)
                   1237:        return OK;
                   1238: 
                   1239:     if ((info = info2ppdu (pb, pi, data, ndata, ppdu)) == NULL)
                   1240:        return (PC_FATAL (pi -> pi_abort.pa_reason) ? NOTOK : DONE);
                   1241: 
                   1242:     if (ppdu == PPDU_TTD) {
                   1243:        pe = NULLPE;
                   1244:        if ((result = encode_PS_User__data (&pe, 1, 0, NULLCP, info))
                   1245:                == NOTOK) {
                   1246: losing: ;
                   1247:            free_PS_User__data (info);
                   1248:            return psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s",
                   1249:                             PY_pepy);
                   1250:        }
                   1251: 
                   1252:        PLOGP (psap2_log,PS_User__data, pe, text, 0);
                   1253: 
                   1254:        goto serialize;
                   1255:     }
                   1256:     else
                   1257:        if (ppdu == PPDU_RS || ppdu == PPDU_RSA) {
                   1258:                                    /* this works 'cause RS-PPDU == RSA-PPDU */
                   1259:            struct type_PS_RS__PPDU rss;
                   1260:            register struct type_PS_RS__PPDU *rs = &rss;
                   1261: 
                   1262:            if ((rs -> context__list = silly_list (pb, pi)) == NULL)
                   1263:                return (PC_FATAL (pi -> pi_abort.pa_reason) ? NOTOK : DONE);
                   1264:            rs -> user__data = info;
                   1265: 
                   1266:            pe = NULLPE;
                   1267:            if ((result = encode_PS_RS__PPDU (&pe, 1, 0, NULLCP, rs))
                   1268:                    == NOTOK) {
                   1269:                free_PS_Identifier__list (rs -> context__list);
                   1270:                goto losing;
                   1271:            }
                   1272: 
                   1273:            PLOGP (psap2_log,PS_RS__PPDU, pe, text, 0);
                   1274: 
                   1275:            free_PS_Identifier__list (rs -> context__list);
                   1276: 
                   1277:            goto serialize;
                   1278:        }
                   1279: 
                   1280:     if (info -> offset == type_PS_User__data_simple) {
                   1281:        register struct qbuf *qb;
                   1282: 
                   1283:        qb = info -> un.simple;
                   1284:        *len = qb -> qb_len;
                   1285: 
                   1286:        qb = qb -> qb_forw;
                   1287:        remque (qb);
                   1288: 
                   1289:        *realbase = (char *) qb, *base = qb -> qb_base;
                   1290: 
                   1291: #ifdef DEBUG
                   1292:        if (psap2_log -> ll_events & LLOG_PDUS)
                   1293:            while (ndata-- > 0)
                   1294:                pvpdu (psap2_log, vunknown_P, *data++, text, 0);        
                   1295: #endif
                   1296:     }
                   1297:     else {
                   1298:        pe = NULLPE;
                   1299:        if (encode_PS_Fully__encoded__data (&pe, 0, 0, NULLCP,
                   1300:                                           info -> un.complex) == NOTOK)
                   1301:            goto losing;
                   1302:        pe -> pe_class = PE_CLASS_APPL, pe -> pe_id = 1;
                   1303: 
                   1304:        PLOGP (psap2_log,PS_User__data, pe, text, 0);
                   1305: 
                   1306: serialize: ;
                   1307:        result = pe2ssdu (pe, base, len);
                   1308: 
                   1309:        pe_free (pe);
                   1310: 
                   1311:        if (result == NOTOK) {
                   1312:            free_PS_User__data (info);
                   1313:            return psaplose (pi, PC_CONGEST, NULLCP, NULLCP);
                   1314:        }
                   1315:     }
                   1316:     free_PS_User__data (info);
                   1317: 
                   1318:     return OK;
                   1319: }
                   1320: 
                   1321: /*  */
                   1322: 
                   1323: #ifndef        DEBUG
                   1324: /* ARGSUSED */
                   1325: #endif
                   1326:     
                   1327: int    ssdu2info (pb, pi, base, len, data, ndata, text, ppdu)
                   1328: register struct psapblk *pb;
                   1329: struct PSAPindication *pi;
                   1330: char   *base;
                   1331: int     len;
                   1332: PE     *data;
                   1333: int    *ndata;
                   1334: char   *text;
                   1335: int    ppdu;
                   1336: {
                   1337:     int    result;
                   1338:     register PE            pe;
                   1339:     register struct type_PS_User__data *info;
                   1340: 
                   1341:     *ndata = 0;
                   1342:     if (base == NULLCP || len <= 0)
                   1343:        return OK;
                   1344: 
                   1345:     if (ppdu == PPDU_RS || ppdu == PPDU_RSA) {
                   1346:        struct type_PS_RS__PPDU *rs;/* this works 'cause RS-PPDU == RSA-PPDU */
                   1347: 
                   1348:        if ((pe = ssdu2pe (base, len, NULLCP, &result)) == NULLPE)
                   1349:            return ppktlose (pb, pi, result == PS_ERR_NMEM ? PC_CONGEST
                   1350:                             : PC_PROTOCOL, ppdu, NULLCP, "%s",
                   1351:                             ps_error (result));
                   1352: 
                   1353:        rs = NULL, info = NULL;
                   1354:        result = decode_PS_RS__PPDU (pe, 1, NULLIP, NULLVP, &rs);
                   1355: 
                   1356: #ifdef DEBUG
                   1357:        if (result == OK && (psap2_log -> ll_events & LLOG_PDUS))
                   1358:            pvpdu (psap2_log, print_PS_RS__PPDU_P, pe, text, 1);
                   1359: #endif
                   1360: 
                   1361:        info = rs -> user__data, rs -> user__data = NULL;
                   1362:        free_PS_RS__PPDU (rs);
                   1363: 
                   1364:        goto punch_it;
                   1365:     }
                   1366: 
                   1367:     if ((info = (struct type_PS_User__data *) calloc (1, sizeof *info))
                   1368:            == NULL) {
                   1369: no_mem: ;
                   1370:        (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory");
                   1371: out: ;
                   1372:         if (info)
                   1373:            free_PS_User__data (info);
                   1374:         return NOTOK;
                   1375:     }
                   1376: 
                   1377:     if (pb -> pb_ncontext <= 1 || ppdu == PPDU_TE) {
                   1378:        register struct qbuf *qb;
                   1379: 
                   1380:        info -> offset = type_PS_User__data_simple;
                   1381: 
                   1382:        if ((qb = (struct qbuf *) malloc (sizeof *qb)) == NULL)
                   1383:            goto no_mem;
                   1384:        info -> un.simple = qb;
                   1385:        qb -> qb_forw = qb -> qb_back = qb;
                   1386:        qb -> qb_data = NULL, qb -> qb_len = len;
                   1387:        if ((qb = (struct qbuf *) malloc (sizeof *qb)) == NULL)
                   1388:            goto no_mem;
                   1389:        insque (qb, info -> un.simple);
                   1390:        qb -> qb_data = base, qb -> qb_len = len;
                   1391:     }
                   1392:     else {
                   1393:        info -> offset = type_PS_User__data_complex;
                   1394: 
                   1395:        if ((pe = ssdu2pe (base, len, NULLCP, &result)) == NULLPE) {
                   1396:            (void) ppktlose (pb, pi, result == PS_ERR_NMEM ? PC_CONGEST
                   1397:                             : PC_PROTOCOL, ppdu, NULLCP, "%s",
                   1398:                             ps_error (result));
                   1399:            goto out;
                   1400:        }
                   1401: 
                   1402:        if (pe -> pe_class != PE_CLASS_APPL
                   1403:                || pe -> pe_form != PE_FORM_CONS
                   1404:                || pe -> pe_id != 1) {
                   1405:            PY_advise (NULLCP,
                   1406:                       "Fully-encoded-data bad class/form/id: %s/%d/0x%x",
                   1407:                       pe_classlist[pe -> pe_class], pe -> pe_form,
                   1408:                       pe -> pe_id);
                   1409:            result = NOTOK;
                   1410:        }
                   1411:        else
                   1412:            result = decode_PS_Fully__encoded__data (pe, 0, NULLIP, NULLVP,
                   1413:                                                     &info -> un.complex);
                   1414: 
                   1415: #ifdef DEBUG
                   1416:        if (result == OK && (psap2_log -> ll_events & LLOG_PDUS))
                   1417:            pvpdu (psap2_log, print_PS_User__data_P, pe, text, 1);
                   1418: #endif
                   1419: 
                   1420: punch_it: ;
                   1421:        pe_free (pe);
                   1422:        
                   1423:        if (result == NOTOK) {
                   1424:            (void) ppktlose (pb, pi, PC_UNRECOGNIZED, ppdu, NULLCP, "%s",
                   1425:                             PY_pepy);
                   1426:            goto out;
                   1427:        }
                   1428:     }
                   1429: 
                   1430:     if ((result = ppdu2info (pb, pi, info, data, ndata, ppdu)) == NOTOK)
                   1431:        result = PC_FATAL (pi -> pi_abort.pa_reason) ? NOTOK : DONE;
                   1432: 
                   1433: #ifdef DEBUG
                   1434:     if (result == OK
                   1435:            && ppdu != PPDU_RS 
                   1436:            && ppdu != PPDU_RSA
                   1437:            && info -> offset == type_PS_User__data_simple
                   1438:            && (psap2_log -> ll_events & LLOG_PDUS)) {
                   1439:        register int    i;
                   1440: 
                   1441:        for (i = *ndata; i > 0; i--)
                   1442:            pvpdu (psap2_log, vunknown_P, *data++, text, 1);
                   1443:     }
                   1444: #endif
                   1445: 
                   1446:     free_PS_User__data (info);
                   1447: 
                   1448:     return result;
                   1449: }
                   1450: 
                   1451: /*  */
                   1452: 
                   1453: #ifndef        DEBUG
                   1454: /* ARGSUSED */
                   1455: #endif
                   1456:     
                   1457: int    qbuf2info (pb, pi, qb, len, data, ndata, text, ppdu)
                   1458: register struct psapblk *pb;
                   1459: struct PSAPindication *pi;
                   1460: struct qbuf *qb;
                   1461: int     len;
                   1462: PE     *data;
                   1463: int    *ndata;
                   1464: char   *text;
                   1465: int    ppdu;
                   1466: {
                   1467:     int            result;
                   1468:     register PE            pe;
                   1469:     register struct qbuf *qp;
                   1470:     struct type_PS_User__data *info;
                   1471: 
                   1472:     *ndata = 0;
                   1473:     if (qb == NULL || len <= 0)
                   1474:        return OK;
                   1475: 
                   1476:     if (ppdu == PPDU_TTD) {
                   1477:        if ((pe = qbuf2pe (qb, len, &result)) == NULLPE)
                   1478:            return ppktlose (pb, pi, result == PS_ERR_NMEM ? PC_CONGEST
                   1479:                             : PC_PROTOCOL, ppdu, NULLCP, "%s",
                   1480:                             ps_error (result));
                   1481: 
                   1482:        info = NULL;
                   1483:        result = decode_PS_User__data (pe, 1, NULLIP, NULLVP, &info);
                   1484: 
                   1485: #ifdef DEBUG
                   1486:        if (result == OK && (psap2_log -> ll_events & LLOG_PDUS))
                   1487:            pvpdu (psap2_log, print_PS_User__data_P, pe, text, 1);
                   1488: #endif
                   1489: 
                   1490:        goto punch_it;
                   1491:     }
                   1492: 
                   1493:     if ((info = (struct type_PS_User__data *) calloc (1, sizeof *info))
                   1494:            == NULL) {
                   1495: no_mem: ;
                   1496:        (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory");
                   1497:        goto out;
                   1498:     }
                   1499: 
                   1500:     if (pb -> pb_ncontext <= 1 || ppdu == PPDU_TE) {
                   1501:        register struct qbuf *qbp,
                   1502:                             *qpp;
                   1503: 
                   1504:        info -> offset = type_PS_User__data_simple;
                   1505:        if ((qp = (struct qbuf *) malloc (sizeof *qp)) == NULL)
                   1506:            goto no_mem;
                   1507:        info -> un.simple = qpp = qp;
                   1508:        qp -> qb_forw = qp -> qb_back = qp;
                   1509:        qp -> qb_data = NULL, qp -> qb_len = len;
                   1510:        for (qp = qb -> qb_forw; qp != qb; qp = qbp) {
                   1511:            qbp = qp -> qb_forw;
                   1512: 
                   1513:            remque (qp);
                   1514:            insque (qp, qpp -> qb_back);
                   1515:        }
                   1516:     }
                   1517:     else {
                   1518:        info -> offset = type_PS_User__data_complex;
                   1519: 
                   1520:        if ((pe = qbuf2pe (qb, len, &result)) == NULLPE) {
                   1521:            (void) ppktlose (pb, pi, result == PS_ERR_NMEM ? PC_CONGEST
                   1522:                             : PC_PROTOCOL, ppdu, NULLCP, "%s",
                   1523:                             ps_error (result));
                   1524:            goto out;
                   1525:        }
                   1526:        if (pe -> pe_class != PE_CLASS_APPL
                   1527:                || pe -> pe_form != PE_FORM_CONS
                   1528:                || pe -> pe_id != 1) {
                   1529:            PY_advise (NULLCP,
                   1530:                       "Fully-encoded-data bad class/form/id: %s/%d/0x%x",
                   1531:                       pe_classlist[pe -> pe_class], pe -> pe_form,
                   1532:                       pe -> pe_id);
                   1533:            result = NOTOK;
                   1534:        }
                   1535:        else
                   1536:            result = decode_PS_Fully__encoded__data (pe, 0, NULLIP, NULLVP,
                   1537:                                                     &info -> un.complex);
                   1538: 
                   1539: #ifdef DEBUG
                   1540:        if (result == OK && (psap2_log -> ll_events & LLOG_PDUS))
                   1541:            pvpdu (psap2_log, print_PS_User__data_P, pe, text, 1);
                   1542: #endif
                   1543: 
                   1544: punch_it: ;
                   1545:        pe_free (pe);
                   1546:        
                   1547:        if (result == NOTOK) {
                   1548:            (void) ppktlose (pb, pi, PC_UNRECOGNIZED, ppdu, NULLCP, "%s",
                   1549:                             PY_pepy);
                   1550:            goto out;
                   1551:        }
                   1552:     }
                   1553: 
                   1554:     if ((result = ppdu2info (pb, pi, info, data, ndata, ppdu)) == NOTOK)
                   1555:        result = PC_FATAL (pi -> pi_abort.pa_reason) ? NOTOK : DONE;
                   1556: 
                   1557: #ifdef DEBUG
                   1558:     if (result == OK
                   1559:            && ppdu != PPDU_TTD
                   1560:            && info -> offset == type_PS_User__data_simple
                   1561:            && (psap2_log -> ll_events & LLOG_PDUS)) {
                   1562:        register int    i;
                   1563: 
                   1564:        for (i = *ndata; i > 0; i--)
                   1565:            pvpdu (psap2_log, vunknown_P, *data++, text, 1);
                   1566:     }
                   1567: #endif
                   1568: 
                   1569:     free_PS_User__data (info);
                   1570: 
                   1571:     return result;
                   1572: 
                   1573: out: ;
                   1574:     if (info)
                   1575:        free_PS_User__data (info);
                   1576: 
                   1577:     return NOTOK;
                   1578: }
                   1579: 
                   1580: /*  */
                   1581: 
                   1582: struct qbuf *info2qb (pe, qp, pi)
                   1583: register PE pe;
                   1584: register struct qbuf *qp;
                   1585: struct PSAPindication *pi;
                   1586: {
                   1587:     int            len;
                   1588:     register struct qbuf *qb;
                   1589:     register PS            ps;
                   1590: 
                   1591:     if ((qb = qp) == NULL) {
                   1592:        if ((qb = (struct qbuf *) malloc ((unsigned) sizeof *qb
                   1593:                                          + (len = ps_get_abs (pe))))
                   1594:                == NULL) {
                   1595: no_mem: ;
                   1596:            (void) psaplose (pi, PC_CONGEST, NULLCP, NULLCP);
                   1597:            goto out;
                   1598:        }       
                   1599: 
                   1600:        qb -> qb_data = qb -> qb_base, qb -> qb_len = len;
                   1601:     }
                   1602: 
                   1603:     if ((ps = ps_alloc (str_open)) == NULLPS)
                   1604:        goto no_mem;
                   1605:     if (str_setup (ps, qb -> qb_data, qb -> qb_len, 1) == NOTOK
                   1606:            || pe2ps_aux (ps, pe, 0) == NOTOK) {
                   1607:        (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding user-info");
                   1608:        ps_free (ps);
                   1609:        goto out;
                   1610:     }
                   1611: 
                   1612:     len = ps -> ps_ptr - ps -> ps_base;
                   1613:     if (qp)
                   1614:        qp -> qb_data += len, qp -> qb_len -= len;
                   1615:     else
                   1616:        qb -> qb_len = len;
                   1617: 
                   1618: #ifdef DEBUG
                   1619:     if (psap_log -> ll_events & LLOG_PDUS)
                   1620:        pe2text (psap_log, pe, 0, len);
                   1621: #endif
                   1622: 
                   1623:     ps_free (ps);
                   1624: 
                   1625:     return qb;
                   1626: 
                   1627: out: ;
                   1628:     if (qb && qb != qp)
                   1629:        free ((char *) qb);
                   1630: 
                   1631:     return NULL;
                   1632: }
                   1633:     
                   1634: /*  */
                   1635: 
                   1636: int    qb2info (qb, pe)
                   1637: register struct qbuf *qb;
                   1638: PE     *pe;
                   1639: {
                   1640:     int            result;
                   1641: #ifdef DEBUG
                   1642:     int            len;
                   1643: #endif
                   1644:     PE     p;
                   1645:     register PS            ps;
                   1646: 
                   1647:     *pe = NULLPE;
                   1648: 
                   1649:     if ((ps = ps_alloc (qbuf_open)) == NULLPS)
                   1650:        return PS_ERR_NMEM;
                   1651: #ifdef DEBUG
                   1652:     len = ps -> ps_byteno;
                   1653: #endif
                   1654:     if (qbuf_setup (ps, qb) == NOTOK || (p = ps2pe (ps)) == NULLPE) {
                   1655:        if ((result = ps -> ps_errno) == PS_ERR_NONE)
                   1656:            result = PS_ERR_EOF;
                   1657:     }
                   1658:     else {
                   1659:        result = PS_ERR_NONE;
                   1660:        *pe = p;
                   1661:     }
                   1662: 
                   1663:     ps -> ps_addr = NULL;      /* so ps_free doesn't free remainder of qbuf */
                   1664: #ifdef DEBUG
                   1665:     len = ps -> ps_byteno - len;
                   1666: #endif
                   1667:     ps_free (ps);
                   1668: 
                   1669: #ifdef DEBUG
                   1670:     if (p && (psap_log -> ll_events & LLOG_PDUS))
                   1671:        pe2text (psap_log, p, 1, len);
                   1672: #endif
                   1673: 
                   1674:     return result;
                   1675: }
                   1676: 
                   1677: /*  */
                   1678: 
                   1679: struct type_PS_Identifier__list *silly_list (pb, pi)
                   1680: register struct psapblk *pb;
                   1681: struct PSAPindication *pi;
                   1682: {
                   1683:     register int    j;
                   1684:     register struct PSAPcontext *qp;
                   1685:     struct type_PS_Identifier__list *list;
                   1686:     register struct type_PS_Identifier__list *lp,
                   1687:                                            **mp;
                   1688: 
                   1689:     list = NULL;
                   1690:     mp = &list;
                   1691: 
                   1692:     for (j = 0, qp = pb -> pb_contexts;
                   1693:             j < pb -> pb_ncontext;
                   1694:             j++, qp++) {
                   1695:        if ((lp = (struct type_PS_Identifier__list *)
                   1696:                        calloc (1, sizeof *lp)) == NULL) {
                   1697: no_mem: ;
                   1698:            (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory");
                   1699:            free_PS_Identifier__list (list);
                   1700:            return NULL;
                   1701:        }
                   1702:        *mp = lp;
                   1703:        mp = &lp -> next;
                   1704:        if ((lp -> element_PS_10 = (struct element_PS_11 *)
                   1705:                            calloc (1, sizeof (struct element_PS_11))) == NULL
                   1706:                || (lp -> element_PS_10 -> transfer__syntax =
                   1707:                        oid_cpy (qp -> pc_atn)) == NULLOID)
                   1708:            goto no_mem;
                   1709:        lp -> element_PS_10 -> identifier = qp -> pc_id;
                   1710:     }
                   1711: 
                   1712:     return list;    
                   1713: }

unix.superglobalmegacorp.com

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