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 p

⟦c61279bc8⟧ TextFile

    Length: 28155 (0x6dfb)
    Types: TextFile
    Names: »pptox400.c«

Derivation

└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
    └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« 
        └─⟦e5a54fb17⟧ 
            └─⟦this⟧ »pp-5.0/Chans/x40088/pptox400.c« 

TextFile

/* pptox400.c: convert PP structures to X.400 88 structures */

# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Chans/x40088/RCS/pptox400.c,v 5.0 90/09/20 15:57:33 pp Exp Locker: pp $";
# endif

/*
 * $Header: /cs/research/pp/hubris/pp-beta/Chans/x40088/RCS/pptox400.c,v 5.0 90/09/20 15:57:33 pp Exp Locker: pp $
 *
 * $Log:	pptox400.c,v $
 * Revision 5.0  90/09/20  15:57:33  pp
 * rcsforce : 5.0 public release
 * 
 */



#include "util.h"
#include "q.h"
#include "adr.h"
#include "dr.h"
#include "Transfer-types.h"
#include "or.h"
#include <isode/cmd_srch.h>
#include <rtsparams.h>

#define STR2QB(s)	str2qb(s, strlen(s), 1)

static struct type_MTA_MessageTransferEnvelope *build_envelope ();
static struct type_MTA_MTSIdentifier *build_msgid ();
struct type_MTA_ORName	*build_addr ();
static struct type_MTA_EncodedInformationTypes *build_eits ();
static struct type_MTA_BuiltInContentType *build_content ();
static PE	build_pmf ();
struct type_UNIV_UTCTime *build_time ();
static struct element_MTA_5 *build_recips ();
static PE	build_ri ();
static struct type_MTA_TraceInformation *build_trace ();
struct type_MTA_GlobalDomainIdentifier *build_gdi ();
struct type_MTA_Extensions *build_pm_extensions ();
struct type_MTA_Extensions *build_prf_ext ();
static struct type_MTA_ORName *conv_or ();
static struct type_MTA_ReportTransferEnvelope *build_drenvelope ();
static struct type_MTA_ReportTransferContent *build_drcontent ();
static struct element_MTA_10 *build_drc_pr_fields ();
static struct type_MTA_LastTraceInformation *build_lasttrace ();
static struct type_MTA_Report *build_report ();
struct type_MTA_ORName *build_fullname ();
static void add_eeit ();

struct type_Transfer_MtsAPDU *build_p1 (qp, adl)
Q_struct *qp;
ADDR	*adl;
{
	struct type_Transfer_MtsAPDU *p1;

	p1 = (struct type_Transfer_MtsAPDU *) smalloc (sizeof *p1);
	bzero ((char *)p1, sizeof *p1);

	p1 -> offset = type_Transfer_MtsAPDU_message;
	p1 -> un.message = (struct type_Transfer_MessageAPDU *)
		smalloc (sizeof *p1 -> un.message);
	p1 -> un.message -> envelope = build_envelope (qp, adl);
	p1 -> un.message -> content = NULL;

	return p1;
}

struct type_Transfer_MtsAPDU *build_dr (qp, recip, dr)
Q_struct *qp;
ADDR	*recip;
DRmpdu	*dr;
{
	struct type_Transfer_MtsAPDU *p1dr;

	p1dr = (struct type_Transfer_MtsAPDU *) smalloc (sizeof *p1dr);
	bzero ((char *)p1dr, sizeof *p1dr);

	p1dr -> offset = type_Transfer_MtsAPDU_report;
	p1dr -> un.report = (struct type_Transfer_ReportAPDU *)
		smalloc (sizeof *p1dr -> un.report);
	p1dr -> un.report -> envelope = build_drenvelope (qp, dr);
	p1dr -> un.report -> content = build_drcontent (qp, recip, dr);

	return p1dr;
}

static struct type_MTA_MessageTransferEnvelope *build_envelope (qp, adl)
Q_struct *qp;
ADDR	*adl;
{
	struct type_MTA_MessageTransferEnvelope *env;

	env = (struct type_MTA_MessageTransferEnvelope *)
		smalloc (sizeof *env);
	bzero ((char *)env, sizeof *env);

	env -> message__identifier = build_msgid (&qp->msgid);

	env -> originator__name = build_addr (qp -> Oaddress -> ad_r400adr);

	env -> original__encoded__information__types =
		build_eits (&qp -> encodedinfo);

	env -> content__type = build_content (adl -> ad_content ?
					      adl -> ad_content :
					      qp -> cont_type);

	if (qp -> ua_id)
		env -> content__identifier =
			STR2QB (qp -> ua_id);

	env -> priority = (struct type_MTA_Priority *)
		smalloc (sizeof *env -> priority);
	env -> priority -> parm = qp -> priority;

	env -> per__message__indicators = build_pmf (qp);

	if (qp -> defertime)
		env -> deferred__delivery__time =
			build_time (qp -> defertime);

	env -> per__domain__bilateral__information = NULL;

	env -> extensions = build_pm_extensions (qp);

	env -> trace__information = build_trace (qp->trace);

	env -> per__recipient__fields = build_recips (qp -> Raddress, adl,
						      qp->disclose_recips);

	return env;
}

static struct type_MTA_MTSIdentifier *build_msgid (mid)
MPDUid *mid;
{
	struct type_MTA_MTSIdentifier *p1msgid;

	p1msgid = (struct type_MTA_MTSIdentifier *) smalloc (sizeof *p1msgid);
	bzero ((char *)p1msgid, sizeof *p1msgid);

	if (mid -> mpduid_string)
		p1msgid -> local__identifier =
			STR2QB (mid -> mpduid_string);

	p1msgid -> global__domain__identifier =
		build_gdi (&mid -> mpduid_DomId);
	return p1msgid;
}

struct type_MTA_ORName	*build_addr (cp)
char	*cp;
{
	OR_ptr or;
	struct type_MTA_ORName *orname;

	if ((or = or_std2or (cp)) == NULLOR) {
		PP_LOG (LLOG_EXCEPTIONS, ("Can't convert %s", cp));
		return NULL;
	}

	orname = conv_or (or);
	or_free (or);
	return orname;
}

static struct type_MTA_EncodedInformationTypes *build_eits (eit)
EncodedIT *eit;
{
	struct type_MTA_EncodedInformationTypes *p1eit;
	LIST_BPT	*ep;
	int	n, internal;
	extern CMD_TABLE bptbl_body_parts88[];

	if (eit == NULL)
		return NULL;

	p1eit = (struct type_MTA_EncodedInformationTypes *)
		smalloc (sizeof *p1eit);
	bzero ((char *)p1eit, sizeof *p1eit);
	p1eit -> built__in__encoded__information__types = NULL;
	p1eit -> external__encoded__information__types = NULL;
	internal = 0;

	for (ep = eit -> eit_types; ep; ep = ep -> li_next) {
		if ((n = cmd_srch (ep -> li_name, bptbl_body_parts88)) != -1) {
			if (n <= 15 )
				internal |= n;
		}
		else 
			add_eeit (&p1eit -> external__encoded__information__types,
				  ep -> li_name);
	}
	{
		char *str = int2strb (internal, 12);
		p1eit -> built__in__encoded__information__types =
			strb2bitstr (str, 12, PE_CLASS_UNIV, PE_PRIM_BITS);
	}

	return p1eit;
}

static void add_eeit (eep, oidn)
struct type_MTA_ExternalEncodedInformationTypes **eep;
char	*oidn;
{
	if (*eep == NULL) {
		*eep = (struct type_MTA_ExternalEncodedInformationTypes *)
			calloc (1, sizeof **eep);
		(*eep) -> ExternalEncodedInformationType = str2oid (oidn);
	}
	else {
		struct type_MTA_ExternalEncodedInformationTypes *ep;

		for (ep = *eep; ep -> next; ep = ep -> next)
			continue;
		ep -> next = (struct type_MTA_ExternalEncodedInformationTypes *)
			calloc (1, sizeof *ep);
		ep -> next -> ExternalEncodedInformationType =
			str2oid (oidn);
	}
}

static struct type_MTA_BuiltInContentType *build_content (str)
char	*str;
{
	struct type_MTA_BuiltInContentType *bict;

	bict = (struct type_MTA_BuiltInContentType *) smalloc (sizeof *bict);
	bzero ((char *)bict, sizeof *bict);
	if (lexequ (str, "p2") == 0)
		bict -> parm =
			int_MTA_BuiltInContentType_interpersonal__messaging__1984;
	else if (lexequ (str, "p22") == 0)
		bict -> parm =
			int_MTA_BuiltInContentType_interpersonal__messaging__1988;
	else if (lexequ (str, "external") == 0)
		bict -> parm = int_MTA_BuiltInContentType_external;
	else	bict -> parm = int_MTA_BuiltInContentType_unidentified;

	return bict;
}

static PE	build_pmf (qp)
Q_struct *qp;
{
	PE pe;

	pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_BITS);

	if (qp -> disclose_recips)
		bit_on (pe, bit_MTA_PerMessageIndicators_disclosure__of__recipients);
	if (qp -> implicit_conversion)
		bit_on (pe, bit_MTA_PerMessageIndicators_implicit__conversion__prohibited);
	if (qp -> alternate_recip_allowed)
		bit_on (pe, bit_MTA_PerMessageIndicators_alternate__recipient__allowed);
	if (qp -> content_return_request)
		bit_on (pe, bit_MTA_PerMessageIndicators_content__return__request);

	return pe;
}

struct type_UNIV_UTCTime *build_time (utc)
UTC	utc;
{
	struct type_UNIV_UTCTime *ut;
	char	*str;

	str = utct2str (utc);
	
	ut = STR2QB (str);
	return ut;
}

static struct element_MTA_5 *build_recips (ad, adl, disclose)
ADDR	*ad;
ADDR	*adl;
int	disclose;
{
	struct element_MTA_5 *rl = NULL, *rlbase = NULL;
	struct type_MTA_PerRecipientMessageTransferFields *prmtf;
	ADDR	*ap, *ap2;
	int	resp;

	for (ap = ad; ap; ap = ap -> ad_next) {
		for (ap2 = adl; ap2; ap2 = ap2 -> ad_next) {
			if (ap2 -> ad_no == ap -> ad_no)
				break;
		}
		if (ap2 == NULLADDR) {
			if (disclose == 0)
				continue;
			else
				resp = FALSE;
		}
		else	resp = ap2 -> ad_resp;
				

		if (rlbase == NULL) 
			rl = rlbase = (struct element_MTA_5 *)
				smalloc (sizeof *rl);
		else {
			rl -> next = (struct element_MTA_5 *)
				smalloc (sizeof *rl);
			rl = rl -> next;
		}
		bzero ((char *)rl, sizeof *rl);
		prmtf = rl -> PerRecipientMessageTransferFields =
			(struct type_MTA_PerRecipientMessageTransferFields *)
			smalloc (sizeof *prmtf);
		prmtf -> recipient__name = build_addr (ap -> ad_r400adr);

		prmtf -> originally__specified__recipient__number =
			(struct type_MTA_OriginallySpecifiedRecipientNumber *)
			smalloc (sizeof *prmtf ->
				 originally__specified__recipient__number);
		prmtf -> originally__specified__recipient__number -> parm =
			ap -> ad_extension;

		if (ap -> ad_explicitconversion != AD_EXP_NONE) {
			prmtf -> explicit__conversion =
				(struct type_MTA_ExplicitConversion *)
					smalloc (sizeof *prmtf -> explicit__conversion);
			prmtf -> explicit__conversion -> parm =
				ap -> ad_explicitconversion;
		}
		else prmtf -> explicit__conversion = NULL;

		prmtf -> per__recipient__indicators = build_ri (resp,
								ad -> ad_mtarreq,
								ad -> ad_usrreq);
		prmtf -> extensions = build_prf_ext (ap);
	}
	return rlbase;
}

static PE	build_ri (resp, mta, usr)
int	resp, mta, usr;
{
	PE	pe;

	pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_BITS);
	if (resp)
		bit_on (pe,
			bit_MTA_PerRecipientIndicators_responsibility);

	switch (mta) {
	    case AD_MTA_NONE:
		break;
	    case AD_MTA_BASIC:
		bit_on (pe,
			bit_MTA_PerRecipientIndicators_originating__MTA__non__delivery__report);
		break;
	    case AD_MTA_CONFIRM:
		bit_on (pe,
			bit_MTA_PerRecipientIndicators_originating__MTA__report);
		break;
	    case AD_MTA_AUDIT_CONFIRM:
		bit_on (pe,
			bit_MTA_PerRecipientIndicators_originating__MTA__non__delivery__report);
		bit_on (pe,
			bit_MTA_PerRecipientIndicators_originating__MTA__report);
		break;
	}
	switch (usr) {
	    case AD_USR_NOREPORT:
		break;
	    case AD_USR_BASIC:
		bit_on (pe,
			bit_MTA_PerRecipientIndicators_originator__non__delivery__report);
		break;
	    case AD_USR_CONFIRM:
		bit_on (pe,
			bit_MTA_PerRecipientIndicators_originator__report);
	}
	return pe;
}

static struct type_MTA_TraceInformationElement *build_traceelement (tp)
Trace	*tp;
{
	struct type_MTA_TraceInformationElement *tie;
	struct type_MTA_DomainSuppliedInformation *dsi;
	DomSupInfo *dsp;

	tie = (struct type_MTA_TraceInformationElement *)
		smalloc (sizeof *tie);
	bzero ((char *)tie, sizeof *tie);
	tie -> global__domain__identifier =
		build_gdi (&tp -> trace_DomId);

	dsp = &tp -> trace_DomSinfo;
	dsi = tie -> domain__supplied__information =
		(struct type_MTA_DomainSuppliedInformation *)
			smalloc (sizeof *tie ->
				 domain__supplied__information);
	bzero ((char *)dsi, sizeof *dsi);
	if (dsp -> dsi_time)
		dsi -> arrival__time = build_time (dsp -> dsi_time);

	dsi -> routing__action =
		(struct type_MTA_RoutingAction *)
			smalloc (sizeof *dsi -> routing__action);
	if (dsp -> dsi_action)
		dsi -> routing__action -> parm = dsp -> dsi_action;
	else	dsi -> routing__action -> parm = 
		int_MTA_RoutingAction_relayed;

	if (dsp -> dsi_attempted_md.global_Country != NULLCP &&
	    dsp -> dsi_attempted_md.global_Admin != NULLCP)
		dsi -> attempted__domain =
			build_gdi (&dsp -> dsi_attempted_md);

	if (dsp -> dsi_deferred)
		dsi -> deferred__time =
			build_time (dsp -> dsi_deferred);

	if (dsp -> dsi_converted.eit_types)
		dsi -> converted__encoded__information__types =
			build_eits (&dsp -> dsi_converted);

	if (dsp -> dsi_other_actions) {
		dsi -> other__actions =
			pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM,
				  PE_PRIM_BITS);
		if (dsp -> dsi_other_actions & ACTION_REDIRECTED)
			bit_on (dsi -> other__actions,
				bit_MTA_OtherActions_redirected);
		if (dsp -> dsi_other_actions & ACTION_EXPANDED)
			bit_on (dsi -> other__actions,
				bit_MTA_OtherActions_dl__operation);
	}
	return tie;
}

int same_prmd (tp1, tp2)
Trace	*tp1, *tp2;
{
	GlobalDomId *d1, *d2;

	d1 = &tp1 -> trace_DomId;
	d2 = &tp2 -> trace_DomId;

	if (d1 -> global_Country && d2 -> global_Country &&
	    lexequ (d1 -> global_Country, d2 -> global_Country) == 0 &&
	    d1 -> global_Admin && d2 -> global_Admin &&
	    lexequ (d1 -> global_Admin, d2 -> global_Admin) == 0) {
		if (d1 -> global_Private == NULL &&
		    d2 -> global_Private == NULL)
			return 1;
		if (d1 -> global_Private && d2 -> global_Private &&
		    lexequ (d1 -> global_Private, d2 -> global_Private) == 0)
			return 1;
	}
	return 0;
	    
}

static struct type_MTA_TraceInformation *build_trace (trp)
Trace	*trp;
{
	Trace	*tp, *tlast;
	struct type_MTA_TraceInformation *trace = NULL, *tbase = NULL;
	extern int trace_type;

	for (tlast = trp; tlast && tlast -> trace_next;
	     tlast = tlast -> trace_next)
		continue;

	if (trace_type == RTSP_TRACE_ADMD) {
		if (tlast != trp && same_prmd (tlast, trp))
			tp = trp;
		else	tp = tlast;
		tbase = (struct type_MTA_TraceInformation *)
			smalloc (sizeof *trace);
		tbase -> next = NULL;
		tbase -> TraceInformationElement =
			build_traceelement (tp);
		return tbase;
	}
			
	for (tp = trp; tp; tp = tp -> trace_next) {
		if (tbase == NULL)
			tbase = trace =
				(struct type_MTA_TraceInformation *)
					smalloc (sizeof *trace);
		else {
			trace -> next =
				(struct type_MTA_TraceInformation *)
					smalloc (sizeof *trace);
			trace = trace -> next;
		}
		bzero ((char *)trace, sizeof *trace);
		trace -> TraceInformationElement =
			build_traceelement(tp);
	}

	return tbase;
}

struct type_MTA_GlobalDomainIdentifier *build_gdi (gdi)
GlobalDomId *gdi;
{
	struct type_MTA_GlobalDomainIdentifier *p1gdi;
	struct type_MTA_AdministrationDomainName *admd;
	struct type_MTA_CountryName *co;
	struct type_MTA_PrivateDomainIdentifier *prmd;

	p1gdi = (struct type_MTA_GlobalDomainIdentifier *)
		smalloc (sizeof *p1gdi);
	bzero ((char *)p1gdi, sizeof *p1gdi);
	
	if (gdi -> global_Country) {
		p1gdi -> country__name = co =
			(struct type_MTA_CountryName *)
				smalloc (sizeof *co);
		co -> offset = type_MTA_CountryName_iso__3166__alpha2__code;
		co -> un.iso__3166__alpha2__code =
			STR2QB (gdi -> global_Country);
	}
	else
		PP_LOG (LLOG_EXCEPTIONS, ("Country missing from GDI"));
	if (gdi -> global_Admin) {
		p1gdi -> administration__domain__name = admd =
			(struct type_MTA_AdministrationDomainName *)
				smalloc (sizeof *admd);
		admd -> offset = type_MTA_AdministrationDomainName_printable;
		admd -> un.printable = STR2QB (gdi -> global_Admin);
	}
	else
		PP_LOG (LLOG_EXCEPTIONS, ("ADMD missing from GDI"));

	if (gdi -> global_Private) {
		p1gdi -> private__domain__identifier = prmd =
			(struct type_MTA_PrivateDomainIdentifier *)
				smalloc (sizeof *prmd);
		prmd -> offset = type_MTA_PrivateDomainIdentifier_printable;
		prmd -> un.printable = STR2QB (gdi -> global_Private);
	}

	return p1gdi;
}

static struct type_MTA_ORName *conv_or (or_tree)
OR_ptr or_tree;
{
	struct type_MTA_ORName *orname;
	OR_ptr or;

	orname = (struct type_MTA_ORName *) smalloc (sizeof *orname);
	bzero ((char *)orname, sizeof *orname);

	for (or = or_tree; or; or = or -> or_next) {
		if (or -> or_type == OR_DD &&
		    or -> or_encoding == OR_ENC_PS)
			build_dd_or (&orname -> domain__defined, or);
		else if (or -> or_type < OR_GQ)
			build_std_or (&orname -> standard__attributes, or);
		else if (or -> or_type == OR_CN)
			build_cn_or (&orname -> directory__name, or);
		else
			build_ext_or (&orname -> extension__attributes, or);
	}
	return orname;
}

build_std_or (std, or)
struct type_MTA_StandardAttributes **std;
OR_ptr or;
{
	if (*std == NULL) {
		*std = (struct type_MTA_StandardAttributes *)
			smalloc (sizeof **std);
		bzero ((char *)*std, sizeof **std);
	}
	
	switch (or -> or_type) {
	    case OR_C:
		{
			struct type_MTA_CountryName *co;
			if ((*std) -> country__name) {
				PP_LOG (LLOG_EXCEPTIONS,
					("two country attribues"));
				return;
			}
			co = (struct type_MTA_CountryName *)
				smalloc (sizeof *co);
			co -> offset = type_MTA_CountryName_iso__3166__alpha2__code;
			co -> un.iso__3166__alpha2__code =
				STR2QB (or -> or_value);
			(*std) -> country__name = co;
		}
		break;
	    case OR_ADMD:
		{
			struct type_MTA_AdministrationDomainName *admd;

			if ((*std) -> administration__domain__name != NULL) {
				PP_LOG (LLOG_EXCEPTIONS,
					("Already got an ADMD"));
				return;
			}
			admd = (*std) -> administration__domain__name =
				(struct type_MTA_AdministrationDomainName *)
					smalloc (sizeof *admd);
			admd -> offset =
				type_MTA_AdministrationDomainName_printable;
			admd -> un.printable = STR2QB (or -> or_value);
		}
		break;
			
	    case OR_PRMD:
		{
			struct type_MTA_PrivateDomainName *prmd;

			if ((*std) -> private__domain__name != NULL ){
				PP_LOG (LLOG_EXCEPTIONS,
					("Already got a PRMD"));
				return;
			}
			prmd = (*std) -> private__domain__name =
				(struct type_MTA_PrivateDomainName *)
					smalloc (sizeof *prmd);
			prmd -> offset = type_MTA_PrivateDomainName_printable;
			prmd -> un.printable = STR2QB (or-> or_value);
		}
		break;

	    case OR_O:
		{
			if ((*std) -> organization__name != NULL) {
				PP_LOG (LLOG_EXCEPTIONS,
					("Already got an Organization"));
				return;
			}
			(*std) -> organization__name = STR2QB (or -> or_value);
		}
		break;
	    case OR_OU:
		{
			struct type_MTA_OrganizationalUnitNames *ou, **oup;

			for (oup = &(*std) -> organizational__unit__names;
			     *oup; oup = &(*oup) -> next)
				continue;
			ou = (struct type_MTA_OrganizationalUnitNames *)
				smalloc (sizeof *ou);
			ou -> OrganizationUnitName = STR2QB (or -> or_value);
			ou -> next = NULL;
			*oup = ou;
		}
		break;
				
	    case OR_X121:
		{
			if ((*std) -> network__address == NULL) {
				PP_LOG (LLOG_EXCEPTIONS,
					("Extra X121 id"));
				return;
			}
			(*std) -> network__address = STR2QB (or -> or_value);
		}
		break;

	    case OR_TID:
		{
			if ((*std) -> terminal__identifier != NULL) {
				PP_LOG (LLOG_EXCEPTIONS,
					("Extra terminal identifier"));
				return;
			}
			(*std) -> terminal__identifier = STR2QB (or -> or_value);
		}
		break;

	    case OR_UAID:
		{
			if ((*std) -> numeric__user__identifier != NULL) {
				PP_LOG (LLOG_EXCEPTIONS,
					("extra numeric user id"));
				return;
			}
			(*std) -> numeric__user__identifier =
				STR2QB (or -> or_value);
		}
		break;
				
	    case OR_S:
	    case OR_G:
	    case OR_I:
	    case OR_GQ:
		{
			struct type_MTA_PersonalName *pn;

			if ((*std) -> personal__name == NULL) {
				pn = (*std) -> personal__name =
					(struct type_MTA_PersonalName *)
						smalloc (sizeof *pn);
				bzero ((char *)pn, sizeof *pn);
			}
			else	pn = (*std) -> personal__name;

			switch (or -> or_type) {
			    case OR_S:
				pn -> surname = STR2QB (or -> or_value);
				break;

			    case OR_G:
				pn -> given__name = STR2QB (or -> or_value);
				break;

			    case OR_I:
				pn -> initials = STR2QB (or -> or_value);
				break;

			    case OR_GQ:
				pn -> generation__qualifier =
					STR2QB (or -> or_value);
				break;
			}
		}
		break;
				
	    default:
		PP_LOG (LLOG_EXCEPTIONS, ("Bad type %d", or -> or_type));
		break;
	}
}

build_cn_or (dn, or)		/* XXX */
OR_ptr or;
{
}

build_dd_or (domd, or)
struct type_MTA_DomainDefinedAttributes **domd;
OR_ptr or;
{
	struct type_MTA_DomainDefinedAttributes **ddp, *dp;

	for (ddp = domd; *ddp; ddp = &(*ddp) -> next)
		continue;

	dp = (struct type_MTA_DomainDefinedAttributes *)
		smalloc (sizeof *dp);
	dp -> DomainDefinedAttribute =
		(struct type_MTA_DomainDefinedAttribute *)
			smalloc (sizeof *dp -> DomainDefinedAttribute);
	dp -> next = NULL;
	dp -> DomainDefinedAttribute -> type = STR2QB (or -> or_ddname);
	dp -> DomainDefinedAttribute -> value = STR2QB (or -> or_value);

	*ddp = dp;
}

build_ext_or (ext, or)		/* XXX */
OR_ptr or;
{
}

static struct type_MTA_ReportTransferEnvelope *build_drenvelope (qp, dr)
Q_struct *qp;
DRmpdu	*dr;
{
	struct type_MTA_ReportTransferEnvelope *env;

	env = (struct type_MTA_ReportTransferEnvelope *)
		smalloc (sizeof *env);
	bzero ((char *)env, sizeof *env);

	env -> report__identifier = build_msgid (dr -> dr_mpduid);

	env -> report__destination__name = build_addr (qp -> Oaddress -> ad_r400adr);

	env -> trace__information = build_trace (dr -> dr_trace);

	env -> extensions = NULL;

	return env;
}

static struct type_MTA_ReportTransferContent *build_drcontent (qp, recip, dr)
Q_struct *qp;
ADDR	*recip;
DRmpdu	*dr;
{
	struct type_MTA_ReportTransferContent *drc;

	drc = (struct type_MTA_ReportTransferContent *) smalloc (sizeof *drc);

	bzero ((char *)drc, sizeof *drc);

	drc -> subject__identifier = build_msgid (&qp -> msgid);

	drc -> subject__intermediate__trace__information =
		build_trace (dr -> dr_subject_intermediate_trace);

	drc -> original__encoded__information__types =
		build_eits (&qp -> encodedinfo);

	if (qp -> cont_type || recip -> ad_content)
		drc -> content__type = build_content (qp -> cont_type);

	if (qp -> ua_id)
		drc -> content__identifier = STR2QB (qp -> ua_id);
	
	drc -> returned__content = NULL; /* XXX */

	drc -> additional__information = NULLPE;

	drc -> extensions = NULL;

	drc -> per__recipient__fields =
		build_drc_pr_fields (qp, recip, dr -> dr_recip_list);

	return drc;
}

static struct element_MTA_10 *build_drc_pr_fields (qp, recip, rr)
Q_struct *qp;
ADDR	*recip;
Rrinfo	*rr;
{
	struct element_MTA_10 *prf;
	struct type_MTA_PerRecipientReportTransferFields *pr;
	ADDR	*ap;

	if (rr == NULL)
		return NULL;
	for (ap = qp -> Raddress; ap; ap = ap -> ad_next)
		if (ap -> ad_no == rr -> rr_recip)
			break;
	if (ap == NULLADDR)
		return build_drc_pr_fields (qp, recip, rr -> rr_next);

	prf = (struct element_MTA_10 *) smalloc (sizeof *prf);

	prf -> PerRecipientReportTransferFields = pr =
		(struct type_MTA_PerRecipientReportTransferFields *)
			smalloc (sizeof *pr);
	bzero ((char *)pr, sizeof *pr);
	pr -> actual__recipient__name = build_addr (ap -> ad_r400adr);

	pr -> originally__specified__recipient__number =
		(struct type_MTA_OriginallySpecifiedRecipientNumber *)
			smalloc (sizeof *pr ->
				 originally__specified__recipient__number);
	pr -> originally__specified__recipient__number -> parm =
		ap -> ad_extension;

	pr -> per__recipient__indicators = build_ri (ap -> ad_resp,
						     ap -> ad_mtarreq,
						     ap -> ad_usrreq);

	pr -> last__trace__information = build_lasttrace (rr);

	if (rr -> rr_originally_intended_recip)
		pr -> originally__intended__recipient__name =
			build_fullname (rr -> rr_originally_intended_recip);

	if (rr -> rr_supplementary)
		pr -> supplementary__information =
			STR2QB (rr -> rr_supplementary);

	pr -> extensions = NULL;

	prf -> next = build_drc_pr_fields (qp, recip, rr -> rr_next);
	return prf;
}

static struct type_MTA_LastTraceInformation *build_lasttrace (rr)
Rrinfo *rr;
{
	struct type_MTA_LastTraceInformation *lti;

	lti = (struct type_MTA_LastTraceInformation *)
		smalloc (sizeof *lti);
	bzero ((char *)lti, sizeof *lti);

	lti -> arrival__time = build_time (rr -> rr_arrival);
	if (rr -> rr_converted)
		lti -> converted__encoded__information__types =
			build_eits (rr -> rr_converted);
	lti -> report = build_report (&rr -> rr_report);

	return lti;
}

static struct type_MTA_Report *build_report (rp)
Report *rp;
{
	struct type_MTA_Report *rep;

	rep = (struct type_MTA_Report *)
		smalloc (sizeof *rep);

	if (rp -> rep_type == DR_REP_SUCCESS) {
		struct type_MTA_DeliveryReport *drp;

		rep -> offset = type_MTA_Report_delivery;

		rep -> un.delivery = drp =
			(struct type_MTA_DeliveryReport *)
				smalloc (sizeof *drp);
		drp -> message__delivery__time =
			build_time (rp->rep.rep_dinfo.del_time);
		drp -> type__of__MTS__user =
			(struct type_MTA_TypeOfMTSUser *)
				smalloc (sizeof *drp -> type__of__MTS__user);
		drp -> type__of__MTS__user -> parm =
			rp -> rep.rep_dinfo.del_type;
	}
	else if (rp -> rep_type == DR_REP_FAILURE) {
		struct type_MTA_NonDeliveryReport *ndr;

		rep -> offset = type_MTA_Report_non__delivery;

		rep -> un.non__delivery = ndr =
			(struct type_MTA_NonDeliveryReport *)
				smalloc (sizeof *ndr);
		ndr -> non__delivery__reason__code =
			(struct type_MTA_NonDeliveryReasonCode *)
				smalloc (sizeof *ndr -> non__delivery__reason__code);
		ndr -> non__delivery__reason__code -> parm =
			rp -> rep.rep_ndinfo.nd_rcode;

		ndr -> non__delivery__diagnostic__code =
			(struct type_MTA_NonDeliveryDiagnosticCode *)
				smalloc (sizeof *ndr -> non__delivery__diagnostic__code);
		ndr -> non__delivery__diagnostic__code -> parm =
			rp -> rep.rep_ndinfo.nd_dcode;
	}
	else
		PP_LOG (LLOG_EXCEPTIONS, ("Bad delivery report type %d",
					  rp -> rep_type));

	return rep;
}

struct type_MTA_ORName *build_fullname (fn)
FullName	*fn;
{
	OR_ptr or;
	struct type_MTA_ORName *orname;

	or = or_std2or (fn -> fn_addr);
	if (or == NULLOR) {
		PP_LOG (LLOG_EXCEPTIONS, ("Can't convert %s", fn -> fn_addr));
		return NULL;
	}

	orname = conv_or (or);
	or_free (or);
	return orname;
}

static struct type_MTA_Extensions *build_pprf_ext (ap) /* XXX */
ADDR *ap;
{
	return NULL;
}

static struct element_MTA_8 *build_prb_recips (ad, adl, disclose)
ADDR	*ad;
ADDR	*adl;
int	disclose;
{
	struct element_MTA_8 *rl = NULL, *rlbase = NULL;
	struct type_MTA_PerRecipientProbeTransferFields *prmtf;
	ADDR	*ap, *ap2;
	int	resp;

	for (ap = ad; ap; ap = ap -> ad_next) {
		for (ap2 = adl; ap2; ap2 = ap2 -> ad_next) {
			if (ap2 -> ad_no == ap -> ad_no)
				break;
		}
		if (ap2 == NULLADDR) {
			if (disclose == 0)
				continue;
			else
				resp = FALSE;
		}
		else	resp = ap2 -> ad_resp;
				

		if (rlbase == NULL) 
			rl = rlbase = (struct element_MTA_8 *)
				smalloc (sizeof *rl);
		else {
			rl -> next = (struct element_MTA_8 *)
				smalloc (sizeof *rl);
			rl = rl -> next;
		}
		bzero ((char *)rl, sizeof *rl);
		prmtf = rl -> PerRecipientProbeTransferFields =
			(struct type_MTA_PerRecipientProbeTransferFields *)
			smalloc (sizeof *prmtf);
		prmtf -> recipient__name = build_addr (ap -> ad_r400adr);

		prmtf -> originally__specified__recipient__number =
			(struct type_MTA_OriginallySpecifiedRecipientNumber *)
			smalloc (sizeof *prmtf ->
				 originally__specified__recipient__number);
		prmtf -> originally__specified__recipient__number -> parm =
			ap -> ad_extension;

		if (ap -> ad_explicitconversion != AD_EXP_NONE) {
			prmtf -> explicit__conversion =
				(struct type_MTA_ExplicitConversion *)
					smalloc (sizeof *prmtf -> explicit__conversion);
			prmtf -> explicit__conversion -> parm =
				ap -> ad_explicitconversion;
		}
		else prmtf -> explicit__conversion = NULL;

		prmtf -> per__recipient__indicators = build_ri (resp,
								ad -> ad_mtarreq,
								ad -> ad_usrreq);
		prmtf -> extensions = build_pprf_ext (ap);
	}
	return rlbase;
}

static struct type_MTA_Extensions *build_pp_extensions (qp)
Q_struct *qp;
{
	return NULL;
}

static struct type_MTA_ProbeTransferEnvelope *build_probe_envelope (qp, adl)
Q_struct *qp;
ADDR *adl;
{
	struct type_MTA_ProbeTransferEnvelope *prb;

	prb = (struct type_MTA_ProbeTransferEnvelope *) smalloc (sizeof *prb);
	bzero ((char *)prb, sizeof *prb);

	prb -> probe__identifier = build_msgid (&qp -> msgid);

	prb -> originator__name = build_addr (qp -> Oaddress -> ad_r400adr);

	prb -> original__encoded__information__types =
		build_eits (&qp -> encodedinfo);

	prb -> content__type = build_content (adl -> ad_content ?
					      adl -> ad_content :
					      qp -> cont_type);
	if (qp -> ua_id)
		prb -> content__identifier = STR2QB (qp -> ua_id);

	prb -> content__length = (struct type_MTA_ContentLength *)
		smalloc (sizeof *prb -> content__length);
	prb -> content__length -> parm = qp -> msgsize;

	prb -> per__message__indicators = build_pmf (qp);

	prb -> per__domain__bilateral__information = NULL;

	prb -> trace__information = build_trace (qp -> trace);

	prb -> extensions = build_pp_extensions (qp);

	prb -> per__recipient__fields = build_prb_recips (qp -> Raddress, adl,
							  qp -> disclose_recips);

	return prb;
}

struct type_Transfer_MtsAPDU *build_probe (qp, recip)
Q_struct *qp;
ADDR	*recip;
{
	struct type_Transfer_MtsAPDU *p1;

	p1 = (struct type_Transfer_MtsAPDU *) smalloc (sizeof *p1);
	bzero ((char *)p1, sizeof *p1);

	p1 -> offset = type_Transfer_MtsAPDU_probe;
	p1 -> un.probe = build_probe_envelope (qp, recip);

	return p1;
}