home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Chans / x40088 / x400inmsg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  11.6 KB  |  500 lines

  1. /* x400inmsg.c: X400(1988) handling of body and envelope */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Chans/x40088/RCS/x400inmsg.c,v 6.0 1991/12/18 20:14:27 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Chans/x40088/RCS/x400inmsg.c,v 6.0 1991/12/18 20:14:27 jpo Rel $
  9.  *
  10.  * $Log: x400inmsg.c,v $
  11.  * Revision 6.0  1991/12/18  20:14:27  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17. #include "Trans-types.h"
  18. #include "util.h"
  19. #include "chan.h"
  20. #include "q.h"
  21. #include "adr.h"
  22. #include "or.h"
  23. #include "prm.h"
  24. #include "dr.h"
  25. #include "retcode.h"
  26. #include <isode/rtsap.h>
  27. #include <varargs.h>
  28.  
  29. #define bit_ison(x,y)    (bit_test(x,y) == 1)
  30.  
  31. extern char *remote_site;
  32. extern char *undefined_bodyparts;
  33. extern char *postmaster;
  34. extern char *myname;
  35. extern char *cont_p2, hdr_p2_bp;
  36.  
  37. enum errstate { st_normal, st_dr, st_probe, st_err_asn, st_err_submit, st_err_junk };
  38. static enum errstate state =  st_normal;
  39.  
  40. extern    CHAN    *mychan;
  41. extern int submit_running;
  42. extern int canabort;
  43. extern int rts_sd;
  44.  
  45. static int splatfnx (va_alist)
  46. va_dcl
  47. {
  48.     char    buffer[BUFSIZ];
  49.     caddr_t    junk;
  50.     RP_Buf rps;
  51.  
  52.     va_list ap;
  53.  
  54.     va_start (ap);
  55.  
  56.     junk = va_arg (ap, caddr_t);
  57.  
  58.     _asprintf (buffer, NULLCP, ap);
  59.  
  60.     if (pps_txt (buffer, &rps) == NOTOK)
  61.         adios (NULLCP, "Write fails: %s", rps.rp_line);
  62.     va_end (ap);
  63. }
  64.  
  65. int hdrproc (pe, type)
  66. PE    pe;
  67. int    type;
  68. {
  69.     struct type_Trans_MtsAPDU *parm;
  70.     struct type_MTA_MessageTransferEnvelope *envelope;
  71.     Q_struct qs, *qp = &qs;
  72.     DRmpdu drs, *dr = &drs;
  73.     struct prm_vars prm;
  74.     RP_Buf    rps, *rp = &rps;
  75.     ADDR    *ap;
  76.     struct qbuf *qbret, *qb;
  77.  
  78.     if (type == NOTOK) {
  79.         PP_OPER (NULLCP, ("Bad message"));
  80.         resetforpostie (st_err_junk, pe, type,
  81.                 "Transfer is not ASN.1");
  82.         return OK;
  83.     }
  84.     state = st_normal;
  85.  
  86.     if (submit_running == 0) {
  87.         if (rp_isbad (io_init (rp)))
  88.             adios (NULLCP, "Can't initialise submit: %s",
  89.                    rp -> rp_line);
  90.         submit_running = 1;
  91.     }
  92.  
  93.     prm_init (&prm);
  94.     prm.prm_opts = PRM_ACCEPTALL | PRM_NOTRACE;
  95.     if (rp_isbad (io_wprm (&prm, rp))) {
  96.         advise (LLOG_EXCEPTIONS, NULLCP, "io_wpm %s", rp -> rp_line);
  97.         return NOTOK;
  98.     }
  99.  
  100.     q_init (qp);
  101.     switch (type) {
  102.         case MT_UMPDU:
  103.         PP_PDUP (MTA_MessageTransferEnvelope, pe,
  104.             "MTA.MessageTransferEnvelope", PDU_READ);
  105.         if (decode_MTA_MessageTransferEnvelope
  106.             (pe, 1, NULLIP, NULLVP, &envelope)
  107.             == NOTOK) {
  108.             PP_OPER(NULLCP, ("Parse of P1 failed [%s]", PY_pepy));
  109.             resetforpostie (st_err_asn, pe, type,
  110.                     "ASN.1 is NOT P1");
  111.             return OK;
  112.         }
  113.         else {
  114.             switch (load_qstruct (qp, envelope)) {
  115.                 case NOTOK:
  116.                 adios (NULLCP, "Transient problem with ASN");
  117.                 case OK:
  118.                 break;
  119.                 case DONE:
  120.                 PP_LOG(LLOG_EXCEPTIONS,
  121.                        ("Some problem with the P1"));
  122.                 resetforpostie (st_err_submit, pe, type,
  123.                         "ASN.1 has a problem");
  124.                 return OK;
  125.             }
  126.         }
  127.         break;
  128.         
  129.         case MT_PMPDU:
  130.         PP_PDUP (Trans_MtsAPDU, pe,
  131.             "Trans.MtsAPDU", PDU_READ);
  132.         if (decode_Trans_MtsAPDU (pe, 1, NULLIP, NULLVP, &parm)
  133.             == NOTOK) {
  134.             PP_OPER (NULLCP, ("Parse of P1 failed [%s]", PY_pepy));
  135.             resetforpostie (st_err_asn, pe, type,
  136.                     "ASN.1 is not a Probe");
  137.             return OK;
  138.         }
  139.         else {
  140.             switch (load_probe (qp, parm -> un.probe)) {
  141.                 case NOTOK:
  142.                 adios (NULLCP, "Transient problem with ASN");
  143.                 case OK:
  144.                 break;
  145.                 case DONE:
  146.                 PP_LOG(LLOG_EXCEPTIONS,
  147.                        ("Some problem with the P1"));
  148.                 resetforpostie (st_err_submit, pe, type,
  149.                         "ASN.1 has a problem");
  150.                 return OK;
  151.             }
  152.         }
  153.         state = st_probe;
  154.         break;
  155.  
  156.         case MT_DMPDU:
  157.         PP_PDUP (Trans_MtsAPDU, pe,
  158.             "Trans.MtsAPDU", PDU_READ);
  159.         if (decode_Trans_MtsAPDU (pe, 1, NULLIP, NULLVP, &parm)
  160.             == NOTOK) {
  161.             PP_OPER (NULLCP, ("Parse of P1 failed [%s]", PY_pepy));
  162.             resetforpostie (st_err_asn, pe, type,
  163.                     "ASN.1 is not a DR");
  164.             return OK;
  165.         }
  166.         else {
  167.             dr_init (dr);
  168.             switch (load_dr (qp, dr, parm -> un.report)) {
  169.                 case NOTOK:
  170.                 adios (NULLCP, "Transient problem with ASN");
  171.                 case OK:
  172.                 break;
  173.                 case DONE:
  174.                 PP_LOG(LLOG_EXCEPTIONS,
  175.                        ("Some problem with the P1"));
  176.                 resetforpostie (st_err_submit, pe, type,
  177.                         "ASN.1 has a problem");
  178.                 return OK;
  179.             }
  180.             if ( parm -> un.report -> content ->
  181.                 returned__content) {
  182.                 if (list_bpt_find (qp -> encodedinfo.eit_types,
  183.                            hdr_p2_bp) == NULL)
  184.                     list_bpt_add(&qp -> encodedinfo.eit_types,
  185.                              list_bpt_new(hdr_p2_bp));
  186.                 qp -> content_return_request = TRUE;
  187.             }
  188.             else {
  189.                 list_bpt_free (&qp -> encodedinfo.eit_types);    
  190.                 qp -> encodedinfo.eit_types = NULL;
  191.             }
  192.             if (qp -> cont_type == NULLCP)
  193.                 qp -> cont_type = strdup(cont_p2);
  194.         }
  195.         state = st_dr;
  196.         break;
  197.         default:
  198.         PP_OPER (NULLCP, ("Unknown type of structure %d",
  199.                   type));
  200.         exit (1);
  201.     }
  202.     qp -> inbound = list_rchan_new (remote_site, NULL);
  203.     qp -> inbound -> li_chan = ch_mta2struct (myname, remote_site);
  204.         
  205.  
  206.     if (rp_isbad (io_wrq (qp, rp))) {
  207.         advise (LLOG_EXCEPTIONS, NULLCP, "io_wrq %s", rp -> rp_line);
  208.         return NOTOK;
  209.     }
  210.  
  211.     if (rp_isbad (io_wadr (qp -> Oaddress, AD_ORIGINATOR, rp))) {
  212.         char ebuf[BUFSIZ];
  213.         advise (LLOG_EXCEPTIONS, NULLCP, "io_wadr %s", rp -> rp_line);
  214.         if (rp_gbval(rp -> rp_val) == RP_BNO) {
  215.             (void) sprintf (ebuf, "Can't set sender %s: %s",
  216.                     qp -> Oaddress -> ad_value,
  217.                     rp -> rp_line);
  218.             resetforpostie (st_err_submit, pe, type, ebuf);
  219.             return OK;
  220.         }
  221.         return NOTOK;
  222.     }
  223.     PP_NOTICE (("Originator %s", qp -> Oaddress -> ad_value));
  224.  
  225.     for (ap = qp -> Raddress; ap; ap = ap -> ad_next) {
  226.         if (ap -> ad_resp == NO)   ap -> ad_status = AD_STAT_DONE;
  227.  
  228.         if (rp_isbad (io_wadr (ap, AD_RECIPIENT, rp))) {
  229.             advise (LLOG_EXCEPTIONS, NULLCP,
  230.                 "io_wadr %s", rp -> rp_line);
  231.             return NOTOK;
  232.         }
  233.         if (ap -> ad_resp)
  234.             PP_NOTICE (("Recipient Address %s", ap -> ad_value));
  235.         else
  236.             PP_NOTICE (("Recipinet (no responsibility) %s",
  237.                     ap -> ad_value));
  238.     }
  239.  
  240.     if (rp_isbad (io_adend (rp))) {
  241.         advise (LLOG_EXCEPTIONS, NULLCP, "io_adend %s",
  242.             rp -> rp_line);
  243.         return NOTOK;
  244.     }
  245.  
  246.     switch (qp -> msgtype) {
  247.         case MT_UMPDU:
  248.         if (rp_isbad (io_tinit (rp))) {
  249.             advise (LLOG_EXCEPTIONS, NULLCP,
  250.                 "io_tinit %s", rp -> rp_line);
  251.             return NOTOK;
  252.         }
  253.     
  254.         if (rp_isbad (io_tpart (qp -> cont_type, FALSE, rp))) {
  255.             advise (LLOG_EXCEPTIONS, NULLCP, "io_tpart %s %s",
  256.                 qp -> cont_type, rp -> rp_line);
  257.             return NOTOK;
  258.         }
  259.         break;
  260.  
  261.         case MT_DMPDU:
  262.         if (rp_isbad (io_wdr (dr, rp))) {
  263.             advise (LLOG_EXCEPTIONS, NULLCP,
  264.                 "io_wdr %s", rp -> rp_line);
  265.             return NOTOK;
  266.         }
  267.         if (rp_isbad (io_tinit (rp))) {
  268.             advise (LLOG_EXCEPTIONS, NULLCP,
  269.                 "io_tinit %s", rp -> rp_line);
  270.             return NOTOK;
  271.         }
  272.         if ((qbret = parm -> un.report -> content ->
  273.             returned__content) != NULL) {
  274.  
  275.             if (rp_isbad (io_tpart (qp -> cont_type, FALSE, rp))) {
  276.                 advise (LLOG_EXCEPTIONS, NULLCP,
  277.                     "io_tpart %s %s",
  278.                     qp -> cont_type, rp -> rp_line);
  279.                 return NOTOK;
  280.             }
  281.             for (qb = qbret -> qb_forw; qb != qbret;
  282.                  qb = qb -> qb_forw) {
  283.                 if (rp_isbad (io_tdata (qb -> qb_data,
  284.                             qb -> qb_len))) {
  285.                     advise (LLOG_EXCEPTIONS, NULLCP,
  286.                         "io_tdata failed");
  287.                     return NOTOK;
  288.                 }
  289.             }
  290.             if (rp_isbad (io_tdend (rp))) {
  291.                 advise (LLOG_EXCEPTIONS, NULLCP,
  292.                     "io_tdend %s", rp -> rp_line);
  293.                 return NOTOK;
  294.             }
  295.         }
  296.         if (rp_isbad (io_tend (rp))) {
  297.             advise (LLOG_EXCEPTIONS, NULLCP,
  298.                 "io_tend %s", rp -> rp_line);
  299.             return NOTOK;
  300.         }
  301.         break;
  302.  
  303.         case MT_PMPDU:
  304.         break;
  305.     }
  306.     return OK;
  307. }
  308.  
  309. resetforpostie (st, pe, type, str)
  310. enum errstate st;
  311. PE    pe;
  312. int    type;
  313. char    *str;
  314. {
  315.     static char line[] = "\n\n----------------------------------------\n\n";
  316.     char    *msg = "<Error>";
  317.     PS    ps;
  318.     RP_Buf    rps, *rp = &rps;
  319.  
  320.     if (submit_running) {
  321.         io_end (NOTOK);
  322.         submit_running = 0;
  323.     }
  324.             
  325.     switch (state = st) {
  326.         case st_err_submit:
  327.         msg = "Submission Error";
  328.         break;
  329.         case st_err_asn:
  330.         msg = "ASN.1 Parsing error";
  331.         break;
  332.         case st_err_junk:
  333.         msg = "Invalid ASN.1";
  334.         break;
  335.         default:
  336.         adios (NULLCP, "Bad state in resetforpostie %d", st);
  337.     }
  338.     if (canabort) {
  339.         sendrtsabort ();
  340.         adios (NULLCP, "Aborted submission: inbound error %s - %s",
  341.                msg, str);
  342.     }
  343.  
  344.     if (pps_1adr (msg, postmaster, rp) == NOTOK)
  345.         adios (NULLCP, "Can't initialize submit for error report: %s",
  346.                rp -> rp_line);
  347.  
  348.     if (pps_txt ("X.400 inbound error detected\n\t", rp) == NOTOK ||
  349.         pps_txt (str, rp) == NOTOK ||
  350.         pps_txt ("\nThe message was received from ", rp) == NOTOK ||
  351.         pps_txt (remote_site ? remote_site : "<unknown-site>", rp) == NOTOK)
  352.         adios (NULLCP, "Error writing data to submit: %s",
  353.                rp -> rp_line);
  354.  
  355.     switch (st) {
  356.         case st_err_asn:
  357.         msg = "\n\nA dump of the ASN.1 follows:\n\n";
  358.         break;
  359.         case st_err_junk:
  360.         msg = "\n\nA hex dump of the incoming message follows:\n\n";
  361.         break;
  362.         case st_err_submit:
  363.         msg = "\n\nA trace of the P1 envelope follows:\n\n";
  364.         break;
  365.     }
  366.     if (pps_txt (msg, rp) == NOTOK ||
  367.         pps_txt (line, rp) == NOTOK)
  368.         adios (NULLCP, "Error writing to submit: %s", rp -> rp_line);
  369.  
  370.     if (st == st_err_junk)
  371.         return;
  372.  
  373.     switch (type) {
  374.         case MT_DMPDU:
  375.         vpushpp (stdout, splatfnx, pe, "DR MPDU", PDU_WRITE);
  376.         break;
  377.         case MT_PMPDU:
  378.         vpushpp (stdout, splatfnx, pe, "Probe MPDU", PDU_WRITE);
  379.         break;
  380.         case MT_UMPDU:
  381.         vpushpp (stdout, splatfnx, pe, "User MPDU", PDU_WRITE);
  382.         break;
  383.     }
  384.     switch (st) {
  385.         case st_err_asn:
  386.         vunknown (pe);
  387.         break;
  388.  
  389.         case st_err_submit:
  390.         switch (type) {
  391.             case MT_DMPDU:
  392.             case MT_PMPDU:
  393.             print_Trans_MtsAPDU(pe, 1, NULLIP, NULLVP, NULLCP);
  394.             break;
  395.             case MT_UMPDU:
  396.             print_MTA_MessageTransferEnvelope (pe, 1, NULLIP,
  397.                                NULLVP, NULLCP);
  398.             break;
  399.         }
  400.     }
  401.     vpopp ();
  402.     if (pps_txt ("\n\nHEX dump of this data now follows", rp) == NOTOK ||
  403.         pps_txt (line, rp) == NOTOK)
  404.         adios (NULLCP, "Can't write to submit: %s", rp -> rp_line);
  405.     if ((ps = ps_alloc (str_open)) == NULLPS)
  406.         adios (NULLCP, "Can't allocate PS stream");
  407.     if (str_setup (ps, NULLCP, 0, 0) == NOTOK)
  408.         adios (NULLCP, "Can't setup PS stream");
  409.     if (pe2ps (ps, pe) == NOTOK)
  410.         adios (NULLCP, "pe2ps failed: %s", ps_error (ps -> ps_errno));
  411.     bodyproc (ps -> ps_base, ps -> ps_ptr - ps -> ps_base);
  412.     ps_free (ps);
  413.     
  414.     if (type == MT_UMPDU) {
  415.         if (pps_txt ("\n\nP2 hex dump follows", rp) == NOTOK ||
  416.             pps_txt (line, rp) == NOTOK)
  417.             adios (NULLCP, "Can't write to submit: %s",
  418.                    rp -> rp_line);
  419.     }
  420. }
  421.  
  422. bodyproc (str, len)
  423. char    *str;
  424. int    len;
  425. {
  426.     char    hexbuf[82];
  427.     int    i;
  428.     RP_Buf    rps, *rp = &rps;
  429.  
  430.     PP_TRACE (("Copy %d bytes", len));
  431.     switch (state) {
  432.         case st_normal:
  433.         if (rp_isbad (io_tdata (str, len))) {
  434.             PP_LOG (LLOG_EXCEPTIONS, ("data write failed"));
  435.             return NOTOK;
  436.         }
  437.         break;
  438.         case st_probe:
  439.         case st_dr:
  440.         PP_LOG (LLOG_EXCEPTIONS, ("Illegal state in bodyproc"));
  441.         break;
  442.  
  443.         case st_err_submit:
  444.         case st_err_asn:
  445.         case st_err_junk:
  446.         for (i = 0; i <= len; i += 40) {
  447.             int n = min (40, len - i);
  448.             n = explode (hexbuf, str + i, n);
  449.             hexbuf[n++] = '\n';
  450.             hexbuf[n] = 0;
  451.             if (pps_txt (hexbuf, rp) == NOTOK)
  452.                 adios (NULLCP, "Error writing to submit: %s",
  453.                        rp -> rp_line);
  454.         }
  455.         break;
  456.     }
  457.     return OK;
  458. }
  459.  
  460. msgfinished ()
  461. {
  462.     RP_Buf rps, *rp = &rps;
  463.  
  464.     switch (state) {
  465.         case st_normal:
  466.         if (rp_isbad (io_tdend (rp)) ||
  467.             rp_isbad (io_tend (rp))) {
  468.             PP_LOG (LLOG_EXCEPTIONS,
  469.                 ("Data termination failed: %s",
  470.                  rp -> rp_line));
  471.             return NOTOK;
  472.         }
  473.         PP_NOTICE (("<<< Message received from %s",
  474.                 remote_site));
  475.         break;
  476.         case st_probe:
  477.         PP_NOTICE (("<<< Probe received from %s",
  478.                 remote_site));
  479.         break;
  480.         case st_dr:
  481.         PP_NOTICE (("<<< DR received from %s",
  482.                 remote_site));
  483.         break;
  484.  
  485.         case st_err_asn:
  486.         case st_err_submit:
  487.         case st_err_junk:
  488.         PP_NOTICE (("<<< Invalid message received from %s",
  489.                 remote_site));
  490.         if (pps_end (OK, rp) == NOTOK) {
  491.             PP_LOG (LLOG_EXCEPTIONS,
  492.                 ("final handshake failed: %s",
  493.                  rp -> rp_line));
  494.             return NOTOK;
  495.         }
  496.         break;
  497.     }
  498.     return OK;
  499. }
  500.