home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / prog / utils / sercli.shr / sercli / src / rexx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-16  |  6.5 KB  |  369 lines

  1. /*
  2. **  $Source: WB_2.1:homes/rkr/prog/sercli/src/RCS/rexx.c,v $
  3. **  $Author: rkr $
  4. **  $Revision: 1.9 $
  5. **  $Locker: rkr $
  6. **  $State: Exp $
  7. **  $Date: 1993/06/16 23:29:30 $
  8. **
  9. **  sercli (an Amiga .device <-> FIFO interface tool)
  10. **  Copyright (C) 1993  Richard Rauch
  11. **
  12. **  See /doc/sercli.doc and /COPYING for use and distribution license.
  13. **
  14. */
  15.  
  16. #include <rexx/errors.h>
  17.  
  18. #include <clib/alib_protos.h>
  19. #include <clib/exec_protos.h>
  20. #include <clib/intuition_protos.h>
  21. #include <clib/rexxsyslib_protos.h>
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26.  
  27. #include "config.h"
  28. #include "defs.h"
  29. #include "rexx.h"
  30. #include "keywords.h"
  31. #include "sercli-config.h"
  32. #include "ser_supp.h"
  33.  
  34. void *RexxSysBase;  /*** screwey `struct RxsLib' name, if you care ***/
  35.  
  36. MsgPort *rexx_port;
  37.  
  38. ULONG rexx_mask;
  39.  
  40. static RexxMsg *rm;
  41.  
  42. /*
  43. **  Reply to an ARexx message.
  44. **
  45. **  Args:
  46. **    {rm}    - The ARexx msg to reply to
  47. **    {rc}    - Result1 to send back
  48. **    {res}    - Result2 to send back
  49. **
  50. **  NOTE that according to ARexx documentation, you should only set {res}
  51. **  when {rc} is 0.  rexx_reply() makes NO such checks!
  52. **
  53. **  {rm} isn't really needed in this context, since we only have the global
  54. **  {rm}, but it's a bit more flexible this way (should probably stick
  55. **  {rm}s in more of the function parameter lists...).
  56. **
  57. */
  58. void rexx_reply (RexxMsg *rm, LONG rc, char *res)
  59. {
  60.     rm->rm_Result1 = rc;
  61.     if ( (rm->rm_Action & RXFF_RESULT) && (res) )
  62.     rm->rm_Result2 = CreateArgstring (res, strlen (res) );
  63.     ReplyMsg ( (Message *)rm);
  64. }
  65.  
  66.  
  67. /*
  68. **  Creates an ARexx port.
  69. **
  70. **  Does NOT open the arexx libraries; that will be handled by autoinit
  71. **  code (if Dillon hasn't yet put auto support for ARexx in, I'll add
  72. **  that...
  73. **
  74. **  Basically, creates a port with {prog_id} (a global; that global
  75. **  defaults to "sercli" but can be set before this function is called...
  76. **  In the current context (i.e., the sercli program) it may be set by
  77. **  read_sercli_config() when reading in a config file with an appropriate
  78. **  config line...).
  79. **
  80. */
  81. void open_rexx (void)
  82. {
  83.     if (RexxSysBase)
  84.     {
  85.     Forbid ();
  86.     {
  87.         if (FindPort (prog_id) )
  88.         exit (10);
  89.         rexx_port = CreatePort (prog_id, 1);
  90.     }
  91.     Permit ();
  92.     rexx_mask = 1 << (rexx_port->mp_SigBit);
  93.     }
  94. }
  95.  
  96.  
  97. /*
  98. **  Closes down the ARexx port.
  99. **
  100. **  Like open_rexx(), close_rexx() does not deal with the libraries (and
  101. **  for analogous reasons).
  102. **
  103. */
  104. void close_rexx (void)
  105. {
  106.     if (rexx_port)
  107.     {
  108.     RemPort (rexx_port);
  109.  
  110.     while (rm = (RexxMsg *) GetMsg (rexx_port) )
  111.         rexx_reply (rm, RC_ERROR, NULL);
  112.  
  113.     DeletePort (rexx_port);
  114.     rexx_port = NULL;
  115.     rexx_mask = 0;
  116.     }
  117. }
  118.  
  119.  
  120. /*
  121. **  Handles all ARexx messages that accumulate at {rexx_port}.
  122. **
  123. **  The {rexx_port} is a global, as is {rm} (the {RexxMsg *}).
  124. **
  125. */
  126. void handle_rexx (void)
  127. {
  128.     int ser_soft_param = 0;
  129.     int ser_hard_param = 0;
  130.  
  131.     while (rm = (RexxMsg *)GetMsg (rexx_port) )
  132.     {
  133.     char *line;
  134.     char *result = 0;
  135.     char *tmp;
  136.     LONG rc = RC_OK;
  137.  
  138.     line = tmp = rm->rm_Args [0];
  139.     while ( (*tmp) && (*tmp++ != ':') )
  140.         ;
  141.  
  142.     while ( (*tmp) && (*tmp == ' ') )
  143.         ++tmp;
  144.  
  145.     switch (match (line, keywords) )
  146.     {
  147.     case OPTION_NOT_FOUND:
  148.         rc = RC_ERROR;
  149.         break;
  150.  
  151.  
  152.     case OPTION_COMMENT:
  153.         break;
  154.  
  155.     /*
  156.     **  General:
  157.     **    Add support to return the "old" values for these serial
  158.     **    param controls?
  159.     **
  160.     **    Or else call ser_soft_set() from each & return the result
  161.     **    of that?
  162.     **
  163.     */
  164.     case SER_BPS:
  165.         if (*tmp)
  166.         {
  167.         ser_bps = strtol (tmp, NULL, 0);
  168.         ser_soft_param = 1;
  169.         }
  170.         else if (alert_loc)
  171.         printf ("Invalid {bps} in rexx msg: {%s}\n", line);
  172.         break;
  173.  
  174.  
  175.     case SER_BITS:
  176.         if (*tmp)
  177.         {
  178.         ser_read_bits = ser_write_bits = strtol (tmp, NULL, 0);
  179.         ser_soft_param = 1;
  180.         }
  181.         else if (alert_loc)
  182.         printf ("Invalid {bits} in rexx msg {%s}.\n", line);
  183.         break;
  184.  
  185.  
  186.     case SER_STOP_BITS:
  187.         if (*tmp)
  188.         {
  189.         ser_stop_bits = strtol (tmp, NULL, 0);
  190.         ser_soft_param = 1;
  191.         }
  192.         else if (alert_loc)
  193.         printf ("Invalid {stop bits} in rexx msg {%s}.\n", line);
  194.         break;
  195.  
  196.  
  197.     case SER_7WIRE:
  198.         ser_7wire = 1;
  199.         ser_hard_param = 1;
  200.         break;
  201.  
  202.  
  203.     case SER_3WIRE:
  204.         ser_7wire = 0;
  205.         ser_hard_param = 1;
  206.         break;
  207.  
  208.  
  209.     case SER_XON_XOFF:
  210.         ser_xon_xoff = 1;
  211.         ser_soft_param = 1; /*** hard?? ***/
  212.         break;
  213.  
  214.  
  215.     case SER_NO_XON_XOFF:
  216.         ser_xon_xoff = 0;
  217.         ser_soft_param = 1; /*** hard?? ***/
  218.         break;
  219.  
  220.  
  221.     case SER_SHARED:
  222.         ser_exclusive = 0;
  223.         ser_hard_param = 1;
  224.         break;
  225.  
  226.  
  227.     case SER_EXCLUSIVE:
  228.         ser_exclusive = 1;
  229.         ser_hard_param = 1;
  230.         break;
  231.  
  232.  
  233.     case SER_NO_RAD_BOOGIE:
  234.         ser_rad_boogie = 0;
  235.         ser_hard_param = 1;
  236.         break;
  237.  
  238.  
  239.     case SER_RAD_BOOGIE:
  240.         ser_rad_boogie = 1;
  241.         ser_hard_param = 1;
  242.         break;
  243.  
  244.  
  245.     case SER_NO_PARITY:
  246.         ser_parity = 0;
  247.         ser_soft_param = 1;
  248.         break;
  249.  
  250.  
  251.     case SER_ODD_PARITY:
  252.         ser_parity = 1;
  253.         ser_soft_param = 1;
  254.         break;
  255.  
  256.  
  257.     case SER_EVEN_PARITY:
  258.         ser_parity = 2;
  259.         ser_soft_param = 1;
  260.         break;
  261.  
  262.  
  263.     case SET_WINDOW_TITLE:
  264.     {
  265.         char buf [256];
  266.  
  267.         int len;
  268.  
  269.         if (nether_name)
  270.         free (nether_name);
  271.  
  272.         /*
  273.         **    return old title; gets freed on way out...
  274.         **
  275.         */
  276.         result = window_title;        /*** Just use nw.Title??? ***/
  277.         nether_name = strdup (tmp);
  278.         len = sprintf
  279.         (
  280.         buf,
  281.         "sercli: with {%s} id {%s}",
  282.         nether_name,
  283.         prog_id
  284.         );
  285.         window_title = strdup (buf);        /*** Just use nw.Title??? ***/
  286.         SetWindowTitles (win, window_title, (UBYTE *)~0);
  287.  
  288.         rc = RC_OK;
  289.         break;
  290.     }
  291.  
  292.  
  293.     case SET_WINDOW_SIZE:
  294.     {
  295.         int new_width;
  296.         int new_height;
  297.  
  298.         rc = RC_ERROR;
  299.  
  300.         sscanf (tmp, "%d %d", &new_width, &new_height);
  301.         if ( (new_width > 0) && (new_height > 0) )
  302.         {
  303.         char buf [256];
  304.  
  305.         SizeWindow (win, new_width - win_width, new_height - win_height);
  306.  
  307.         sprintf (buf, "%d %d", win_width, win_height);
  308.         result = strdup (buf);
  309.  
  310.         win_width = new_width;
  311.         win_height = new_height;
  312.  
  313.         rc = RC_OK;
  314.         }
  315.         break;
  316.     }
  317.  
  318.  
  319.     case ALERT_LOC:
  320.         alert_loc = 1;
  321.         break;
  322.  
  323.  
  324.     case ALERT_SER:
  325.         alert_ser = 1;
  326.         break;
  327.  
  328.  
  329.     case NO_ALERT_LOC:
  330.         alert_loc = 0;
  331.         break;
  332.  
  333.  
  334.     case NO_ALERT_SER:
  335.         alert_ser = 0;
  336.         break;
  337.  
  338.  
  339.     case SER_QUERY:
  340.         /*
  341.         **    Not really and "error," but this'll do the job for now.
  342.         **
  343.         */
  344.         handle_error (error_type_serial, query_ser () );
  345.         break;
  346.  
  347.  
  348.     default:
  349.         if (alert_loc)
  350.         printf ("rexx command {%s} not implemented.\n", line);
  351.         rc = RC_ERROR;
  352.         break;
  353.     }
  354.  
  355.     rexx_reply (rm, rc, result);
  356.     if (result)
  357.         free (result);
  358.     }
  359.  
  360.     if (ser_hard_param)
  361.     {
  362.     close_ser ();
  363.     open_ser ();
  364.     }
  365.     else if (ser_soft_param)
  366.     set_ser_soft ();
  367. }
  368.  
  369.