|
|
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: 6680 (0x1a18)
Types: TextFile
Names: »ro2ssrespond.c«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape
└─⟦eba4602b1⟧ »./isode-5.0.tar.Z«
└─⟦d3ac74d73⟧
└─⟦this⟧ »isode-5.0/rosap/ro2ssrespond.c«
/* ro2ssrespond.c - responder */
#ifndef lint
static char *rcsid = "$Header: /f/osi/rosap/RCS/ro2ssrespond.c,v 6.0 89/03/18 23:42:19 mrose Rel $";
#endif
/*
* $Header: /f/osi/rosap/RCS/ro2ssrespond.c,v 6.0 89/03/18 23:42:19 mrose Rel $
*
* Based on an TCP-based implementation by George Michaelson of University
* College London.
*
*
* $Log: ro2ssrespond.c,v $
* Revision 6.0 89/03/18 23:42:19 mrose
* Release 5.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
RO-BEGIN.INDICATION */
int RoInit (vecp, vec, ros, roi)
int vecp;
char **vec;
struct RoSAPstart *ros;
struct RoSAPindication *roi;
{
int result;
register struct assocblk *acb;
register PE pe;
struct SSAPref ref;
struct SSAPstart sss;
register struct SSAPstart *ss = &sss;
struct SSAPindication sis;
register struct SSAPindication *si = &sis;
register struct SSAPabort *sa = &si -> si_abort;
isodetailor (NULLCP, 0);
missingP (vec);
missingP (ros);
missingP (roi);
if ((acb = newacblk ()) == NULL)
return rosaplose (roi, ROS_CONGEST, NULLCP, "out of memory");
acb -> acb_flags |= ACB_ROS;
(void) RoSService (acb, roi);
if (SInit (vecp, vec, ss, si) == NOTOK) {
(void) ss2roslose (acb, roi, "SInit", sa);
goto out1;
}
acb -> acb_fd = ss -> ss_sd;
acb -> acb_uabort = SUAbortRequest;
acb -> acb_requirements = ss -> ss_requirements & SR_BCSUBSET;
if (acb -> acb_requirements & SR_DUPLEX)
acb -> acb_requirements = SR_DUPLEX;
else
if (acb -> acb_requirements & SR_HALFDUPLEX)
acb -> acb_requirements = SR_HALFDUPLEX;
else {
(void) rosaplose (roi, ROS_PROTOCOL, NULLCP,
"desired session requirements unavailable");
goto out2;
}
if (acb -> acb_requirements & SR_HALFDUPLEX) {
if (((ss -> ss_settings >> ST_DAT_SHIFT) & ST_MASK) == ST_RESP_VALUE) {
acb -> acb_settings = ss -> ss_settings;
acb -> acb_flags |= ACB_TURN;
}
else {
acb -> acb_settings = ST_INIT_VALUE << ST_DAT_SHIFT;
acb -> acb_flags &= ~ACB_TURN;
}
}
if ((pe = ssdu2pe (ss -> ss_data, ss -> ss_cc, NULLCP, &result))
== NULLPE) {
(void) rosaplose (roi, result != PS_ERR_NMEM ? ROS_PROTOCOL
: ROS_CONGEST, NULLCP, "%s", ps_error (result));
goto out2;
}
SSFREE (ss);
acsap_data = NULLPE;
if (parse_OACS_PConnect (pe, 1, NULLIP, NULLVP, NULLCP) == NOTOK) {
(void) pylose ();
pe_free (pe);
goto out2;
}
PLOG (rosap_log, print_OACS_PConnect, pe, "PConnect", 1);
bzero ((char *) ros, sizeof *ros);
ros -> ros_sd = acb -> acb_fd;
ros -> ros_initiator.roa_addr = ss -> ss_calling; /* struct copy */
ros -> ros_port = htons ((u_short) acsap_application);
ros -> ros_data = pe_expunge (pe, acsap_data);
return OK;
out2: ;
bzero ((char *) &ref, sizeof ref);
(void) SConnResponse (acb -> acb_fd, &ref, NULLSA, SC_CONGEST, 0, 0,
SERIAL_NONE, NULLCP, 0, si);
acb -> acb_fd = NOTOK;
out1: ;
SSFREE (ss);
freeacblk (acb);
return NOTOK;
}
/* \f
RO-BEGIN.RESPONSE */
int RoBeginResponse (sd, status, data, roi)
int sd;
int status;
PE data;
struct RoSAPindication *roi;
{
int len,
result;
char *base;
register PE pe,
p,
q,
r;
register struct assocblk *acb;
struct SSAPref ref;
struct SSAPindication sis;
register struct SSAPindication *si = &sis;
register struct SSAPabort *sa = &si -> si_abort;
if ((acb = findacblk (sd)) == NULL || (acb -> acb_flags & ACB_CONN))
return rosaplose (roi, ROS_PARAMETER, NULLCP,
"invalid association descriptor");
if (!(acb -> acb_flags & ACB_ROS))
return rosaplose (roi, ROS_PARAMETER, NULLCP,
"not an association descriptor for ROS");
switch (status) {
case ROS_ACCEPT:
break;
case ROS_VALIDATE:
case ROS_BUSY:
if (data)
return rosaplose (roi, ROS_PARAMETER, NULLCP,
"user data not permitted when refusing association");
break;
default:
return rosaplose (roi, ROS_PARAMETER, NULLCP,
"bad value for status parameter");
}
missingP (roi);
bzero ((char *) &ref, sizeof ref); /* ECMA says don't encode this yet */
base = NULLCP;
switch (status) {
case ROS_ACCEPT:
/* begin PAccept PSDU */
if ((pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, PE_CONS_SET))
== NULLPE) {
no_mem: ;
(void) rosaplose (roi, ROS_CONGEST, NULLCP, "out of memory");
goto out1;
}
if (set_add (pe, p = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS,
PACC_DTS)) == NOTOK
|| set_add (p, num2prim (SYN_X409, PE_CLASS_CONT,
DTS_SYNTAX)) == NOTOK
|| set_add (pe, p = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS,
PACC_DATA)) == NOTOK
|| set_add (p, q = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS,
PACC_DATA_CN)) == NOTOK
|| set_add (q, r = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS,
CN_OPEN)) == NOTOK
|| set_add (r, data ? data : pe_alloc (PE_CLASS_UNIV,
PE_FORM_PRIM, PE_PRIM_NULL))
== NOTOK)
goto no_mem;
/* end PAccept PSDU */
status = SC_ACCEPT;
break;
default:
/* begin PRefuse PSDU */
if ((pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, PE_CONS_SET))
== NULLPE
|| set_add (pe, num2prim (status, PE_CLASS_CONT,
PREF_REASON)) == NOTOK)
goto no_mem;
/* end PRefuse PSDU */
status = SC_REJECTED;
break;
}
#ifdef DEBUG
if (rosap_log -> ll_events & LLOG_PDUS)
if (status == SC_ACCEPT)
vpdu (rosap_log, print_OACS_PAccept, pe, "PAccept", 0)
else
vpdu (rosap_log, print_OACS_PRefuse, pe, "PRefuse", 0);
#endif
if (pe2ssdu (pe, &base, &len) == NOTOK)
goto no_mem;
if (SConnResponse (acb -> acb_fd, &ref, NULLSA, status,
acb -> acb_requirements, acb -> acb_settings, SERIAL_NONE,
base, len, si) == NOTOK) {
acb -> acb_fd = NOTOK;
(void) ss2roslose (acb, roi, "SConnResponse", sa);
goto out3;
}
if (status == SC_ACCEPT)
acb -> acb_flags |= ACB_CONN;
else {
acb -> acb_fd = NOTOK;
freeacblk (acb);
}
result = OK;
out2: ;
if (pe) {
if (data)
(void) pe_extract (pe, data);
pe_free (pe);
}
if (base)
free (base);
return result;
out1: ;
(void) SConnResponse (acb -> acb_fd, &ref, NULLSA, SC_CONGEST, 0, 0,
SERIAL_NONE, NULLCP, 0, si);
acb -> acb_fd = NOTOK;
out3: ;
freeacblk (acb);
result = NOTOK;
goto out2;
}