DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T r

⟦a475f6635⟧ TextFile

    Length: 11664 (0x2d90)
    Types: TextFile
    Names: »ro2rts.c«

Derivation

└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
    └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« 
        └─⟦de7628f85⟧ 
            └─⟦this⟧ »isode-6.0/rosap/ro2rts.c« 

TextFile

/* ro2rts.c - ROPM: RtSAP interface */

#ifndef	lint
static char *rcsid = "$Header: /f/osi/rosap/RCS/ro2rts.c,v 7.0 89/11/23 22:21:15 mrose Rel $";
#endif

/* 
 * $Header: /f/osi/rosap/RCS/ro2rts.c,v 7.0 89/11/23 22:21:15 mrose Rel $
 *
 * Based on an TCP-based implementation by George Michaelson of University
 * College London.
 *
 *
 * $Log:	ro2rts.c,v $
 * Revision 7.0  89/11/23  22:21:15  mrose
 * Release 6.0
 * 
 */

/*
 *				  NOTICE
 *
 *    Acquisition, use, and distribution of this module and related
 *    materials are subject to the restrictions of a license agreement.
 *    Consult the Preface in the User's Manual for the full terms of
 *    this agreement.
 *
 */


/* LINTLIBRARY */

#include <stdio.h>
#include "ropkt.h"
#include "tailor.h"

/* \f

   DATA */

int	rtslose ();
int	rtsINDICATIONser ();

/* \f

   bind underlying service */

int	RoRtService (acb, roi)
register struct assocblk   *acb;
struct RoSAPindication *roi;
{
    if (!(acb -> acb_flags & ACB_RTS))
	return rosaplose (roi, ROS_OPERATION, NULLCP,
		"not an association descriptor for ROS on reliable transfer");

    acb -> acb_putosdu = ro2rtswrite;
    acb -> acb_rowaitrequest = ro2rtswait;
    acb -> acb_ready = ro2rtsready;
    acb -> acb_rosetindications = ro2rtsasync;
    acb -> acb_roselectmask = ro2rtsmask;
    acb -> acb_ropktlose = NULLIFP;

    acb -> acb_flags |= ACB_STICKY;

    return OK;
}

/* \f

   define vectors for INDICATION events */

#define	e(i)	(indication ? (i) : NULLIFP)


/* ARGSUSED */

int	ro2rtsasync (acb, indication, roi)
register struct assocblk   *acb;
IFP	indication;
struct RoSAPindication *roi;
{
    struct RtSAPindication  rtis;
    register struct RtSAPabort *rta = &rtis.rti_abort;

    if (RtSetIndications (acb -> acb_fd, e (rtsINDICATIONser), &rtis)
	    == NOTOK)
	switch (rta -> rta_reason) {
	    case RTS_WAITING: 
		return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP);

	    default: 
		(void) rtslose (acb, roi, "RtSetIndications", rta);
		freeacblk (acb);
		return NOTOK;
	}

    if (acb -> acb_rosindication = indication)
	acb -> acb_flags |= ACB_ASYN;
    else
	acb -> acb_flags &= ~ACB_ASYN;

    return OK;
}

#undef	e

/* \f

   map association descriptors for select() */

/* ARGSUSED */

int	ro2rtsmask (acb, mask, nfds, roi)
register struct assocblk   *acb;
fd_set *mask;
int    *nfds;
struct RoSAPindication *roi;
{
    struct RtSAPindication  rtis;
    register struct RtSAPabort *rta = &rtis.rti_abort;

    if (RtSelectMask (acb -> acb_fd, mask, nfds, &rtis) == NOTOK)
	switch (rta -> rta_reason) {
	    case RTS_WAITING: 
		return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP);

	    default: 
		(void) rtslose (acb, roi, "RtSelectMask", rta);
		freeacblk (acb);
		return NOTOK;
	}

    return OK;
}

/* \f

   RtSAP interface */

#define	doRTSdata(a,i,t,r)	acb2osdu ((a), (i), (t) -> rtt_data, (r))


int	ro2rtswait (acb, invokeID, secs, roi)
register struct assocblk *acb;
int    *invokeID,
	secs;
register struct RoSAPindication *roi;
{
    int     result;
    struct RtSAPindication  rtis;
    register struct RtSAPindication *rti = &rtis;

    if (acb -> acb_apdu) {
	result = acb2osdu (acb, NULLIP, acb -> acb_apdu, roi);
	acb -> acb_apdu = NULLPE;

	return result;
    }
    if (acb -> acb_flags & ACB_CLOSING) {
	acb -> acb_flags |= ACB_FINN;
	acb -> acb_flags &= ~ACB_CLOSING;
	if (acb -> acb_flags & ACB_FINISH) {
	    acb -> acb_flags &= ~ACB_FINISH;

	    roi -> roi_type = ROI_FINISH;
	    {
		register struct AcSAPfinish  *acf = &roi -> roi_finish;

		*acf = acb -> acb_finish;	/* struct copy */
	    }
	}
	else {
	    roi -> roi_type = ROI_END;
	    {
		register struct RoSAPend   *roe = &roi -> roi_end;

		bzero ((char *) roe, sizeof *roe);
	    }
	}

	return DONE;
    }

    for (;;) {
	switch (result = RtWaitRequest (acb -> acb_fd, secs, rti)) {
	    case NOTOK: 
		return doRTSabort (acb, &rti -> rti_abort, roi);

	    case OK: 
		if ((result = doRTSdata (acb, invokeID, &rti -> rti_transfer,
			roi)) != OK)
		    return (result != DONE ? result : OK);
		continue;

	    case DONE: 
		switch (rti -> rti_type) {
		    case RTI_TURN: 
			if (doRTSturn (acb, &rti -> rti_turn, roi) != OK)
			    return result;
			continue;

		    case RTI_CLOSE: 
			if (doRTSclose (acb, &rti -> rti_close, roi) != OK)
			    return result;
			continue;

		    case RTI_FINISH:
			if (doRTSfinish (acb, &rti -> rti_finish, roi) != OK)
			    return result;
			continue;

		    default: 
			(void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
				"unknown indication (0x%x) from rts",
				rti -> rti_type);
			break;
		}
		break;

	    default: 
		(void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
			"unexpected return from RtWaitRequest=%d", result);
		break;
	}
	break;
    }

    freeacblk (acb);
    return NOTOK;
}

/* \f

 */

/* ARGSUSED */

int	ro2rtswrite (acb, pe, fe, priority, roi)
register struct assocblk *acb;
register PE pe;
PE	fe;
int	priority;
struct RoSAPindication *roi;
{
    int	    result;
    struct RtSAPindication  rtis;
    register struct RtSAPabort *rta = &rtis.rti_abort;

#ifdef	DEBUG
    if (rosap_log -> ll_events & LLOG_PDUS)
	if (acb -> acb_flags & ACB_ACS)
	    vpdu (rosap_log, print_ROS_ROSEapdus, pe, "ROSEapdus", 0)
	else
	    vpdu (rosap_log, print_ROS_OPDU, pe, "OPDU", 0);
#endif

    result = RtTransferRequest (acb -> acb_fd, pe, NOTOK, &rtis);

    if (fe)
	(void) pe_extract (pe, fe);
    pe_free (pe);

    if (result == OK)
	return OK;

    if (rta -> rta_reason == RTS_TRANSFER)
	return rosaplose (roi, ROS_APDU, NULLCP, NULLCP);

    (void) rtslose (acb, roi, "RtTransferRequest", rta);

    freeacblk (acb);
    return NOTOK;
}

/* \f

 */

static int  doRTSturn (acb, rtu, roi)
register struct assocblk *acb;
register struct RtSAPturn *rtu;
register struct RoSAPindication *roi;
{
    struct RtSAPindication  rtis;
    register struct RtSAPindication *rti = &rtis;
    register struct RtSAPabort *rta = &rti -> rti_abort;

    if (rtu -> rtu_please) {
	if (RtGTurnRequest (acb -> acb_fd, rti) == NOTOK)
	    return rtslose (acb, roi, "RtGTurnRequest", rta);
    }

    return OK;
}

/* \f

 */

/* ARGSUSED */

static int  doRTSclose (acb, rtc, roi)
register struct assocblk *acb;
struct RtSAPclose *rtc;
register struct RoSAPindication *roi;
{
    if (acb -> acb_flags & ACB_INIT) {
	(void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
		"association management botched");
	freeacblk (acb);
	return NOTOK;
    }

    roi -> roi_type = ROI_END;
    {
	register struct RoSAPend   *roe = &roi -> roi_end;

	bzero ((char *) roe, sizeof *roe);
    }

    return DONE;
}

/* \f

 */

static int  doRTSfinish (acb, acf, roi)
register struct assocblk *acb;
struct AcSAPfinish *acf;
register struct RoSAPindication *roi;
{
    if (acb -> acb_flags & ACB_INIT) {
	(void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
		"association management botched");
	ACFFREE (acf);
	freeacblk (acb);
	return NOTOK;
    }

    roi -> roi_type = ROI_FINISH;
    roi -> roi_finish = *acf;	/* struct copy */

    return DONE;
}

/* \f

 */

static int  doRTSabort (acb, rta, roi)
register struct assocblk *acb;
register struct RtSAPabort *rta;
register struct RoSAPindication *roi;
{
    if (!rta -> rta_peer) {
	if (rta -> rta_reason == RTS_TIMER)
	    return rosaplose (roi, ROS_TIMER, NULLCP, NULLCP);

	(void) rtslose (acb, roi, NULLCP, rta);
    }
    else
	(void) rosaplose (roi, ROS_ABORTED, NULLCP, NULLCP);

    RTAFREE (rta);
    acb -> acb_fd = NOTOK;
    freeacblk (acb);

    return NOTOK;
}

/* \f

 */

static int  rtsINDICATIONser (sd, rti)
int	sd;
register struct RtSAPindication *rti;
{
    int     result;
    IFP	    handler;
    register struct assocblk   *acb;
    struct RoSAPindication  rois;
    register struct RoSAPindication *roi = &rois;

    if ((acb = findacblk (sd)) == NULL)
	return;

    handler = acb -> acb_rosindication;

    switch (rti -> rti_type) {
	case RTI_TURN: 
	    result = doRTSturn (acb, &rti -> rti_turn, roi);
	    break;

	case RTI_TRANSFER: 
	    result = doRTSdata (acb, NULLIP, &rti -> rti_transfer, roi);
	    break;

	case RTI_ABORT: 
	    result = doRTSabort (acb, &rti -> rti_abort, roi);
	    break;

	case RTI_CLOSE: 
	    result = doRTSclose (acb, &rti -> rti_close, roi);
	    break;

	case RTI_FINISH: 
	    result = doRTSfinish (acb, &rti -> rti_finish, roi);
	    break;

	default: 
	    result = ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
		    "unknown indication (0x%x) from rts",
		    rti -> rti_type);
	    freeacblk (acb);
	    break;
    }

    if (result != OK)
	(*handler) (sd, roi);
}

/* \f

 */

int	ro2rtsready (acb, priority, roi)
register struct assocblk *acb;
int	priority;
struct RoSAPindication *roi;
{
    int	    result;
    struct RtSAPindication  rtis;
    register struct RtSAPindication *rti = &rtis;
    register struct RtSAPabort *rta = &rti -> rti_abort;

    if (acb -> acb_apdu || (acb -> acb_flags & ACB_CLOSING))
	return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP);

    if (RtPTurnRequest (acb -> acb_fd, priority, rti) == NOTOK) {
	(void) rtslose (acb, roi, "RtPTurnRequest", rta);
	goto out;
    }

    do {
	switch (result = RtWaitRequest (acb -> acb_fd, NOTOK, rti)) {
	    case NOTOK: 
		return doRTSabort (acb, &rti -> rti_abort, roi);

	    case OK: 
		acb -> acb_apdu = rti -> rti_transfer.rtt_data;
		return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP);

	    case DONE: 
		switch (rti -> rti_type) {
		    case RTI_TURN: 
			if (doRTSturn (acb, &rti -> rti_turn, roi) != OK)
			    return result;
			continue;

		    case RTI_CLOSE: 
			switch (doRTSclose (acb, &rti -> rti_close, roi)) {
			    case NOTOK:
				return NOTOK;

			    case OK:
				break;

			    case DONE:
				acb -> acb_flags |= ACB_CLOSING;
				acb -> acb_flags &= ~ACB_FINN;
				return rosaplose (roi, ROS_WAITING, NULLCP,
					NULLCP);
			}
			continue;

		    case RTI_FINISH: 
			switch (doRTSfinish (acb, &rti -> rti_finish, roi)) {
			    case NOTOK:
				return NOTOK;

			    case OK:
				break;

			    case DONE:
				acb -> acb_flags |= ACB_FINISH | ACB_CLOSING;
				acb -> acb_flags &= ~ACB_FINN;
							/* struct copy */
				acb -> acb_finish = roi -> roi_finish;
				return rosaplose (roi, ROS_WAITING, NULLCP,
					NULLCP);
			}
			continue;

		    default: 
			(void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
				"unknown indication (0x%x) from rts",
				rti -> rti_type);
			break;
		}
		goto out;

	    default: 
		(void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP,
			"unexpected return from RtWaitRequest=%d", result);
		goto out;
	}
    }
    while (!(acb -> acb_flags & ACB_TURN));

    return OK;

out: ;
    freeacblk (acb);
    return NOTOK;
}

/* \f

 */

static int rtslose (acb, roi, event, rta)
register struct assocblk *acb;
register struct RoSAPindication *roi;
char   *event;
register struct RtSAPabort *rta;
{
    int     reason;
    char   *cp,
            buffer[BUFSIZ];

    if (event)
	SLOG (rosap_log, LLOG_EXCEPTIONS, NULLCP,
	      (rta -> rta_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event,
	       RtErrString (rta -> rta_reason), rta -> rta_cc, rta -> rta_cc,
	       rta -> rta_data));

    cp = "";
    switch (rta -> rta_reason) {
	case RTS_ADDRESS: 
	    reason = ROS_ADDRESS;
	    break;

	case RTS_REFUSED:
	    reason = ROS_REFUSED;
	    break;

	case RTS_CONGEST: 
	    reason = ROS_CONGEST;
	    break;

	default: 
	    (void) sprintf (cp = buffer, " (%s at rts)",
		    RtErrString (rta -> rta_reason));
	case RTS_SESSION:
	    reason = ROS_RTS;
	    break;
    }

    if (rta -> rta_cc > 0)
	return ropktlose (acb, roi, reason, NULLCP, "%*.*s%s",
		rta -> rta_cc, rta -> rta_cc, rta -> rta_data, cp);
    else
	return ropktlose (acb, roi, reason, NULLCP, "%s", *cp ? cp + 1 : cp);
}