DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T x

⟦038b9023d⟧ TextFile

    Length: 10268 (0x281c)
    Types: TextFile
    Names: »x400topp.c«

Derivation

└─⟦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« 

TextFile

/* 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;
}