Annotation of 43BSDReno/contrib/isode-beta/psap2/psaprovider.c, revision 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.