home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 277.lha / TestRH / doc / testrh.doc < prev    next >
Encoding:
Text File  |  1989-08-08  |  12.7 KB  |  279 lines

  1.  
  2.     Ever since I started using AREXX, I developed strong ideas on what
  3. feautures make a Rexx Host. Rather than to simply say what I want, I
  4. decided to put together an example.
  5.  
  6.     Actually, last year I started adding a bi-directional Rexx port to
  7. DME. But <.....>        had already added a
  8. a Rexx port, and in a way that was incompatible with my then version.
  9. So I cancelled my project. Finding nothing else to do during this
  10. summer, I decided to create an example out of it. Mainly I want to be
  11. able to say, "If I can do it, so can any programmer". In the meantime,
  12. I also had the opportunity to look at the proposals of <..............>
  13. on adding a rexx port to MicroEmacs, and at Tom Rokicki's version of
  14. FreeDraw.
  15.  
  16. Now, let me list the levels of Rexx support a program may have:
  17.  
  18.     1(a). ARexx is a glorified macro processor cum variable handler.
  19.     1(b). Commands will also be accepted from ARexx.
  20.   However the program does not have both 1(a) and 1(b).
  21.  
  22.     2. The program exists in two modes: In the active mode, 1(a) is
  23.     supported. In the idle mode 1(b) is supported.
  24.  
  25.     3. Full bidirectional support is there. [If that is the case, support
  26.     for asynchrnous arexx invocations may also be given.]
  27.  
  28. Tom's FreeDraw does all three. But I want a few more features:
  29.     Firstly, there should be a way to control the access. My suggestion
  30. would be to have paswords. External commands must be prefixed with the
  31. password while the restriction is in effect. Restriction placed by
  32. the user at the console must take precedence over others.
  33.     No commands must be carried out after the program reaches the
  34. halt condition: This when the halt command is recieved from the console
  35. but before the program has cleaned up after itself.
  36.     Anything else that is in this example, but I have forgotten. :-)
  37.  
  38. ---------------------------------------------------------------------------
  39.  
  40. USERS' MANUAL FOR testrh
  41.  
  42. The user interface is crude: After all this is only a "proof of concept".
  43.  
  44. This program will run only from CLI. The point is that the source code is
  45. all that is important. You also need arp.library and, of course, the ARexx
  46. system library.
  47.  
  48. This program should be invoked as "testrh upw" where upw is any ascii
  49. string. This string will be used as the password when you "lock" the
  50. Rexx server. This program then opens a public port named "RDE" and waits.
  51.  
  52. To send a command to the host, you simply address it to the port.
  53. To give a command to this program, you first hit Control-D. Then you
  54. will be prompted for the command. Enter the command and any arguments for
  55. that command, followed by carriage return.
  56.  
  57. In the string you enter, the seven characters ()`'\^$ have special meaning.
  58. Further, ' ' (space) is used as a field seperator. If the argument you
  59. want to enter contains spaces, enclose that in (): Thus, to enter
  60.         abc xyz
  61. as a single argument, you will type (abc xyz). These nest: Thus
  62.         ((abc def) (xyz uvw))
  63. means "(abc def) (xyz uvw)". (abc (def xyz) is illegal. Alternatively, you
  64. may use `' in place of ().
  65.  
  66. The character '^' is a prefix that causes the following char to be
  67. interpreted as a control char: ^a means char '\001'. Backslash (\)
  68. is the escape char: \^ is the caret, \( is open paran and \\ is the
  69. backslash. Finally, $ is replaced by a global string variable that
  70. (usually) contains the result string returned by a Rexx macro.
  71.  
  72. The following commands can be given from the keyboard:
  73.     quit            [no args]
  74.         Close up shop and quit.
  75.  
  76.     lockrh          [no args]
  77.         Put the "user lock" on the rexx host. If an external command is
  78.     prefixed by the password set in the command line of the invocation,
  79.     the command will not be executed.
  80.  
  81.     unlockrh        [no args]
  82.         removes the user lock.
  83.  
  84.     clrrhlocks      [no args]
  85.         Removes the user lock and any lock placed by a Rexx macro.
  86.  
  87.     execute arg
  88.         The arg is passed to AmigaDOS via Execute().
  89.  
  90. The previous five command are privilaged: They cannot be executed via
  91. ARexx macros. The rest may executed either from the console or from the
  92. Rexx port.
  93.  
  94.     set arg
  95.         arg is placed in the string variable $.
  96.  
  97.     show            [no args]
  98.         The string in $ is printed in the console window.
  99.  
  100.     rxc arg
  101.         arg is passed to ARexx as a command invocation.
  102.  
  103.     rxo arg1 arg2
  104.         arg2 is passed to ARexx. The manner is controlled by the options
  105.         specified in arg1: arg1 must consist of exactly five characters:
  106.         Thus it must be: (f|.)(r|.)(s|.)(t|.)(a|.) These are interpreted
  107.         as follows: If the last char is 'a', the message is sent
  108.         asynchronously; we will not wait for ARexx to complete the call.
  109.         If the fourth char is a 't', command string tokenization is
  110.         requested from Rexx. If the third char is an 's', the command is
  111.         sent as string file. if the second char is an 'r', a result string
  112.         will be requested. If the first char is an 'f', the invocation is a
  113.         function invocation rather than a command invocation. Further, arg2
  114.         is interpreted in a special way: It is parsed into seperate pieces
  115.         seperated by spaces [unless enclosed in () or `']. There can at
  116.         most 14 such pieces.
  117.  
  118.         Some examples are:
  119.             rxo .rs.. (EXIT TIME()) : Will put the system time into $.
  120.             <.............>
  121.  
  122. Any other command is considered to be an implicit invocation of an ARexx
  123. macro.
  124.  
  125.  
  126. The following commands make sense only from ARexx macros:
  127.  
  128.     LOCK mpw
  129.         This places a macro lock on the Rexx host. Till this lock is
  130.         removed via UNLOCK, or by a clrrhlocks command from the console,
  131.         all external commands must be prefixed by the password given as the
  132.         argument of this command. Note that this lock may be forcibly
  133.         removed by the user. So select mpw to be distinct from any commands
  134.         you may give.
  135.  
  136.     UNLOCK          [no args]
  137.         This removes the macro lock.
  138.  
  139.     MSGTOUSR msg
  140.         Prints out the message string msg at the console window.
  141.  
  142.     STRING
  143.         You must request a result string when sending this command. The
  144.         current value of $ is returned as the result string.
  145.  
  146. Anything other than these four commands will be passed to the general
  147. command dispatcher to be interpreted the same way as commands from the
  148. console.
  149.  
  150. P.S: Both implied invocations of ARexx macros and string file invocations
  151. set the inital host address to be "REXX". All other invocations set the
  152. initial address to be "RDE".
  153.  
  154. ----------------------------------------------------------------
  155.                 A short guide to the code
  156.  
  157. I have tried to make this as easy to reuse as possible. If you want to
  158. just link this code into your program, with or wothout modifications,
  159. you need to read this. At best, you can just define some string aliases
  160. and assemble the support routines. Unfortunately, this assembles only
  161. with the Manx assembler. It is becuase I am too lazy to make it assemble
  162. with others. But somebody may wnat to try.
  163.  
  164. The following global variables must have been initialized somewhere in
  165. your code.
  166.         RexxSysBase: Pointer to the ARexx system library.
  167.         SysBase: Pointer to the Exec library.
  168.         ArpBase: Pointer to arp library. This is used only to call the
  169.                 case-insensitive Strncmp. Change this if you don't want
  170.                 to rely on arp.library.
  171.  
  172.         RHPort:  Pointer to the message port used to communicate
  173.                  with ARexx
  174.         RHFlags: (UWORD) flags on the state of this host. See the .i
  175.                 file for the bit definitions.
  176.         ChkPorts: (UWORD) flags to indicate invalid signals for msg ports.
  177.                 The bit for RHPort will be set after the end of a
  178.                 synchronous invocation.
  179.         CmdErr: (ULONG) Error flags. More serious errors should correspond
  180.                 to the higher bits. The severity level is set based on this.
  181.  
  182. The following global variables are declared in rderxsupp.asm. They may need
  183. to be modified by you.
  184.  
  185. RHUsrPassWd:  Pointer to the pass word set by the user.
  186. RHMcrPassWd:  Pointer to the pass word set by an external macro
  187. RHOutCount:   No of outstanding messages. Do not exit till this goes to 0.
  188. RMSeqNo:      The serial no of the last msg to Rexx. (modulo 2^16) Can be
  189.                 used to keep track of async messages.
  190.  
  191. The following are constants used.
  192. rhcmds: This is an array listing the commands to the rexx host. It is an
  193. array of        struct {rhcn *name; int *fn()}
  194. where rhcn is a struct {UBYTE len; char nm[1]}, with len&127 = length of
  195. te command name, bit 7 of len is set if this command doesnot return a
  196. result string; fn is the address of the function to call.
  197.  
  198. CErc: This is an array of UWORDs listing the return codes corresponding
  199. to the bits of CmdErr.
  200.  
  201. The following two functions must exist:
  202.  
  203. do_command(char *cmdstr):
  204.         This is the general command parser/interpreter. It will be passed
  205. the command string sent from ARexx (minus the password if any). It must
  206. not alter its argument. [This is important if you expect to allow external
  207. commands.]
  208.  
  209. drm_end(union {int err; char *result} r2, long r1;
  210.            union {ULONG no;void *adr} id)
  211.         This function is called after the return of messages we sent to
  212. ARexx. The "id" argument is always the id passed to sendrxmsg() when the
  213. message was sent. The (r1, r2) fields are to be interpreted as follows:
  214.        case (r1 = 0, r2 = 0) : No errors, no result string.
  215.        case (r1 = 0, r2 != 0): No errors; r2.result points at a copy
  216.                                        of the result string. This
  217.                                        store must be free()'ed by you.
  218.        case (r1>0)           : There was an error. r1 = severity and
  219.                                        r2 = error code.
  220.        case (r1 = -1)        : The macro went ok, but couldn't malloc()
  221.                                        memory for the result string.
  222.  
  223. The following routines are avaiable for rexx support:
  224.  
  225. disprxmsg(struct RxMsg *msg)
  226.         This disposes of rexx messages. If the message is one we sent,
  227. it releases all allocated resources and then calls drm_end().
  228.         If the message is external, it first checks for Halt condition.
  229. Then it checks for locks. If there is a lick, the pass word is checked and
  230. if valid, the command string is extracted. Then it sees if the command
  231. is rexx-host specific. If so, the correspoding function is called as
  232.                 rv = fn(char *arg, char *str, long len)
  233. Here arg is a pointer to the argument. This string must not be altered.
  234. The return value is actually composed of rv, str and len. Only the
  235. following combinations are valid. Any other combination may cause
  236. memory loss or corruption:
  237.         rv = 0; len = 0; str = NULL: No errors. No result string.
  238.         rv = 0; len != 0; str != NULL: No errors.  str points at
  239.                 the result string and len is its length. The storage for
  240.                 str must have been allocated with malloc() as a call of
  241.                 of the form "free(str)" will be made.
  242.         rv != 0; len any; str = NULL: There was error. rv = severity
  243.                 level and len = secondary code.
  244.  
  245.  
  246. sendrxmsg(ULONG act, ULONG flgs, union {long no char *str} args[],
  247.                 union {ULONG no; void *adr} id)
  248. This routine creates and sends messages to ARexx. The arguments to this
  249. function have the follwoing meaning:
  250.   act : entered as is into rm_Action field.
  251.            act&0x0f will be used as the no of args to be converted.
  252.            must be less than 15, but NOT equal
  253.   flgs: this is a bit field with bits 0:14 being the flags for
  254.            conversion: bit i is 0 => args[i] is a string
  255.                        bit i is 1 => args[i] is a long.
  256.                 if SRMB_ASYNCH is set, the message is sent asynchornously:
  257.                     sendrxmsg will not wait for the message to come back.
  258.                 if SRMB_HOSTNM is set, the initial Host will ARexx itself.
  259.                     [usually it is ourselves.]
  260.                 if SRMB_TONAME is set, the message is sent to the port named
  261.                     'AREXX'. Otherwise it is sent ot 'REXX'. This is valid
  262.                     only from v1.10 on. THIS IS NOT TO BE USED AS A COPOUT
  263.                     BY THOSE NOT WISHING TO IMPLEMENT ASYNCHRONOUS
  264.                     CAPABILITY. [only by those who CAN'T :-)]
  265.  
  266.   args: This is an array 0..14 of union{long ; char *}. Used to
  267.            fill the rexx msg.
  268.   id  : This is the message id. Will be entered as is into
  269.            rm_Args[15] field of the rexx message.
  270.            Is passed as an argument to drm_end.
  271. Return value:  0 --> all ok
  272.                1 --> too many outstanding messages.
  273.                2 --> Unable to create the message/argstrings
  274.                3 --> No public (A)REXX port
  275.  
  276. The last support routine is rxerrmsg(n): It returns a string containing
  277. a description of the error with code n. It is basically a fluffed up
  278. ErrorMsg() call.
  279.