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

1.1       root        1: /* psaprovider.c - PPM: implement the pseudo-presentation protocol */
                      2: 
                      3: #ifndef        lint
                      4: static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/psaprovider.c,v 7.1 90/07/01 21:05:36 mrose Exp $";
                      5: #endif
                      6: 
                      7: /* 
                      8:  * $Header: /f/osi/psap2-lpp/RCS/psaprovider.c,v 7.1 90/07/01 21:05:36 mrose Exp $
                      9:  *
                     10:  * Contributed by The Wollongong Group, Inc.
                     11:  *
                     12:  *
                     13:  * $Log:       psaprovider.c,v $
                     14:  * Revision 7.1  90/07/01  21:05:36  mrose
                     15:  * pepsy
                     16:  * 
                     17:  * Revision 7.0  89/11/23  22:16:00  mrose
                     18:  * Release 6.0
                     19:  * 
                     20:  */
                     21: 
                     22: /*
                     23:  *                               NOTICE
                     24:  *
                     25:  *    Acquisition, use, and distribution of this module and related
                     26:  *    materials are subject to the restrictions of a license agreement.
                     27:  *    Consult the Preface in the User's Manual for the full terms of
                     28:  *    this agreement.
                     29:  *
                     30:  */
                     31: 
                     32: 
                     33: /* LINTLIBRARY */
                     34: 
                     35: #include <stdio.h>
                     36: #include <signal.h>
                     37: #define        LPP
                     38: #include "PS-types.h"
                     39: #include "ppkt.h"
                     40: #include "tailor.h"
                     41: 
                     42: /*    DATA */
                     43: 
                     44: static int  once_only = 0;
                     45: static struct psapblk psapque;
                     46: static struct psapblk *PHead = &psapque;
                     47: 
                     48: /*    P-DATA.REQUEST */
                     49: 
                     50: int    PDataRequest (sd, data, ndata, pi)
                     51: int    sd;
                     52: PE     *data;
                     53: int    ndata;
                     54: struct PSAPindication *pi;
                     55: {
                     56:     SBV            smask;
                     57:     int            result;
                     58:     register struct psapblk *pb;
                     59: 
                     60:     if (data == NULL || ndata <= 0 || data[0] == NULLPE || ndata > NPDATA_PS)
                     61:        return psaplose (pi, PC_PARAMETER, NULLCP, "bad user data");
                     62:     if (data[0] -> pe_context != PCI_ROSE)
                     63:        return psaplose (pi, PC_PARAMETER, NULLCP,
                     64:                         "wrong context for user data");
                     65:     missingP (pi);
                     66: 
                     67:     smask = sigioblock ();
                     68: 
                     69:     psapPsig (pb, sd);
                     70: 
                     71:     if ((result = PDataRequestAux (pb, data[0], pi)) == NOTOK)
                     72:        freepblk (pb);
                     73: 
                     74:     (void) sigiomask (smask);
                     75: 
                     76:     return result;
                     77: }
                     78: 
                     79: /*  */
                     80: 
                     81: static int  PDataRequestAux (pb, data, pi)
                     82: register struct psapblk *pb;
                     83: PE     data;
                     84: struct PSAPindication *pi;
                     85: {
                     86:     int            result;
                     87: #ifdef DEBUG
                     88:     char   *cp;
                     89: #endif
                     90:     PE     pe;
                     91:     PS     ps;
                     92: 
                     93:     pe = NULLPE;
                     94: 
                     95:     if (pb -> pb_reliability == LOW_QUALITY) {
                     96:        struct type_PS_CL__UserData__PDU *pdu;
                     97: 
                     98:        if ((pdu = (struct type_PS_CL__UserData__PDU *) malloc (sizeof *pdu))
                     99:                == NULL)
                    100:            return psaplose (pi, PC_CONGEST, NULLCP, "out of memory");
                    101: 
                    102:        pdu -> reference = pb -> pb_reference;
                    103:        pdu -> user__data = data;
                    104: 
                    105:        result = encode_PS_CL__UserData__PDU (&pe, 1, 0, NULLCP, pdu);
                    106: #ifdef DEBUG
                    107:        cp = "CL-UserData-PDU";
                    108: #endif
                    109: 
                    110:        pdu -> reference = NULL;
                    111:        pdu -> user__data = NULLPE;
                    112:        free_PS_CL__UserData__PDU (pdu);
                    113:     }
                    114:     else {
                    115:        result = encode_PS_UserData__PDU (&pe, 1, 0, NULLCP, data);
                    116: #ifdef DEBUG
                    117:        cp = "UserData-PDU";
                    118: #endif
                    119:     }
                    120: 
                    121:     if (result != NOTOK) {
                    122:        PLOGP (psap2_log,PS_PDUs, pe, cp, 0);
                    123: 
                    124:        if ((result = pe2ps (ps = pb -> pb_stream, pe)) == NOTOK)
                    125:            (void) pslose (pi, ps -> ps_errno);
                    126:        else
                    127:            result = OK;
                    128:     }
                    129:     else
                    130:        (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s",
                    131:                         PY_pepy);
                    132: 
                    133:     if (pe)
                    134:        pe_free (pe);
                    135: 
                    136:     return result;
                    137: }
                    138: 
                    139: /*    P-READ.REQUEST (pseudo; synchronous read) */
                    140: 
                    141: int    PReadRequest (sd, px, secs, pi)
                    142: int    sd;
                    143: struct PSAPdata *px;
                    144: int    secs;
                    145: struct PSAPindication *pi;
                    146: {
                    147:     SBV            smask;
                    148:     int            nfds,
                    149:            result;
                    150:     fd_set  mask;
                    151:     register struct psapblk *pb;
                    152:     struct PSAPabort *pa = &pi -> pi_abort;
                    153: 
                    154:     missingP (px);
                    155:     missingP (pi);
                    156: 
                    157:     smask = sigioblock ();
                    158: 
                    159:     psapPsig (pb, sd);
                    160: 
                    161:     FD_ZERO (&mask);
                    162:     FD_SET (pb -> pb_fd, &mask);
                    163:     nfds = pb -> pb_fd + 1;
                    164: 
                    165:     for (;;) {
                    166:        fd_set   ifds,
                    167:                 efds;
                    168:        register PS     ps = pb -> pb_stream;
                    169: 
                    170:        ifds = mask;    /* struct copy */
                    171:        efds = mask;    /* struct copy */
                    172: 
                    173:        if ((ps -> ps_primeP == NULLIFP || (*ps -> ps_primeP) (ps, 1) == OK)
                    174:                && (*pb -> pb_selectfnx) (nfds, &ifds, NULLFD, &efds, secs)
                    175:                        <= OK) {
                    176:            result = psaplose (pi, PC_TIMER, NULLCP, NULLCP);
                    177:            break;
                    178:        }
                    179: 
                    180:        if (FD_ISSET (pb -> pb_fd, &ifds) || FD_ISSET (pb -> pb_fd, & efds))
                    181:            if ((result = PReadRequestAux (pb, px, pi)) != NOTOK
                    182:                    || secs != NOTOK
                    183:                    || pa -> pa_reason != PC_TIMER)
                    184:                break;
                    185:     }
                    186: 
                    187:     if (result == NOTOK && pa -> pa_reason != PC_TIMER)
                    188:        freepblk (pb);
                    189:        
                    190:     (void) sigiomask (smask);
                    191: 
                    192:     return result;
                    193: }
                    194: 
                    195: /*  */
                    196: 
                    197: static int  PReadRequestAux (pb, px, pi)
                    198: register struct psapblk *pb;
                    199: struct PSAPdata *px;
                    200: struct PSAPindication *pi;
                    201: {
                    202:     int            result;
                    203:     PE     pe;
                    204:     PS      ps;
                    205:     struct type_PS_PDUs *pdu;
                    206:     struct type_PS_SessionConnectionIdentifier *pref;
                    207: 
                    208:     if ((pe = ps2pe (ps = pb -> pb_stream)) == NULLPE)
                    209:        return pslose (pi, ps -> ps_errno);
                    210: 
                    211:     pdu = NULL;
                    212:     result = decode_PS_PDUs (pe, 1, NULLIP, NULLVP, &pdu);
                    213: 
                    214: #ifdef DEBUG
                    215:     if (result == OK && (psap2_log -> ll_events & LLOG_PDUS))
                    216:        pvpdu (psap2_log, print_PS_PDUs_P, pe, "PDU", 1);
                    217: #endif
                    218: 
                    219:     pe_free (pe);
                    220: 
                    221:     if (result == NOTOK) {
                    222:        if (pb -> pb_reliability == LOW_QUALITY)
                    223:            goto bad_ref2;
                    224: 
                    225:        (void) ppktlose (pb, pi, PC_UNRECOGNIZED, NULLRF, NULLCP,
                    226:                         "error decoding PDU: %s", PY_pepy);
                    227:        goto out;
                    228:     }
                    229: 
                    230:     switch (pdu -> offset) {
                    231:        case type_PS_PDUs_releaseRequest:
                    232:        {
                    233:            register struct PSAPfinish *pf = &pi -> pi_finish;
                    234:            register struct type_PS_ReleaseRequest__PDU *rr =
                    235:                                    pdu -> un.releaseRequest;
                    236: 
                    237:            if (pb -> pb_reliability == LOW_QUALITY
                    238:                    && refcmp (pb -> pb_reference, (pref = rr -> reference))) {
                    239: bad_ref1: ;
                    240:                (void) ppktlose (pb, pi, PC_SESSION, pref, NULLCP,
                    241:                                 "reference mismatch");
                    242: bad_ref2: ;
                    243:                if (pdu)
                    244:                    free_PS_PDUs (pdu);
                    245:                return psaplose (pi, PC_TIMER, NULLCP, NULLCP);
                    246:            }
                    247:            
                    248:            pe = rr -> user__data, rr -> user__data = NULLPE;
                    249: 
                    250:            pi -> pi_type = PI_FINISH;
                    251:            bzero ((char *) pf, sizeof *pf);
                    252: 
                    253:            (pf -> pf_info[0] = pe) -> pe_context = PCI_ACSE;
                    254:            pf -> pf_ninfo = 1;
                    255: 
                    256:            pb -> pb_flags |= PB_FINN;
                    257:            result = DONE;
                    258:        }
                    259:        break;
                    260: 
                    261:        case type_PS_PDUs_abort:
                    262:        {
                    263:            register struct PSAPabort *pa = &pi -> pi_abort;
                    264:            register struct type_PS_Abort__PDU *ab = pdu -> un.abort;
                    265: 
                    266:            if (pb -> pb_reliability == LOW_QUALITY
                    267:                    && refcmp (pb -> pb_reference, (pref = ab -> reference)))
                    268:                goto bad_ref2;
                    269: 
                    270:            if (ab -> reason) {
                    271:                switch (ab -> reason -> parm) {
                    272:                    case int_PS_Abort__reason_reason__not__specified:
                    273:                    default:
                    274:                        result = PC_NOTSPECIFIED;
                    275:                        break;
                    276: 
                    277:                    case int_PS_Abort__reason_unrecognized__ppdu:
                    278:                    case int_PS_Abort__reason_unexpected__ppdu:
                    279:                    case int_PS_Abort__reason_unrecognized__ppdu__parameter:
                    280:                        result = PC_UNRECOGNIZED
                    281:                                + (ab -> reason -> parm
                    282:                                    - int_PS_Abort__reason_unrecognized__ppdu);
                    283:                        break;
                    284: 
                    285:                    case int_PS_Abort__reason_invalid__ppdu__parameter:
                    286:                        result = PC_INVALID;
                    287:                        break;
                    288: 
                    289:                    case int_PS_Abort__reason_reference__mismatch:
                    290:                        result = PC_SESSION;
                    291:                        break;
                    292:                }
                    293:                result = psaplose (pi, result, NULLCP, NULLCP);
                    294:                break;
                    295:            }
                    296:            pe = ab -> user__data, ab -> user__data = NULLPE;
                    297: 
                    298:            pi -> pi_type = PI_ABORT;
                    299:            bzero ((char *) pa, sizeof *pa);
                    300: 
                    301:            pa -> pa_peer = 1;
                    302:            pa -> pa_reason = PC_ABORTED;
                    303:            (pa -> pa_info[0] = pe) -> pe_context = PCI_ACSE;
                    304:            pa -> pa_ninfo = 1;
                    305: 
                    306:            result = NOTOK;
                    307:        }
                    308:        break;
                    309: 
                    310:        case type_PS_PDUs_userData:
                    311:        {
                    312:            if (pb -> pb_reliability == LOW_QUALITY)
                    313:                goto bad_ref2;
                    314: 
                    315:            pe = pdu -> un.userData, pdu -> un.userData = NULLPE;
                    316: 
                    317:            bzero ((char *) px, sizeof *px);
                    318: 
                    319:            px -> px_type = SX_NORMAL;
                    320:            (px -> px_info[0] = pe) -> pe_context = PCI_ROSE;
                    321:            px -> px_ninfo = 1;
                    322: 
                    323:            result = OK;
                    324:        }
                    325:        break;
                    326: 
                    327:        case type_PS_PDUs_cL__userData:
                    328:        {
                    329:            register struct type_PS_CL__UserData__PDU *cl =
                    330:                                    pdu -> un.cL__userData;
                    331: 
                    332:            if (pb -> pb_reliability == LOW_QUALITY
                    333:                    && refcmp (pb -> pb_reference, (pref = cl -> reference)))
                    334:                goto bad_ref1;
                    335: 
                    336:            pe = cl -> user__data, cl -> user__data = NULLPE;
                    337: 
                    338:            bzero ((char *) px, sizeof *px);
                    339: 
                    340:            px -> px_type = SX_NORMAL;
                    341:            (px -> px_info[0] = pe) -> pe_context = PCI_ROSE;
                    342:            px -> px_ninfo = 1;
                    343: 
                    344:            result = OK;
                    345:        }
                    346:        break;
                    347: 
                    348:        case type_PS_PDUs_connectRequest:
                    349:        /* this works 'cause the "reference" is always the FIRST element */
                    350:            result = ppktlose (pb, pi, PC_SESSION,
                    351:                               pdu -> un.connectRequest -> reference, NULLCP,
                    352:                               "unexpected PDU %d", pdu -> offset);
                    353:            break;
                    354: 
                    355:        default:
                    356:        /* this works 'cause the "reference" is always the FIRST element */
                    357:            result = ppktlose (pb, pi, PC_SESSION,
                    358:                               pdu -> un.connectResponse -> reference, NULLCP,
                    359:                               "unexpected PDU %d", pdu -> offset);
                    360:            break;
                    361:     }
                    362: 
                    363: out: ;
                    364:     if (pdu)
                    365:        free_PS_PDUs (pdu);
                    366: 
                    367:     return result;
                    368: }
                    369: 
                    370: /*    define vectors for INDICATION events */
                    371: 
                    372: /* ARGSUSED */
                    373: 
                    374: int    PSetIndications (sd, data, tokens, sync, activity, report, finish,
                    375:                         abort, pi)
                    376: int    sd;
                    377: IFP    data,
                    378:        tokens,
                    379:        sync,
                    380:        activity,
                    381:        report,
                    382:        finish,
                    383:        abort;
                    384: struct PSAPindication *pi;
                    385: {
                    386:     missingP (pi);
                    387: 
                    388:     return psaplose (pi, PC_OPERATION, NULLCP, NULLCP);
                    389: }
                    390: 
                    391: /*    INTERNAL */
                    392: 
                    393: struct psapblk  *newpblk () {
                    394:     register struct psapblk *pb;
                    395: 
                    396:     pb = (struct psapblk   *) calloc (1, sizeof *pb);
                    397:     if (pb == NULL)
                    398:        return NULL;
                    399: 
                    400:     pb -> pb_fd = NOTOK;
                    401: 
                    402:     if (once_only == 0) {
                    403:        PHead -> pb_forw = PHead -> pb_back = PHead;
                    404:        once_only++;
                    405:     }
                    406: 
                    407:     insque (pb, PHead -> pb_back);
                    408: 
                    409:     return pb;
                    410: }
                    411: 
                    412: 
                    413: int    freepblk (pb)
                    414: register struct psapblk *pb;
                    415: {
                    416: #ifdef notdef
                    417:     register int    i;
                    418:     register struct PSAPcontext *qp;
                    419: #endif
                    420: 
                    421:     if (pb == NULL)
                    422:        return;
                    423: 
                    424:     if (pb -> pb_fd != NOTOK && pb -> pb_closefnx)
                    425:        (void) (*pb -> pb_closefnx) (pb -> pb_fd);
                    426: 
                    427:     if (pb -> pb_retry)
                    428:        pe_free (pb -> pb_retry);
                    429:     if (pb -> pb_response)
                    430:        pe_free (pb -> pb_response);
                    431:     if (pb -> pb_reference)
                    432:        free_PS_SessionConnectionIdentifier (pb -> pb_reference);
                    433:     if (pb -> pb_stream)
                    434:        ps_free (pb -> pb_stream);
                    435: 
                    436: #ifdef notdef  /* don't need this stuff */
                    437:     for (qp = pb -> pb_contexts, i = pb -> pb_ncontexts - 1;
                    438:            i >= 0;
                    439:            qp++, i--) {
                    440:        if (qp -> pc_asn)
                    441:            oid_free (qp -> pc_asn);
                    442:        if (qp -> pc_atn)
                    443:            oid_free (qp -> pc_atn);
                    444:     }
                    445:     if (pb -> pb_asn)
                    446:        oid_free (pb -> pb_asn);
                    447:     if (pb -> pb_atn)
                    448:        oid_free (pb -> pb_atn);
                    449: #endif
                    450: 
                    451:     if (pb -> pb_ber)
                    452:        oid_free (pb -> pb_ber);
                    453: 
                    454:     remque (pb);
                    455: 
                    456:     free ((char *) pb);
                    457: }
                    458: 
                    459: /*  */
                    460: 
                    461: struct psapblk   *findpblk (sd)
                    462: register int sd;
                    463: {
                    464:     register struct psapblk *pb;
                    465: 
                    466:     if (once_only == 0)
                    467:        return NULL;
                    468: 
                    469:     for (pb = PHead -> pb_forw; pb != PHead; pb = pb -> pb_forw)
                    470:        if (pb -> pb_fd == sd)
                    471:            return pb;
                    472: 
                    473:     return NULL;
                    474: }
                    475: 
                    476: /*  */
                    477: 
                    478: int    refcmp (ref1, ref2)
                    479: register struct type_PS_SessionConnectionIdentifier *ref1,
                    480:                                                     *ref2;
                    481: {
                    482:     if (ref1 == NULLRF)
                    483:        return (ref2 != NULLRF);
                    484:     else
                    485:        if (ref2 == NULLRF)
                    486:            return 1;
                    487: 
                    488:     if (qb_cmp (ref1 -> callingSSUserReference, ref2 -> callingSSUserReference)
                    489:            || qb_cmp (ref1 -> commonReference, ref2 -> commonReference)
                    490:            || qb_cmp (ref1 -> additionalReferenceInformation,
                    491:                       ref2 -> additionalReferenceInformation)) {
                    492:        SLOG (psap2_log, LLOG_EXCEPTIONS, NULLCP, ("reference mismatch"));
                    493: 
                    494:        return 1;
                    495:     }
                    496: 
                    497:     return 0;
                    498: }
                    499: 
                    500: 
                    501: static int  qb_cmp (qb1, qb2)
                    502: register struct qbuf *qb1,
                    503:                     *qb2;
                    504: {
                    505:     register int    i,
                    506:                    len1,
                    507:                    len2;
                    508:     register char  *cp1,
                    509:                   *cp2;
                    510:     register struct qbuf *qp1,
                    511:                         *qp2;
                    512: 
                    513:     if (qb1 == NULL)
                    514:        return (qb2 != NULL);
                    515:     else
                    516:        if (qb2 == NULL)
                    517:            return 1;
                    518:            
                    519:     for (qp1 = qb1 -> qb_forw; qp1 != qb1; qp1 = qp1 -> qb_forw)
                    520:        if ((len1 = qp1 -> qb_len) > 0)
                    521:            break;
                    522:     cp1 = qp1 -> qb_data;
                    523: 
                    524:     for (qp2 = qb2 -> qb_forw; qp2 != qb2; qp2 = qp2 -> qb_forw)
                    525:        if ((len2 = qp2 -> qb_len) > 0)
                    526:            break;
                    527:     cp2 = qp2 -> qb_data;
                    528: 
                    529:     for (;;) {
                    530:        if (qp1 == qb1)
                    531:            return (qb2 != qb2);
                    532:        else
                    533:            if (qp2 == qb2)
                    534:                return 1;
                    535: 
                    536:        if ((i = len1) > len2)
                    537:            i = len2;
                    538:        if (bcmp (cp1, cp2, i))
                    539:            return 1;
                    540: 
                    541:        if ((len1 -= i) <= 0) {
                    542:            for (qp1 = qp1 -> qb_forw; qp1 != qb1; qp1 = qp1 -> qb_forw)
                    543:                if ((len1 = qp1 -> qb_len) > 0)
                    544:                    break;
                    545:            cp1 = qp1 -> qb_data;
                    546:        }
                    547:        else
                    548:            cp1 += i;
                    549:        
                    550:        if ((len2 -= i) <= 0) {
                    551:            for (qp2 = qp2 -> qb_forw; qp2 != qb2; qp2 = qp2 -> qb_forw)
                    552:                if ((len2 = qp2 -> qb_len) > 0)
                    553:                    break;
                    554:            cp2 = qp2 -> qb_data;
                    555:        }
                    556:        else
                    557:            cp2 += i;
                    558:     }
                    559: }
                    560: 
                    561: /*  */
                    562: 
                    563: struct SSAPref *pdu2ref (ref)
                    564: register struct type_PS_SessionConnectionIdentifier *ref;
                    565: {
                    566:     int            i;
                    567:     static struct SSAPref sfs;
                    568:     register struct SSAPref *sf = &sfs;
                    569: 
                    570:     pdu2sel (sf -> sr_udata, &i, sizeof sf -> sr_udata,
                    571:             ref -> callingSSUserReference);
                    572:     sf -> sr_ulen = i;
                    573: 
                    574:     pdu2sel (sf -> sr_cdata, &i, sizeof sf -> sr_cdata,
                    575:             ref -> commonReference);
                    576:     sf -> sr_clen = i;
                    577: 
                    578:     pdu2sel (sf -> sr_adata, &i, sizeof sf -> sr_adata,
                    579:             ref -> additionalReferenceInformation);
                    580:     sf -> sr_alen = i;
                    581: 
                    582:     sf -> sr_vlen = 0;
                    583: 
                    584:     return sf;
                    585: }
                    586: 
                    587: /*  */
                    588: 
                    589: int    pdu2sel (sel, len, i, pb)
                    590: char   *sel;
                    591: int    *len;
                    592: register int i;
                    593: register struct qbuf *pb;
                    594: {
                    595:     register char  *cp;
                    596:     register struct qbuf *qb;
                    597: 
                    598:     if (pb == NULL) {
                    599:        *len = 0;
                    600:        return;
                    601:     }
                    602: 
                    603:     cp = sel;
                    604:     for (qb = pb -> qb_forw; qb != pb && i > 0; qb = qb -> qb_forw) {
                    605:        if (qb -> qb_len > i)
                    606:            qb -> qb_len = i;
                    607:        bcopy (qb -> qb_data, cp, qb -> qb_len);
                    608:        cp += qb -> qb_len, i -= qb -> qb_len;
                    609:     }
                    610: 
                    611:     *len = cp - sel;
                    612: }

unix.superglobalmegacorp.com

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