|
|
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: 16859 (0x41db)
Types: TextFile
Names: »x400in88.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z«
└─⟦e5a54fb17⟧
└─⟦this⟧ »pp-5.0/Chans/x40088/x400in88.c«
/* x400in88.c: X400(1988) protocol machine - inbound */
# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Chans/x40088/RCS/x400in88.c,v 5.0 90/09/20 15:58:37 pp Exp Locker: pp $";
# endif
/*
* $Header: /cs/research/pp/hubris/pp-beta/Chans/x40088/RCS/x400in88.c,v 5.0 90/09/20 15:58:37 pp Exp Locker: pp $
*
* $Log: x400in88.c,v $
* Revision 5.0 90/09/20 15:58:37 pp
* rcsforce : 5.0 public release
*
*/
#include "util.h"
#include "chan.h"
#include "q.h"
#include "adr.h"
#include "or.h"
#include "retcode.h"
#include <isode/rtsap.h>
#include "Transfer-types.h"
#include "RTS84-types.h"
extern char *quedfldir;
char *myname;
CHAN *mychan;
char *myhost;
int submit_running;
int canabort = 0;
extern IFP asn_procfnx;
extern int hdrproc (), bodyproc ();
static struct timeval data_timer;
static int data_bytes = 0;
static enum { x400_1988, x400_1984 } stack = x400_1984;
static int rts_sd;
static void rts_adios ();
static void rts_advise ();
static int rts_close ();
static int rts_indication ();
static int rts_turn ();
static int rts_abort ();
static int rts_finish ();
static int rts_uptrans ();
static char *SReportString ();
void advise (), adios ();
#if PP_DEBUG >= PP_DEBUG_SOME
static int do_debug_transfer ();
#endif
static void acs_adios ();
main (argc, argv)
int argc;
char **argv;
{
int sd = -1;
RP_Buf rps, *rp = &rps;
int opt;
extern int optind;
extern char *optarg;
if (myname = rindex (argv[0], '/'))
myname++;
if (myname == NULL || *myname == NULL)
myname = argv[0];
while ((opt = getopt (argc, argv, "c:no")) != EOF) {
switch (opt) {
case 'n':
stack = x400_1988;
break;
case 'o':
stack = x400_1984;
break;
case 'c':
myname = optarg;
break;
default:
adios (NULLCP, "Unknown argument -%c", opt);
}
}
if (stack == x400_1988)
canabort = 1;
chan_init (myname);
if ((mychan = ch_nm2struct (myname)) == NULLCHAN)
adios (NULLCP, "No channel %s", myname);
pp_setuserid();
(void) chdir (quedfldir);
or_myinit();
if (rp_isbad (io_init(rp)))
adios (NULLCP, "Initialisation error %s", rp -> rp_line);
submit_running = 1;
PP_NOTICE (("Starting %s (%s)", mychan->ch_name, mychan->ch_show));
#if PP_DEBUG >= 0
if (argv[optind] && strcmp (argv[optind], "debug") == 0) {
do_debug_transfer ();
exit(0);
}
#endif
switch (stack) {
case x400_1984:
sd = rts_init_1984 (argc, argv);
break;
case x400_1988:
sd = rts_init_1988 (argc, argv);
break;
default:
adios (NULLCP, "Illegal stack");
break;
}
rts_receive (sd);
exit (0);
}
static int rts_uptrans ();
static int check_contexts (ctxlist)
struct PSAPctxlist *ctxlist;
{
OID a_ctx, r_ctx, m_ctx, t_ctx;
int a,r,m, i;
struct PSAPcontext *pp;
a = r = m = 0;
#define aCSE "2.2.1.0.1"
#define rTSE "2.6.0.2.8"
#define mTSE "2.6.0.2.7"
a_ctx = str2oid (aCSE);
r_ctx = str2oid (rTSE);
m_ctx = str2oid (mTSE);
for (i = 0, pp = ctxlist -> pc_ctx;
i < ctxlist -> pc_nctx; pp++, i++) {
if (oid_cmp (pp -> pc_asn, a_ctx) == 0) {
a = 1;
continue;
}
if (oid_cmp (pp -> pc_asn, r_ctx) == 0) {
r = 1;
continue;
}
if (oid_cmp (pp -> pc_asn, m_ctx) == 0) {
m = 1;
continue;
}
advise (NULLCP, "Unexpected context %s",
sprintoid (pp -> pc_asn));
}
if (a != 1)
advise (NULLCP, "context %s not present", aCSE);
if (r != 1)
advise (NULLCP, "context %s not present", rTSE);
if (m != 1)
advise (NULLCP, "context %s not present", mTSE);
oid_free (a_ctx);
oid_free (m_ctx);
oid_free (r_ctx);
return OK;
}
rts_init_1988 (argc, argv)
int argc;
char **argv;
{
struct RtSAPstart rtss;
struct RtSAPstart *rts = &rtss;
struct RtSAPindication rtis;
struct RtSAPindication *rti = &rtis;
struct RtSAPabort *rta = &rti -> rti_abort;
struct AcSAPstart *acs = &rts -> rts_start;
struct PSAPstart *ps = &acs -> acs_start;
struct typre_Transfer_Bind1988Result *res;
PE accept_pe;
OID r_ctx;
r_ctx = oid_cpy (str2oid(rTSE));
PP_TRACE (("rts_init_1988 ()"));
sleep (30);
if (RtInit_Aux (argc, argv, rts, rti, r_ctx) == NOTOK)
rts_adios (rta, "RtInit");
advise (LLOG_NOTICE, NULLCP, "RT-OPEN.INDICATION: <%d, %s, %s, 0x%x>",
rts -> rts_sd,
rts -> rts_mode == RTS_TWA ? "twa" : "mono",
rts -> rts_turn == RTS_RESPONDER ? "responder" : "initiator",
rts -> rts_data);
advise (LLOG_NOTICE, NULLCP, "ACSE: <%d, %s, %s, %s, %d>",
acs -> acs_sd, oid2ode (acs -> acs_context),
sprintaei (&acs -> acs_callingtitle),
sprintaei (&acs -> acs_calledtitle), acs -> acs_ninfo);
advise (LLOG_NOTICE, NULLCP,
"PSAP: <%d, %s, %s, %d, %d, %d>",
ps -> ps_sd,
paddr2str (&ps -> ps_calling, NULLNA),
paddr2str (&ps -> ps_called, NULLNA),
ps -> ps_isn, ps -> ps_ssdusize);
rts_sd = rts -> rts_sd;
if (check_contexts (&ps -> ps_ctxlist) == NOTOK) {
(void) RtOpenResponse (rts_sd, ACS_PERMANENT, NULLOID, NULLAEI,
&ps -> ps_called, NULLPC,
ps -> ps_defctxresult,
NULLPE,
rti);
adios (NULLCP, "Bad presentation context");
}
if (rts -> rts_data == NULLPE) {
(void) RtOpenResponse (rts_sd, ACS_PERMANENT, NULLOID, NULLAEI,
&ps -> ps_called, NULLPC,
ps -> ps_defctxresult,
int2prim (int_MTA_MTABindError_authentication__error),
rti);
adios (NULLCP, "No initial user data");
}
PP_PDU (print_Transfer_Bind1988Argument, rts -> rts_data,
"RTS88.BindArgument", PDU_READ);
if (rts_decode_request (rts, &accept_pe, &res, mychan, 1) != OK) {
PP_OPER (NULLCP, ("rts_decode_request failed"));
(void) RtOpenResponse (rts_sd, ACS_PERMANENT, NULLOID,
NULLAEI, &ps -> ps_called, NULLPC,
ps -> ps_defctxresult,
int2prim (int_MTA_MTABindError_authentication__error),
rti);
adios (NULLCP, "Connection aborted");
}
PP_PDU (print_Transfer_Bind1988Result, accept_pe,
"RTS88.BindResult", PDU_WRITE);
RTSFREE (rts);
if (RtOpenResponse (rts_sd, ACS_ACCEPT, NULLOID, NULLAEI,
&ps -> ps_called, NULLPC, ps -> ps_defctxresult,
accept_pe, rti) == NOTOK)
rts_adios (rta, "RT-OPEN.RESPONSE");
free_Transfer_Bind1988Result (res);
if (RtSetUpTrans (rts_sd, rts_uptrans, rti) == NOTOK)
rts_adios (rta, "RtSetUpTrans");
return rts_sd;
}
rts_init_1984 (argc, argv)
int argc;
char **argv;
{
struct RtSAPstart rtss;
struct RtSAPstart *rts = &rtss;
struct RtSAPindication rtis;
struct RtSAPindication *rti = &rtis;
struct RtSAPabort *rta = &rti -> rti_abort;
struct type_RTS84_Request *request = 0; /* XXX */
int retval;
PE accept_pe;
struct SSAPaddr *sai = &rts -> rts_initiator.rta_addr;
struct TSAPaddr *tai = &sai -> sa_addr;
struct NSAPaddr *nai = tai -> ta_addrs;
if (RtBInit (argc, argv, rts, rti) == NOTOK)
rts_adios (rta, "RtBInit");
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_DBG (("more .... <<%s, '%s' '%d'>, '%s' '%d'>",
na2str (nai),
&tai->ta_selector[0], tai->ta_selectlen,
&sai->sa_selector[0], sai->sa_selectlen));
rts_sd = rts -> rts_sd;
if (rts -> rts_data == NULLPE) {
(void) RtBeginResponse (rts_sd, RTS_VALIDATE, NULLPE, rti);
adios (NULLCP, "No initial user data");
}
PP_PDU (print_RTS84_Request, rts -> rts_data,
"RTS84.Request", PDU_READ);
if ((retval = rts_decode_request (rts, &accept_pe,
&request, mychan, 0)) != OK) {
PP_OPER (NULLCP, ("Can't decode incoming request"));
RtBeginResponse (rts_sd, retval, NULLPE, rti);
adios (NULLCP, "Connection aborted");
}
PP_PDU (print_RTS84_Request, accept_pe, "RTS84.Response", PDU_WRITE);
RTSFREE (rts);
if (RtBeginResponse (rts_sd, RTS_ACCEPT, accept_pe, rti) == NOTOK)
rts_adios (rta, "RT-BEGIN.RESPONSE");
if (RtSetUpTrans (rts_sd, rts_uptrans, rti) == NOTOK)
rts_adios (rta, "RtSetUpTrans");
return rts_sd;
}
rts_receive (sd)
int sd;
{
int result;
struct RtSAPindication rtis;
struct RtSAPindication *rti = &rtis;
for (;;) {
switch (result = RtWaitRequest (sd, NOTOK, rti)) {
case NOTOK:
case OK:
case DONE:
rts_indication (sd, rti);
break;
default:
adios (NULLCP, "Unknown return from RoWaitRequest=%d",
result);
}
}
}
static int rts_indication (sd, rti)
int sd;
register struct RtSAPindication *rti;
{
switch (rti -> rti_type) {
case RTI_TURN:
rts_turn (sd, &rti -> rti_turn);
break;
case RTI_TRANSFER:
if (data_bytes)
timer_end (&data_timer, data_bytes,
"Transfer Completed");
break;
case RTI_ABORT:
rts_abort (sd, &rti -> rti_abort);
break;
case RTI_CLOSE:
rts_close (sd, &rti -> rti_close);
break;
case RTI_FINISH:
rts_finish (sd, &rti -> rti_finish);
break;
default:
adios (NULLCP, "unknown indication type=%d", rti -> rti_type);
}
}
static rts_turn (sd, rtu)
int sd;
register struct RtSAPturn *rtu;
{
struct RtSAPindication rtis;
register struct RtSAPindication *rti = &rtis;
register struct RtSAPabort *rta = &rti -> rti_abort;
if (rtu -> rtu_please) {
if (RtGTurnRequest (sd, rti) == NOTOK)
rts_adios (rta, "RT-TURN-GIVE.REQUEST");
}
}
static int rts_abort (sd, rta)
int sd;
register struct RtSAPabort *rta;
{
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_advise (rta, "RT-P-ABORT.INDICATION");
}
static int rts_close (sd, rtc)
int sd;
struct RtSAPclose *rtc;
{
struct RtSAPindication rtis;
register struct RtSAPindication *rti = &rtis;
register struct RtSAPabort *rta = &rti -> rti_abort;
extern char *remote_site;
advise (LLOG_NOTICE, NULLCP, "RT-END.INDICATION");
if (stack == x400_1988)
advise (LLOG_EXCEPTIONS, NULLCP, "rts_close - 1988mode!");
if (RtEndResponse (sd, rti) == NOTOK)
rts_adios (rta, "RT-END.RESPONSE");
PP_NOTICE (("Normal disconnect from %s", remote_site));
exit (0);
}
static int rts_finish (sd, acf)
int sd;
register struct AcSAPfinish *acf;
{
struct RtSAPindication rtis;
register struct RtSAPindication *rti = &rtis;
register struct RtSAPabort *rta = &rti -> rti_abort;
if (stack == x400_1984)
advise (LLOG_EXCEPTIONS, NULLCP, "rtsfinish - 1984 mode!");
if (RtCloseResponse (sd, ACR_NORMAL, NULLPE, rti) == NOTOK)
rts_adios (rta, "RT-CLOSE.RESPONSE");
ACFFREE (acf);
PP_NOTICE (("Normal disconnected form %s", myhost));
exit (0);
}
static void rts_adios (rta, event)
register struct RtSAPabort *rta;
char *event;
{
rts_advise (rta, event);
_exit (1);
}
static void rts_advise (rta, event)
register struct RtSAPabort *rta;
char *event;
{
char buffer[BUFSIZ];
if (rta -> rta_cc > 0)
(void) sprintf (buffer, "[%s] %*.*s",
RtErrString (rta -> rta_reason),
rta -> rta_cc, rta -> rta_cc, rta -> rta_data);
else
(void) sprintf (buffer, "[%s]",
RtErrString (rta -> rta_reason));
advise (LLOG_NOTICE, NULLCP, "%s: %s", event, buffer);
}
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;
PP_TRACE (("rts_uptrans()"));
switch (type) {
case SI_DATA:
PP_DBG (("SI_DATA"));
data_bytes += qbp -> qb_len;
PP_TRACE (("Data %d bytes (%d so far)", qbp -> qb_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_DBG (("S-MINOR-SYNC.INDICATION: %ld", sn->sn_ssn));
break;
case SI_ACTIVITY:
switch (sv->sv_type) {
case SV_START:
PP_DBG (("S-ACTIVITY-START.INDICATION"));
data_bytes = 0;
timer_start (&data_timer);
asn_init (hdrproc, bodyproc,
stack == x400_1988 ? 1 : 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_DBG (("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"));
PP_LOG (LLOG_EXCEPTIONS,
("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;
}
#if PP_DEBUG >= PP_DEBUG_SOME
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
static void acs_adios (aca, event)
register struct AcSAPabort *aca;
char *event;
{
char buffer[BUFSIZ];
if (aca -> aca_cc > 0)
(void) sprintf (buffer, "[%s] %*.*s",
AcErrString (aca -> aca_reason),
aca -> aca_cc, aca -> aca_cc, aca -> aca_data);
else
(void) sprintf (buffer, "[%s]",
AcErrString (aca -> aca_reason));
adios (NULLCP, "%s: %s (source %d)", event, buffer,
aca -> aca_source);
}
#include <varargs.h>
#ifndef lint
static void adios (va_alist)
va_dcl
{
va_list ap;
va_start (ap);
_ll_log (pp_log_oper, LLOG_FATAL, ap);
_ll_log (pp_log_norm, LLOG_FATAL, ap);
va_end (ap);
_exit (1);
}
#else
/* VARARGS2 */
static void adios (what, fmt)
char *what,
*fmt;
{
adios (what, fmt);
}
#endif
#ifndef lint
static void advise (va_alist)
va_dcl
{
int code;
va_list ap;
va_start (ap);
code = va_arg (ap, int);
_ll_log (pp_log_norm, code, ap);
va_end (ap);
}
#else
/* VARARGS3 */
static void advise (code, what, fmt)
char *what,
*fmt;
int code;
{
advise (code, what, fmt);
}
#endif
#define RC_BASE 0x80
static char *reason_err0[] = {
"no specific reason stated",
"user receiving ability jeopardized",
"reserved(1)",
"user sequence error",
"reserved(2)",
"local SS-user error",
"unreceoverable procedural error"
};
static int reason_err0_cnt = sizeof reason_err0 / sizeof reason_err0[0];
static char *reason_err8[] = {
"demand data token"
};
static int reason_err8_cnt = sizeof reason_err8 / sizeof reason_err8[0];
static char *SReportString (code)
int code;
{
register int fcode;
static char buffer[BUFSIZ];
if (code == SP_PROTOCOL)
return "SS-provider protocol error";
code &= 0xff;
if (code & RC_BASE)
if ((fcode = code & ~RC_BASE) < reason_err8_cnt)
return reason_err8[fcode];
else
if (code < reason_err0_cnt)
return reason_err0[code];
(void) sprintf (buffer, "unknown reason code 0x%x", code);
return buffer;
}
sendrtsabort ()
{
struct RtSAPindication rtis;
register struct RtSAPindication *rti = &rtis;
register struct RtSAPabort *rta = &rti -> rti_abort;
if(RtUAbortRequest (rts_sd, NULLPE, rti) == NOTOK)
rts_advise (rta, "RT-U-ABORT.Request");
}