|
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: 20750 (0x510e) Types: TextFile Names: »x400inext.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« └─⟦e5a54fb17⟧ └─⟦this⟧ »pp-5.0/Chans/x40088/x400inext.c«
/* x400inext.c: X400(1988) extensions handling - inbound */ # ifndef lint static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Chans/x40088/RCS/x400inext.c,v 5.0 90/09/20 15:58:41 pp Exp Locker: pp $"; # endif /* * $Header: /cs/research/pp/hubris/pp-beta/Chans/x40088/RCS/x400inext.c,v 5.0 90/09/20 15:58:41 pp Exp Locker: pp $ * * $Log: x400inext.c,v $ * Revision 5.0 90/09/20 15:58:41 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 "Extensions-types.h" #include "Transfer-types.h" extern void decode_Extensions_LatestDeliveryTime (), decode_Extensions_PhysicalRenditionAttributes (), decode_Extensions_RecipientNumberForAdvice (), decode_Extensions_RequestedDeliveryMethod (), decode_Extensions_PhysicalDeliveryModes (); #if PP_DEBUG > 0 extern void print_Extensions_LatestDeliveryTime (), print_Extensions_PhysicalRenditionAttributes (), print_Extensions_RecipientNumberForAdvice (), print_Extensions_RequestedDeliveryMethod (), print_Extensions_PhysicalDeliveryModes (); #else #define print_Extensions_LatestDeliveryTime NULLIFP #define print_Extensions_PhysicalRenditionAttributes NULLIFP #define print_Extensions_RecipientNumberForAdvice NULLIFP #define print_Extensions_RequestedDeliveryMethod NULLIFP #define print_Extensions_PhysicalDeliveryModes NULLIFP #endif static void decode_ext_time (); void do_local_extension (); void do_global_extension (); static Extension *flatten_ext (); static void ext_recip_reassign (); static void ext_dlxp (); static void ext_conv (); static void ext_ora (); static void ext_dlexph (); static void ext_inttrace (); static int pe2crit (); static DLHistory *ext_decode_dlh (); #define decode_singleint(type, ip, critp, defcrit, pfnx, dfnx, ffnx, label, ext) \ { \ struct type *genp; \ \ PP_PDU (pfnx, ext -> value, label, PDU_READ); \ if (dfnx (ext -> value, 1, NULLIP, NULLVP, &genp) == NOTOK) \ adios (NULLCP, "Can't parse %s value [%s]", label, PY_pepy); \ \ (ip) = genp -> parm; \ (critp) = pe2crit (ext -> criticality, defcrit); \ ffnx (genp); \ } static void decode_extension (value, crit, defcrit, pfnx, dfnx, ffnx, label, decoder, ext) caddr_t value; int *crit; int defcrit; IFP pfnx, dfnx, ffnx; VFP decoder; char *label; struct type_MTA_ExtensionField *ext; { caddr_t *genp; #if PP_DEBUG > 0 if (pfnx && pp_log_norm -> ll_events & LLOG_PDUS) _vpdu (pp_log_norm, pfnx, ext -> value, label, PDU_READ); #endif if ((*dfnx) (ext -> value, 1, NULLIP, NULLVP, &genp) == NOTOK) adios (NULLCP, "Can't parse %s value [%s]", label, PY_pepy); (*decoder) (value, genp); *crit = pe2crit (ext -> criticality, defcrit); (*ffnx) (genp); } extern OR_ptr do_or_address (); #define bit_ison(x,y) (bit_test(x,y) == 1) load_pm_extensions (qp, ext) Q_struct *qp; struct type_MTA_Extensions *ext; { struct type_MTA_Extensions *ep; for (ep = ext; ep; ep = ep -> next) { switch (ep -> ExtensionField -> type -> offset) { case type_MTA_ExtensionType_local: do_local_extension (&qp -> per_message_extensions, ep -> ExtensionField); break; case type_MTA_ExtensionType_global: do_global_extension (ep -> ExtensionField -> type -> un.global, qp, ep -> ExtensionField); break; default: PP_LOG (LLOG_EXCEPTIONS, ("Unknown extension type %d", ep -> ExtensionField -> type -> offset)); break; } } } squash_ext (qbp, value) struct qbuf **qbp; PE value; { char *cp; int len; PS ps; if ((ps = ps_alloc (str_open)) == NULLPS) adios (NULLCP, "Can't allocate PS"); len = ps_get_abs (value); cp = smalloc (len); if (str_setup (ps, cp, len, 1) == NOTOK) adios (NULLCP, "Can't setup stream [%s]", ps_error (ps -> ps_errno)); if (pe2ps (ps, value) == NOTOK) adios (NULLCP, "pe2ps failed [%s]", ps_error (ps -> ps_errno)); ps_free (ps); *qbp = str2qb (cp, len, 1); free (cp); } static Extension *flatten_ext (ext) struct type_MTA_ExtensionField *ext; { Extension *ep; ep = (Extension *)smalloc (sizeof *ep); if (ext -> type -> offset == type_MTA_ExtensionType_global) { ep -> ext_int = ext -> type -> un.global; ep -> ext_oid = NULLOID; } else { ep -> ext_int = EXT_OID_FORM; ep -> ext_oid = oid_cpy (ext -> type -> un.local); } squash_ext (&ep -> ext_value, ext -> value); ep -> ext_criticality = pe2crit (ext -> criticality, CRITICAL_NONE); ep -> ext_next = NULL; return ep; } void do_local_extension (elist, ext) Extension **elist; struct type_MTA_ExtensionField *ext; { Extension *ep, **epp; PP_LOG (LLOG_EXCEPTIONS, ("Unknown local extension %s", sprintoid (ext -> type -> un.local))); ep = flatten_ext (ext); for (epp = elist; *epp; epp = &(*epp) -> ext_next) continue; *epp = ep; } static void ext_security (qbp, critp, defcrit, ext) struct qbuf **qbp; int *critp; int defcrit; struct type_MTA_ExtensionField *ext; { squash_ext (qbp, ext -> value); *critp = pe2crit (ext -> criticality, defcrit); } static void do_global_extension (n, qp, ext) int n; Q_struct *qp; struct type_MTA_ExtensionField *ext; { Extension *ep, **epp; switch (n) { case EXT_RECIPIENT_REASSIGNMENT_PROHIBITED: decode_singleint (type_Extensions_RecipientReassignmentProhibited, qp -> recip_reassign_prohibited, qp -> recip_reassign_crit, EXT_RECIPIENT_REASSIGNMENT_PROHIBITED_DC, print_Extensions_RecipientReassignmentProhibited, decode_Extensions_RecipientReassignmentProhibited, free_Extensions_RecipientReassignmentProhibited, "Extension.RecipientReassignmentProhibited", ext); break; case EXT_DL_EXPANSION_PROHIBITED: decode_singleint (type_Extensions_DLExpansionProhibited, qp -> dl_expansion_prohibited, qp -> dl_expansion_crit, EXT_DL_EXPANSION_PROHIBITED_DC, print_Extensions_DLExpansionProhibited, decode_Extensions_DLExpansionProhibited, free_Extensions_DLExpansionProhibited, "Extension.DLExpansionProhibited", ext); break; case EXT_LATEST_DELIVERY_TIME: decode_extension (&qp -> latest_time, &qp -> latest_time_crit, EXT_LATEST_DELIVERY_TIME_DC, print_Extensions_LatestDeliveryTime, decode_Extensions_LatestDeliveryTime, free_Extensions_LatestDeliveryTime, "Extensions.LatestDeliveryTime", decode_ext_time, ext); break; case EXT_CONVERSION_WITH_LOSS_PROHIBITED: decode_singleint (type_Extensions_ConversionWithLossProhibited, qp -> conversion_with_loss_prohibited, qp -> conversion_with_loss_crit, EXT_CONVERSION_WITH_LOSS_PROHIBITED_DC, print_Extensions_ConversionWithLossProhibited, decode_Extensions_ConversionWithLossProhibited, free_Extensions_ConversionWithLossProhibited, "Extensions.ConversionWithLossProhibited", ext); break; case EXT_DL_EXPANSION_HISTORY: ext_dlexph (qp, ext); break; case EXT_ORIGINATOR_RETURN_ADDRESS: ext_ora (qp, ext); break; case EXT_INTERNAL_TRACE_INFORMATION: ext_inttrace (&qp -> trace, ext); break; case EXT_ORIGINATOR_CERTIFICATE: ext_security (&qp -> originator_certificate, &qp -> originator_certificate_crit, EXT_ORIGINATOR_CERTIFICATE_DC, ext); break; case EXT_CONTENT_CONFIDENTIALITY_ALGORITHM_IDENTIFIER: ext_security (&qp -> algorithm_identifier, &qp -> algorithm_identifier_crit, EXT_CONTENT_CONFIDENTIALITY_ALGORITHM_IDENTIFIER_DC, ext); break; case EXT_MESSAGE_ORIGIN_AUTHENTICATION_CHECK: ext_security (&qp -> message_origin_auth_check, &qp -> message_origin_auth_check_crit, EXT_MESSAGE_ORIGIN_AUTHENTICATION_CHECK_DC, ext); break; case EXT_MESSAGE_SECURITY_LABEL: ext_security (&qp -> security_label, &qp -> security_label_crit, EXT_MESSAGE_SECURITY_LABEL, ext); break; default: PP_NOTICE (("Unknown global extension type %d", n)); /* fall */ case EXT_CONTENT_CORRELATOR: ep = flatten_ext (ext); for (epp = &qp -> per_message_extensions; *epp; epp = &(*epp) -> ext_next) continue; *epp = ep; break; } } static void ext_ora (qp, ext) Q_struct *qp; struct type_MTA_ExtensionField *ext; { struct type_Extensions_OriginatorReturnAddress *ora; OR_ptr or; char buf[BUFSIZ]; PP_PDU (print_Extensions_OriginatorReturnAddress, ext -> value, "Extensions.OriginatorReturnAddress", PDU_READ); if (decode_Extensions_OriginatorReturnAddress (ext -> value, 1, NULLIP, NULLVP, &ora) == NOTOK) adios (NULLCP, "Can't parse originator return address [%s]", PY_pepy); or = do_or_address (ora -> standard__attributes, ora -> domain__defined__attributes, ora -> extension__attributes); or_or2std (or, buf, 0); or_free (or); qp -> originator_return_address = fn_new (buf, NULLCP); qp -> originator_return_address_crit = pe2crit (ext -> criticality, EXT_ORIGINATOR_RETURN_ADDRESS_DC); free_Extensions_OriginatorReturnAddress (ora); } static void ext_dlexph (qp, ext) Q_struct *qp; struct type_MTA_ExtensionField *ext; { struct type_Extensions_DLExpansionHistory *dlh, *dlhp; DLHistory *dp; PP_PDU (print_Extensions_DLExpansionHistory, ext -> value, "Extensions.DLExpansionHistory", PDU_READ); if (decode_Extensions_DLExpansionHistory (ext -> value, 1, NULLIP, NULLVP, &dlh) == NOTOK) adios (NULLCP, "Can't parse DLExpansionHistory value [%s]", PY_pepy); for (dlhp = dlh; dlhp; dlhp = dlhp -> next) { dp = ext_decode_dlh (dlhp -> DLExpansion); dlh_add (&qp -> dl_expansion_history, dp); } qp -> dl_expansion_history_crit = pe2crit (ext -> criticality, EXT_DL_EXPANSION_HISTORY_DC); free_Extensions_DLExpansionHistory (dlh); } static DLHistory *ext_decode_dlh (dlp) struct type_Extensions_DLExpansion *dlp; { char buf[BUFSIZ]; UTC ut; OR_ptr or; DLHistory *dp; load_time (&ut, dlp -> dl__expansion__time); or = do_or_address (dlp -> address -> standard__attributes, dlp -> address -> domain__defined, dlp -> address -> extension__attributes); or_or2std (or, buf, 0); or_free (or); dp = dlh_new (buf, NULLCP, ut); free ((char *)ut); return dp; } static void decode_ext_time (utc, genp) UTC *utc; struct type_UNIV_UTCTime *genp; { load_time (utc, genp); } static void ext_inttrace (trace, ext) Trace **trace; struct type_MTA_ExtensionField *ext; { struct type_Extensions_InternalTraceInformation *intt, *ip; PP_PDU (print_Extensions_InternalTraceInformation, ext -> value, "Extension.InternalTraceInformation", PDU_READ); if (decode_Extensions_InternalTraceInformation (ext -> value, 1, NULLIP, NULLVP, &intt) == NOTOK) adios (NULLCP, "Can't parse InternalTraceInformation [%s]", PY_pepy); for (ip = intt; ip; ip = ip -> next) { struct type_Extensions_InternalTraceInformationElement *te; struct type_Extensions_MTASuppliedInformation *msi; Trace *tp; te = ip -> InternalTraceInformationElement; tp = trace_new (); load_gdi (&tp -> trace_DomId, te -> global__domain__identifier); tp -> trace_mta = qb2str (te -> mta__name); msi = te -> mta__supplied__information; if (msi -> arrival__time) load_time (&tp -> trace_DomSinfo.dsi_time, msi -> arrival__time); if (msi -> routing__action) tp -> trace_DomSinfo.dsi_action = msi -> routing__action -> parm; if (msi -> deferred__time) load_time (&tp -> trace_DomSinfo.dsi_deferred, msi -> deferred__time); if (msi -> other__actions) { if (bit_ison (msi -> other__actions, bit_MTA_OtherActions_redirected)) tp -> trace_DomSinfo.dsi_other_actions |= ACTION_REDIRECTED; if (bit_ison (msi -> other__actions, bit_MTA_OtherActions_dl__operation)) tp -> trace_DomSinfo.dsi_other_actions |= ACTION_EXPANDED; } if (msi -> attempted) { switch (msi -> attempted -> offset) { case choice_Extensions_1_mta: tp -> trace_DomSinfo.dsi_attempted_mta = qb2str (msi -> attempted -> un.mta); break; case choice_Extensions_1_domain: load_gdi (&tp -> trace_DomSinfo.dsi_attempted_md, msi -> attempted -> un.domain); break; default: break; } } trace_add (trace, tp); } } static void decode_ext_pdm (value, genp) int *value; PE genp; { #define setbit(t,v) \ (*value) |= (bit_ison(genp, (t)) ? (v) : 0) setbit (bit_Extensions_PhysicalDeliveryModes_ordinary__mail, AD_PM_ORD); setbit (bit_Extensions_PhysicalDeliveryModes_special__delivery, AD_PM_SPEC); setbit (bit_Extensions_PhysicalDeliveryModes_express__mail, AD_PM_EXPR); setbit (bit_Extensions_PhysicalDeliveryModes_counter__collection, AD_PM_CNT); setbit (bit_Extensions_PhysicalDeliveryModes_counter__collection__with__telephone__advice, AD_PM_CNT_PHONE); setbit (bit_Extensions_PhysicalDeliveryModes_counter__collection__with__telex__advice, AD_PM_CNT_TLX); setbit (bit_Extensions_PhysicalDeliveryModes_counter__collection__with__teletex__advice, AD_PM_CNT_TTX); setbit (bit_Extensions_PhysicalDeliveryModes_bureau__fax__delivery, AD_PM_CNT_BUREAU); #undef setbit } static void decode_ext_pra (value, gen) OID *value; OID gen; { *value = oid_cpy (gen); } static void decode_ext_rnfa (value, genp) char **value; struct qbuf *genp; { *value = qb2str (genp); } static void decode_ext_rdm (value, genp) int value[AD_RDM_MAX]; struct type_Extensions_RequestedDeliveryMethod *genp; { int i; for (i = 0; i < AD_RDM_MAX && genp; i++, genp = genp -> next) value[i] = genp -> element_Extensions_0; } do_global_ext_prf (n, ad, ext) int n; ADDR *ad; struct type_MTA_ExtensionField *ext; { Extension *ep, **epp; switch (n) { case EXT_MESSAGE_TOKEN: ext_security (&ad -> ad_message_token, &ad -> ad_message_token_crit, EXT_MESSAGE_TOKEN_DC, ext); break; case EXT_CONTENT_INTEGRITY_CHECK: ext_security (&ad -> ad_content_integrity, &ad -> ad_content_integrity_crit, EXT_CONTENT_INTEGRITY_CHECK_DC, ext); break; case EXT_PROOF_OF_DELIVERY_REQUEST: decode_singleint (type_Extensions_ProofOfDeliveryRequest, ad -> ad_proof_delivery, ad -> ad_proof_delivery_crit, EXT_PROOF_OF_DELIVERY_REQUEST_DC, print_Extensions_ProofOfDeliveryRequest, decode_Extensions_ProofOfDeliveryRequest, free_Extensions_ProofOfDeliveryRequest, "Extensions.ProofOfDeliveryRequest", ext); break; case EXT_PHYSICAL_FORWARDING_PROHIBITED: decode_singleint (type_Extensions_PhysicalForwardingProhibited, ad -> ad_phys_forward, ad -> ad_phys_forward_crit, EXT_PHYSICAL_FORWARDING_PROHIBITED_DC, print_Extensions_PhysicalForwardingProhibited, decode_Extensions_PhysicalForwardingProhibited, free_Extensions_PhysicalForwardingProhibited, "Extensions.PhysicalForwardingProhibited", ext); break; case EXT_PHYSICAL_FORWARDING_ADDRESS_REQUEST: decode_singleint (type_Extensions_PhysicalForwardingAddressRequest, ad -> ad_phys_fw_ad_req, ad -> ad_phys_fw_ad_crit, EXT_PHYSICAL_FORWARDING_ADDRESS_REQUEST_DC, print_Extensions_PhysicalForwardingAddressRequest, decode_Extensions_PhysicalForwardingAddressRequest, free_Extensions_PhysicalForwardingAddressRequest, "Extensions.PhysicalForwardingAddressRequest", ext); break; case EXT_REGISTERED_MAIL: decode_singleint (type_Extensions_RegisteredMailType, ad -> ad_reg_mail_type, ad -> ad_reg_mail_type_crit, EXT_REGISTERED_MAIL_DC, print_Extensions_RegisteredMailType, decode_Extensions_RegisteredMailType, free_Extensions_RegisteredMailType, "Extensions.RegisteredMailType", ext); break; case EXT_PHYSICAL_DELIVERY_REPORT_REQUEST: decode_singleint (type_Extensions_PhysicalDeliveryReportRequest, ad -> ad_pd_report_request, ad -> ad_pd_report_request_crit, EXT_PHYSICAL_DELIVERY_REPORT_REQUEST_DC, print_Extensions_PhysicalDeliveryReportRequest, decode_Extensions_PhysicalDeliveryReportRequest, free_Extensions_PhysicalDeliveryReportRequest, "Extensions.PhysicalDeliveryReportRequest", ext); break; case EXT_PHYSICAL_RENDITION_ATTRIBUTES: decode_extension (&ad -> ad_phys_rendition_attribs, &ad -> ad_phys_rendition_attribs_crit, EXT_PHYSICAL_RENDITION_ATTRIBUTES_DC, print_Extensions_PhysicalRenditionAttributes, decode_Extensions_PhysicalRenditionAttributes, free_Extensions_PhysicalRenditionAttributes, "Extensions.PhysicalRenditionAttributes", decode_ext_pra, ext); break; case EXT_RECIPIENT_NUMBER_FOR_ADVICE: decode_extension (&ad -> ad_recip_number_for_advice, &ad -> ad_recip_number_for_advice_crit, EXT_RECIPIENT_NUMBER_FOR_ADVICE_DC, print_Extensions_RecipientNumberForAdvice, decode_Extensions_RecipientNumberForAdvice, free_Extensions_RecipientNumberForAdvice, "Extensions.RecipientNumberForAdvice", decode_ext_rnfa, ext); break; case EXT_REQUESTED_DELIVERY_METHOD: decode_extension (ad -> ad_req_del, &ad -> ad_req_del_crit, EXT_REQUESTED_DELIVERY_METHOD_DC, print_Extensions_RequestedDeliveryMethod, decode_Extensions_RequestedDeliveryMethod, free_Extensions_RequestedDeliveryMethod, "Extensions.RequestedDeliveryMethod", decode_ext_rdm, ext); break; case EXT_PHYSICAL_DELIVERY_MODES: decode_extension (&ad -> ad_phys_modes, &ad -> ad_phys_modes_crit, EXT_PHYSICAL_DELIVERY_MODES_DC, print_Extensions_PhysicalDeliveryModes, decode_Extensions_PhysicalDeliveryModes, free_Extensions_PhysicalDeliveryModes, "Extensions.PhysicalDeliveryModes", decode_ext_pdm, ext); break; default: PP_NOTICE (("Unknown global extension type %d", n)); /* fall */ case EXT_ORIGINATOR_REQUESTED_ALTERNATE_RECIPIENT: ep = flatten_ext (ext); for (epp = &ad -> ad_per_recip_ext_list; *epp; epp = &(*epp) -> ext_next) continue; *epp = ep; break; } } static int pe2crit (pe, defcrit) PE pe; int defcrit; { char *str; int len, n; if (pe == NULLPE) return defcrit; str = bitstr2strb (pe, &len); n = strb2int(str, len); free (str); return n; } do_global_repe_prf (n, dr, ext) int n; DRmpdu *dr; struct type_MTA_ExtensionField *ext; { Extension *ep, **epp; switch (n) { case EXT_INTERNAL_TRACE_INFORMATION: ext_inttrace (&dr -> dr_trace, ext); break; case EXT_MESSAGE_SECURITY_LABEL: ext_security (&dr -> dr_security_label, &dr -> dr_security_label_crit, EXT_MESSAGE_SECURITY_LABEL_DC, ext); break; case EXT_REPORT_ORIGIN_AUTHENTICATION_CHECK: ext_security (&dr -> dr_report_origin_auth_check, &dr -> dr_report_origin_auth_check_crit, EXT_REPORT_ORIGIN_AUTHENTICATION_CHECK_DC, ext); break; case EXT_REPORTING_MTA_CERTIFICATE: ext_security (&dr -> dr_reporting_mta_certificate, &dr -> dr_reporting_mta_certificate_crit, EXT_REPORTING_MTA_CERTIFICATE_DC, ext); break; case EXT_ORIGINATOR_AND_DL_EXPANSION_HISTORY: case EXT_REPORT_DL_NAME: default: ep = flatten_ext (ext); for (epp = &dr -> dr_per_envelope_extensions; *epp; epp = &(*epp) -> ext_next) continue; *epp = ep; break; } } do_global_cont_prf (n, dr, ext) int n; DRmpdu *dr; struct type_MTA_ExtensionField *ext; { Extension *ep, **epp; switch (n) { case EXT_CONTENT_CORRELATOR: default: ep = flatten_ext (ext); for (epp = &dr -> dr_per_envelope_extensions; *epp; epp = &(*epp) -> ext_next) continue; *epp = ep; break; } } do_global_rr_prf (n, rr, ext) int n; Rrinfo *rr; struct type_MTA_ExtensionField *ext; { Extension *ep, **epp; switch (n) { case EXT_RECIPIENT_CERTIFICATE: ext_security (&rr -> rr_report_origin_authentication_check, &rr -> rr_report_origin_authentication_check_crit, EXT_RECIPIENT_CERTIFICATE_DC, ext); break; case EXT_REDIRECTION_HISTORY: case EXT_PHYSICAL_FORWARDING_ADDRESS: case EXT_PROOF_OF_DELIVERY: default: ep = flatten_ext (ext); for (epp = &rr -> rr_per_recip_extensions; *epp; epp = &(*epp) -> ext_next) continue; *epp = ep; break; } }