|
|
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 x
Length: 12788 (0x31f4)
Types: TextFile
Names: »x400in84.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z«
└─⟦e5a54fb17⟧
└─⟦this⟧ »pp-5.0/Chans/x40084/x400in84.c«
/* x400in84.c: receives the incomming x400 messages */
# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Chans/x40084/RCS/x400in84.c,v 5.0 90/09/20 15:56:30 pp Exp Locker: pp $";
# endif
/*
* $Header: /cs/research/pp/hubris/pp-beta/Chans/x40084/RCS/x400in84.c,v 5.0 90/09/20 15:56:30 pp Exp Locker: pp $
*
* $Log: x400in84.c,v $
* Revision 5.0 90/09/20 15:56:30 pp
* rcsforce : 5.0 public release
*
*/
#include "head.h"
#include "prm.h"
#include "dr.h"
#include "q.h"
#include "RTS84-types.h"
#include <sys/stat.h>
#include <isode/rtsap.h>
#include <isode/psap.h>
#include <isode/isoservent.h>
#include <isode/cmd_srch.h>
/* -- defines -- */
/* --- hex dump of msg --- */
#define qb2postie(qb) (send2postie (NULLPE, qb, 0))
/* --- splat of msg --- */
#define pe2postie1(pe) (send2postie (pe, (struct qbuf *)0, 1))
/* --- pretty print of msg --- */
#define pe2postie(pe) (send2postie (pe, (struct qbuf *)0, 2))
#define RTS_MAX_NO_OF_TURNS 5
#define RTS_SENT_TURN 'S'
#define SUBMIT_NOT_CALLED 1
/* -- externals -- */
extern int errno,
body_len;
extern char *isodesetailor(),
*hdr_p2_bp,
*cont_p2,
*loc_dom_site,
*quedfldir,
*body_string,
*rcmd_srch(),
*remote_site;
extern int hdrproc(),
bodyproc(),
msgfinished();
extern void isodetailor();
extern ADDR *adr_new();
extern Q_struct *PPQuePtr;
extern DRmpdu *DRptr;
extern CMD_TABLE qtbl_mt_type[];
extern IFP asn_procfnx;
/* -- statics -- */
static struct timeval data_timer;
static int data_bytes=0,
initial_mode,
initial_turn,
nturns=0,
rts_uptrans();
int submit_running = 0;
static char turn_status=' ';
CHAN *mychan;
/* -- globals -- */
char *myname = "x400in84";
#ifdef PP_DEBUG
static int do_debug_transfer();
#endif
/* -- local routines -- */
void set_msg_adrs();
static int qblen();
static int rts_uptrans();
static int rts_do_turn();
static void rts_get_request();
static void rts_abort();
static void rts_close();
static void rts_get_request();
static void rts_indication();
/* --------------------- Main Routine ---------------------------------- */
/*ARGSUSED)*/
main (argc, argv, envp)
int argc;
char **argv,
**envp;
{
int sd;
struct RtSAPstart rtss;
register struct RtSAPstart *rts = &rtss;
struct RtSAPindication rtis;
register struct RtSAPindication *rti = &rtis;
register struct RtSAPabort *rta = &rti -> rti_abort;
struct SSAPaddr *sai = &rts -> rts_initiator.rta_addr;
struct TSAPaddr *tai = &sai -> sa_addr;
struct NSAPaddr *nai = tai -> ta_addrs;
PE accept_pe = NULLPE;
struct type_RTS84_Request *request = 0;
int retval;
RP_Buf rps, *rp = &rps;
int opt;
extern char *optarg;
extern int optind;
/* -- Reading of the tailor file info -- */
if (myname = rindex (argv[0], '/'))
myname++;
if (myname == NULL || *myname == NULL)
myname = argv[0];
while ((opt = getopt (argc, argv, "c:")) != EOF) {
switch (opt) {
case 'c':
myname = optarg;
break;
default:
adios (NULLCP, "Unknown argument -%c", opt);
}
}
chan_init (myname);
if ((mychan = ch_nm2struct (myname)) == NULLCHAN)
adios (NULLCP, "No such channel %s", myname);
pp_setuserid();
(void) chdir (quedfldir);
or_myinit();
PP_NOTICE (("Starting %s (%s)", mychan->ch_name, mychan->ch_show));
/* --- *** ---
Since isode/isoservices calls x400in84, the RTS connection needs
to be terminated, if an error occurs, otherwise the connection
hangs ... the remote initiator waits for a response and none
is forthcoming ...
--- *** --- */
#if PP_DEBUG
if (argv[optind] && strcmp (argv[optind], "debug") == 0) {
do_debug_transfer();
exit (0);
}
#endif
if (RtBInit (argc, argv, rts, rti) == NOTOK) {
rts_exceptions (rta, "RtBInit");
exit (NOTOK);
}
/* --- And lots & lots of tracing! --- */
PP_TRACE (("RT-BEGIN.INDICATION: <%d, %s, %s, %d, 0x%x>",
rts->rts_sd,
rts->rts_mode == RTS_TWA ? "twa" : "mon",
rts->rts_turn == RTS_RESPONDER ? "responder" : "initiator",
ntohs (rts->rts_port),
rts->rts_data));
PP_TRACE (("Calling addresses: <<%s, %s>, %s>",
na2str (nai),
sel2str (tai->ta_selector, tai->ta_selectlen, 1),
sel2str (sai->sa_selector, sai->sa_selectlen, 1)));
PP_TRACE (("more .... <<%s, '%s' '%d'>, '%s' '%d'>",
na2str (nai),
&tai->ta_selector[0], tai->ta_selectlen,
&sai->sa_selector[0], sai->sa_selectlen));
/* -- Important in determining the logic of the RTS turns -- */
initial_mode = rts->rts_mode;
initial_turn = rts->rts_turn;
sd = rts -> rts_sd;
/* -- x400in84 never transmits information -- */
if (initial_turn == RTS_RESPONDER && initial_mode == RTS_MONOLOGUE) {
do_reason ("main/turn=responder && mode=monologue");
RtBeginResponse (sd, RTS_REJECT, NULLPE, rti);
exit (NOTOK);
}
if (rts->rts_data == NULLPE) {
do_reason ("main/Rejected -- no user data parameter");
RtBeginResponse (sd, RTS_REJECT, NULLPE, rti);
exit (NOTOK);
}
PP_PDU (print_RTS84_Request, rts -> rts_data,
"RTS84.Request", PDU_READ);
if ((retval = rts_decode_request (rts, &accept_pe,
&request, mychan)) != OK) {
RtBeginResponse (sd, retval, NULLPE, rti);
exit (NOTOK);
}
PP_PDU (print_RTS84_Request, accept_pe, "RRTS84.Response", PDU_WRITE);
if (RtBeginResponse (sd, RTS_ACCEPT, accept_pe, rti) == NOTOK) {
rts_advise (rta, "RT-BEGIN.RESPONSE Accept");
RtBeginResponse (sd, RTS_REMOTE, NULLPE, rti);
exit (NOTOK);
}
if (accept_pe)
pe_free (accept_pe);
if (request)
free_RTS84_Request (request);
/* --- *** ---
Initialise submit as late as possible so if error occurs earlier on
x400in and submit are not both running.
--- *** --- */
if (rp_isbad (io_init(rp)))
adios (NULLCP, "io_init error: %s", rp -> rp_line);
submit_running = 1;
/* -- Returns the turn. x400in84 never transmits info -- */
if (initial_turn == RTS_RESPONDER) {
if (RtGTurnRequest (sd, rti) == NOTOK)
rts_adios (rta, "RT-TURN-GIVE.REQUEST");
turn_status = RTS_SENT_TURN;
nturns++;
}
RTSFREE (rts);
/* -- Sets up the RTS to receive incomming data -- */
if (RtSetUpTrans (sd, rts_uptrans, rti) == NOTOK)
rts_adios (rta, "RtSetUpTrans upcall");
rts_get_request (sd);
do_reason ("main/Impossible to arrive here!");
exit (NOTOK);
}
void set_msg_adrs()
{
ADDR *ap;
for (ap = PPQuePtr->Raddress; ap; ap = ap->ad_next)
if (ap->ad_resp == NO)
ap->ad_status = AD_STAT_DONE;
}
/* --------------------- Static Routines ------------------------------- */
static void rts_get_request (sd)
int sd;
{
struct RtSAPindication rti;
int loop_forever = TRUE,
result;
while (loop_forever) {
switch (result = RtWaitRequest (sd, NOTOK, &rti)) {
case NOTOK:
case OK:
case DONE:
PP_TRACE (("rts_get_request (%d)", result));
rts_indication (sd, &rti);
break;
default:
do_reason ("rts_get_request/result='%d'", result);
}
}
}
static void rts_indication (sd, rti)
int sd;
struct RtSAPindication *rti;
{
switch (rti->rti_type) {
case RTI_TURN:
PP_TRACE (("RTI_TURN"));
if (rts_do_turn (sd, &rti->rti_turn) == NOTOK)
rts_abort (sd, &rti->rti_abort);
break;
case RTI_TRANSFER:
PP_TRACE (("RTI_TRANSFER"));
/* -- rts_uptrans() does all the work -- */
timer_end (&data_timer, data_bytes, "Transfer Completed");
break;
case RTI_ABORT:
PP_TRACE (("RTI_ABORT"));
rts_abort (sd, &rti->rti_abort);
break;
case RTI_CLOSE:
PP_TRACE (("RTI_CLOSE"));
rts_close (sd, &rti->rti_close);
break;
default:
do_reason ("rts_indication/'%d' unknown", rti->rti_type);
rts_abort (sd, &rti->rti_abort);
break;
}
}
static int rts_do_turn (sd, rtu)
int sd;
struct RtSAPturn *rtu;
{
struct RtSAPindication rti;
PP_TRACE (("rts_do_turn %s %s %d %s",
initial_mode == RTS_TWA ? "twa" : "mon",
initial_turn == RTS_RESPONDER ? "responder" : "initiator",
nturns,
turn_status == RTS_SENT_TURN ? "send" : "received"));
/* -- Remote site is requesting the turn which x400in84 -- */
/* -- already possesses -- */
if (rtu->rtu_please)
if (turn_status == RTS_SENT_TURN) {
do_reason ("rts_do_turn/Already sent turn!");
return NOTOK;
}
else {
/* -- should never have turn! but left for now -- */
do_reason ("rts_do_turn/Should not have turn!");
return NOTOK;
}
/* -- Remote site is transferring the turn to x400in84 -- */
if (initial_turn == RTS_INITIATOR && initial_mode == RTS_MONOLOGUE) {
do_reason ("rts_do_turn/Should not give turn in Monologue!");
return NOTOK;
}
if (nturns > RTS_MAX_NO_OF_TURNS) {
do_reason ("rts_do_turn/Too many turns occurred!");
return NOTOK;
}
/* -- Returns turn but keeps count to prevent turn looping -- */
if (RtGTurnRequest (sd, &rti) == NOTOK) {
do_reason ("rts_do_turn/RT-TURN-GIVE.REQUEST failed");
return NOTOK;
}
turn_status = RTS_SENT_TURN;
nturns++;
return OK;
}
/*ARGSUSED*/
static void rts_abort (sd, rta)
int sd;
register struct RtSAPabort *rta;
{
if (submit_running)
io_end (NOTOK);
if (rta->rta_peer)
rts_adios (rta, "RT-U-ABORT.INDICATION");
if (RTS_FATAL (rta->rta_reason))
rts_adios (rta, "RT-P-ABORT.INDICATION");
rts_adios (rta, "RT-P-ABORT.INDICATION (error)");
}
/* ARGSUSED */
static void rts_close (sd, rtc)
int sd;
struct RtSAPclose *rtc;
{
struct RtSAPindication rtis;
register struct RtSAPindication *rti = &rtis;
register struct RtSAPabort *rta = &rti->rti_abort;
PP_TRACE (("RT-END.INDICATION %d", sd));
if (RtEndResponse (sd, rti) == NOTOK)
rts_adios (rta, "RT-END-RESPONSE.REQUEST error");
if (submit_running)
io_end (OK);
PP_NOTICE (("Connection successfully terminated"));
exit (0);
}
static struct qbuf *fullqb = NULL;
/*ARGSUSED)*/
static int rts_uptrans (sd, type, addr, rti)
int sd;
int type;
caddr_t addr;
struct RtSAPindication *rti;
{
register struct SSAPactivity *sv = (struct SSAPactivity *) addr;
register struct SSAPsync *sn = (struct SSAPsync *) addr;
register struct SSAPreport *sp = (struct SSAPreport *) addr;
register struct qbuf *qbp = (struct qbuf *) addr;
PE pe = NULLPE;
int len;
PP_TRACE (("rts_uptrans()"));
switch (type) {
case SI_DATA:
PP_TRACE (("SI_DATA"));
len = qblen (qbp);
data_bytes += len;
PP_TRACE (("Data %d bytes (%d so far)", len, data_bytes));
switch ((*asn_procfnx)(qbp)) {
case NOTOK:
default:
io_end (NOTOK);
submit_running = 0;
return rtsaplose (rti, RTS_TRANSFER, NULLCP,
"process data failed");
case OK:
case DONE:
break;
}
break;
case SI_SYNC:
PP_TRACE (("S-MINOR-SYNC.INDICATION: %ld", sn->sn_ssn));
break;
case SI_ACTIVITY:
switch (sv->sv_type) {
case SV_START:
PP_TRACE (("S-ACTIVITY-START.INDICATION"));
data_bytes = 0;
timer_start (&data_timer);
asn_init (hdrproc, bodyproc, 0);
break;
case SV_INTRIND:
case SV_DISCIND:
PP_LOG (LLOG_EXCEPTIONS,
("activity %s: %s",
sv->sv_type == SV_INTRIND ?
"interrupted" : "discarded",
SReportString (sv->sv_reason)));
break;
case SV_ENDIND:
PP_TRACE (("S-ACTIVITY-END.INDICATION"));
PP_TRACE (("Accumulated '%d'", data_bytes));
if (msgfinished() == NOTOK)
return rtsaplose (rti, RTS_TRANSFER,
NULLCP,
"data termination failed");
break;
default:
return (rtsaplose (rti, RTS_TRANSFER, NULLCP,
"unexpected activity indication=0x%x",
sv->sv_type));
}
break;
case SI_REPORT:
if (!sp->sp_peer)
return (rtsaplose (rti, RTS_TRANSFER, NULLCP,
"unexpected provider-initiated SI_REPORT"));
do_reason ("rts_uptrans/Exception Report: '%s'",
SReportString (sp->sp_reason));
if (pe)
pe_free (pe);
break;
default:
return (rtsaplose (rti, RTS_TRANSFER, NULLCP,
"unknown rts_uptrans type=0x%x", type));
}
return OK;
}
static int qblen (qbstart)
struct qbuf *qbstart;
{
int len;
register struct qbuf *qb;
for (len = 0, qb = qbstart->qb_forw; qb != qbstart; qb = qb->qb_forw)
len += qb -> qb_len;
return len;
}
/* --------------------- Postmaster Routines ---------------------------- */
#if PP_DEBUG
static int do_debug_transfer()
{
char buf[BUFSIZ];
int n;
int result = NOTOK;
struct qbuf *qb;
struct SSAPactivity ssa;
struct RtSAPindication rti;
bzero ((char *)&ssa, sizeof ssa);
bzero ((char *)&rti, sizeof rti);
ssa.sv_type = SV_START;
rts_uptrans (0, SI_ACTIVITY, (caddr_t)&ssa, &rti);
while ((n = fread (buf, 1, sizeof buf, stdin)) > 0) {
qb = str2qb (buf, n, 1);
rts_uptrans (0, SI_DATA, (caddr_t)qb, &rti);
qb_free (qb);
}
ssa.sv_type = SV_ENDIND;
rts_uptrans (0, SI_ACTIVITY, (caddr_t)&ssa, &rti);
if (result != DONE)
advise (NULLCP, "Read message - not parsed");
}
#endif