═══ 1. LICENSE terms ═══ SRI is copyright (╕) Colin Adams 1992,1993. SRI (Squish/Rexx Interface) may be used freely in a non-commercial envrionment. If SRI is to be used in a commercial environment then a cheque for 10 pounds sterling drawn on a UK bank (or 15 pounds sterling if via International Money order, or the like) should be sent to: Colin Adams 14 Colman Court Preston Lancashire PR1 8DL United Kingdom ═══ 2. Introduction ═══ RXMSGAPI is a Rexx DLL to allow Rexx programmers to call functions within Scott Dudley's MSGAPI.DLL. This enables the Rexx programmer to write applications to manipulate FidoNet-style Squish and *.MSG message bases. Scott Dudley's MSGAPI.DOC document is essential supplemental reading. ═══ 3. Using the MSGAPI interface ═══ 1. Installation 2. Writing a Rexx exec that uses MSGAPI ═══ 3.1. Installation ═══ 1. Copy RXMSGAPI.DLL to a directory specified in your LIBPATH statement, in CONFIG.SYS . Do not rename the .DLL file. 2. Reboot OS/2. 3. Inspect the supplied test.cmd Rexx exec - suitably edited, also test2.cmd. 4. Write your own very first Rexx MSGAPI program. ═══ 3.2. Writing a Rexx exec that uses MSGAPI ═══ 1. Allocating the DLL 2. Freeing the DLL ═══ 3.2.1. Allocating the DLL ═══ In order to activate the MSGAPI interface, you must first make the DLL available to your Rexx exec. As IBM do not document this very well (HELP REX0115 will give you a clue), I will give complete instructions: 1. Register the DLL and name the command environment The RXSUBCOM command must be used to perform this operation. All following examples assume a default environment of CMD (the OS/2 command processor). /* Rexx exec using MSGAPI */ 'RXSUBCOM Register MSGAPI RXMSGAPI RXMSGAPI' The first parameter to the Register function of RXSUBCOM, names the command environment you wish to use on the address command. In this case MSGAPI. You can change this to whatever you wish, but it is not recommended. 2. Load the DLL. 'RXSUBCOM Load MSGAPI RXMSGAPI' 3. Commands can now be sent to the MSGAPI interface using address MSGAPI (or whatever you named it). ═══ 3.2.2. Freeing the DLL ═══ When you have finished using the interface, you can save storage by freeing it up: address CMD 'rxsubcom drop msgapi' ═══ 4. Reference ═══ Note: All RXMSGAPI command names are case sensitive. For parameters that will be passed to MSGAPI, consult MSGAPI.DOC . In particular, Rexx NAMES passed to an API must be in UPPER CASE. ═══ 4.1. Return codes ═══ RXMSGAPI raises the FAILURE condition if an unknown command request is passed to it - this represents a Rexx programmer error, and should be trapped during development of your Rexx code. In all other error cases, RXMSGAPI raises the ERROR condition. It is a question of programming style wether or not to trap this condition. 1. Parameter validation errors 2. Rexx Shared Variables interface return codes 3. API return codes ═══ 4.1.1. Parameter validation errors ═══ If the DLL detects a problem with the parameters passed to it (only rudimentary checking is done - e.g. are the right number passed) it returns one of the following codes in RC: -9991 Error with first parameter -9992 Error with second parameter -9993 Error with third parameter -9994 Error with fourth parameter etc. If there is an error from the Rexx Shared Variables interface, then RXMSGAPI returns -8880 minus the error code from the interface - (you have probably specified the wrong variable name). ═══ 4.1.2. Rexx Shared Variables interace return codes ═══ RXSHV_OK - 0 The request was processed with out error (all flag bits are FALSE). RXSHV_NEWV - 1 The named variable was uninitialized. RXSHV_LVAR - 2 No more variables are available for an RXSHV_NEXTV operation. RXSHV_TRUNC - 4 A variable value or variable name was truncated because the supplied RXSTRING was too small for the copied value. RXSHV_BADN - 8 The variable name specified in shvname was invalid for the requested operation. RXSHV_MEMFL - 16 The REXX interpreter was unable to obtain the storage required to complete the request. RXSHV_BADF - 128 The shared variable request block contains an invalid function code. ═══ 4.1.3. API return codes ═══ If the API returns error-free, then RC is set to 0. Otherwise RC is set to a string of the form: APIname returned error code number ═══ 4.2. OPEN_API ═══ address MSGAPI 'OPEN_API [default_zone [revision_level]]' where: o revision_level requests which version of the MSG API you wish to request - omit for the default - 0. Note: Anything other than 0 may cause a general protection fault - it does here! o default_zone indicates a default fidonet zone - defaults to 2 if omitted ═══ 4.3. CLOSE_API ═══ address MSGAPI 'CLOSE_API' ═══ 4.4. OPEN_AREA ═══ address MSGAPI 'OPEN_AREA' 'msg_area' 'msg_area_name' 'mode' 'type' where: o msg_area is the NAME of a Rexx variable that will be set by OPEN_AREA. You then pass this name to the other MSGAPI calls (actually you can pass any variable name to the other MSGAPI calls, as long as the VALUE of the variable contains the value set by OPEN_AREA). o msg_area_name is the name of a squish or *.msg area. This name should be a *.MSG directory name or a squish base name, as per squish.cfg. It is NOT the TAG name. o mode is the access mode for the area. Possible values are: MSGAREA_NORMAL open fails if the area does not exist MSGAREA_CRIFNEC open will attempt to create the area if it does not exist. Open will fail if it is unable to create the area. MSGAREA_CREATE open will attempt to create the area or truncate it to no messages. o type is the type of message area. Possible values are: SQUISH Squish format area SDM *.MSG format area SDMECHO *.MSG format echomail area (1.MSG contains a highwatermark) ═══ 4.5. CLOSE_AREA ═══ address MSGAPI 'CLOSE_AREA' 'msg_area' where: msg_area is the NAME of a Rexx variable. This variable should contain the value set by an OPEN_AREA call. ═══ 4.6. OPEN_MSG ═══ address MSGAPI 'OPEN_MSG' 'msg_handle' 'msg_area' 'mode' 'message_number' where: o msg_handle is the NAME of a Rexx variable. OPEN_MSG will set this and its value should be passed to other API functions. o msg_area is the NAME of a Rexx variable. This should contain a value obtained from OPEN_AREA. o mode is the access mode for the area. Possible values are: MOPEN_CREATE create a NEW message. MOPEN_READ open an existing message for READ ONLY. MOPEN_WRITE open an existing message for WRITE ONLY. MOPEN_RW open an existing message for both reading and writing. o message_number is the number of the message. See MSGAPI.DOC for the meaning. For MOPEN_READ or MOPEN_RW you can also specify: MSGNUM_CUR The current message MSGNUM_NEXT The next message MSGNUM_PREV The previous message. as per MSGAPI.DOC . ═══ 4.7. CLOSE_MSG ═══ address MSGAPI 'CLOSE_MSG' 'msg_var' where: msg_var is the NAME of a Rexx variable. This variable should contain the value set by an OPEN_MSG call. ═══ 4.8. READ_MSG ═══ address MSGAPI 'READ_MSG' 'msg_handle' 'xmsg_stem' 'offset' 'bytes' 'text_var' 'control_bytes' 'control_var' Where: o msg_handle is the NAME of a Rexx variable. This variable should contain the value set be an OPEN_MSG call. o xmsg_stem is the NAME of a Rexx stem variable. The name MUST contain a terminating period, or the name MUST be the literal: NULL. If the name is NULL then no message header information will be returned. Otherwise READ_MSG will set the following variables: (assume an xmsg_stem value of XMSG.) - XMSG.attr - XMSG.from - XMSG.to - XMSG.subj - XMSG.orig - XMSG.dest - XMSG.date_written - XMSG.date_arrived - XMSG.utc_ofs - XMSG.replyto - XMSG.replies.[1..10] - XMSG.ftsc_date See MSGAPI header files for the meaning/values of these fields. o offset should be a decimal number specifying an offset into the body of the message at which to start reading text. Specify 0 for the begining of the message body. o bytes specifies the maximum number of bytes to read from the message body. Specify 0 if you do not wish to read the message text. o text_var should be the NAME of a Rexx variable to hold the read message text. Specify the literal name NULL if you do not wish to read the message body. o control_bytes specifies the maximum number of bytes of control information to be read. Specify 0 if you do not wish to read the control information. o control_var should be the NAME of a Rexx variable to hold the control information read. Specify the literal NULL if you do not wish to read the control information. RC is set to the number of bytes transferred. ═══ 4.9. WRITE_MSG ═══ address MSGAPI 'WRITE_MSG' 'msg_handle' 'append' 'xmsg_stem' 'text' 'textlen' 'totlen' 'control_len' 'control_var' Where: o msg_handle is the NAME of a Rexx variable. This variable should contain the value set be an OPEN_MSG call. o append Set to 1 to append message text. Otherwise set to 0. o xmsg_stem is the NAME of a Rexx stem variable. The name MUST contain a terminating period, or the name MUST be the literal: NULL. If the name is NULL then no message header information will be set. Otherwise WRITE_MSG will set the message header from the following variables: (assume an xmsg_stem value of XMSG.) - XMSG.attr This must be numeric. - XMSG.from This should be the name of the user from whom the message is coming. - XMSG.to This should be the name of the user to whom the message is going. - XMSG.subj This should be the subject of the message. - XMSG.orig This should be the originating address of the message in the form: zone:net/node.point ALL components should be specified. @fidonet.org must NOT be added. - XMSG.dest This should be the destination address. Form as per Originating Address. - XMSG.date_written This should be the date and time when the message is written in UTC. The form MUST be: dd/mm/yyyy:hh:mm:ss - XMSG.date_arrived This should be the date the message has arrived. Set it to the date the message is written. - XMSG.utc_ofs The number of minutes past UTC in your local area. - XMSG.replyto The Unique Message-id of a message to which this is a reply. - XMSG.replies.[1..10] Stems .1 through .10 must be set to the Unique message-ids which are replies to this message. Therefore set all to 0. - XMSG.ftsc_date Set this string to the FTSC date and time of the message. o text is the NAME of a Rexx variable. This variable should contain the text of the message. Specify the literal NULL if no message text is to be written. o textlen is the length of the text of the message. Set to 0 if no message text is to be written. o totlen is the TOTAL length of the text of the message. Of special use for writing multi-pass messages. Set to 0 if no message text is to be written. o control_len is the length of the control information. Set to 0 if no control information is to be written. o control_var is the NAME of a Rexx variable. This variable should contain the control information for the message. Specify the literal NULL if no control information is to be written. ═══ 4.10. KILL_MSG ═══ address MSGAPI 'KILL_MSG' 'msg_area' 'message_number' Where: o msg_area is the NAME of a Rexx variable. This should contain a value obtained from OPEN_AREA. o message_number is the number of the message to kill. ═══ 4.11. LOCK ═══ address MSGAPI 'LOCK' 'msg_area' Where: o msg_area is the NAME of a Rexx variable. This should contain a value obtained from OPEN_AREA. ═══ 4.12. UNLOCK ═══ address MSGAPI 'UNLOCK' 'msg_area' Where: o msg_area is the NAME of a Rexx variable. This should contain a value obtained from OPEN_AREA. ═══ 4.13. GET_CURRENT_POSITION ═══ address MSGAPI 'GET_CURRENT_POSITION' 'message_handle' 'position' Where: o message_handle is the NAME of a Rexx variable. This should contain a value obtained from OPEN_MSG. o position is the NAME of a Rexx variable. This will be set to the current position within the body of the message, if RC is set to zero. ═══ 4.14. MSGN_TO_UID ═══ address MSGAPI 'MSGN_TO_UID' 'msg_area' 'msgnum' Where: o msg_area is the NAME of a Rexx variable. This should contain a value obtained from OPEN_AREA. o msgnum is the NAME of a Rexx variable. This should contain the message number to be converted. If RC is set to zero, then conversion is successful. ═══ 4.15. UID_TO_MSGN ═══ address MSGAPI 'UID_TO_MSGN' 'msg_area' 'msgnum' 'type' Where: o msg_area is the NAME of a Rexx variable. This should contain a value obtained from OPEN_AREA. o msgnum is the NAME of a Rexx variable. This should contain the message number to be converted. If RC is set to zero, then conversion is successful. o type is an ASCII literal specifying the type of conversion to be performed: EXACT Returns the message number if it exists, or 0. PREV Returns the message number if it exists, or the previous message. NEXT Returns the message number if it exists, or the next message. ═══ 4.16. GET_HIGH_WATER ═══ address MSGAPI 'GET_HIGH_WATER' 'msg_area' 'mark' Where: o msg_area is the NAME of a Rexx variable. This should contain a value obtained from OPEN_AREA. o mark is the NAME of a Rexx variable. This will be set to the high-water-mark if RC is zero. ═══ 4.17. SET_HIGH_WATER ═══ address MSGAPI 'SET_HIGH_WATER' 'msg_area' 'mark' Where: o msg_area is the NAME of a Rexx variable. This should contain a value obtained from OPEN_AREA. o mark is the NAME of a Rexx variable. This should contain the high-water-mark to be set. ═══ 4.18. GET_TEXT_LENGTH ═══ address MSGAPI 'GET_TEXT_LENGTH' 'message_handle' 'length' Where: o message_handle is the NAME of a Rexx variable. This should contain a value obtained from OPEN_MSG. o length is the NAME of a Rexx variable. This will be set to the length of the body of the message, if RC is set to zero. ═══ 4.19. GET_CONTROL_LENGTH ═══ address MSGAPI 'GET_CONTROL_LENGTH' 'message_handle' 'length' Where: o message_handle is the NAME of a Rexx variable. This should contain a value obtained from OPEN_MSG. o length is the NAME of a Rexx variable. This will be set to the length of the control information of the message, if RC is set to zero. ═══ 4.20. GET_CURRENT_MSG ═══ address MSGAPI 'GET_CURRENT_MSG' 'msg_area' 'msg_num' Where: o msg_area is the NAME of a Rexx variable. This should contain a value obtained from OPEN_AREA. o msg_num is the NAME of a Rexx variable. This will be set to the message number if RC is set to zero. ═══ 4.21. GET_NUMBER_MSGS ═══ address MSGAPI 'GET_NUMBER_MSGS' 'msg_area' 'number' Where: o msg_area is the NAME of a Rexx variable. This should contain a value obtained from OPEN_AREA. o number is the NAME of a Rexx variable. This will be set to the number of messages in the area, if RC is set to zero. ═══ 4.22. GET_HIGH_MSG ═══ address MSGAPI 'GET_HIGH_MSG' 'msg_area' 'number' Where: o msg_area is the NAME of a Rexx variable. This should contain a value obtained from OPEN_AREA. o number is the NAME of a Rexx variable. This will be set to the number of the highest message in the area, if RC is set to zero. ═══ 4.23. VALIDATE ═══ address MSGAPI 'VALIDATE' 'type' 'msg_area_name' Where: o msg_area_name is the name of a squish or *.msg area. This name should be a *.MSG directory name or a squish base name, as per squish.cfg. It is NOT the TAG name. o type is the type of message area. Possible values are: SQUISH Squish format area SDM *.MSG format area SDMECHO *.MSG format echomail area (1.MSG contains a highwatermark) RC will be set to 0 if the area exists and is valid. ═══ 4.24. VALID_MESSAGE_HANDLE ═══ address MSGAPI 'VALID_MESSAGE_HANDLE' 'message_handle' Where: o message_handle is the NAME of a Rexx variable. This should contain a value obtained from OPEN_MSG. RC will be set to 0 if the handle is valid. ═══ 4.25. VALID_AREA_HANDLE ═══ address MSGAPI 'VALID_AREA_HANDLE' 'msg_area' Where: o msg_area is the NAME of a Rexx variable. This should contain a value obtained from OPEN_AREA. RC will be set to 0 if the handle is valid.