|
|
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: 10268 (0x281c)
Types: TextFile
Names: »x400topp.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z«
└─⟦e5a54fb17⟧
└─⟦this⟧ »pp-5.0/Chans/x40084/x400topp.c«
/* x400topp.c: X400(1984) protocol to submit format - inbound */
# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Chans/x40084/RCS/x400topp.c,v 5.0 90/09/20 15:56:40 pp Exp Locker: pp $";
# endif
/*
* $Header: /cs/research/pp/hubris/pp-beta/Chans/x40084/RCS/x400topp.c,v 5.0 90/09/20 15:56:40 pp Exp Locker: pp $
*
* $Log: x400topp.c,v $
* Revision 5.0 90/09/20 15:56:40 pp
* rcsforce : 5.0 public release
*
*/
#include "util.h"
#include "chan.h"
#include "q.h"
#include "adr.h"
#include "or.h"
#include "prm.h"
#include "dr.h"
#include "retcode.h"
#include <isode/rtsap.h>
#include <varargs.h>
extern char *remote_site;
extern char *postmaster;
extern int submit_running;
extern CHAN *mychan;
extern Q_struct *PPQuePtr;
extern DRmpdu *DRptr;
int log_msgtype = 0; /* -- logging of msgtypes -- */
enum errstate {
st_normal, st_dr, st_probe, st_err_asn, st_err_submit, st_err_junk
};
static enum errstate state = st_normal;
static int do_extra_encodedtypes ();
/* -- local routines -- */
int bodyproc();
int hdrproc();
int msgfinished();
static int do_extra_encodedtypes();
static int splatfnx();
static void rebuild_eits();
static void resetforpostie();
/* ------------------- Begin Routines ------------------------------------ */
int hdrproc (pe, type)
PE pe;
int type;
{
ADDR *ap;
struct prm_vars prm;
RP_Buf rps, *rp = &rps;
PP_TRACE (("hdrproc (type = '%d')", type));
if (type == NOTOK) {
PP_OPER (NULLCP, ("Bad message"));
resetforpostie (st_err_junk, pe, type, "Transfer is not ASN.1");
return OK;
}
state = st_normal;
if (submit_running == 0) {
if (rp_isbad (io_init (rp)))
adios (NULLCP, "Can't initialise submit: %s",
rp -> rp_line);
submit_running = 1;
}
prm_init (&prm);
prm.prm_opts = PRM_ACCEPTALL | PRM_NOTRACE;
if (rp_isbad (io_wprm (&prm, rp)))
adios (NULLCP, "io_wpm failed %s", rp -> rp_line);
q_init (PPQuePtr);
dr_init (DRptr);
PPQuePtr -> msgtype = log_msgtype = type;
switch (type) {
case MT_UMPDU:
PP_PDU (print_P1_UMPDUEnvelope, pe,
"P1.UMPDUEnvelope", PDU_READ);
PPQuePtr -> inbound = list_rchan_new (remote_site,
mychan -> ch_name);
if (do_P1_UMPDUEnvelope (pe, 1, NULLIP, NULLVP, PPQuePtr)
== NOTOK) {
PP_OPER (NULLCP, ("Parse of P1 failed [%s]", PY_pepy));
resetforpostie (st_err_asn, pe, type,
"ASN.1 is NOT P1");
return OK;
}
rebuild_eits (&PPQuePtr -> encodedinfo,
&PPQuePtr -> orig_encodedinfo,
PPQuePtr -> trace);
break;
case MT_PMPDU:
PP_PDU (print_P1_MPDU, pe,
"P1.MPDU(Probe)", PDU_READ);
if (do_P1_MPDU (pe, 1, NULLIP, NULLVP, NULL)
== NOTOK) {
PP_OPER (NULLCP, ("Parse of P1 failed [%s]", PY_pepy));
resetforpostie (st_err_asn, pe, type,
"ASN.1 is not a Probe");
return OK;
}
state = st_probe;
rebuild_eits (&PPQuePtr -> encodedinfo,
&PPQuePtr -> orig_encodedinfo,
PPQuePtr -> trace);
break;
case MT_DMPDU:
PP_PDU (print_P1_MPDU, pe,
"P1.MPDU(DR)", PDU_READ);
if (do_P1_MPDU (pe, 1, NULLIP, NULLVP, NULL)
== NOTOK) {
PP_OPER (NULLCP, ("Parse of P1 failed [%s]", PY_pepy));
resetforpostie (st_err_asn, pe, type,
"ASN.1 is not a DR");
return OK;
}
state = st_dr;
rebuild_eits (&PPQuePtr -> encodedinfo,
&PPQuePtr -> orig_encodedinfo,
DRptr -> dr_trace);
break;
default:
adios (NULLCP, "Unknown type of structure %d", type);
}
do_extra_encodedtypes (&PPQuePtr -> encodedinfo);
set_msg_adrs();
if (rp_isbad (io_wrq (PPQuePtr, rp)))
adios (NULLCP, "io_wrq %s", rp -> rp_line);
PP_NOTICE (("Originator %s", PPQuePtr -> Oaddress -> ad_value));
if (rp_isbad (io_wadr (PPQuePtr -> Oaddress, AD_ORIGINATOR, rp))) {
char ebuf[BUFSIZ];
do_reason ("io_wadr %s", rp -> rp_line);
if (rp_gbval(rp -> rp_val) == RP_BNO) {
(void) sprintf (ebuf, "Bad originator address %s: %s",
PPQuePtr -> Oaddress -> ad_value,
rp -> rp_line);
resetforpostie (st_err_submit, pe, type, ebuf);
return OK;
}
exit (NOTOK);
}
for (ap = PPQuePtr -> Raddress; ap; ap = ap -> ad_next) {
PP_NOTICE (("Recipient Address %s", ap -> ad_value));
if (rp_isbad (io_wadr (ap, AD_RECIPIENT, rp)))
switch (PPQuePtr -> msgtype) {
case MT_DMPDU:
break;
default:
adios (NULLCP, "io_wadr %s", rp -> rp_line);
}
}
if (rp_isbad (io_adend (rp)))
adios (NULLCP, "io_adend %s", rp -> rp_line);
switch (PPQuePtr -> msgtype) {
case MT_UMPDU:
if (rp_isbad (io_tinit (rp)))
adios (NULLCP, "io_tinit %s", rp -> rp_line);
if (rp_isbad (io_tpart (PPQuePtr -> cont_type, FALSE, rp)))
adios (NULLCP, "io_tpart %s %s",
PPQuePtr -> cont_type, rp -> rp_line);
break;
case MT_DMPDU:
if (rp_isbad (io_wdr (DRptr, rp)))
adios (NULLCP, "io_wdr %s", rp -> rp_line);
break;
case MT_PMPDU:
break;
}
return OK;
}
int bodyproc (str, len)
char *str;
int len;
{
char hexbuf[82];
int i;
RP_Buf rps, *rp = &rps;
PP_TRACE (("Copy %d bytes", len));
switch (state) {
case st_normal:
if (rp_isbad (io_tdata (str, len))) {
PP_LOG (LLOG_EXCEPTIONS, ("data write failed"));
return NOTOK;
}
break;
case st_probe:
case st_dr:
PP_LOG (LLOG_EXCEPTIONS, ("Illegal state in bodyproc"));
break;
case st_err_submit:
case st_err_asn:
case st_err_junk:
for (i = 0; i <= len; i += 40) {
int n = min (40, len - i);
n = explode (hexbuf, str + i, n);
hexbuf[n++] = '\n';
hexbuf[n] = 0;
if (pps_txt (hexbuf, rp) == NOTOK)
adios (NULLCP, "Error writing to submit: %s",
rp -> rp_line);
}
break;
}
return OK;
}
int msgfinished ()
{
RP_Buf rps, *rp = &rps;
switch (state) {
case st_normal:
if (rp_isbad (io_tdend (rp)) ||
rp_isbad (io_tend (rp))) {
PP_LOG (LLOG_EXCEPTIONS,
("Data termination failed: %s",
rp -> rp_line));
return NOTOK;
}
break;
case st_probe:
case st_dr:
break;
case st_err_asn:
case st_err_submit:
case st_err_junk:
pps_end (OK, rp);
break;
}
return OK;
}
/* ------------------- Static Routines ------------------------------------ */
static int splatfnx (va_alist)
va_dcl
{
char buffer[BUFSIZ];
caddr_t junk;
RP_Buf rps;
va_list ap;
va_start (ap);
junk = va_arg (ap, caddr_t);
_asprintf (buffer, NULLCP, ap);
PP_TRACE (("splatfnx '%s'", buffer));
if (pps_txt (buffer, &rps) == NOTOK)
adios (NULLCP, "Write fails: %s", rps.rp_line);
va_end (ap);
}
static void rebuild_eits (eits, orig, trace)
EncodedIT *eits, *orig;
Trace *trace;
{
Trace *tp;
LIST_BPT *lasteit = NULL;
for (tp = trace; tp; tp = tp -> trace_next)
if (tp -> trace_DomSinfo.dsi_converted.eit_types)
lasteit = tp -> trace_DomSinfo.dsi_converted.eit_types;
if (lasteit)
list_bpt_add (&eits -> eit_types, list_bpt_dup (lasteit));
else
list_bpt_add (&eits -> eit_types,
list_bpt_dup (orig -> eit_types));
}
static void resetforpostie (st, pe, type, str)
enum errstate st;
PE pe;
int type;
char *str;
{
static char line[] = "\n\n----------------------------------------\n\n";
char *msg = "<Error>";
RP_Buf rps, *rp = &rps;
PS ps;
PP_NOTICE (("Resending the %s to Postmaster",
type == MT_DMPDU ? "Delivery Report" :
type == MT_PMPDU ? "Probe" : "Message"));
if (submit_running) {
io_end (NOTOK);
submit_running = 0;
}
switch (state = st) {
case st_err_submit:
msg = "Submission Error";
break;
case st_err_asn:
msg = "ASN.1 Parsing error";
break;
case st_err_junk:
msg = "Invalid ASN.1";
break;
default:
adios (NULLCP, "Bad state in resetforpostie %d", st);
}
if (pps_1adr (msg, postmaster, rp) == NOTOK)
adios (NULLCP, "Can't initialize submit for error report: %s",
rp -> rp_line);
if (pps_txt ("X.400 inbound error detected\n\t", rp) == NOTOK ||
pps_txt (str, rp) == NOTOK ||
pps_txt ("\nThe message was received from ", rp) == NOTOK ||
pps_txt (remote_site ? remote_site : "<unknown-site>", rp) == NOTOK)
adios (NULLCP, "Error writing data to submit: %s",
rp -> rp_line);
switch (st) {
case st_err_asn:
msg = "\n\nA dump of the ASN.1 follows:\n\n";
break;
case st_err_junk:
msg = "\n\nA hex dump of the incoming message follows:\n\n";
break;
case st_err_submit:
msg = "\n\nA trace of the P1 envelope follows:\n\n";
break;
}
if (pps_txt (msg, rp) == NOTOK ||
pps_txt (line, rp) == NOTOK)
adios (NULLCP, "Error writing to submit: %s", rp -> rp_line);
if (st == st_err_junk)
return;
switch (type) {
case MT_DMPDU:
vpushpp (stdout, splatfnx, pe, "DR MPDU", PDU_WRITE);
break;
case MT_PMPDU:
vpushpp (stdout, splatfnx, pe, "Probe MPDU", PDU_WRITE);
break;
case MT_UMPDU:
vpushpp (stdout, splatfnx, pe, "User MPDU", PDU_WRITE);
break;
}
switch (st) {
case st_err_asn:
vunknown (pe);
break;
case st_err_submit:
switch (type) {
case MT_DMPDU:
case MT_PMPDU:
print_P1_MPDU(pe, 1, NULLIP, NULLVP, NULLCP);
break;
case MT_UMPDU:
print_P1_UMPDUEnvelope (pe, 1, NULLIP,
NULLVP, NULLCP);
break;
}
}
vpopp ();
if (pps_txt ("\n\nHEX dump of this data now follows", rp) == NOTOK ||
pps_txt (line, rp) == NOTOK)
adios (NULLCP, "Can't write to submit: %s", rp -> rp_line);
if ((ps = ps_alloc (str_open)) == NULLPS)
adios (NULLCP, "Can't allocate PS stream");
if (str_setup (ps, NULLCP, 0, 0) == NOTOK)
adios (NULLCP, "Can't setup PS stream");
if (pe2ps (ps, pe) == NOTOK)
adios (NULLCP, "pe2ps failed: %s", ps_error (ps -> ps_errno));
bodyproc (ps -> ps_base, ps -> ps_ptr - ps -> ps_base);
ps_free (ps);
if (type == MT_UMPDU) {
if (pps_txt ("\n\nP2 hex dump follows", rp) == NOTOK ||
pps_txt (line, rp) == NOTOK)
adios (NULLCP, "Can't write to submit: %s",
rp -> rp_line);
}
}
static int do_extra_encodedtypes (ep)
EncodedIT *ep;
{
extern char *hdr_p2_bp;
LIST_BPT *base = NULLIST_BPT,
*new;
if ((new = list_bpt_new (hdr_p2_bp)) == NULLIST_BPT)
return NOTOK;
list_bpt_add (&base, new);
if (ep ->eit_types)
list_bpt_add (&base, ep->eit_types);
ep->eit_types = base;
return OK;
}