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

  1. /* channel_control.c: control the channel process */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Lib/qmgr/RCS/chan_control.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/chan_control.c,v 6.0 1991/12/18 20:23:58 jpo Rel $
  9.  *
  10.  * $Log: chan_control.c,v $
  11.  * Revision 6.0  1991/12/18  20:23:58  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include <stdio.h>
  19. #include <syslog.h>
  20. #include <setjmp.h>
  21. #include <varargs.h>
  22. #include "qmgr.h"
  23. #include "retcode.h"
  24. #include <isode/tsap.h>
  25. #include "ll_log.h"
  26.  
  27. static jmp_buf toplevel;
  28.  
  29.  
  30. static IFP      startfnx;
  31. static IFP      stopfnx;
  32. static IFP      initchfnx;
  33. static struct type_Qmgr_DeliveryStatus *(*workfnx)();
  34.  
  35. static int     ros_init (), ros_work (), ros_lose ();
  36. static int     ros_worker (), error (), ureject ();
  37. static void    adios ();
  38. static void    acs_advise ();
  39. static void    ros_adios (), ros_advise ();
  40. static void    ros_indication ();
  41.  
  42. #ifdef notdef
  43. static  char    *myservice = "pp channel";
  44. #endif
  45. extern struct RyOperation table_Qmgr_Operations[];
  46.  
  47. int channel_control (argc, argv, init, work, finish)
  48. int     argc;
  49. char    **argv;
  50. IFP     init;
  51. struct type_Qmgr_DeliveryStatus *(*work)();
  52. IFP     finish;
  53. {
  54.     AEI         aei = NULLAEI;
  55.     struct TSAPdisconnect   tds;
  56.     struct TSAPdisconnect  *td = &tds;
  57.     struct RoSAPindication  rois;
  58.     register struct RoSAPindication *roi = &rois;
  59.     register struct RoSAPpreject   *rop = &roi -> roi_preject;
  60.  
  61.     PP_DBG (("starting"));
  62.  
  63.     workfnx = work;
  64.     initchfnx = init;
  65.     stopfnx = finish;
  66.  
  67.     if (RyDispatch (NOTOK, table_Qmgr_Operations,
  68.             operation_Qmgr_processmessage,
  69.             ros_worker, roi) == NOTOK)
  70.         ros_adios (rop, "processmessage");
  71.     if (RyDispatch (NOTOK, table_Qmgr_Operations,
  72.             operation_Qmgr_channelInitialise,
  73.             ros_worker, roi) == NOTOK)
  74.         ros_adios (rop, "channelInitialise");
  75.  
  76.     if (isodeserver (argc, argv, aei, ros_init, ros_work, ros_lose, td)
  77.         == NOTOK) {
  78.         if (td -> td_cc > 0)
  79.             adios (NULLCP, "isodeserver: [%s] %*.*s",
  80.                    TErrString (td -> td_reason),
  81.                    td -> td_cc, td -> td_cc,
  82.                    td -> td_data);
  83.         else
  84.             adios (NULLCP, "isodeserver: [%s]",
  85.                    TErrString (td -> td_reason));
  86.     }
  87.  
  88.     return 0;
  89. }
  90.  
  91. static int ros_result (sd, val, rox, roi)
  92. int     sd;
  93. struct type_Qmgr_DeliveryStatus *val;
  94. struct RoSAPinvoke *rox;
  95. struct RoSAPindication *roi;
  96. {
  97.     if (val == NULL)
  98.         return error (sd, error_Qmgr_congested, (caddr_t) NULL,
  99.                   rox, roi);
  100.  
  101.     if (RyDsResult (sd, rox -> rox_id, (caddr_t) val, ROS_NOPRIO, roi)
  102.             == NOTOK)
  103.         ros_adios (&roi -> roi_preject, "RESULT");
  104.     return OK;
  105. }
  106.  
  107. static int ros_worker (sd, ryo, rox, in, roi)
  108. int     sd;
  109. struct RyOperation *ryo;
  110. struct RoSAPinvoke *rox;
  111. caddr_t in;
  112. struct RoSAPindication *roi;
  113. {
  114.     struct type_Qmgr_DeliveryStatus *status;
  115.  
  116.     if (rox -> rox_nolinked == 0) {
  117.         PP_LOG (LLOG_EXCEPTIONS,
  118.             ("RO-INVOKE.INDICATION/%d: %s, unknown linkage %d",
  119.             sd, ryo -> ryo_name, rox -> rox_linkid));
  120.         return ureject (sd, ROS_IP_LINKED, rox, roi);
  121.     }
  122.     PP_DBG (("RO-INVOKE.INDICATION/%d: %s", sd, ryo -> ryo_name));
  123.  
  124.     switch (ryo -> ryo_op) {
  125.         case operation_Qmgr_channelInitialise:
  126.         switch ((*initchfnx) (in)) {
  127.             case OK:
  128.             if (RyDsResult (sd, rox -> rox_id, (caddr_t) NULL,
  129.                     ROS_NOPRIO, roi) == NOTOK)
  130.                 ros_adios (&roi -> roi_preject, "RESULT");
  131.             return OK;
  132.  
  133.             case NOTOK:
  134.             default:
  135.             return error (sd, error_Qmgr_protocol, (caddr_t) NULL,
  136.                       rox, roi);
  137.         }
  138.  
  139.         case operation_Qmgr_processmessage:
  140.         status = (*workfnx) (in);
  141.         return ros_result (sd, status, rox, roi);
  142.  
  143.         default:
  144.         PP_LOG (LLOG_EXCEPTIONS,
  145.             ("RO-INVOKE.INDICATION/%d: operation %s not expected",
  146.             sd, ryo -> ryo_name));
  147.         return error (sd, error_Qmgr_protocol, (caddr_t) NULL,
  148.                   rox, roi);
  149.     }
  150. }
  151.  
  152. /*   */
  153.  
  154. static int  ros_init (vecp, vec)
  155. int     vecp;
  156. char  **vec;
  157. {
  158.     int     reply,
  159.         result,
  160.         sd;
  161.     struct AcSAPstart   acss;
  162.     register struct AcSAPstart *acs = &acss;
  163.     struct AcSAPindication  acis;
  164.     register struct AcSAPindication *aci = &acis;
  165.     register struct AcSAPabort   *aca = &aci -> aci_abort;
  166.     register struct PSAPstart *ps = &acs -> acs_start;
  167.     struct RoSAPindication  rois;
  168.     register struct RoSAPindication *roi = &rois;
  169.     register struct RoSAPpreject   *rop = &roi -> roi_preject;
  170.  
  171.     if (AcInit (vecp, vec, acs, aci) == NOTOK) {
  172.     acs_advise (aca, "initialization fails");
  173.     return NOTOK;
  174.     }
  175.     PP_DBG (("A-ASSOCIATE.INDICATION: <%d, %s, %s, %s, %d>",
  176.         acs -> acs_sd, sprintoid (acs -> acs_context),
  177.         sprintaei (&acs -> acs_callingtitle),
  178.         sprintaei (&acs -> acs_calledtitle), acs -> acs_ninfo));
  179.  
  180.     sd = acs -> acs_sd;
  181.  
  182.     for (vec++; *vec; vec++)
  183.     PP_LOG (LLOG_EXCEPTIONS, ("unknown argument \"%s\"", *vec));
  184.  
  185.     reply = startfnx ? (*startfnx) (sd, acs) : ACS_ACCEPT;
  186.  
  187.     result = AcAssocResponse (sd, reply, 
  188.         reply != ACS_ACCEPT ? ACS_USER_NOREASON : ACS_USER_NULL,
  189.         NULLOID, NULLAEI, NULLPA, NULLPC, ps -> ps_defctxresult,
  190.         ps -> ps_prequirements, ps -> ps_srequirements, SERIAL_NONE,
  191.         ps -> ps_settings, &ps -> ps_connect, NULLPEP, 0, aci);
  192.  
  193.     ACSFREE (acs);
  194.  
  195.     if (result == NOTOK) {
  196.     acs_advise (aca, "A-ASSOCIATE.RESPONSE");
  197.     return NOTOK;
  198. }
  199.     if (reply != ACS_ACCEPT)
  200.     return NOTOK;
  201.  
  202.     if (RoSetService (sd, RoPService, roi) == NOTOK)
  203.     ros_adios (rop, "set RO/PS fails");
  204.  
  205.     return sd;
  206. }
  207.  
  208. /*   */
  209.  
  210. static int  ros_work (fd)
  211. int     fd;
  212. {
  213.     int     result;
  214.     caddr_t out;
  215.     struct AcSAPindication  acis;
  216.     struct RoSAPindication  rois;
  217.     register struct RoSAPindication *roi = &rois;
  218.     register struct RoSAPpreject   *rop = &roi -> roi_preject;
  219.  
  220.     switch (setjmp (toplevel)) {
  221.     case OK: 
  222.         break;
  223.  
  224.     default: 
  225.         if (stopfnx)
  226.         (*stopfnx) ();
  227.     case DONE:
  228.         (void) AcUAbortRequest (fd, NULLPEP, 0, &acis);
  229.         (void) RyLose (fd, roi);
  230.         return NOTOK;
  231.     }
  232.  
  233.     switch (result = RyWait (fd, NULLIP, &out, OK, roi)) {
  234.     case NOTOK: 
  235.         if (rop -> rop_reason == ROS_TIMER)
  236.         break;
  237.     case OK: 
  238.     case DONE: 
  239.         ros_indication (fd, roi);
  240.         break;
  241.  
  242.     default: 
  243.         adios (NULLCP, "unknown return from RoWaitRequest=%d", result);
  244.     }
  245.  
  246.     return OK;
  247. }
  248.  
  249. /*   */
  250.  
  251. static void ros_indication (sd, roi)
  252. int     sd;
  253. register struct RoSAPindication *roi;
  254. {
  255.     int     reply,
  256.         result;
  257.  
  258.     switch (roi -> roi_type) {
  259.     case ROI_INVOKE: 
  260.     case ROI_RESULT: 
  261.     case ROI_ERROR: 
  262.         adios (NULLCP, "unexpected indication type=%d", roi -> roi_type);
  263.         break;
  264.  
  265.     case ROI_UREJECT: 
  266.         {
  267.         register struct RoSAPureject   *rou = &roi -> roi_ureject;
  268.  
  269.         if (rou -> rou_noid)
  270.             PP_LOG (LLOG_EXCEPTIONS, ("RO-REJECT-U.INDICATION/%d: %s",
  271.                 sd, RoErrString (rou -> rou_reason)));
  272.         else
  273.             PP_LOG (LLOG_EXCEPTIONS, 
  274.                 ("RO-REJECT-U.INDICATION/%d: %s (id=%d)",
  275.                 sd, RoErrString (rou -> rou_reason),
  276.                 rou -> rou_id));
  277.         }
  278.         break;
  279.  
  280.     case ROI_PREJECT: 
  281.         {
  282.         register struct RoSAPpreject   *rop = &roi -> roi_preject;
  283.  
  284.         if (ROS_FATAL (rop -> rop_reason))
  285.             ros_adios (rop, "RO-REJECT-P.INDICATION");
  286.         ros_advise (rop, "RO-REJECT-P.INDICATION");
  287.         }
  288.         break;
  289.  
  290.     case ROI_FINISH: 
  291.         {
  292.         register struct AcSAPfinish *acf = &roi -> roi_finish;
  293.         struct AcSAPindication  acis;
  294.         register struct AcSAPabort *aca = &acis.aci_abort;
  295.  
  296.         PP_TRACE (("A-RELEASE.INDICATION/%d: %d",
  297.             sd, acf -> acf_reason));
  298.  
  299.         result = AcRelResponse (sd, reply = ACS_ACCEPT,
  300.                     ACR_NORMAL, NULLPEP, 0, &acis);
  301.  
  302.         ACFFREE (acf);
  303.  
  304.         if (result == NOTOK)
  305.             acs_advise (aca, "A-RELEASE.RESPONSE");
  306.         else
  307.             if (reply != ACS_ACCEPT)
  308.             break;
  309.  
  310.         if (stopfnx)
  311.             (*stopfnx)();
  312.  
  313.         longjmp (toplevel, DONE);
  314.         }
  315.     /* NOTREACHED */
  316.  
  317.     default: 
  318.         adios (NULLCP, "unknown indication type=%d", roi -> roi_type);
  319.     }
  320. }
  321.  
  322. /*   */
  323.  
  324. static int  ros_lose (td)
  325. struct TSAPdisconnect *td;
  326. {
  327.     if (td -> td_cc > 0)
  328.     PP_LOG (LLOG_EXCEPTIONS, ("TNetAccept: [%s] %*.*s",
  329.         TErrString (td -> td_reason), td -> td_cc, td -> td_cc,
  330.         td -> td_data));
  331.     else
  332.     PP_LOG (LLOG_EXCEPTIONS, ("TNetAccept: [%s]",
  333.         TErrString (td -> td_reason)));
  334. }
  335.  
  336. /*     ERRORS */
  337.  
  338. static void    ros_adios (rop, event)
  339. register struct RoSAPpreject *rop;
  340. char   *event;
  341. {
  342.     ros_advise (rop, event);
  343.  
  344.     longjmp (toplevel, NOTOK);
  345. }
  346.  
  347.  
  348. static void    ros_advise (rop, event)
  349. register struct RoSAPpreject *rop;
  350. char   *event;
  351. {
  352.     char    buffer[BUFSIZ];
  353.  
  354.     if (rop -> rop_cc > 0)
  355.     (void) sprintf (buffer, "[%s] %*.*s", RoErrString (rop -> rop_reason),
  356.         rop -> rop_cc, rop -> rop_cc, rop -> rop_data);
  357.     else
  358.     (void) sprintf (buffer, "[%s]", RoErrString (rop -> rop_reason));
  359.  
  360.     PP_LOG (LLOG_EXCEPTIONS, ("%s: %s", event, buffer));
  361. }
  362.  
  363. /*   */
  364.  
  365. static void    acs_advise (aca, event)
  366. register struct AcSAPabort *aca;
  367. char   *event;
  368. {
  369.     char    buffer[BUFSIZ];
  370.  
  371.     if (aca -> aca_cc > 0)
  372.     (void) sprintf (buffer, "[%s] %*.*s",
  373.         AcErrString (aca -> aca_reason),
  374.         aca -> aca_cc, aca -> aca_cc, aca -> aca_data);
  375.     else
  376.     (void) sprintf (buffer, "[%s]", AcErrString (aca -> aca_reason));
  377.  
  378.     PP_LOG (LLOG_EXCEPTIONS, ("%s: %s (source %d)", event, buffer,
  379.         aca -> aca_source));
  380. }
  381.  
  382. /*   */
  383.  
  384. #ifndef lint
  385.  
  386. static void    adios (va_alist)
  387. va_dcl
  388. {
  389.     va_list ap;
  390.  
  391.     va_start (ap);
  392.  
  393.     _ll_log (pp_log_oper, LLOG_FATAL, ap);
  394.  
  395.     va_end (ap);
  396.  
  397.     _exit (1);
  398. }
  399. #else
  400. /* VARARGS */
  401.  
  402. static void    adios (what, fmt)
  403. char   *what,
  404.        *fmt;
  405. {
  406.     adios (what, fmt);
  407. }
  408. #endif
  409.  
  410. /*     ERROR */
  411.  
  412. static int  error (sd, err, param, rox, roi)
  413. int     sd,
  414.     err;
  415. caddr_t param;
  416. struct RoSAPinvoke *rox;
  417. struct RoSAPindication *roi;
  418. {
  419.     if (RyDsError (sd, rox -> rox_id, err, param, ROS_NOPRIO, roi) == NOTOK)
  420.     ros_adios (&roi -> roi_preject, "ERROR");
  421.  
  422.     return OK;
  423. }
  424.  
  425. static int  ureject (sd, reason, rox, roi)
  426. int     sd,
  427.     reason;
  428. struct RoSAPinvoke *rox;
  429. struct RoSAPindication *roi;
  430. {
  431.     if (RyDsUReject (sd, rox -> rox_id, reason, ROS_NOPRIO, roi) == NOTOK)
  432.     ros_adios (&roi -> roi_preject, "U-REJECT");
  433.  
  434.     return OK;
  435. }
  436.