Annotation of 43BSDReno/contrib/isode-beta/tsap/ts2bsd.c, revision 1.1

1.1     ! root        1: /* ts2bsd.c - TPM: 4.4BSD OSI TP4 interface */
        !             2: #define STATIC /**/
        !             3: 
        !             4: #ifndef        lint
        !             5: static char *rcsid = "$Header: /f/osi/tsap/RCS/ts2bsd.c,v 7.9 90/07/09 14:51:13 mrose Exp $";
        !             6: #endif
        !             7: 
        !             8: /* 
        !             9:  * $Header: /f/osi/tsap/RCS/ts2bsd.c,v 7.9 90/07/09 14:51:13 mrose Exp $
        !            10:  *
        !            11:  *
        !            12:  * $Log:       ts2bsd.c,v $
        !            13:  * Revision 7.9  90/07/09  14:51:13  mrose
        !            14:  * sync
        !            15:  * 
        !            16:  * Revision 7.8  90/03/23  17:31:16  mrose
        !            17:  * 8
        !            18:  * 
        !            19:  * Revision 7.7  90/03/22  08:38:02  mrose
        !            20:  * touch-up
        !            21:  * 
        !            22:  * Revision 7.6  89/12/19  10:18:28  mrose
        !            23:  * DLOG
        !            24:  * 
        !            25:  * Revision 7.5  89/12/18  17:49:48  mrose
        !            26:  * touch-up
        !            27:  * 
        !            28:  * Revision 7.4  89/12/08  16:26:47  mrose
        !            29:  * keith
        !            30:  * 
        !            31:  * Revision 7.1  89/12/01  10:46:26  mrose
        !            32:  * touch-up
        !            33:  * 
        !            34:  * Revision 7.0  89/11/23  22:30:36  mrose
        !            35:  * Release 6.0
        !            36:  * 
        !            37:  */
        !            38: 
        !            39: /*
        !            40:  *                               NOTICE
        !            41:  *
        !            42:  *    Acquisition, use, and distribution of this module and related
        !            43:  *    materials are subject to the restrictions of a license agreement.
        !            44:  *    Consult the Preface in the User's Manual for the full terms of
        !            45:  *    this agreement.
        !            46:  *
        !            47:  */
        !            48: 
        !            49: 
        !            50: /* LINTLIBRARY */
        !            51: 
        !            52: #include <stdio.h>
        !            53: #include "tpkt.h"
        !            54: 
        !            55: #ifdef TP4
        !            56: #include "tp4.h"
        !            57: #endif
        !            58: 
        !            59: #ifdef BSD_TP4
        !            60: #include <errno.h>
        !            61: #include <sys/ioctl.h>
        !            62: #include <sys/uio.h>
        !            63: #include "tailor.h"
        !            64: 
        !            65: /*#define      MAXTP4          8192    /* until we have a dynamic estimate... */
        !            66: #define        MAXTP4          1024    /* until we have a dynamic estimate... */
        !            67: #define        TP4SLOP           12    /* estimate of largest DT PCI */
        !            68: 
        !            69: /*    DATA */
        !            70: 
        !            71: STATIC struct msghdr msgs;
        !            72: STATIC union osi_control_msg ocm;
        !            73: 
        !            74: 
        !            75: extern int  errno;
        !            76: 
        !            77: /* Ancillary routines */
        !            78: STATIC int sendCmsg(fd, cc, type, data)
        !            79: int    fd;
        !            80: int    cc;
        !            81: int    type;
        !            82: char   *data;
        !            83: {
        !            84:     int            result;
        !            85:     register struct msghdr *msg = &msgs;
        !            86:     register union osi_control_msg *oc = &ocm;
        !            87: 
        !            88:     bzero ((char *) msg, sizeof *msg);
        !            89:     msg -> msg_control = oc -> ocm_data;
        !            90: 
        !            91:     bzero ((char *) oc, sizeof *oc);
        !            92:     oc -> ocm_control.ocm_cmhdr.cmsg_level = SOL_TRANSPORT;
        !            93:     oc -> ocm_control.ocm_cmhdr.cmsg_type = type;
        !            94:     oc -> ocm_control.ocm_cmhdr.cmsg_len = sizeof oc -> ocm_control.ocm_cmhdr;
        !            95: 
        !            96:     if (cc) {
        !            97:        bcopy (data, oc -> ocm_control.ocm_cmdata, cc);
        !            98:        oc -> ocm_control.ocm_cmhdr.cmsg_len += cc;
        !            99:     }
        !           100:     msg -> msg_controllen = oc -> ocm_control.ocm_cmhdr.cmsg_len;
        !           101: 
        !           102:     return sendmsg (fd, msg, 0);
        !           103: }
        !           104: 
        !           105: int tp4getCmsg(fd, cc, type, data)
        !           106: int    fd;
        !           107: int    *cc;
        !           108: int    *type;
        !           109: char   *data;
        !           110: {
        !           111:     int            result;
        !           112:     register struct msghdr *msg = &msgs;
        !           113:     register union osi_control_msg *oc = &ocm;
        !           114: 
        !           115:     bzero ((char *) msg, sizeof *msg);
        !           116:     msg -> msg_control = oc -> ocm_data;
        !           117:     msg -> msg_controllen = sizeof oc -> ocm_data;
        !           118: 
        !           119:     bzero ((char *) oc, sizeof *oc);
        !           120: 
        !           121:     result = recvmsg (fd, msg, 0);
        !           122:     if (result >= 0 && cc && type && data)  {
        !           123:        register int n =
        !           124:                (oc -> ocm_control.ocm_cmhdr.cmsg_len
        !           125:                                - sizeof (oc -> ocm_control.ocm_cmhdr));
        !           126:        if (n > 0) {
        !           127:                *type = oc-> ocm_control.ocm_cmhdr.cmsg_type;
        !           128:                if (n > *cc)
        !           129:                        n = *cc;
        !           130:                bcopy(oc -> ocm_control.ocm_cmdata, data, n);
        !           131:                *cc = n;
        !           132:        }
        !           133:     }
        !           134:     return (result);
        !           135: }
        !           136: 
        !           137: /*    UPPER HALF */
        !           138: 
        !           139: STATIC int  TConnect (tb, expedited, data, cc, td)
        !           140: register struct tsapblk *tb;
        !           141: char    *data;
        !           142: int    expedited,
        !           143:        cc;
        !           144: struct TSAPdisconnect *td;
        !           145: {
        !           146:     int            len;
        !           147:     union sockaddr_osi sock;
        !           148:     struct sockaddr_iso        *ifaddr = &sock.osi_sockaddr;
        !           149:     struct tp_conn_param tcp;
        !           150:     register struct tp_conn_param *p = &tcp;
        !           151: 
        !           152:     if (gen2tp4X (&tb -> tb_responding, &sock) == NOTOK)
        !           153:        return tsaplose (td, DR_ADDRESS, NULLCP,
        !           154:                         "unable to parse remote address");
        !           155: 
        !           156:     len = sizeof *p;
        !           157:     if (getsockopt (tb -> tb_fd, SOL_TRANSPORT, TPOPT_PARAMS, (char *) p, &len)
        !           158:            == NOTOK)
        !           159:        SLOG (tsap_log, LLOG_EXCEPTIONS, "TPOPT_PARAMS", ("unable to get"));
        !           160:     else {
        !           161:        if (p -> p_xpd_service ? !expedited : expedited) {
        !           162:            p -> p_xpd_service = expedited ? 1 : 0;
        !           163:            if (setsockopt (tb -> tb_fd, SOL_TRANSPORT, TPOPT_PARAMS,
        !           164:                            (char *) p, sizeof *p) == NOTOK)
        !           165:                SLOG (tsap_log, LLOG_EXCEPTIONS, "TPOPT_PARAMS",
        !           166:                      ("unable to set"));
        !           167:        }
        !           168: 
        !           169:        if (expedited)
        !           170:            tb -> tb_flags |= TB_EXPD;
        !           171:        if (p -> p_tpdusize > 0) {
        !           172:            if (p -> p_tpdusize > 10)
        !           173:                p -> p_tpdusize = 10;
        !           174:            tb -> tb_tpduslop = TP4SLOP;
        !           175:            tb -> tb_tsdusize = (1 << p -> p_tpdusize) - tb -> tb_tpduslop;
        !           176:        }
        !           177:     }
        !           178: 
        !           179:     if (data &&
        !           180:                sendCmsg(tb->tb_fd, data, cc, TPOPT_CONN_DATA) == NOTOK)
        !           181:        return tsaplose (td, DR_CONGEST, "TPOPT_CONN_DATA", "unable to send");
        !           182: 
        !           183: /*
        !           184:    this is a real hack to pass information between TConnect and TRetry:
        !           185:        if tb_srcref is 0xffff:    this indicates that the connect is still
        !           186:                                   in progress
        !           187: 
        !           188:        if tb_srcref is 0xfffe:    this indicates the connect is done
        !           189: 
        !           190:        otherwise:                 this indicates a TS error
        !           191:  */
        !           192: 
        !           193:     if (connect (tb -> tb_fd, (struct sockaddr *) ifaddr, ifaddr -> siso_len)
        !           194:                == NOTOK) {
        !           195:        if (errno == EINPROGRESS) {
        !           196:            tb -> tb_srcref = 0xffff;
        !           197:            return CONNECTING_1;
        !           198:        }
        !           199: 
        !           200:        if (!(errno & TP_ERROR_MASK))
        !           201:            return tsaplose (td, DR_REFUSED, "connection",
        !           202:                             "unable to establish");
        !           203: 
        !           204:        tb -> tb_srcref = (errno & ~TP_ERROR_MASK) & 0xff;
        !           205:     }
        !           206:     else
        !           207:        tb -> tb_srcref = 0xfffe;
        !           208: 
        !           209:     return DONE;
        !           210: }
        !           211: 
        !           212: /*  */
        !           213: 
        !           214: STATIC int  TRetry (tb, async, tc, td)
        !           215: register struct tsapblk *tb;
        !           216: int    async;
        !           217: struct TSAPconnect *tc;
        !           218: struct TSAPdisconnect *td;
        !           219: {
        !           220:     int            len,
        !           221:            onoff,
        !           222:            flags,
        !           223:            reason;
        !           224:     union sockaddr_osi sock;
        !           225:     struct sockaddr_iso        *ifaddr = &sock.osi_sockaddr;
        !           226:     struct tp_conn_param tcp;
        !           227:     int cmsgtype = 0;
        !           228:     register struct tp_conn_param *p = &tcp;
        !           229: 
        !           230:     switch (tb -> tb_srcref) {
        !           231:        case 0xfffe:
        !           232:            reason = NOTOK;
        !           233:            break;
        !           234:        
        !           235:        default:
        !           236:            reason = tb -> tb_srcref;
        !           237: 
        !           238:        case 0xffff:
        !           239:            if (async)
        !           240:                switch ((*tb -> tb_retryfnx) (tb, td)) {
        !           241:                    case NOTOK:
        !           242:                        goto out;
        !           243: 
        !           244:                    case OK:
        !           245:                        return CONNECTING_1;
        !           246: 
        !           247:                    case DONE:
        !           248:                        break;
        !           249:                }
        !           250: 
        !           251:            (void) gen2tp4X (&tb -> tb_responding, &sock);
        !           252:            if (connect (tb -> tb_fd, (struct sockaddr *) ifaddr,
        !           253:                         ifaddr -> siso_len) == NOTOK)
        !           254:                switch (errno) {
        !           255:                    case EINPROGRESS:
        !           256:                        return CONNECTING_1;
        !           257: 
        !           258:                    case EISCONN:
        !           259:                        reason = NOTOK;
        !           260:                        break;
        !           261: 
        !           262:                    default:
        !           263:                        /* for the moment, u.u_error limited to one byte */
        !           264:                        /* this will be fixed real soon now. */
        !           265:                        /* if (!(errno & TP_ERROR_MASK))  */
        !           266:                        if (errno > 0) {
        !           267:                            (void) tsaplose (td, DR_REFUSED, "connection",
        !           268:                                             "unable to establish");
        !           269:                            goto out;
        !           270:                        }
        !           271:                        reason = (errno & ~TP_ERROR_MASK) & 0xff;
        !           272:                        break;
        !           273:                }
        !           274:            break;
        !           275:     }
        !           276: 
        !           277: 
        !           278:     if (async)
        !           279:        (void) ioctl (tb -> tb_fd, FIONBIO, (onoff = 0, (char *) &onoff));
        !           280: 
        !           281:     if (reason == NOTOK) {
        !           282:        tc -> tc_sd = tb -> tb_fd;
        !           283:        tc -> tc_tsdusize = tb -> tb_tsdusize = MAXTP4;
        !           284: 
        !           285:        len = sizeof sock;
        !           286:        if (getsockname (tb -> tb_fd, (struct sockaddr *) ifaddr, &len)
        !           287:                != NOTOK) {
        !           288:            ifaddr -> siso_len = len;
        !           289:            (void) tp42genX (&tb -> tb_responding, &sock);
        !           290:        }
        !           291:        else
        !           292:            SLOG (tsap_log, LLOG_EXCEPTIONS, "failed", ("getpeername"));
        !           293:        copyTSAPaddrX (&tb -> tb_responding, &tc -> tc_responding);
        !           294: 
        !           295:        len = sizeof *p;
        !           296:        if (getsockopt (tb -> tb_fd, SOL_TRANSPORT, TPOPT_PARAMS, (char *) p,
        !           297:                        &len)== NOTOK)
        !           298:            SLOG (tsap_log, LLOG_EXCEPTIONS, "TPOPT_PARAMS",
        !           299:                  ("unable to get"));
        !           300:        else {
        !           301:            if (!p -> p_xpd_service)
        !           302:                tb -> tb_flags &= ~TB_EXPD;
        !           303: 
        !           304:            if (p -> p_tpdusize > 0) {
        !           305:                if (p -> p_tpdusize > 10)
        !           306:                    p -> p_tpdusize = 10;
        !           307:                tb -> tb_tpduslop = TP4SLOP;
        !           308:                tb -> tb_tsdusize = (1 << p -> p_tpdusize) - tb -> tb_tpduslop;
        !           309:            }
        !           310:        }
        !           311:        tc -> tc_expedited = (tb -> tb_flags & TB_EXPD) ? 1 : 0;
        !           312:        tc -> tc_cc = sizeof tc -> tc_data;
        !           313:        if (tp4getCmsg(tb->tb_fd, &cmsgtype, &tc->tc_cc, tc->tc_data) < 0) {
        !           314:            tc -> tc_cc = 0;
        !           315:        } else if (cmsgtype != TPOPT_CFRM_DATA)
        !           316:            tc -> tc_cc = 0;
        !           317: 
        !           318:        tb -> tb_flags |= TB_CONN;
        !           319: #ifdef  MGMT
        !           320:        if (tb -> tb_manfnx)
        !           321:            (*tb -> tb_manfnx) (OPREQOUT, tb);
        !           322: #endif
        !           323:        if (tb -> tb_calling)
        !           324:            free ((char *) tb -> tb_calling), tb -> tb_calling = NULL;
        !           325:        if (tb -> tb_called)
        !           326:            free ((char *) tb -> tb_called), tb -> tb_called = NULL;
        !           327: 
        !           328:        return DONE;
        !           329:     }
        !           330: 
        !           331:     td -> td_reason = reason;
        !           332:     td -> td_cc = sizeof td -> td_data;
        !           333:     if (tp4getCmsg(tb->tb_fd, &cmsgtype, &td->td_cc, td->td_data) < 0)
        !           334:        td -> td_cc = 0;
        !           335:     else if (cmsgtype != TPOPT_DISC_DATA)
        !           336:        td -> td_cc = 0;
        !           337: 
        !           338: out: ;
        !           339:     freetblk (tb);
        !           340: 
        !           341:     return NOTOK;
        !           342: }
        !           343: 
        !           344: /*  */
        !           345: 
        !           346: STATIC int  TStart (tb, cp, ts, td)
        !           347: register struct tsapblk *tb;
        !           348: char   *cp;
        !           349: struct TSAPstart *ts;
        !           350: struct TSAPdisconnect *td;
        !           351: {
        !           352:     int            i,
        !           353:            len;
        !           354:     struct tp_conn_param tcp;
        !           355:     register struct tp_conn_param *p = &tcp;
        !           356: 
        !           357:     len = sizeof *p;
        !           358:     if (getsockopt (tb -> tb_fd, SOL_TRANSPORT, TPOPT_PARAMS, (char *) p, &len)
        !           359:            == NOTOK)
        !           360:        SLOG (tsap_log, LLOG_EXCEPTIONS, "TPOPT_PARAMS", ("unable to get"));
        !           361:     else {
        !           362:        if (p -> p_xpd_service)
        !           363:            tb -> tb_flags |= TB_EXPD;
        !           364:        if (p -> p_tpdusize > 0) {
        !           365:            if (p -> p_tpdusize > 10)
        !           366:                p -> p_tpdusize = 10;
        !           367:            tb -> tb_tpduslop = TP4SLOP;
        !           368:            tb -> tb_tsdusize = (1 << p -> p_tpdusize) - tb -> tb_tpduslop;
        !           369:        }
        !           370:     }
        !           371: 
        !           372:     ts -> ts_sd = tb -> tb_fd;
        !           373:     copyTSAPaddrX (&tb -> tb_initiating, &ts -> ts_calling);
        !           374:     copyTSAPaddrX (&tb -> tb_responding, &ts -> ts_called);
        !           375:     ts -> ts_expedited = (tb -> tb_flags & TB_EXPD) ? 1 : 0;
        !           376:     ts -> ts_tsdusize = tb -> tb_tsdusize;
        !           377: 
        !           378:     if ((i = strlen (cp)) > 0) {
        !           379:        if (i > 2 * TS_SIZE)
        !           380:            return tsaplose (td, DR_CONNECT, NULLCP,
        !           381:                             "too much initial user data");
        !           382: 
        !           383:        ts -> ts_cc = implode ((u_char *) ts -> ts_data, cp, i);
        !           384:     }
        !           385:     else
        !           386:        ts -> ts_cc = 0;
        !           387: 
        !           388:     return OK;
        !           389: }
        !           390: 
        !           391: /*  */
        !           392: 
        !           393: /* ARGSUSED */
        !           394: 
        !           395: STATIC int  TAccept (tb, responding, data, cc, qos, td)
        !           396: register struct tsapblk *tb;
        !           397: char   *data;
        !           398: int    responding,
        !           399:        cc;
        !           400: struct QOStype *qos;
        !           401: struct TSAPdisconnect *td;
        !           402: {
        !           403:     int            len;
        !           404:     struct tp_conn_param tcp;
        !           405:     register struct tp_conn_param *p = &tcp;
        !           406: 
        !           407:     len = sizeof *p;
        !           408:     if (getsockopt (tb -> tb_fd, SOL_TRANSPORT, TPOPT_PARAMS, (char *) p, &len)
        !           409:            == NOTOK)
        !           410:        SLOG (tsap_log, LLOG_EXCEPTIONS, "TPOPT_PARAMS", ("unable to get"));
        !           411:     else {
        !           412:        if (!p -> p_xpd_service)
        !           413:            tb -> tb_flags &= ~TB_EXPD;
        !           414:        else
        !           415:            if (!(tb -> tb_flags & TB_EXPD)) {
        !           416:                p -> p_xpd_service = 0;
        !           417:                if (setsockopt (tb -> tb_fd, SOL_TRANSPORT, TPOPT_PARAMS,
        !           418:                                (char *) p, sizeof *p) == NOTOK)
        !           419:                    SLOG (tsap_log, LLOG_EXCEPTIONS, "TPOPT_PARAMS",
        !           420:                          ("unable to set"));
        !           421:            }
        !           422: 
        !           423:        if (p -> p_tpdusize > 0) {
        !           424:            if (p -> p_tpdusize > 10)
        !           425:                p -> p_tpdusize = 10;
        !           426:            tb -> tb_tpduslop = TP4SLOP;
        !           427:            tb -> tb_tsdusize = (1 << p -> p_tpdusize) - tb -> tb_tpduslop;
        !           428:        }
        !           429:     }
        !           430: 
        !           431:     if (sendCmsg (tb -> tb_fd, cc, TPOPT_CFRM_DATA, data) == NOTOK)
        !           432:        return tsaplose (td, DR_CONGEST, "TPOPT_CFRM_DATA", "unable to send");
        !           433: 
        !           434:     tb -> tb_flags |= TB_CONN;
        !           435: #ifdef  MGMT
        !           436:     if (tb -> tb_manfnx)
        !           437:        (*tb -> tb_manfnx) (OPREQIN, tb);
        !           438: #endif
        !           439: 
        !           440:     return OK;
        !           441: }
        !           442: 
        !           443: /*  */
        !           444: 
        !           445: /* life would be nice if we didn't have to worry about the maximum number of
        !           446:    bytes that can be written in a single syscall() */
        !           447: 
        !           448: #ifndef        MSG_MAXIOVLEN
        !           449: #define        MSG_MAXIOVLEN   NTPUV
        !           450: #endif
        !           451: 
        !           452: 
        !           453: STATIC int  TWrite (tb, uv, expedited, td)
        !           454: register struct tsapblk *tb;
        !           455: register struct udvec *uv;
        !           456: int    expedited;
        !           457: struct TSAPdisconnect *td;
        !           458: {
        !           459:     register int cc;
        !           460:     int            flags,
        !           461:            j,
        !           462:            len;
        !           463: #ifdef MGMT
        !           464:     int            dlen;
        !           465: #endif
        !           466:     register char *bp,
        !           467:                  *ep;
        !           468:     register struct qbuf *qb;
        !           469:     register struct msghdr *msg = &msgs;
        !           470:     struct iovec iovs[MSG_MAXIOVLEN];
        !           471:     register struct iovec *vv,
        !           472:                          *wv;
        !           473: 
        !           474:     bzero ((char *) msg, sizeof *msg);
        !           475: 
        !           476:     flags = expedited ? MSG_OOB : 0;
        !           477:     
        !           478: #ifdef MGMT
        !           479:     dlen = 0;
        !           480: #endif
        !           481: 
        !           482:     if (!expedited && (tb -> tb_flags & TB_QWRITES)) {
        !           483:        int     onoff,
        !           484:                nc;
        !           485:        struct udvec *xv;
        !           486: 
        !           487:        cc = 0;
        !           488:        for (xv = uv; xv -> uv_base; xv++)
        !           489:            cc += xv -> uv_len;
        !           490: #ifdef MGMT
        !           491:        dlen = cc;
        !           492: #endif
        !           493: 
        !           494:        if ((qb = (struct qbuf *) malloc (sizeof *qb + (unsigned) cc))
        !           495:                == NULL) {
        !           496:            (void) tsaplose (td, DR_CONGEST, NULLCP,
        !           497:                             "unable to malloc %d octets for pseudo-writev, failing...",
        !           498:                             cc);
        !           499:            freetblk (tb);
        !           500: 
        !           501:            return NOTOK;
        !           502:        }
        !           503:        qb -> qb_forw = qb -> qb_back = qb;
        !           504:        qb -> qb_data = qb -> qb_base, qb -> qb_len = cc;
        !           505: 
        !           506:        bp = qb -> qb_data;
        !           507:        for (xv = uv; xv -> uv_base; xv++) {
        !           508:            bcopy (xv -> uv_base, bp, xv -> uv_len);
        !           509:            bp += xv -> uv_len;
        !           510:        }
        !           511: 
        !           512:        if (tb -> tb_qwrites.qb_forw != &tb -> tb_qwrites) {
        !           513:            nc = 0;
        !           514:            goto insert;
        !           515:        }
        !           516: 
        !           517:        vv = iovs;
        !           518:        vv -> iov_base = qb -> qb_data, vv -> iov_len = qb -> qb_len;
        !           519:        vv++;
        !           520: 
        !           521:        msg -> msg_iov = iovs;
        !           522:        msg -> msg_iovlen = vv - iovs;
        !           523: 
        !           524:        (void) ioctl (tb -> tb_fd, FIONBIO, (onoff = 1, (char *) &onoff));
        !           525: 
        !           526:        nc = sendmsg (tb -> tb_fd, msg, MSG_EOR);
        !           527: 
        !           528:        (void) ioctl (tb -> tb_fd, FIONBIO, (onoff = 0, (char *) &onoff));
        !           529: 
        !           530:        if (nc != cc) {
        !           531:            if (nc == NOTOK) {
        !           532:                if (errno != EWOULDBLOCK) {
        !           533:                    (void) tsaplose (td, DR_CONGEST, "failed", "sendmsg");
        !           534:                    goto losing;
        !           535:                }
        !           536: 
        !           537:                nc = 0;
        !           538:            }
        !           539:            if ((*tb -> tb_queuePfnx) (tb, 1, td) == NOTOK)
        !           540:                goto losing;
        !           541: 
        !           542:            qb -> qb_data += nc, qb -> qb_len -= nc;
        !           543: insert: ;
        !           544:            insque (qb, tb -> tb_qwrites.qb_back);
        !           545:            DLOG (tsap_log, LLOG_TRACE,
        !           546:                  ("queueing blocked write of %d of %d octets", nc, cc));
        !           547:        }
        !           548:        else
        !           549:            free ((char *) qb);
        !           550:        goto done;
        !           551: 
        !           552: losing: ;
        !           553:        free ((char *) qb);
        !           554:        freetblk (tb);
        !           555: 
        !           556:        return NOTOK;
        !           557:     }
        !           558: 
        !           559:     ep = (bp = uv -> uv_base) + (cc = uv -> uv_len);
        !           560:     while (uv -> uv_base) {
        !           561:        wv = (vv = iovs) + MSG_MAXIOVLEN;
        !           562:        for (len = tb -> tb_tsdusize; len > 0 && vv < wv; len -= j) {
        !           563:            j = min (cc, len);
        !           564: #ifdef MGMT
        !           565:            dlen += j;
        !           566: #endif
        !           567:            vv -> iov_base = bp, vv -> iov_len = j, vv++;
        !           568:            bp += j, cc -= j;
        !           569: 
        !           570:            if (bp >= ep) {
        !           571:                if ((bp = (++uv) -> uv_base) == NULL)
        !           572:                    break;
        !           573:                ep = bp + (cc = uv -> uv_len);
        !           574:            }
        !           575:        }
        !           576: 
        !           577:        if (expedited || uv -> uv_base == NULL)
        !           578:            flags |= MSG_EOR;
        !           579: 
        !           580:        msg -> msg_iov = iovs;
        !           581:        msg -> msg_iovlen = vv - iovs;
        !           582: 
        !           583:        if (sendmsg (tb -> tb_fd, msg, flags) == NOTOK) {
        !           584:            (void) tsaplose (td, DR_CONGEST, "failed", "sendmsg");
        !           585:            freetblk (tb);
        !           586: 
        !           587:            return NOTOK;
        !           588:        }
        !           589:     }
        !           590: 
        !           591: done: ;
        !           592: #ifdef  MGMT
        !           593:     if (tb -> tb_manfnx)
        !           594:        (*tb -> tb_manfnx) (USERDT, tb, dlen);
        !           595: #endif
        !           596: 
        !           597:     return OK;
        !           598: }
        !           599: 
        !           600: /*  */
        !           601: 
        !           602: STATIC int  TDrain (tb, td)
        !           603: register struct tsapblk *tb;
        !           604: struct TSAPdisconnect *td;
        !           605: {
        !           606:     int            nc,
        !           607:            onoff,
        !           608:            result;
        !           609:     register struct qbuf *qb;
        !           610:     register struct msghdr *msg = &msgs;
        !           611:     struct iovec vvs;
        !           612:     register struct iovec *vv = &vvs;
        !           613: 
        !           614:     bzero ((char *) msg, sizeof *msg);
        !           615:     msg -> msg_iov = vv, msg -> msg_iovlen = 1;
        !           616: 
        !           617:     (void) ioctl (tb -> tb_fd, FIONBIO, (onoff = 1, (char *) &onoff));
        !           618: 
        !           619:     while ((qb = tb -> tb_qwrites.qb_forw) != &tb -> tb_qwrites) {
        !           620:        vv -> iov_base = qb -> qb_data, vv -> iov_len = qb -> qb_len;
        !           621: 
        !           622:        if (nc = sendmsg (tb -> tb_fd, msg, MSG_EOR) != qb -> qb_len) {
        !           623:            if (nc == NOTOK) {
        !           624:                if (errno != EWOULDBLOCK) {
        !           625:                    result = tsaplose (td, DR_NETWORK, "failed",
        !           626:                                      "write to network");
        !           627:                    goto out;
        !           628:                }
        !           629: 
        !           630:                nc = 0;
        !           631:            }
        !           632: 
        !           633:            qb -> qb_data += nc, qb -> qb_len -= nc;
        !           634:            DLOG (tsap_log, LLOG_TRACE,
        !           635:                  ("wrote %d of %d octets from blocked write", nc,
        !           636:                   qb -> qb_len));
        !           637: 
        !           638:            result = OK;
        !           639:            goto out;
        !           640:        }
        !           641: 
        !           642:        DLOG (tsap_log, LLOG_TRACE,
        !           643:              ("finished blocked write of %d octets", qb -> qb_len));
        !           644:        remque (qb);
        !           645:        free ((char *) qb);
        !           646:     }
        !           647:     result = DONE;
        !           648: 
        !           649: out: ;
        !           650:     (void) ioctl (tb -> tb_fd, FIONBIO, (onoff = 0, (char *) &onoff));
        !           651: 
        !           652:     return result;
        !           653: }
        !           654: 
        !           655: /*  */
        !           656: 
        !           657: /* ARGSUSED */
        !           658: 
        !           659: STATIC int  TRead (tb, tx, td, async, oob)
        !           660: register struct tsapblk *tb;
        !           661: register struct TSAPdata *tx;
        !           662: struct TSAPdisconnect *td;
        !           663: int    async,
        !           664:        oob;
        !           665: {
        !           666:     int            cc;
        !           667:     register struct qbuf *qb;
        !           668:     register struct msghdr *msg = &msgs;
        !           669:     register union osi_control_msg *oc = &ocm;
        !           670:     struct iovec iovs[1];
        !           671:     static struct qbuf *spare_qb = 0;
        !           672: 
        !           673:     bzero ((char *) tx, sizeof *tx);
        !           674:     tx -> tx_qbuf.qb_forw = tx -> tx_qbuf.qb_back = &tx -> tx_qbuf;
        !           675: 
        !           676:     for (;;) {
        !           677:        qb = NULL;
        !           678:        if (spare_qb) {
        !           679:                if (spare_qb -> qb_len >= tb -> tb_tsdusize)
        !           680:                        qb = spare_qb;
        !           681:                else
        !           682:                        free ((char *)spare_qb);
        !           683:                spare_qb = NULL;
        !           684:        }
        !           685:        if (qb == NULL && (qb = (struct qbuf *) malloc ((unsigned) (sizeof *qb
        !           686:                                                     + tb -> tb_tsdusize)))
        !           687:                == NULL) {
        !           688:            (void) tsaplose (td, DR_CONGEST, NULLCP, NULLCP);
        !           689:            break;
        !           690:        }
        !           691:        qb -> qb_data = qb -> qb_base;
        !           692: 
        !           693:        bzero ((char *) msg, sizeof *msg);
        !           694:        msg -> msg_iov = iovs;
        !           695:        msg -> msg_iovlen = 1;
        !           696:        msg -> msg_control = oc -> ocm_data;
        !           697:        msg -> msg_controllen = sizeof oc -> ocm_data;
        !           698: 
        !           699:        iovs[0].iov_base = qb -> qb_data;
        !           700:        iovs[0].iov_len = tb -> tb_tsdusize;
        !           701: 
        !           702:        bzero ((char *) oc, sizeof *oc);
        !           703: 
        !           704:        if ((cc = recvmsg(tb -> tb_fd, msg, 0)) == NOTOK) {
        !           705:        /*if ((cc = recvmsg(tb -> tb_fd, msg, oob ? MSG_OOB : 0)) == NOTOK) */
        !           706:            if (!(errno & TP_ERROR_MASK)) {
        !           707:                (void) tsaplose (td, DR_CONGEST, "failed", "recvfrom");
        !           708:                break;
        !           709:            }
        !           710: 
        !           711:            if ((td -> td_reason = errno & ~TP_ERROR_MASK) != DR_NORMAL)
        !           712:                SLOG (tsap_log, LLOG_EXCEPTIONS, NULLCP,
        !           713:                      ("TP error %d", td -> td_reason));
        !           714:            td -> td_cc = 0;
        !           715:            break;
        !           716:        }
        !           717: 
        !           718:        if (msg -> msg_controllen) {
        !           719:            if (msg -> msg_controllen < sizeof oc -> ocm_control.ocm_cmhdr) {
        !           720:                (void) tsaplose (td, DR_CONGEST, NULLCP,
        !           721:                    "truncated control message, got %d expecting at least %d",
        !           722:                                 msg -> msg_controllen,
        !           723:                                 sizeof oc -> ocm_control.ocm_cmhdr);
        !           724:                break;
        !           725:            }
        !           726: 
        !           727:            if (oc -> ocm_control.ocm_cmhdr.cmsg_level != SOL_TRANSPORT) {
        !           728:                (void) tsaplose (td, DR_CONGEST, NULLCP,
        !           729:                                 "unexpected message (level 0x%x, type 0x%x)",
        !           730:                                 oc -> ocm_control.ocm_cmhdr.cmsg_level,
        !           731:                                 oc -> ocm_control.ocm_cmhdr.cmsg_type);
        !           732:                break;
        !           733:            }
        !           734:            if (oc -> ocm_control.ocm_cmhdr.cmsg_type == TPOPT_DISC_DATA) {
        !           735:                td -> td_reason = DR_NORMAL;
        !           736:                if ((td -> td_cc = oc -> ocm_control.ocm_cmhdr.cmsg_len
        !           737:                                    - sizeof oc -> ocm_control.ocm_cmhdr) > 0)
        !           738:                    bcopy (oc -> ocm_control.ocm_cmdata, td -> td_data, cc);
        !           739:                break;
        !           740:            }
        !           741:        }
        !           742: 
        !           743:        if (msg -> msg_flags & MSG_OOB) {
        !           744:            if (cc > 0) {
        !           745:                insque (qb, tx -> tx_qbuf.qb_back);
        !           746:                tx -> tx_cc = (qb -> qb_len = cc);
        !           747:            }
        !           748:            else
        !           749:                free ((char *) qb);
        !           750:            tx -> tx_expedited = 1;
        !           751: 
        !           752:            return OK;
        !           753:        }
        !           754: 
        !           755:        tb -> tb_len += (qb -> qb_len = cc);
        !           756:        if (cc > 0) {
        !           757:            register struct qbuf *qb2 = tb -> tb_qbuf.qb_back;
        !           758: 
        !           759:            if (qb2 != &tb->tb_qbuf && qb2->qb_len + cc <= tb->tb_tsdusize) {
        !           760:                bcopy(qb -> qb_data, qb2 -> qb_len + qb2 -> qb_data, cc);
        !           761:                qb2 -> qb_len += cc;
        !           762:                (spare_qb = qb) -> qb_len = tb -> tb_tsdusize;
        !           763:            } else
        !           764:                insque (qb, qb2);
        !           765:        } else
        !           766:            free ((char *) qb);
        !           767: 
        !           768: #ifdef MGMT
        !           769:        if (tb -> tb_manfnx)
        !           770:            (*tb -> tb_manfnx) (USERDR, tb, tb -> tb_len);
        !           771: #endif
        !           772:        if (!(msg -> msg_flags & MSG_EOR)) {
        !           773:            if (async) {
        !           774:                register struct qbuf *qb2 = tb -> tb_qbuf.qb_back;
        !           775:                if (qb2 != &tb->tb_qbuf && qb2->qb_len <= tb->tb_tsdusize)
        !           776:                        printf("short return %d\n", qb2->qb_len);
        !           777:                return DONE;
        !           778:            }
        !           779:            continue;
        !           780:        }
        !           781:        tx -> tx_expedited = 0;
        !           782:        if (tb -> tb_qbuf.qb_forw != &tb -> tb_qbuf) {
        !           783:            tx -> tx_qbuf = tb -> tb_qbuf;      /* struct copy */
        !           784:            tx -> tx_qbuf.qb_forw -> qb_back =
        !           785:                tx -> tx_qbuf.qb_back -> qb_forw = &tx -> tx_qbuf;
        !           786:            tx -> tx_cc = tb -> tb_len;
        !           787:            tb -> tb_qbuf.qb_forw =
        !           788:                tb -> tb_qbuf.qb_back = &tb -> tb_qbuf;
        !           789:            tb -> tb_len = 0;
        !           790:        }
        !           791: 
        !           792:        {
        !           793:            register struct qbuf *qb2 = tb -> tb_qbuf.qb_back;
        !           794:            if (qb2 != &tb->tb_qbuf && qb2->qb_len <= tb->tb_tsdusize)
        !           795:                    printf("short return %d\n", qb2->qb_len);
        !           796:        }
        !           797:        return OK;
        !           798:     }
        !           799:     if (qb)
        !           800:        free ((char *) qb);
        !           801: 
        !           802:     freetblk (tb);
        !           803: 
        !           804:     return NOTOK;
        !           805: }
        !           806: 
        !           807: /*  */
        !           808: 
        !           809: STATIC int  TDisconnect (tb, data, cc, td)
        !           810: register struct tsapblk *tb;
        !           811: char   *data;
        !           812: int    cc;
        !           813: struct TSAPdisconnect *td;
        !           814: {
        !           815:     int            result;
        !           816: 
        !           817:     if (sendCmsg(tb -> tb_fd, cc, TPOPT_DISC_DATA, data) == NOTOK)
        !           818:        result = tsaplose (td, DR_CONGEST, "TPOPT_DISC_DATA",
        !           819:                           "unable to send");
        !           820:     else
        !           821:        result = OK;
        !           822: 
        !           823:     freetblk (tb);
        !           824: 
        !           825:     return result;
        !           826: }
        !           827: /*  */
        !           828: 
        !           829: /* ARGSUSED */
        !           830: 
        !           831: STATIC int  TLose (tb, reason, td)
        !           832: register struct tsapblk *tb;
        !           833: int    reason;
        !           834: struct TSAPdisconnect *td;
        !           835: {
        !           836:     register struct msghdr *msg = &msgs;
        !           837:     register union osi_control_msg *oc = &ocm;
        !           838: 
        !           839:     SLOG (tsap_log, LLOG_EXCEPTIONS, NULLCP, ("TPM error %d", reason));
        !           840: 
        !           841:     bzero ((char *) msg, sizeof *msg);
        !           842:     msg -> msg_control = oc -> ocm_data;
        !           843:     msg -> msg_controllen = sizeof oc -> ocm_data;
        !           844: 
        !           845:     bzero ((char *) oc, sizeof *oc);
        !           846:     oc -> ocm_control.ocm_cmhdr.cmsg_level = SOL_TRANSPORT;
        !           847:     oc -> ocm_control.ocm_cmhdr.cmsg_type = TPOPT_DISC_DATA;
        !           848:     oc -> ocm_control.ocm_cmhdr.cmsg_len = sizeof oc -> ocm_control.ocm_cmhdr;
        !           849: 
        !           850:     if (sendmsg (tb -> tb_fd, msg, 0) == NOTOK)
        !           851:        SLOG (tsap_log, LLOG_EXCEPTIONS, "TPOPT_DISC_DATA",
        !           852:              ("unable to send"));
        !           853: }
        !           854: 
        !           855: /*    LOWER HALF */
        !           856: 
        !           857: /* ARGSUSED */
        !           858: 
        !           859: int    tp4open (tb, local_ta, local_na, remote_ta, remote_na, td, async)
        !           860: register struct tsapblk *tb;
        !           861: struct TSAPaddr *local_ta,
        !           862:                *remote_ta;
        !           863: struct NSAPaddr *local_na,
        !           864:                *remote_na;
        !           865: struct TSAPdisconnect *td;
        !           866: int    async;
        !           867: {
        !           868:     int            fd,
        !           869:            onoff;
        !           870:     struct TSAPaddr tzs;
        !           871:     register struct TSAPaddr *tz = &tzs;
        !           872:     register struct NSAPaddr *nz = tz -> ta_addrs;
        !           873:     union sockaddr_osi sock;
        !           874:     struct sockaddr_iso        *ifaddr = &sock.osi_sockaddr;
        !           875: 
        !           876:     bzero ((char *) tz, sizeof *tz);
        !           877:     if (local_ta)
        !           878:        *tz = *local_ta;        /* struct copy */
        !           879:     if (local_na) {
        !           880:        *nz = *local_na;        /* struct copy */
        !           881:        tz -> ta_naddr = 1;
        !           882:     }
        !           883: 
        !           884:     (void) gen2tp4 (tz, &sock);
        !           885: 
        !           886:     if ((fd = socket (AF_ISO, SOCK_SEQPACKET, 0)) == NOTOK)
        !           887:        return tsaplose (td, DR_CONGEST, "socket", "unable to start");
        !           888: 
        !           889:     if (ifaddr->siso_nlen || ifaddr->siso_tlen)
        !           890:        if (bind (fd, (struct sockaddr *) ifaddr, ifaddr -> siso_len) == NOTOK) {
        !           891:        (void) tsaplose (td, DR_ADDRESS, "socket", "unable to bind");
        !           892:        (void) close (fd);
        !           893:        return NOTOK;
        !           894:     }
        !           895: 
        !           896:     tb -> tb_fd = fd;
        !           897:     (void) tp4init (tb);
        !           898: 
        !           899:     if (async)
        !           900:        (void) ioctl (fd, FIONBIO, (onoff = 1, (char *) &onoff));
        !           901: 
        !           902:     return (async ? OK : DONE);
        !           903: }
        !           904: 
        !           905: /*  */
        !           906: 
        !           907: /* ARGSUSED */
        !           908: 
        !           909: STATIC int  retry_tp4_socket (tb, td)
        !           910: register struct tsapblk *tb;
        !           911: struct TSAPdisconnect *td;
        !           912: {
        !           913:     fd_set  mask;
        !           914: 
        !           915:     FD_ZERO (&mask);
        !           916:     FD_SET (tb -> tb_fd, &mask);
        !           917:     if (xselect (tb -> tb_fd + 1, NULLFD, &mask, NULLFD, 0) < 1)
        !           918:        return OK;
        !           919: 
        !           920:     return DONE;
        !           921: }
        !           922: 
        !           923: /*  */
        !           924: 
        !           925: /* ARGSUSED */
        !           926: 
        !           927: char   *tp4save (fd, td)
        !           928: int fd;
        !           929: struct TSAPdisconnect *td;
        !           930: {
        !           931:     static char buffer[BUFSIZ];
        !           932: 
        !           933:     (void) sprintf (buffer, "%c%d", NT_BSD, fd);
        !           934:     return buffer;
        !           935: }
        !           936: 
        !           937: /*  */
        !           938: 
        !           939: int    tp4restore (tb, buffer, td)
        !           940: register struct tsapblk *tb;
        !           941: char   *buffer;
        !           942: struct TSAPdisconnect *td;
        !           943: {
        !           944:     int            fd, len, ucdlen;
        !           945:     union sockaddr_osi sock;
        !           946:     struct sockaddr_iso        *ifaddr = &sock.osi_sockaddr;
        !           947: 
        !           948:     if (sscanf (buffer, "%d", &fd) != 1 || fd < 0)
        !           949:        return tsaplose (td, DR_PARAMETER, NULLCP,
        !           950:                        "bad initialization vector \"%s\"", buffer);
        !           951: 
        !           952:     tb -> tb_fd = fd;
        !           953:     (void) tp4init (tb);
        !           954:     len = sizeof sock;
        !           955:     if (getsockname (fd, (struct sockaddr *) ifaddr, &len) == NOTOK) {
        !           956:        (void) tsaplose (td, DR_CONGEST, "listen",
        !           957:                         "getsockname failed for tp4restore");
        !           958:        (void) close (fd);
        !           959:        return NOTOK;
        !           960:     }
        !           961:     ifaddr -> siso_len = len;
        !           962:     (void) tp42genX (&tb -> tb_responding, &sock);
        !           963:     len = sizeof sock;
        !           964:     if (getpeername (fd, (struct sockaddr *) ifaddr, &len) == NOTOK) {
        !           965:        (void) tsaplose (td, DR_CONGEST, "listen",
        !           966:                         "getpeername failed for tp4restore");
        !           967:        (void) close (fd);
        !           968:        return NOTOK;
        !           969:     }
        !           970:     ifaddr -> siso_len = len;
        !           971:     (void) tp42genX (&tb -> tb_initiating, &sock);
        !           972:     return OK;
        !           973: }
        !           974: 
        !           975: /*  */
        !           976: 
        !           977: int    tp4init (tb)
        !           978: register struct tsapblk *tb;
        !           979: {
        !           980:     tb -> tb_connPfnx = TConnect;
        !           981:     tb -> tb_retryPfnx = TRetry;
        !           982: 
        !           983:     tb -> tb_startPfnx = TStart;
        !           984:     tb -> tb_acceptPfnx = TAccept;
        !           985: 
        !           986:     tb -> tb_writePfnx = TWrite;
        !           987:     tb -> tb_readPfnx = TRead;
        !           988:     tb -> tb_discPfnx = TDisconnect;
        !           989:     tb -> tb_losePfnx = TLose;
        !           990: 
        !           991:     tb -> tb_drainPfnx = TDrain;
        !           992: 
        !           993: #ifdef  MGMT
        !           994:     tb -> tb_manfnx = TManGen;
        !           995: #endif
        !           996: 
        !           997:     tb -> tb_flags |= TB_TP4;
        !           998: 
        !           999:     tb -> tb_tsdusize = MAXTP4 - (tb -> tb_tpduslop = 0);
        !          1000: 
        !          1001:     tb -> tb_retryfnx = retry_tp4_socket;
        !          1002: 
        !          1003:     tb -> tb_closefnx = close_tp4_socket;
        !          1004:     tb -> tb_selectfnx = select_tp4_socket;
        !          1005: }
        !          1006: 
        !          1007: /*  */
        !          1008: 
        !          1009: /* ARGSUSED */
        !          1010: 
        !          1011: int    start_tp4_server (local_ta, backlog, opt1, opt2, td)
        !          1012: struct TSAPaddr *local_ta;
        !          1013: int    backlog,
        !          1014:        opt1,
        !          1015:        opt2;
        !          1016: struct TSAPdisconnect *td;
        !          1017: {
        !          1018:     int            sd,
        !          1019:            onoff;
        !          1020:     register struct NSAPaddr *na = local_ta -> ta_addrs;
        !          1021:     union sockaddr_osi sock;
        !          1022:     struct sockaddr_iso        *ifaddr = &sock.osi_sockaddr;
        !          1023: 
        !          1024:     (void) gen2tp4 (local_ta, &sock);
        !          1025: 
        !          1026:     if ((sd = socket (AF_ISO, SOCK_SEQPACKET, 0)) == NOTOK)
        !          1027:        return tsaplose (td, DR_CONGEST, "socket", "unable to start");
        !          1028: 
        !          1029:     if (bind (sd, (struct sockaddr *) ifaddr, ifaddr -> siso_len) == NOTOK) {
        !          1030:        (void) tsaplose (td, DR_ADDRESS, "socket", "unable to bind");
        !          1031:        (void) close (sd);
        !          1032:        return NOTOK;
        !          1033:     }
        !          1034: 
        !          1035:     if (na -> na_addrlen == 0) {       /* unique listen */
        !          1036:        int     len;
        !          1037: 
        !          1038:        len = sizeof sock;
        !          1039:        if (getsockname (sd, (struct sockaddr *) ifaddr, &len) == NOTOK) {
        !          1040:            (void) tsaplose (td, DR_CONGEST, "listen",
        !          1041:                             "getsockname failed for unique");
        !          1042:            (void) close (sd);
        !          1043:            return NOTOK;
        !          1044:        }
        !          1045:        ifaddr -> siso_len = len;
        !          1046: 
        !          1047:        (void) tp42gen (local_ta, &sock);
        !          1048:     }
        !          1049: 
        !          1050:     if (opt1)
        !          1051:        (void) setsockopt (sd, SOL_SOCKET, opt1, NULLCP, 0);
        !          1052:     if (opt2)
        !          1053:        (void) setsockopt (sd, SOL_SOCKET, opt2, NULLCP, 0);
        !          1054:     
        !          1055:     onoff = 1;
        !          1056: 
        !          1057:     (void) listen (sd, backlog);
        !          1058: 
        !          1059:     return sd;
        !          1060: }
        !          1061: 
        !          1062: /*  */
        !          1063: 
        !          1064: int    join_tp4_client (fd, remote_ta, td)
        !          1065: int    fd;
        !          1066: struct TSAPaddr *remote_ta;
        !          1067: struct TSAPdisconnect *td;
        !          1068: {
        !          1069:     int            len,
        !          1070:            sd;
        !          1071:     union sockaddr_osi sock;
        !          1072:     struct sockaddr_iso        *ifaddr = &sock.osi_sockaddr;
        !          1073: 
        !          1074:     len = sizeof sock;
        !          1075:     if ((sd = accept (fd, (struct sockaddr *) ifaddr, &len)) == NOTOK)
        !          1076:        return tsaplose (td, DR_NETWORK, "socket", "unable to accept");
        !          1077:     ifaddr -> siso_len = len;
        !          1078:        
        !          1079:     (void) tp42gen (remote_ta, &sock);
        !          1080:     
        !          1081:     return sd;
        !          1082: }
        !          1083: 
        !          1084: /*  */
        !          1085: 
        !          1086: STATIC int  gen2tp4 (generic, specific)
        !          1087: struct TSAPaddr *generic;
        !          1088: union sockaddr_osi *specific;
        !          1089: {
        !          1090:     register char *cp;
        !          1091:     struct sockaddr_iso        *ifaddr = &specific -> osi_sockaddr;
        !          1092: 
        !          1093:     bzero ((char *) specific, sizeof *specific);
        !          1094: 
        !          1095:     cp = ifaddr -> siso_data;
        !          1096: 
        !          1097:     if (generic -> ta_naddr > 0) {
        !          1098:        register struct NSAPaddr *na = generic -> ta_addrs;
        !          1099: 
        !          1100:        if (ifaddr -> siso_nlen = na -> na_addrlen) {
        !          1101:            bcopy (na -> na_address, cp, na -> na_addrlen);
        !          1102:            cp += na -> na_addrlen;
        !          1103:        }
        !          1104:     }
        !          1105: 
        !          1106:     if (ifaddr -> siso_tlen = generic -> ta_selectlen) {
        !          1107:        bcopy (generic -> ta_selector, cp, generic -> ta_selectlen);
        !          1108:        cp += generic -> ta_selectlen;
        !          1109:     }
        !          1110: 
        !          1111:     if ((ifaddr -> siso_len = cp - (char *) ifaddr) < sizeof *ifaddr)
        !          1112:        ifaddr -> siso_len = sizeof *ifaddr;
        !          1113:     ifaddr -> siso_family = AF_ISO;
        !          1114: 
        !          1115:     return OK;
        !          1116: }
        !          1117: 
        !          1118: 
        !          1119: 
        !          1120: STATIC int  gen2tp4X (generic, specific)
        !          1121: struct tsapADDR *generic;
        !          1122: union sockaddr_osi *specific;
        !          1123: {
        !          1124:     struct TSAPaddr tas;
        !          1125: 
        !          1126:     copyTSAPaddrX (generic, &tas);
        !          1127:     return gen2tp4 (&tas, specific);
        !          1128: }
        !          1129: 
        !          1130: /*  */
        !          1131: 
        !          1132: int    tp42gen (generic, specific)
        !          1133: struct TSAPaddr *generic;
        !          1134: union sockaddr_osi *specific;
        !          1135: {
        !          1136:     register char *cp;
        !          1137:     register struct NSAPaddr *na = generic -> ta_addrs;
        !          1138:     struct sockaddr_iso        *ifaddr = &specific -> osi_sockaddr;
        !          1139: 
        !          1140:     bzero ((char *) generic, sizeof *generic);
        !          1141: 
        !          1142:     cp = ifaddr -> siso_data;
        !          1143:     if (na -> na_addrlen = ifaddr -> siso_nlen) {
        !          1144:        na -> na_stack = NA_NSAP;
        !          1145:        na -> na_community = ts_comm_nsap_default;
        !          1146:        bcopy (cp, na -> na_address, na -> na_addrlen);
        !          1147:        cp += na -> na_addrlen;
        !          1148: 
        !          1149:        generic -> ta_naddr++;
        !          1150:     }
        !          1151: 
        !          1152:     if (generic -> ta_selectlen = ifaddr -> siso_tlen)
        !          1153:        bcopy (cp, generic -> ta_selector, generic -> ta_selectlen);
        !          1154: 
        !          1155:     return OK;
        !          1156: }
        !          1157: 
        !          1158: 
        !          1159: int    tp42genX (generic, specific)
        !          1160: struct tsapADDR *generic;
        !          1161: union sockaddr_osi *specific;
        !          1162: {
        !          1163:     int            result;
        !          1164:     struct TSAPaddr tas;
        !          1165: 
        !          1166:     if ((result = tp42gen (&tas, specific)) == OK)
        !          1167:        copyTSAPaddrY (&tas, generic);
        !          1168: 
        !          1169:     return result;
        !          1170: }
        !          1171: #endif

unix.superglobalmegacorp.com

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