home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Lib / qmgr / submit2qmgr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  10.5 KB  |  455 lines

  1. /* submit_interface: interface to qmgr for submit's use */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Lib/qmgr/RCS/submit2qmgr.c,v 6.0 1991/12/18 20:23:58 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Lib/qmgr/RCS/submit2qmgr.c,v 6.0 1991/12/18 20:23:58 jpo Rel $
  9.  *
  10.  * $Log: submit2qmgr.c,v $
  11.  * Revision 6.0  1991/12/18  20:23:58  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include "head.h"
  19. #include <varargs.h>
  20.  
  21. #include "qmgr.h"
  22.  
  23. /* Sumbit types */
  24. #include "q.h"
  25. #include "prm.h"
  26.  
  27. /* Outside routines */
  28. struct type_Qmgr_MsgStruct      *qstruct2qmgr();
  29.  
  30. /* DATA */
  31. static char *myservice =        "pp qmgr";
  32.  
  33. /* OPERATIONS */
  34. static int     newmessage_result();
  35. static int     general_error();
  36.  
  37. #define newmessage_error        general_error
  38.  
  39. static void    acs_log ();
  40. static void    ros_log ();
  41. static int getresult ();
  42. static int conn_status;
  43. static char qmgr_addr[] = "qmgr-pa.cache";
  44.  
  45. /*   */
  46. static struct PSAPaddr *get_addr (hostname)
  47. char *hostname;
  48. {
  49.     register struct PSAPaddr *pa;
  50.     AEI     aei;
  51.     char buf[BUFSIZ];
  52.     FILE *fp = NULL;
  53.  
  54.     if ((fp = fopen (qmgr_addr, "r")) != NULL &&
  55.     fgets (buf, sizeof buf, fp) != NULL &&
  56.     (pa = str2paddr (buf)) != NULLPA) {
  57.         (void) fclose (fp);
  58.         return pa;
  59.     }
  60.     if (fp)
  61.         (void) fclose (fp);
  62.  
  63.     if ((aei = _str2aei(hostname, myservice, QMGR_CTX_OID, 0, dap_user,
  64.               dap_passwd)) == NULLAEI) {
  65.         PP_LOG (LLOG_EXCEPTIONS,
  66.             ("qmgr_start %s-%s: unknown application-entity",
  67.              hostname,myservice));
  68.         return NULLPA;
  69.     }
  70.     if ((pa = aei2addr(aei)) == NULLPA) {
  71.         PP_LOG (LLOG_EXCEPTIONS,
  72.             ("qmgr_address translation failed"));
  73.         return NULLPA;
  74.     }
  75.     if ((fp = fopen (qmgr_addr, "w")) != NULL) {
  76.         (void) fprintf (fp, "%s\n", _paddr2str (pa, NULLNA, -1));
  77.         (void) fclose (fp);
  78.     }
  79.     else
  80.         PP_SLOG (LLOG_EXCEPTIONS, qmgr_addr,
  81.              ("Can't write qmgr addr cache"));
  82.     return pa;
  83. }
  84.  
  85. /* main interface routines */
  86.  
  87. int qmgr_start(hostname, status, async)
  88. char    *hostname;
  89. int *status;
  90. int async;
  91. {
  92.     int sd;
  93.     struct SSAPref sfs;
  94.     register struct SSAPref *sf;
  95.     register struct PSAPaddr *pa;
  96.     struct AcSAPconnect accs;
  97.     register struct AcSAPconnect   *acc = &accs;
  98.     struct AcSAPindication  acis;
  99.     register struct AcSAPindication *aci = &acis;
  100.     register struct AcSAPabort *aca = &aci -> aci_abort;
  101.     OID     ctx,
  102.         pci;
  103.     struct PSAPctxlist pcs;
  104.     register struct PSAPctxlist *pc = &pcs;
  105.     struct RoSAPindication rois;
  106.     register struct RoSAPindication *roi = &rois;
  107.     register struct RoSAPpreject *rop = &roi -> roi_preject;
  108.  
  109.     if ((pa = get_addr (hostname)) == NULLPA) {
  110.         PP_LOG (LLOG_EXCEPTIONS, ("Can't get paddr of qmgr"));
  111.         return NOTOK;
  112.     }
  113.  
  114.     if ((ctx = oid_cpy(QMGR_AC)) == NULLOID) {
  115.         PP_LOG (LLOG_EXCEPTIONS,
  116.             ("qmgr_start: out of memory"));
  117.         return NOTOK;
  118.     }
  119.     if ((pci = oid_cpy(QMGR_PCI)) == NULLOID) {
  120.         PP_LOG (LLOG_EXCEPTIONS,
  121.             ("qmgr_start: out of memory"));
  122.         return NOTOK;
  123.     }
  124.     pc->pc_nctx = 1;
  125.     pc->pc_ctx[0].pc_id = 1;
  126.     pc->pc_ctx[0].pc_asn = pci;
  127.     pc->pc_ctx[0].pc_atn = NULLOID;
  128.  
  129.     if ((sf = addr2ref ("submit")) == NULL) {
  130.         sf = &sfs;
  131.         (void) bzero ((char *) sf, sizeof(*sf));
  132.     }
  133.  
  134.     switch (AcAsynAssocRequest (ctx, NULLAEI, NULLAEI, NULLPA, pa, pc, NULLOID,
  135.                 0, ROS_MYREQUIRE, SERIAL_NONE, 0, sf, NULLPEP,
  136.                 0, NULLQOS, acc, aci, async)) {
  137.     case NOTOK:
  138.         *status = conn_status = NOTOK;
  139.         acs_log(aca,"A-ASSOCIATE.REQUEST");
  140.         return NOTOK;
  141.  
  142.     case CONNECTING_2:
  143.         *status = conn_status = CONNECTING_2;
  144.         sd = acc -> acc_sd;
  145.         ACCFREE (acc);
  146.         return sd;
  147.  
  148.     case CONNECTING_1: /* if !async - this is OK */
  149.         if (async == 1) {
  150.             *status = conn_status = CONNECTING_1;
  151.             sd = acc -> acc_sd;
  152.             ACCFREE (acc);
  153.             return sd;
  154.         }
  155.         /* otherwise - we are really DONE */
  156.  
  157.     case DONE:
  158.         if (acc->acc_result != ACS_ACCEPT) {
  159.             PP_LOG (LLOG_EXCEPTIONS,
  160.                 ("qmgr_start: Association rejected: [%s]",
  161.                  AcErrString(acc->acc_result)));
  162.             return NOTOK;
  163.         }
  164.         sd = acc->acc_sd;
  165.         ACCFREE(acc);
  166.         if (RoSetService(sd, RoPService, roi) == NOTOK) {
  167.             ros_log(rop,"set RO/PS fails");
  168.             return NOTOK;
  169.         }
  170.         *status = conn_status = DONE;
  171.         return sd;
  172.     }
  173.     return NOTOK;
  174. }
  175.  
  176. int qmgr_retry (fd, status)
  177. int    fd;
  178. int    *status;
  179. {
  180.     struct AcSAPconnect accs;
  181.     register struct AcSAPconnect   *acc = &accs;
  182.     struct AcSAPindication  acis;
  183.     register struct AcSAPindication *aci = &acis;
  184.     register struct AcSAPabort *aca = &aci -> aci_abort;
  185.     struct RoSAPindication rois;
  186.     register struct RoSAPindication *roi = &rois;
  187.     register struct RoSAPpreject *rop = &roi -> roi_preject;
  188.     int    result;
  189.  
  190.     PP_DBG (("acsap_retry(%d)", fd));
  191.     if (conn_status == DONE)
  192.         return fd;
  193.     switch (result = AcAsynRetryRequest (fd, acc, aci)) {
  194.         case CONNECTING_1:
  195.         case CONNECTING_2:
  196.         ACCFREE (acc);
  197.         *status = conn_status = result;
  198.         return fd;
  199.         case NOTOK:
  200.         acs_log (aca, "A-ASSOCIATE.REQUEST");
  201.         conn_status = NOTOK;
  202.         return NOTOK;
  203.         case DONE:
  204.         if (acc -> acc_result != ACS_ACCEPT) {
  205.             PP_LOG (LLOG_EXCEPTIONS,
  206.                 ("Association Rejected: [%s]",
  207.                  AcErrString (acc -> acc_result)));
  208.             return NOTOK;
  209.         }
  210.         ACCFREE (acc);
  211.         if (RoSetService (fd, RoPService, roi) == NOTOK) {
  212.             ros_log (rop, "set RO/PS fails");
  213.             return NOTOK;
  214.         }
  215.         *status = conn_status = DONE;
  216.         return fd;
  217.         default:
  218.         PP_LOG (LLOG_EXCEPTIONS,
  219.             ("Bad response from AcAsynRetryRequest"));
  220.         return NOTOK;
  221.     }
  222. }
  223.  
  224.  
  225. static int outstanding = NOTOK;
  226.  
  227. int qmgr_end(sd)
  228. int     sd;
  229. {
  230.     struct AcSAPrelease acrs;
  231.     register struct AcSAPrelease   *acr = &acrs;
  232.     struct AcSAPindication  acis;
  233.     register struct AcSAPindication *aci = &acis;
  234.     register struct AcSAPabort *aca = &aci -> aci_abort;
  235.  
  236.     if (outstanding != NOTOK)
  237.         if (getresult (sd, outstanding, 60) == NOTOK)
  238.             return NOTOK;
  239.  
  240.     outstanding = NOTOK;
  241. #ifdef CONNECTING_1
  242.     if (AcRelRequest(sd,ACF_NORMAL,NULLPEP,0, NOTOK, acr,aci) == NOTOK) {
  243. #else
  244.     if (AcRelRequest(sd,ACF_NORMAL,NULLPEP,0,acr,aci) == NOTOK) {
  245. #endif
  246.         acs_log(aca,"A-RELEASE.REQUEST");
  247.         return NOTOK;
  248.     }
  249.  
  250.     if (!acr->acr_affirmative) {
  251.         (void) AcUAbortRequest (sd, NULLPEP, 0, aci);
  252.         PP_LOG (LLOG_EXCEPTIONS,
  253.             ("qmgr_end: Release rejected by peer: %d",
  254.              acr->acr_reason));
  255.         return NOTOK;
  256.     }
  257.  
  258.     ACRFREE(acr);
  259.     return OK;
  260. }
  261.  
  262.  
  263. int message_send (sd, file, prm, que, sender, recips, rcount)
  264. int             sd;
  265. char            *file;
  266. struct prm_vars *prm;
  267. Q_struct        *que;
  268. ADDR            *sender,
  269.         *recips;
  270. int             rcount;
  271. {
  272. /* copied from invoke in ryinitiator */
  273.     int                             result;
  274.     struct type_Qmgr_MsgStruct      *in;
  275.     struct RoSAPindication          rois;
  276.     register struct RoSAPindication *roi = &rois;
  277.     register struct RoSAPpreject    *rop = &roi->roi_preject;
  278.  
  279.     while (conn_status != DONE && conn_status != NOTOK) {
  280.         int status = conn_status;
  281.         sd = qmgr_retry (sd, &status);
  282.         if (conn_status == DONE)
  283.             break;
  284.         sleep (1);
  285.     }
  286.     if (sd == NOTOK || conn_status == NOTOK)
  287.         return NOTOK;
  288.  
  289.     if (outstanding != NOTOK)
  290.         if (getresult (sd, outstanding, NOTOK) == NOTOK)
  291.             return NOTOK;
  292.     outstanding = NOTOK;
  293.  
  294.     if ((in = qstruct2qmgr(file,prm,que,sender,recips,rcount)) == NULL) {
  295.         PP_LOG (LLOG_EXCEPTIONS,
  296.             ("qstruct2qmgr failure for '%s'",
  297.              file));
  298.         return NOTOK;
  299.     }
  300.     if (in->recipientlist == NULL) {
  301.         /* no users waiting so no need to pass to qmgr */
  302.         PP_LOG (LLOG_EXCEPTIONS,
  303.             ("message_send: No recips for '%s'",
  304.              file));
  305.         free_Qmgr_PerMessageInfo(in->messageinfo);
  306.         free((char *) in);
  307.         return OK;
  308.     }
  309.  
  310.     switch (result = RyStub (sd, table_Qmgr_Operations, 
  311.                  operation_Qmgr_newmessage,
  312.                  outstanding = RyGenID(sd), NULLIP,
  313.                  (caddr_t) in, 
  314.                  newmessage_result,
  315.                  newmessage_error, ROS_ASYNC, roi)) {
  316.         case NOTOK:
  317.         if (ROS_FATAL(rop->rop_reason)) {
  318.             PP_LOG (LLOG_EXCEPTIONS,
  319.                 ("STUB"));
  320.             return outstanding = NOTOK;
  321.         }
  322.         PP_LOG (LLOG_EXCEPTIONS,
  323.             ("message_send:STUB"));
  324.         break;
  325.  
  326.         case OK:
  327.         break;
  328.  
  329.         case DONE:
  330.         PP_LOG (LLOG_EXCEPTIONS,
  331.             ("got RO-END.INDICATION"));
  332.         outstanding = NOTOK;
  333.         return qmgr_end(sd);
  334.  
  335.         default:
  336.         PP_LOG (LLOG_EXCEPTIONS,
  337.             ("submit_interface unknown return from RyStub=%d",result));
  338.         return outstanding = NOTOK;
  339.     }
  340.     if (in)
  341.         free_Qmgr_MsgStruct(in);
  342.     return OK;
  343. }
  344.  
  345. /*   */
  346. /* subsiduary routines */
  347.  
  348. /* ARGSUSED */
  349. static int newmessage_result (sd, id, dummy, result, roi)
  350. int                                     sd,
  351.                     id,
  352.                     dummy;
  353. struct type_Qmgr_Pseudo__newmessage     *result;
  354. struct RoSAPindication                  *roi;
  355. {
  356.     return OK;
  357. }
  358.  
  359. /* ARGSUSED */
  360. static int general_error (sd, id, error, parameter, roi)
  361. int     sd,
  362.     id,
  363.     error;
  364. caddr_t parameter;
  365. struct RoSAPindication *roi;
  366. {
  367.     register struct RyError *rye;
  368.  
  369.     if (error == RY_REJECT) {
  370.         PP_LOG (LLOG_EXCEPTIONS, ("%s", RoErrString ((int) parameter)));
  371.         return OK;
  372.     }
  373.  
  374.     if (rye = finderrbyerr (table_Qmgr_Errors, error))
  375.         PP_LOG (LLOG_EXCEPTIONS, ("%s", rye -> rye_name));
  376.     else
  377.         PP_LOG (LLOG_EXCEPTIONS, ("Error %d", error));
  378.  
  379.     return OK;
  380. }
  381.  
  382. /*   */
  383.  
  384. static void    ros_log (rop, event)
  385. register struct RoSAPpreject *rop;
  386. char   *event;
  387. {
  388.     char    buffer[BUFSIZ];
  389.  
  390.     if (rop -> rop_cc > 0)
  391.     (void) sprintf (buffer, "[%s] %*.*s", RoErrString (rop -> rop_reason),
  392.         rop -> rop_cc, rop -> rop_cc, rop -> rop_data);
  393.     else
  394.     (void) sprintf (buffer, "[%s]", RoErrString (rop -> rop_reason));
  395.  
  396.     PP_LOG (LLOG_EXCEPTIONS,
  397.         ("Lib/qmgr/submit_interface %s: %s", event, buffer));
  398. }
  399.  
  400. /*   */
  401.  
  402. static void    acs_log (aca, event)
  403. register struct AcSAPabort *aca;
  404. char   *event;
  405. {
  406.     char    buffer[BUFSIZ];
  407.  
  408.     if (aca -> aca_cc > 0)
  409.         (void) sprintf (buffer, "[%s] %*.*s",
  410.                 AcErrString (aca -> aca_reason),
  411.                 aca -> aca_cc, aca -> aca_cc, aca -> aca_data);
  412.     else
  413.         (void) sprintf (buffer, "[%s]",
  414.                 AcErrString (aca -> aca_reason));
  415.  
  416.     PP_LOG (LLOG_EXCEPTIONS,
  417.         ("Lib/qmgr/submit_interface %s: %s (source %d)", event, buffer,
  418.          aca -> aca_source));
  419. }
  420.  
  421. static int getresult (sd, id, delay)
  422. int    sd, id, delay;
  423. {
  424.     caddr_t out;
  425.     struct RoSAPindication          rois;
  426.     register struct RoSAPindication *roi = &rois;
  427.     register struct RoSAPpreject    *rop = &roi->roi_preject;
  428.     
  429.     switch (RyWait (sd, &id, &out, delay, roi)) {
  430.         case NOTOK:
  431.         if (rop -> rop_reason == ROS_TIMER)
  432.             break;
  433.         ros_log (rop, "RyWait Stub");
  434.         if (ROS_FATAL (rop -> rop_reason)) {
  435.             PP_LOG (LLOG_EXCEPTIONS,
  436.                 ("qmgr-interface failed fatally"));
  437.             return NOTOK;
  438.         }
  439.         break;
  440.         case OK:
  441.         break;
  442.  
  443.         case DONE:
  444.         PP_LOG (LLOG_EXCEPTIONS,
  445.             ("qmgr interface quit"));
  446.         return NOTOK;
  447.  
  448.         default:
  449.         PP_LOG (LLOG_EXCEPTIONS,
  450.             ("qmgr interface - bad response"));
  451.         return NOTOK;
  452.     }
  453.     return OK;
  454. }
  455.