|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T r
Length: 11664 (0x2d90)
Types: TextFile
Names: »ro2rts.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z«
└─⟦de7628f85⟧
└─⟦this⟧ »isode-6.0/rosap/ro2rts.c«
/* 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);
}