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