home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / jËzyki_programowania / amigae / moremodules / rexxc / rexxc.e < prev    next >
Text File  |  1977-12-31  |  40KB  |  1,702 lines

  1. ->
  2. ->    rexxC.e
  3. ->
  4. ->    version 0.25
  5. ->
  6. ->    ARexx port handling class in E v3.2a
  7. ->
  8. ->    Piotr Obminski    (piotr@augs.se)
  9. ->
  10. ->    last compilation 29-Jul-95
  11. ->
  12. ->    1 TAB = 4 spaces    <--------------------- see this? -----<<
  13. ->
  14. -> -------------------------------------------------------------------
  15. ->    BUGS, QUIRKS & LIMITATIONS:
  16. ->
  17. ->    1. I have not had any big success with functions, there must be
  18. ->    something I don't quite understand about them...
  19. ->
  20. ->    2. No inline assembler or any serious optimization, some string
  21. ->    operation pretty elementary (but safe & easy to understand). But
  22. ->    ARexx itself is no lightning ;-)
  23. ->
  24. ->    3. Very little testing for this version (but I'm moving in a few days)
  25. ->
  26. ->    4. The code is formatted in an unusual style that reminds one of Ada,
  27. ->    but I REALLY BELIEVE THAT CODE MUST BE AS READABLE AS POSSIBLE!
  28. ->    Baby, that's my style!
  29. ->
  30. -> -------------------------------------------------------------------
  31.  
  32. OPT MODULE, PREPROCESS
  33.  
  34. OPT REG = 5
  35.  
  36.  
  37. MODULE    'exec/ports', 'exec/nodes', 'exec/lists', 'rexxsyslib',
  38.         'rexx/rexxio', 'rexx/rxslib', 'rexx/errors', 'rexx/storage',
  39.         'dos/dos'
  40.  
  41. -> ---------------------------------------------------------------
  42.  
  43. #define DEBUG
  44.  
  45. -> ---------------------------------------------------------------
  46.  
  47. #define NEED_getUnconfirmedCount
  48. #define NEED_commandList        -> always needed for receiving
  49.  
  50. #define NEED_loopReceive
  51. #define NEED_waitReceive        -> will be used by loopReceive()
  52. #define NEED_get
  53.  
  54. #define NEED_isLastTokenized
  55. #define NEED_getArgStr
  56.  
  57. #define NEED_longToStr
  58. #define NEED_charToStr
  59.  
  60. #define NEED_version
  61.  
  62. #define NEED_passPort
  63. #define NEED_defaultIn
  64. #define NEED_defaultOut
  65. #define NEED_brutal
  66.  
  67. #define NEED_command
  68. #define NEED_commandFile
  69. #define NEED_commandString
  70. #define NEED_commandQuick
  71. #define NEED_commandFileQuick
  72.  
  73. #define NEED_function
  74. #define NEED_functionQuick
  75. #define NEED_do_send_function
  76.  
  77. #define NEED_commandStringQuick
  78. #define NEED_commandToken
  79. #define NEED_commandFileToken
  80. #define NEED_commandstringToken
  81. #define NEED_commandQuickToken
  82. #define NEED_commandFileQuickToken
  83. #define NEED_commandStringQuickToken
  84.  
  85. #define NEED_addServer
  86.  
  87. #define NEED_addServerQuick
  88. #define NEED_addLibrary
  89. #define NEED_addLibraryQuick
  90. #define NEED_removeLibrary
  91. #define NEED_removeLibraryQuick
  92. #define NEED_addClip
  93. #define NEED_addClipQuick
  94. #define NEED_removeClip
  95. #define NEED_removeClipQuick
  96.  
  97. #define NEED_functionString
  98. #define NEED_functionStringQuick
  99.  
  100. #define NEED_openGlobalConsole
  101. #define NEED_openGlobalConsoleQuick
  102. #define NEED_closeGlobalConsole
  103. #define NEED_closeGlobalConsoleQuick
  104.  
  105. -> PRIVATE --------------------------------------------------
  106.  
  107. #define NEED_swallowReplies
  108. #define NEED_swallowRepliesQuick
  109. #define NEED_handle_reply
  110.  
  111. #define NEED_do_send_command
  112. #define NEED_do_send_command_quick
  113. #define NEED_do_send_misc
  114. #define NEED_do_function_string
  115.  
  116. #define NEED_free_message_all
  117. #define NEED_checkCBList
  118.  
  119. #define NEED_handle_incoming
  120. #define NEED_command_executor
  121. #define NEED_reply_message
  122. #define NEED_find_command
  123.  
  124. #define NEED_we_want_reply
  125.  
  126. -> automatic  -----------------------------------------------
  127.  
  128. #ifdef  NEED_loopReceive
  129.     #ifndef NEED_waitReceive
  130.         #define NEED_waitReceive
  131.     #endif
  132. #endif
  133.  
  134. -> ---------------------------------------------------------------
  135.  
  136. CONST    VERSION_NUM        = 0,
  137.         REVISION_NUM    = 25
  138.  
  139. -> ---------------------------------------------------------------
  140.  
  141. ->
  142. ->    values for state_flags
  143. ->
  144. SET ST_DOSPIN, ST_SHUTDOWN
  145.  
  146. -> ---------------------------------------------------------------
  147.  
  148. ->
  149. ->    values for settings_flags
  150. ->
  151. EXPORT SET    SE_RECEIVING_PORT,    -> public port for receiving commands etc.
  152.             SE_SENDING_PORT,    -> private port with no name (for sending)
  153.             SE_BRUTAL,            -> don't wait for replies in end()
  154.             SE_LIST_SORTED        -> callback-list (still not used)
  155.  
  156. -> ---------------------------------------------------------------
  157.  
  158. ->
  159. -> exceptioninfo values (our exception value is 'rexx'):
  160. ->
  161. -> all are 'user' errors ;)
  162. ->
  163. EXPORT ENUM    EXI_BAD_CALLBACKS,            -> bad callback-list
  164.             EXI_PORT_NOT_UNIQUE            -> port-name not unique
  165.  
  166. -> ---------------------------------------------------------------
  167.  
  168. EXPORT OBJECT rexxC
  169.     PRIVATE
  170.         receiving_port        : PTR TO mp
  171.         sending_port        : PTR TO mp
  172.         unconfirmed_count    : LONG            -> how many answers we want
  173.         last_reply_argstr    : PTR TO rexxarg
  174.         last_args            : PTR TO CHAR    ->  arguments after command-name
  175.         remaining_arg_len    : LONG
  176.         fLastTokenized        : LONG
  177.     -> ---------------------------------------------
  178.         com_callback_list    : PTR TO LONG    -> command-names & callbacks
  179.         default_extension    : PTR TO CHAR
  180.         pass_port            : LONG
  181.         default_input        : LONG
  182.         default_output        : LONG
  183.         state_flags            : LONG            -> managed by the class itself
  184.         settings_flags        : LONG            -> set by the user
  185.         rec_signal_mask        : LONG
  186.         send_signal_mask    : LONG
  187.         break_mask            : LONG
  188. ENDOBJECT
  189.  
  190. -> ---------------------------------------------------------------
  191.  
  192. RAISE    "REXX"        IF    OpenLibrary()    = NIL,
  193.         "MEM"        IF    String()        = NIL,
  194.         "PORT"        IF    CreateMsgPort()    = NIL
  195.  
  196. -> ---------------------------------------------------------------
  197.  
  198. CONST DEFAULT_SETTIGS = SE_SENDING_PORT OR SE_RECEIVING_PORT
  199.  
  200. -> ---------------------------------------------------------------
  201.  
  202. ->
  203. -> error-values for do_send... routines
  204. ->
  205. EXPORT CONST    DCC_NO_ERROR            = 0,
  206.                 DCC_GOT_NO_REPLY        = 1,
  207.                 DCC_HOST_NOT_FOUND        = 2,
  208.                 DCC_MSG_NOT_CREATED        = 3,
  209.                 DCC_ABORTED_SWALLOWING    = 4,
  210.                 DCC_NO_FILE                = 5        -> for file-commands
  211.  
  212. -> ---------------------------------------------------------------
  213.  
  214. ->
  215. ->    what a speed-gain!
  216. ->
  217. CONST    MY_RXFF_NOIO = $10000            -> it is:  1 << 16
  218.  
  219. -> ---------------------------------------------------------------
  220.  
  221.  
  222. ->
  223. ->    is 0 the best thing as default priority?
  224. ->
  225. ->    also needs: I/O, pass-port
  226. ->
  227. EXPORT PROC rexxC(    port_name        = NIL    : PTR TO CHAR,
  228.                     callbacks        = NIL    : PTR TO LONG,
  229.                     priority        = 0,
  230.                     default_ext        = NIL    : PTR TO CHAR,
  231.                     passPort        = NIL,
  232.                     defaultIn        = NIL,
  233.                     defaultOut        = NIL,
  234.                     break_mask        = 0,
  235.                     fCtrlC            = TRUE,
  236.                     settings        = DEFAULT_SETTIGS ) OF rexxC
  237.  
  238.     rexxsysbase := OpenLibrary( 'rexxsyslib.library', 0 )
  239.  
  240.     self.fileExtension( default_ext )
  241.  
  242.     IF callbacks <> NIL THEN self.commandList( callbacks )
  243.  
  244.     IF settings AND SE_RECEIVING_PORT
  245.         IF port_name = NIL THEN port_name := self.fix_port_name()
  246.         self.receiving_port := self.create_port( port_name, priority )
  247.     ENDIF
  248.  
  249.     self.rec_signal_mask := Shl( 1, self.receiving_port.sigbit )
  250.  
  251.     IF settings AND SE_SENDING_PORT THEN
  252.                         self.sending_port := self.create_port( NIL, 0 )
  253.  
  254.     self.send_signal_mask := Shl( 1, self.sending_port.sigbit )
  255.  
  256.     self.settings_flags := settings
  257.  
  258.     self.breakMask( break_mask, fCtrlC )
  259.  
  260.     self.pass_port        := passPort
  261.  
  262.     self.default_input    := defaultIn
  263.     self.default_output    := defaultOut
  264. ENDPROC
  265.  
  266. -> ---------------------------------------------------------------
  267.  
  268. ->
  269. ->
  270. ->
  271. EXPORT PROC end() OF rexxC
  272.     DEF    msg            : PTR TO rexxmsg,
  273.         signal_mask
  274.  
  275.     IF self.receiving_port <> NIL
  276.         RemPort( self.receiving_port )
  277.  
  278.         Forbid()
  279.  
  280.         WHILE msg := GetMsg( self.receiving_port )
  281.             IF IsRexxMsg( msg ) THEN msg.result1 := RC_FATAL
  282.             ReplyMsg( msg )
  283.         ENDWHILE
  284.         DeleteMsgPort( self.receiving_port )
  285.  
  286.         Permit()
  287.     ENDIF
  288.  
  289.     IF self.sending_port <> NIL
  290.         IF self.last_reply_argstr <> NIL THEN
  291.                             DeleteArgstring( self.last_reply_argstr )
  292.  
  293.         IF ( self.settings_flags AND SE_BRUTAL ) = FALSE
  294.             WHILE self.unconfirmed_count > 0
  295.  
  296.                 signal_mask := Wait( self.send_signal_mask OR self.break_mask )
  297.  
  298.                 IF signal_mask AND self.break_mask THEN JUMP delete_port
  299.  
  300.                 msg := GetMsg( self.sending_port )
  301.  
  302.                 IF msg.mn::mn.ln::ln.type = NT_REPLYMSG
  303.                     IF self.we_want_reply( msg.args[ 15 ] )
  304.                         self.unconfirmed_count := self.unconfirmed_count - 1
  305.                     ENDIF
  306.                     self.free_message_all( msg )
  307.                 ENDIF
  308.             ENDWHILE
  309.         ELSE
  310.             WHILE msg := GetMsg( self.sending_port )
  311.                 IF msg.mn::mn.ln::ln.type = NT_REPLYMSG
  312.                     IF self.we_want_reply( msg.args[ 15 ] )
  313.                         self.unconfirmed_count := self.unconfirmed_count - 1
  314.                     ENDIF
  315.                     self.free_message_all( msg )
  316.                 ENDIF
  317.             ENDWHILE
  318.         ENDIF
  319.  
  320. delete_port:
  321.         DeleteMsgPort( self.sending_port )
  322.     ENDIF
  323.  
  324.     self.fileExtension( NIL )
  325.  
  326.     CloseLibrary( rexxsysbase )
  327. ENDPROC
  328.  
  329. -> =================================================================
  330.  
  331. ->
  332. ->
  333. ->
  334. #ifdef NEED_unconfirmedCount
  335. EXPORT PROC unconfirmedCount() OF rexxC IS self.unconfirmed_count
  336. #endif
  337.  
  338. -> ---------------------------------------------------------------
  339.  
  340. ->
  341. ->
  342. ->
  343. #ifdef NEED_commandList
  344. EXPORT PROC commandList( cblist : PTR TO LONG ) OF rexxC
  345.  
  346.     IF self.checkCBList( cblist ) = FALSE THEN
  347.                                 Throw( "rexx", EXI_BAD_CALLBACKS )
  348.  
  349.     self.com_callback_list    := cblist
  350. ENDPROC
  351. #endif
  352.  
  353. -> ---------------------------------------------------------------
  354.  
  355. ->
  356. -> check validity of non-NIL callback-list
  357. ->
  358. #ifdef NEED_checkCBList
  359. EXPORT PROC checkCBList( list : PTR TO LONG ) OF rexxC
  360.     DEF    len
  361.  
  362.     IF list = NIL THEN RETURN TRUE        -> YES!
  363.  
  364.     len := ListLen( list )
  365.     IF ( len < 2 ) OR ( Mod( len, 2 ) <> 0 ) THEN RETURN FALSE
  366. ENDPROC TRUE
  367. #endif
  368.  
  369. -> ---------------------------------------------------------------
  370.  
  371. ->
  372. -> breaks looping & Wait()'ing for INCOMING messages
  373. ->
  374. EXPORT PROC break() OF rexxC
  375.     self.state_flags := self.state_flags AND Not( ST_DOSPIN )
  376. ENDPROC
  377.  
  378. -> ---------------------------------------------------------------
  379.  
  380. ->
  381. -> LOOP waiting for message, EXECUTE & answer them if possible
  382. ->
  383. -> should it RETURN anything?
  384. ->
  385. #ifdef NEED_loopReceive
  386. EXPORT PROC loopReceive() OF rexxC
  387.  
  388.     self.state_flags := self.state_flags OR ST_DOSPIN
  389.  
  390.     LOOP
  391.         IF ( self.state_flags AND ST_DOSPIN ) = FALSE THEN RETURN
  392.  
  393.         self.waitReceive()
  394.       ENDLOOP
  395. ENDPROC
  396. #endif
  397.  
  398. -> ---------------------------------------------------------------
  399.  
  400. ->
  401. -> wait for a message, EXECUTE them if possible, then answer it
  402. ->
  403. -> should it RETURN anything?
  404. ->
  405. #ifdef NEED_waitReceive
  406. EXPORT PROC waitReceive() OF rexxC
  407.     DEF signal_mask
  408.  
  409.     signal_mask := Wait( self.rec_signal_mask OR self.break_mask )
  410.  
  411.     IF signal_mask AND self.break_mask THEN
  412.                         self.break() ELSE self.handle_incoming()
  413. ENDPROC
  414. #endif
  415.  
  416. -> ---------------------------------------------------------------
  417.  
  418. ->
  419. -> get (if already present) message, EXECUTE it if possible & answer
  420. ->
  421. -> should it RETURN anything?
  422. ->
  423. #ifdef NEED_get
  424. EXPORT PROC get() OF rexxC
  425.      DEF    rexx_msg                : PTR TO rexxmsg,
  426.         rexx_args                : PTR TO LONG,
  427.         result_1    = RC_ERROR    : LONG,
  428.         result_2    = NIL        : PTR TO CHAR
  429.  
  430.     IF self.receiving_port = NIL THEN RETURN
  431.  
  432.     rexx_msg := GetMsg( self.receiving_port )
  433.  
  434.     IF ( rexx_msg = NIL ) OR ( IsRexxMsg( rexx_msg ) = FALSE ) THEN RETURN
  435.  
  436.     IF ( rexx_msg.action AND RXCODEMASK ) = RXCOMM
  437.         rexx_args    := rexx_msg.args
  438.         result_1, result_2 := self.command_executor( rexx_args[ 0 ] )
  439.     ELSE
  440.         IF rexx_msg.action AND RXFF_NONRET THEN JUMP reset_it
  441.     ENDIF
  442.  
  443.     self.reply_message( rexx_msg, result_1, result_2 )
  444.  
  445. reset_it:
  446.     self.last_args            := NIL
  447.     self.remaining_arg_len    := 0
  448. ENDPROC
  449. #endif
  450.  
  451. -> ---------------------------------------------------------------
  452.  
  453. ->
  454. ->    to be used ONLY ONCE for every message!
  455. ->
  456. #ifdef NEED_isLastTokenized
  457. EXPORT PROC isLastTokenized() OF rexxC IS self.fLastTokenized
  458. #endif
  459.  
  460. -> ---------------------------------------------------------------
  461.  
  462. ->
  463. ->    to be used ONLY ONCE for every message!
  464. ->
  465. #ifdef NEED_getArgStr
  466. EXPORT PROC getArgStr() OF rexxC
  467.     DEF    last_args, remaining_arg_len
  468.  
  469.     last_args                := self.last_args
  470.     remaining_arg_len        := self.remaining_arg_len
  471.  
  472.     self.last_args            := NIL
  473.     self.remaining_arg_len    := 0
  474.  
  475. ENDPROC last_args, remaining_arg_len, self.fLastTokenized
  476. #endif
  477.  
  478. -> ---------------------------------------------------------------
  479.  
  480. ->
  481. ->
  482. ->
  483. #ifdef NEED_version
  484. EXPORT PROC version() OF rexxC IS VERSION_NUM, REVISION_NUM
  485. #endif
  486.  
  487. -> ---------------------------------------------------------------
  488.  
  489. ->
  490. ->
  491. ->
  492. #ifdef NEED_passPort
  493. EXPORT PROC passPort( port_address ) OF rexxC
  494.     self.pass_port := port_address
  495. ENDPROC
  496. #endif
  497.  
  498. -> ---------------------------------------------------------------
  499.  
  500. ->
  501. ->
  502. ->
  503. #ifdef NEED_defaultIn
  504. EXPORT PROC defaultIn( file ) OF rexxC
  505.     self.default_input := file
  506. ENDPROC
  507. #endif
  508.  
  509. -> ---------------------------------------------------------------
  510.  
  511. ->
  512. ->
  513. ->
  514. #ifdef NEED_defaultOut
  515. EXPORT PROC defaultOut( file ) OF rexxC
  516.     self.default_output    := file
  517. ENDPROC
  518. #endif
  519.  
  520. -> ---------------------------------------------------------------
  521.  
  522. ->
  523. ->
  524. ->
  525. EXPORT PROC breakMask( new_mask, fCtrlC ) OF rexxC
  526.     DEF ctrl_c = 0
  527.  
  528.     IF fCtrlC THEN ctrl_c := SIGBREAKF_CTRL_C
  529.  
  530.     self.break_mask := new_mask OR ctrl_c
  531. ENDPROC
  532.  
  533. -> ---------------------------------------------------------------
  534.  
  535. ->
  536. ->
  537. ->
  538. #ifdef NEED_brutal
  539. EXPORT PROC brutal( fBbrutal ) OF rexxC
  540.     IF fBbrutal = TRUE
  541.         self.settings_flags := self.settings_flags OR SE_BRUTAL
  542.     ELSE
  543.         self.settings_flags := self.settings_flags AND Not( SE_BRUTAL )
  544.     ENDIF
  545. ENDPROC
  546. #endif
  547.  
  548. -> ---------------------------------------------------------------
  549.  
  550. ->
  551. ->
  552. ->
  553. EXPORT PROC fileExtension( ext = NIL : PTR TO CHAR ) OF rexxC
  554.     DEF temp
  555.  
  556.     IF self.default_extension <> NIL THEN Dispose( self.default_extension )
  557.  
  558.     IF ext <> NIL
  559.         temp := String( StrLen( ext ) )
  560.         StrCopy( temp, ext )
  561.         self.default_extension := temp
  562.     ENDIF
  563. ENDPROC TRUE
  564.  
  565. -> ---------------------------------------------------------------
  566.  
  567. ->
  568. ->
  569. ->
  570. #ifdef NEED_command
  571. EXPORT PROC command(    host_name    : PTR TO CHAR,
  572.                         cmd_to_send    : PTR TO CHAR ) OF rexxC
  573.  
  574. ENDPROC self.do_send_command( host_name, cmd_to_send, RXCOMM )
  575. #endif
  576.  
  577. -> ---------------------------------------------------------------
  578.  
  579. ->
  580. ->
  581. ->
  582. #ifdef NEED_commandFile
  583. EXPORT PROC commandFile( file_name : PTR TO CHAR ) OF rexxC
  584.  
  585. ENDPROC self.do_send_command( 'REXX', file_name, RXCOMM )
  586. #endif
  587.  
  588. -> ---------------------------------------------------------------
  589.  
  590. ->
  591. ->
  592. ->
  593. #ifdef NEED_commandString
  594. EXPORT PROC commandString( string : PTR TO CHAR ) OF rexxC
  595.  
  596. ENDPROC self.do_send_command( 'REXX', string, RXCOMM OR RXFF_STRING )
  597. #endif
  598.  
  599. -> ---------------------------------------------------------------
  600.  
  601. ->
  602. -> sends command without swallowing any replies or waiting for anything
  603. ->
  604. #ifdef NEED_commandQuick
  605. EXPORT PROC commandQuick(    host_name        : PTR TO CHAR,
  606.                             cmd_to_send        : PTR TO CHAR ) OF rexxC
  607.  
  608. ENDPROC self.do_send_command_quick( host_name, cmd_to_send, RXCOMM )
  609. #endif
  610. -> ---------------------------------------------------------------
  611.  
  612. ->
  613. ->
  614. ->
  615. #ifdef NEED_commandFileQuick
  616. EXPORT PROC commandFileQuick( file_name : PTR TO CHAR ) OF rexxC
  617.  
  618. ENDPROC self.do_send_command_quick( 'AREXX', file_name, RXCOMM )
  619. #endif
  620.  
  621. -> ---------------------------------------------------------------
  622.  
  623. ->
  624. -> executes 'string-file' without swallowing or waiting for reply
  625. ->
  626. #ifdef NEED_commandStringQuick
  627. EXPORT PROC commandStringQuick( string : PTR TO CHAR ) OF rexxC
  628.  
  629. ENDPROC self.do_send_command( 'AREXX', string, RXCOMM OR RXFF_STRING )
  630. #endif
  631.  
  632. -> ---------------------------------------------------------------
  633.  
  634. ->
  635. ->
  636. ->
  637. #ifdef NEED_commandToken
  638. EXPORT PROC commandToken(    host_name    : PTR TO CHAR,
  639.                             cmd_to_send    : PTR TO CHAR ) OF rexxC
  640.  
  641. ENDPROC self.do_send_command( host_name, cmd_to_send, RXCOMM OR RXFF_TOKEN )
  642. #endif
  643.  
  644. -> ---------------------------------------------------------------
  645.  
  646. ->
  647. ->
  648. ->
  649. #ifdef NEED_commandFileToken
  650. EXPORT PROC commandFileToken( file_name : PTR TO CHAR ) OF rexxC
  651.     DEF    ret_val1,
  652.         ret_val2    : PTR TO CHAR,
  653.         ret_val3,
  654.         lock
  655.  
  656.     lock := Lock( file_name, ACCESS_READ )
  657.  
  658.     IF lock = NIL THEN RETURN RC_FATAL, NIL, DCC_NO_FILE
  659.  
  660.     ret_val1, ret_val2, ret_val3 :=
  661.             self.do_send_command( 'REXX', file_name, RXCOMM OR RXFF_TOKEN )
  662.  
  663.     UnLock( lock )
  664. ENDPROC ret_val1, ret_val2, ret_val3
  665. #endif
  666.  
  667. -> ---------------------------------------------------------------
  668.  
  669. ->
  670. ->
  671. ->
  672. #ifdef NEED_commandStringToken
  673. EXPORT PROC stringToken( string : PTR TO CHAR ) OF rexxC
  674.  
  675. ENDPROC self.do_send_command( 'REXX', string,
  676.                                 RXCOMM OR RXFF_STRING OR RXFF_TOKEN )
  677. #endif
  678.  
  679. -> ---------------------------------------------------------------
  680.  
  681. ->
  682. -> sends command without swallowing any replies or waiting for anything
  683. ->
  684. #ifdef NEED_commandQuickToken
  685. EXPORT PROC commandQuickToken(    host_name        : PTR TO CHAR,
  686.                                 cmd_to_send        : PTR TO CHAR ) OF rexxC
  687.  
  688. ENDPROC self.do_send_command_quick( host_name,
  689.                                 cmd_to_send, RXCOMM OR RXFF_TOKEN )
  690. #endif
  691.  
  692. -> ---------------------------------------------------------------
  693.  
  694. ->
  695. ->
  696. ->
  697. ->
  698. #ifdef NEED_fileQuickToken
  699. EXPORT PROC fileQuickToken( file_name : PTR TO CHAR ) OF rexxC
  700.     DEF    ret_val, lock
  701.  
  702.     lock := Lock( file_name, ACCESS_READ )
  703.  
  704.     IF lock = NIL THEN RETURN RC_FATAL, NIL, DCC_NO_FILE
  705.  
  706.     ret_val :=
  707.         self.do_send_command_quick( 'AREXX', file_name, RXCOMM OR RXFF_TOKEN )
  708.  
  709.     UnLock( lock )
  710.  
  711. ENDPROC ret_val
  712. #endif
  713.  
  714. -> ---------------------------------------------------------------
  715.  
  716. ->
  717. -> executes 'string-file' without swallowing or waiting for reply
  718. ->
  719. #ifdef NEED_commandStringQuickToken
  720. EXPORT PROC commandStringQuickToken( string : PTR TO CHAR ) OF rexxC
  721.  
  722. ENDPROC self.do_send_command( 'AREXX', string,
  723.                                 RXCOMM OR RXFF_STRING OR RXFF_TOKEN )
  724. #endif
  725.  
  726. -> ---------------------------------------------------------------
  727.  
  728. ->
  729. ->
  730. ->
  731. #ifdef NEED_addServer
  732. EXPORT PROC addServer( port_name, priority ) OF rexxC
  733.  
  734. ENDPROC self.do_send_misc( port_name, Bounds( priority, -100, 100 ),
  735.                                                     0, 0, RXADDFH )
  736. #endif
  737. -> ---------------------------------------------------------------
  738.  
  739. ->
  740. ->
  741. ->
  742. #ifdef NEED_addServerQuick
  743. EXPORT PROC addServerQuick( port_name, priority ) OF rexxC
  744.  
  745. ENDPROC self.do_send_misc( port_name, Bounds( priority, -100, 100 ),
  746.                                         0, 0, RXADDFH OR RXFF_NONRET )
  747. #endif
  748.  
  749. -> ---------------------------------------------------------------
  750.  
  751. ->
  752. ->
  753. ->
  754. #ifdef NEED_addLibrary
  755. EXPORT PROC addLibrary(    library_name,
  756.                         priority,
  757.                         entry_point,
  758.                         version_num ) OF rexxC IS
  759.     self.do_send_misc( library_name, Bounds( priority, -100, 100 ),
  760.                         entry_point, version_num, RXADDLIB )
  761. #endif
  762.  
  763. -> ---------------------------------------------------------------
  764.  
  765. ->
  766. ->
  767. ->
  768. #ifdef NEED_addLibraryQuick
  769. EXPORT PROC addLibraryQuick(    library_name,
  770.                                 priority,
  771.                                 entry_point,
  772.                                 version_num ) OF rexxC IS
  773.     self.do_send_misc( library_name, Bounds( priority, -100, 100 ),
  774.                         entry_point, version_num, RXADDLIB OR RXFF_NONRET )
  775. #endif
  776.  
  777. -> ---------------------------------------------------------------
  778.  
  779. ->
  780. ->
  781. ->
  782. #ifdef NEED_removeLibrary
  783. EXPORT PROC removeLibrary( library_name ) OF rexxC IS
  784.                         self.do_send_misc( library_name, 0, 0, 0, RXREMLIB )
  785. #endif
  786.  
  787. -> ---------------------------------------------------------------
  788.  
  789. ->
  790. ->
  791. ->
  792. #ifdef NEED_removeLibraryQuick
  793. EXPORT PROC removeLibraryQuick( library_name ) OF rexxC IS
  794.                         self.do_send_misc( library_name, 0, 0, 0, RXREMLIB )
  795. #endif
  796.  
  797. -> ---------------------------------------------------------------
  798.  
  799. ->
  800. ->
  801. ->
  802. #ifdef NEED_addClip
  803. EXPORT PROC addClip(    clip_name : PTR TO CHAR,
  804.                         clip_value : PTR TO CHAR ) OF rexxC IS
  805.     self.do_send_misc( clip_name, clip_value, StrLen( clip_value), 0, RXADDFH )
  806. #endif
  807.  
  808. -> ---------------------------------------------------------------
  809.  
  810. ->
  811. ->
  812. ->
  813. #ifdef NEED_addClipQuick
  814. EXPORT PROC addClipQuick(    clip_name : PTR TO CHAR,
  815.                             clip_value : PTR TO CHAR ) OF rexxC IS
  816.     self.do_send_misc( clip_name, clip_value, StrLen( clip_value),
  817.                                             0, RXADDCON OR RXFF_NONRET )
  818. #endif
  819.  
  820. -> ---------------------------------------------------------------
  821.  
  822. ->
  823. ->
  824. ->
  825. #ifdef NEED_removeClip
  826. EXPORT PROC removeClip( clip_name : PTR TO CHAR ) OF rexxC IS
  827.                         self.do_send_misc( clip_name, 0, 0, 0, RXREMCON )
  828. #endif
  829.  
  830. -> ---------------------------------------------------------------
  831.  
  832. ->
  833. ->
  834. ->
  835. #ifdef NEED_removeClipQuick
  836. EXPORT PROC removeClipQuick( clip_name : PTR TO CHAR ) OF rexxC IS
  837.             self.do_send_misc( clip_name, 0, 0, 0, RXREMCON OR RXFF_NONRET )
  838. #endif
  839.  
  840. -> ---------------------------------------------------------------
  841.  
  842. ->
  843. ->
  844. ->
  845. #ifdef NEED_functionString
  846. EXPORT PROC functionString(    string : PTR TO CHAR ) OF rexxC IS
  847.     self.do_function_string( string, RXFF_RESULT OR RXFF_STRING )
  848. #endif
  849.  
  850. -> ---------------------------------------------------------------
  851.  
  852. ->
  853. ->
  854. ->
  855. #ifdef NEED_functionStringQuick
  856. EXPORT PROC functionStringQuick( string : PTR TO CHAR ) OF rexxC IS
  857.     self.do_function_string( string, RXFF_STRING OR RXFF_NONRET )
  858. #endif
  859.  
  860. -> ---------------------------------------------------------------
  861.  
  862. ->
  863. ->
  864. ->
  865. #ifdef NEED_openGlobalConsole
  866. EXPORT PROC openGlobalConsole() OF rexxC IS
  867.                                 self.do_send_misc( 0, 0, 0, 0, RXTCOPN )
  868. #endif
  869.  
  870. -> ---------------------------------------------------------------
  871.  
  872. ->
  873. ->
  874. ->
  875. #ifdef NEED_openGlobalConsoleQuick
  876. EXPORT PROC openGlobalConsoleQuick() OF rexxC IS
  877.                     self.do_send_misc( 0, 0, 0, 0, RXTCOPN OR RXFF_NONRET )
  878. #endif
  879.  
  880. -> ---------------------------------------------------------------
  881.  
  882. ->
  883. ->
  884. ->
  885. #ifdef NEED_closeGlobalConsole
  886. EXPORT PROC closeGlobalConsole() OF rexxC IS
  887.                                 self.do_send_misc( 0, 0, 0, 0, RXTCCLS )
  888. #endif
  889.  
  890. -> ---------------------------------------------------------------
  891.  
  892. ->
  893. ->
  894. ->
  895. #ifdef NEED_closeGlobalConsoleQuick
  896. EXPORT PROC closeGlobalConsoleQuick() OF rexxC IS
  897.                     self.do_send_misc( 0, 0, 0, 0, RXTCCLS OR RXFF_NONRET )
  898. #endif
  899.  
  900. -> ---------------------------------------------------------------
  901.  
  902. ->
  903. ->
  904. ->
  905. #ifdef NEED_function
  906. EXPORT PROC function(    name            : PTR TO CHAR,
  907.                         arg_list = NIL    : PTR TO LONG ) OF rexxC IS
  908.             self.do_send_function( name, arg_list, RXFF_RESULT )
  909. #endif
  910.  
  911. -> ---------------------------------------------------------------
  912.  
  913. ->
  914. ->
  915. ->
  916. #ifdef NEED_functionQuick
  917. EXPORT PROC functionQuick(    name            : PTR TO CHAR,
  918.                             arg_list = NIL    : PTR TO LONG ) OF rexxC IS
  919.         self.do_send_function( name, arg_list, RXFF_NONRET )
  920. #endif
  921.  
  922. -> ====================== PRIVATE PROC'esses =======================
  923.  
  924. ->
  925. -> maybe someday it will produce a name based on task-name; but in fact
  926. -> it's user's problem...
  927. ->
  928. PROC fix_port_name() OF rexxC IS 'rexx_port'
  929.  
  930. -> ---------------------------------------------------------------
  931.  
  932. ->
  933. -> still should RETURN return-values for answers?!
  934. ->
  935. #ifdef NEED_handle_incoming
  936. PROC handle_incoming() OF rexxC
  937.      DEF    rexx_msg                : PTR TO rexxmsg,
  938.         rexx_args                : PTR TO LONG,
  939.         result_1    = RC_FATAL    : LONG,
  940.         result_2    = NIL        : PTR TO CHAR
  941.  
  942.     IF self.receiving_port = NIL THEN RETURN
  943.  
  944.       WHILE rexx_msg := GetMsg( self.receiving_port )
  945.  
  946.         IF IsRexxMsg( rexx_msg ) = FALSE THEN JUMP reset_them
  947.  
  948.         rexx_args    := rexx_msg.args
  949.  
  950.         IF ( rexx_msg.action AND RXCODEMASK ) = RXCOMM
  951.  
  952.             self.fLastTokenized := ( rexx_msg.action AND RXFF_TOKEN )
  953.  
  954.             result_1, result_2    := self.command_executor( rexx_args[ 0 ] )
  955.         ELSE
  956.             IF rexx_msg.action AND RXFF_NONRET
  957.                 self.free_message_all( rexx_msg )
  958.                 JUMP reset_them
  959.             ENDIF
  960.         ENDIF
  961.  
  962.         self.reply_message( rexx_msg, result_1, result_2 )
  963.  
  964. reset_them:
  965.     self.last_args            := NIL
  966.     self.remaining_arg_len    := 0
  967.     ENDWHILE
  968. ENDPROC
  969. #endif
  970.  
  971. -> ---------------------------------------------------------------
  972.  
  973. ->
  974. ->
  975. ->
  976. #ifdef NEED_reply_message
  977. PROC reply_message(    rexx_msg    : PTR TO rexxmsg,
  978.                     rc1            : LONG,
  979.                     rc2            : PTR TO CHAR ) OF rexxC
  980.  
  981.     rexx_msg.result1 := rc1
  982.  
  983.     IF rexx_msg.action AND RXFF_RESULT
  984.         IF rc1 = RC_OK
  985.             IF rc2 <> NIL
  986.                 rexx_msg.result2 := CreateArgstring( rc2, StrLen( rc2 ) )
  987.  
  988.                 IF rexx_msg.result2 = NIL
  989.                     rexx_msg.result1    := RC_ERROR
  990.                     rexx_msg.result2    := ERR10_003    -> 'no memory available'
  991.                 ENDIF
  992.             ENDIF
  993.         ENDIF
  994.     ENDIF
  995.  
  996.     ReplyMsg( rexx_msg )
  997.  
  998. ENDPROC
  999. #endif
  1000.  
  1001. -> ---------------------------------------------------------------
  1002.  
  1003. ->
  1004. ->
  1005. ->
  1006. #ifdef NEED_free_message_all
  1007. PROC free_message_all( rexx_msg    : PTR TO rexxmsg ) OF rexxC
  1008.     DEF    rexx_args    : PTR TO LONG
  1009.  
  1010.     rexx_args := rexx_msg.args
  1011.  
  1012.     IF rexx_args[ 0 ] <> NIL THEN DeleteArgstring( rexx_args[ 0 ] )
  1013.  
  1014.     DeleteRexxMsg( rexx_msg )
  1015. ENDPROC
  1016. #endif
  1017.  
  1018. -> ---------------------------------------------------------------
  1019.  
  1020. ->
  1021. -> calls appropriate callback if command matches argument
  1022. ->
  1023. #ifdef NEED_command_executor
  1024. PROC command_executor( what : PTR TO CHAR ) OF rexxC
  1025.     DEF    ptr                    : PTR TO LONG,
  1026.         callback_ptr        : PTR TO LONG,
  1027.         cb_ret_val    = NIL    : PTR TO LONG,
  1028.         len,
  1029.         top_addres,
  1030.         command_len,
  1031.         temp_ptr            : PTR TO CHAR,
  1032.         i = 0
  1033.  
  1034.     ptr := self.com_callback_list
  1035.     IF ptr = NIL THEN JUMP not_found
  1036.  
  1037.     len            := ListLen( ptr )
  1038.  
  1039.     top_addres    := ptr[ len ]
  1040.  
  1041.     WHILE i < len
  1042.         command_len    := self.find_command( ^ptr, what )
  1043.         IF command_len <> 0
  1044.             ptr++
  1045.  
  1046.             IF ptr > top_addres THEN JUMP not_found
  1047.  
  1048.             IF ( callback_ptr := ^ptr ) = NIL THEN JUMP not_found
  1049.  
  1050.             temp_ptr := what + command_len
  1051.             TrimStr( temp_ptr )
  1052.  
  1053.             self.last_args            := TrimStr( temp_ptr )
  1054.             self.remaining_arg_len    := temp_ptr - what
  1055.             cb_ret_val                := callback_ptr()
  1056.  
  1057.             RETURN RC_OK, cb_ret_val
  1058.         ENDIF
  1059.         ptr := ptr + 8                -> it is: 2 * ( SIZEOF LONG )
  1060.         INC i; INC i
  1061.     ENDWHILE
  1062.  
  1063. not_found:
  1064.  
  1065. ENDPROC RC_WARN, NIL
  1066. #endif
  1067.  
  1068. -> ---------------------------------------------------------------
  1069.  
  1070. ->
  1071. -> compares arg 'command' (things like 'BEEP') with arg, returns
  1072. ->    command-string-length
  1073. ->
  1074. #ifdef NEED_find_command
  1075. PROC find_command(    command : PTR TO CHAR,
  1076.                     string    : PTR TO CHAR ) OF rexxC
  1077.     DEF len
  1078.  
  1079.     len := StrLen( command )
  1080.  
  1081.     IF StrCmp( command, string, len ) THEN
  1082.             RETURN len    -> command FOUND OK! -- RETURN command-name length
  1083.  
  1084. ENDPROC 0                -> command NOT found! -- RETURN 0
  1085. #endif
  1086.  
  1087. -> ---------------------------------------------------------------
  1088.  
  1089. ->
  1090. ->
  1091. ->
  1092. PROC create_port( port_name : PTR TO CHAR, priority ) OF rexxC
  1093.     DEF    port    = NIL    :    PTR TO mp,
  1094.         node    = NIL    :    PTR TO ln
  1095.  
  1096.     IF port_name = NIL THEN RETURN CreateMsgPort()
  1097.  
  1098.     -> -----------------------------------------------------------
  1099.  
  1100.     Forbid()
  1101.  
  1102.     ->
  1103.     -> is the name of our port (in spe) unique?
  1104.     ->
  1105.     IF FindPort( port_name ) = NIL
  1106.         IF port := CreateMsgPort()            -> could we create the port?
  1107.  
  1108.                node        := port.ln
  1109.             node.name    := port_name        -> fill in the name
  1110.             node.pri    := priority            -> public port priority
  1111.  
  1112.             AddPort( port )                    -> make this port public
  1113.         ENDIF
  1114.     ENDIF
  1115.  
  1116.     Permit()
  1117.  
  1118.     ->
  1119.     -> if no port at this point, it must be NOT-UNIQUE!
  1120.     ->
  1121.     IF port = NIL THEN Throw( "rexx", EXI_PORT_NOT_UNIQUE )
  1122.  
  1123. ENDPROC port
  1124.  
  1125. -> ---------------------------------------------------------------
  1126. -> ---------------------------------------------------------------
  1127. -> ---------------------------------------------------------------
  1128.  
  1129. ->
  1130. -> WAIT & swallow ALL replies; RETURN's self.unconfirmed_count;
  1131. -> breakable with ^C
  1132. ->
  1133. #ifdef NEED_swallowReplies
  1134. PROC swallowReplies() OF rexxC
  1135.     DEF    rexx_msg    = NIL    : PTR TO rexxmsg,
  1136.         signal_mask
  1137.  
  1138.     IF self.unconfirmed_count = 0 THEN RETURN 0
  1139.  
  1140.     WHILE self.unconfirmed_count > 0
  1141.  
  1142.         signal_mask := Wait( self.send_signal_mask OR self.break_mask )
  1143.  
  1144.         IF signal_mask AND self.break_mask THEN JUMP the_end
  1145.  
  1146.           WHILE rexx_msg := GetMsg( self.sending_port )
  1147.             IF rexx_msg.mn::mn.ln::ln.type = NT_REPLYMSG
  1148.                 IF self.we_want_reply( rexx_msg.args[ 15 ] )
  1149.                     self.unconfirmed_count := self.unconfirmed_count - 1
  1150.                 ENDIF
  1151.                 self.free_message_all( rexx_msg )
  1152.             ENDIF
  1153.         ENDWHILE
  1154.     ENDWHILE
  1155.  
  1156. the_end:
  1157.  
  1158. ENDPROC self.unconfirmed_count
  1159. #endif
  1160.  
  1161. -> ---------------------------------------------------------------
  1162.  
  1163. ->
  1164. -> swallows all replies that are ALREADY PRESENT;
  1165. -> RETURN's self.unconfirmed_count
  1166. ->
  1167. #ifdef NEED_swallowRepliesQuick
  1168. PROC swallowRepliesQuick() OF rexxC
  1169.     DEF    rexx_msg = NIL    : PTR TO rexxmsg
  1170.  
  1171.     IF self.unconfirmed_count = 0 THEN RETURN 0
  1172.  
  1173.       WHILE rexx_msg := GetMsg( self.sending_port )
  1174.         IF rexx_msg.mn::mn.ln::ln.type = NT_REPLYMSG
  1175.             IF self.we_want_reply( rexx_msg.args[ 15 ] )
  1176.                 self.unconfirmed_count := self.unconfirmed_count - 1
  1177.             ENDIF
  1178.             self.free_message_all( rexx_msg )
  1179.         ENDIF
  1180.     ENDWHILE
  1181. ENDPROC self.unconfirmed_count
  1182. #endif
  1183.  
  1184. -> ---------------------------------------------------------------
  1185.  
  1186. ->
  1187. -> wait for ONLY ONE reply, and RETURN return-values
  1188. ->
  1189. #ifdef NEED_handle_reply
  1190. PROC handle_reply() OF rexxC
  1191.     DEF rexx_msg    : PTR TO rexxmsg,
  1192.         signal_mask, result_1
  1193.  
  1194.     IF self.last_reply_argstr <> NIL THEN
  1195.                             DeleteArgstring( self.last_reply_argstr )
  1196.  
  1197.     self.last_reply_argstr := NIL
  1198.  
  1199.     signal_mask := Wait( self.send_signal_mask OR self.break_mask )
  1200.  
  1201.     IF signal_mask AND self.break_mask THEN JUMP the_end_here
  1202.  
  1203.     rexx_msg := GetMsg( self.sending_port )
  1204.  
  1205.     IF rexx_msg.mn::mn.ln::ln.type = NT_REPLYMSG
  1206.         result_1 := rexx_msg.result1
  1207.  
  1208.         ->
  1209.         -> store reply-string only if it is really present!
  1210.         ->
  1211.         IF ( rexx_msg.action AND RXFF_RESULT ) AND ( result_1 = RC_OK )
  1212.             self.last_reply_argstr := rexx_msg.result2
  1213.         ENDIF
  1214.         IF self.we_want_reply( rexx_msg.args[ 15 ] )
  1215.             self.unconfirmed_count := self.unconfirmed_count - 1
  1216.         ENDIF
  1217.         self.free_message_all( rexx_msg )
  1218.     ENDIF
  1219.  
  1220. the_end_here:
  1221.  
  1222. ENDPROC result_1, self.last_reply_argstr
  1223. #endif
  1224.  
  1225. -> =================================================================
  1226. -> =================================================================
  1227. -> =================================================================
  1228.  
  1229. ->
  1230. -> the error_value should be something like 0 for 'no error',
  1231. -> 1 for 'broken before reply come', 2 for 'not even sent', 3 for
  1232. -> 'host not found', 4 for 'not even all replies swallowed before sending'
  1233. ->
  1234. #ifdef NEED_do_send_command
  1235. PROC do_send_command(    host_name        : PTR TO CHAR,
  1236.                         cmd_to_send        : PTR TO CHAR,
  1237.                         my_actions ) OF rexxC
  1238.  
  1239.     DEF    arexx_port        = NIL        : PTR TO mp,
  1240.         rexx_msg        = NIL        : PTR TO rexxmsg,
  1241.         rexx_args                    : PTR TO LONG,
  1242.         list_node        = NIL        : PTR TO ln,
  1243.         temp_arg_str    = NIL        : PTR TO CHAR,
  1244.         result_1        = RC_FATAL    : LONG,
  1245.         result_2        = NIL        : PTR TO CHAR,
  1246.         error_value        = DCC_ABORTED_SWALLOWING
  1247.  
  1248.  
  1249.       list_node := self.sending_port.ln
  1250.  
  1251.     VOID self.swallowReplies()
  1252.  
  1253.     IF self.unconfirmed_count > 0 THEN RETURN RC_FATAL, NIL, error_value
  1254.  
  1255.     error_value    := DCC_MSG_NOT_CREATED
  1256.  
  1257.     rexx_msg    := CreateRexxMsg(    self.sending_port,
  1258.                                     self.default_extension,
  1259.                                     list_node.name )
  1260.  
  1261.       IF rexx_msg = NIL THEN JUMP clean_up
  1262.  
  1263.       rexx_args := rexx_msg.args
  1264.  
  1265.     temp_arg_str := CreateArgstring( cmd_to_send, StrLen( cmd_to_send ) )
  1266.  
  1267.       IF temp_arg_str = NIL THEN JUMP clean_up
  1268.  
  1269.     rexx_args[ 0 ]         := temp_arg_str
  1270.     rexx_msg.action        := RXFF_RESULT OR my_actions
  1271.     rexx_msg.passport    := self.pass_port
  1272.  
  1273.     IF ( self.default_input <> NIL ) OR ( self.default_output <> NIL )
  1274.         rexx_msg.stdin    := self.default_input
  1275.         rexx_msg.stdout    := self.default_output
  1276.         rexx_msg.action    := rexx_msg.action OR MY_RXFF_NOIO
  1277.     ENDIF
  1278.  
  1279.     error_value := DCC_HOST_NOT_FOUND
  1280.  
  1281.     Forbid()
  1282.  
  1283.     ->
  1284.     -> send our message to the port if it exists
  1285.     ->
  1286.     arexx_port := FindPort( host_name )
  1287.     IF arexx_port <> NIL THEN PutMsg( arexx_port, rexx_msg )
  1288.  
  1289.     Permit()
  1290.  
  1291.     ->
  1292.     -> this is written in this way in order to have Permit() earlier
  1293.     ->
  1294.     IF arexx_port <> NIL
  1295.         error_value                := DCC_GOT_NO_REPLY
  1296.         self.unconfirmed_count    := self.unconfirmed_count + 1
  1297.  
  1298.         result_1, result_2        := self.handle_reply()
  1299.  
  1300.         RETURN result_1, result_2, DCC_NO_ERROR
  1301.     ENDIF
  1302.  
  1303. clean_up:
  1304.  
  1305.     IF temp_arg_str <> NIL THEN DeleteArgstring( temp_arg_str )
  1306.  
  1307.     DeleteRexxMsg( rexx_msg )
  1308.  
  1309. ENDPROC RC_FATAL, NIL, error_value
  1310. #endif
  1311.  
  1312. -> ---------------------------------------------------------------
  1313.  
  1314. ->
  1315. -> the error_value probably should be something like 0 for 'no error',
  1316. -> 2 for 'not sent', 1 for 'broken before reply come'
  1317. ->
  1318. #ifdef NEED_do_send_command_quick
  1319. PROC do_send_command_quick(    host_name        : PTR TO CHAR,
  1320.                             cmd_to_send        : PTR TO CHAR,
  1321.                             my_actions ) OF rexxC
  1322.  
  1323.     DEF    arexx_port        = NIL        : PTR TO mp,
  1324.         rexx_msg        = NIL        : PTR TO rexxmsg,
  1325.         rexx_args                    : PTR TO LONG,
  1326.         list_node        = NIL        : PTR TO ln,
  1327.         temp_arg_str    = NIL        : PTR TO CHAR
  1328.  
  1329.  
  1330.       list_node := self.sending_port.ln
  1331.  
  1332.     rexx_msg := CreateRexxMsg(    self.sending_port,
  1333.                                 self.default_extension,
  1334.                                 list_node.name )
  1335.  
  1336.       IF rexx_msg = NIL THEN JUMP clean_after_error
  1337.  
  1338.       rexx_args        := rexx_msg.args
  1339.  
  1340.     temp_arg_str    := CreateArgstring( cmd_to_send, StrLen( cmd_to_send ) )
  1341.  
  1342.       IF temp_arg_str = NIL THEN JUMP clean_after_error
  1343.  
  1344.     rexx_args[ 0 ]    := temp_arg_str
  1345.     rexx_args[ 15 ]    := { no_reply_string }
  1346.  
  1347.     rexx_msg.action    := my_actions
  1348.  
  1349.     rexx_msg.passport    := self.pass_port
  1350.  
  1351.     IF ( self.default_input <> NIL ) OR ( self.default_output <> NIL )
  1352.         rexx_msg.stdin    := self.default_input
  1353.         rexx_msg.stdout    := self.default_output
  1354.  
  1355.         rexx_msg.action    := rexx_msg.action OR MY_RXFF_NOIO
  1356.     ENDIF
  1357.  
  1358.     self.swallowRepliesQuick()
  1359.  
  1360.     Forbid()
  1361.  
  1362.     ->
  1363.     -> send our message to the port if it exists
  1364.     ->
  1365.     IF ( arexx_port := FindPort( host_name ) ) <> NIL THEN
  1366.                                         PutMsg( arexx_port, rexx_msg )
  1367.  
  1368.     Permit()
  1369.  
  1370.     IF arexx_port <> NIL THEN RETURN RC_OK
  1371.  
  1372. clean_after_error:
  1373.  
  1374.     IF temp_arg_str <> NIL THEN DeleteArgstring( temp_arg_str )
  1375.  
  1376.     DeleteRexxMsg( rexx_msg )
  1377.  
  1378. ENDPROC RC_FATAL
  1379. #endif
  1380.  
  1381. -> ---------------------------------------------------------------
  1382.  
  1383. ->
  1384. ->
  1385. ->
  1386. #ifdef NEED_do_send_misc
  1387. PROC do_send_misc( arg_0, arg_1, arg_2, arg_3, my_action ) OF rexxC
  1388.     DEF    arexx_port        = NIL        : PTR TO mp,
  1389.         rexx_msg        = NIL        : PTR TO rexxmsg,
  1390.         rexx_args                    : PTR TO LONG,
  1391.         list_node        = NIL        : PTR TO ln,
  1392.         temp_arg_str    = NIL        : PTR TO CHAR,
  1393.         result_1        = RC_FATAL    : LONG,
  1394.         result_2        = NIL        : PTR TO CHAR,
  1395.         error_value        = DCC_ABORTED_SWALLOWING
  1396.  
  1397.  
  1398.       list_node := self.sending_port.ln
  1399.  
  1400.     IF my_action AND RXFF_NONRET
  1401.         self.swallowRepliesQuick()
  1402.     ELSE
  1403.         VOID self.swallowReplies()
  1404.         IF self.unconfirmed_count > 0 THEN RETURN RC_FATAL, NIL, error_value
  1405.     ENDIF
  1406.  
  1407.     error_value    := DCC_MSG_NOT_CREATED
  1408.  
  1409.     rexx_msg    := CreateRexxMsg(    self.sending_port,
  1410.                                     self.default_extension,
  1411.                                     list_node.name )
  1412.  
  1413.       IF rexx_msg = NIL THEN JUMP clean_me_up
  1414.  
  1415.       rexx_args := rexx_msg.args
  1416.  
  1417.     temp_arg_str := CreateArgstring( arg_0, StrLen( arg_0 ) )
  1418.     IF temp_arg_str = NIL THEN JUMP clean_me_up
  1419.  
  1420.     rexx_args[ 0 ]    := temp_arg_str
  1421.  
  1422.     rexx_msg.action    := my_action
  1423.  
  1424.     rexx_args[ 1 ]    := arg_1
  1425.     rexx_args[ 2 ]    := arg_2
  1426.     rexx_args[ 3 ]    := arg_3
  1427.  
  1428.     IF my_action AND RXFF_NONRET THEN
  1429.             rexx_args[ 15 ] := CreateArgstring(    { no_reply_string },
  1430.                                             StrLen( { no_reply_string } ) )
  1431.  
  1432.     error_value        := DCC_HOST_NOT_FOUND
  1433.  
  1434.     Forbid()
  1435.  
  1436.     ->
  1437.     -> send our message to the port if it exists
  1438.     ->
  1439.     arexx_port := FindPort( 'REXX' )
  1440.     IF arexx_port <> NIL THEN PutMsg( arexx_port, rexx_msg )
  1441.  
  1442.     Permit()
  1443.  
  1444.     ->
  1445.     -> this is written in this way in order to have Permit() earlier
  1446.     ->
  1447.     IF arexx_port <> NIL
  1448.         error_value := DCC_GOT_NO_REPLY
  1449.  
  1450.         IF ( my_action AND RXFF_NONRET ) = FALSE
  1451.  
  1452.             self.unconfirmed_count    := self.unconfirmed_count + 1
  1453.  
  1454.             result_1, result_2        := self.handle_reply()
  1455.  
  1456.             RETURN result_1, result_2, DCC_NO_ERROR
  1457.  
  1458.         ELSE
  1459.  
  1460.             DeleteArgstring( temp_arg_str )
  1461.  
  1462.             RETURN RC_OK, NIL, DCC_NO_ERROR        -> but nothing replied
  1463.  
  1464.         ENDIF
  1465.     ENDIF
  1466.  
  1467. clean_me_up:
  1468.  
  1469.     DeleteRexxMsg( rexx_msg )
  1470.  
  1471. ENDPROC result_1, NIL, error_value
  1472. #endif
  1473.  
  1474. -> ---------------------------------------------------------------
  1475.  
  1476. ->
  1477. ->
  1478. ->
  1479. #ifdef NEED_do_send_function
  1480. PROC do_send_function(    func_name    : PTR TO CHAR,
  1481.                         func_args    : PTR TO LONG,
  1482.                         modifiers ) OF rexxC
  1483.  
  1484.     DEF    arexx_port        = NIL        : PTR TO mp,
  1485.         rexx_msg        = NIL        : PTR TO rexxmsg,
  1486.         rexx_args                    : PTR TO LONG,
  1487.         list_node        = NIL        : PTR TO ln,
  1488.         result_1        = RC_FATAL    : LONG,
  1489.         result_2        = NIL        : PTR TO CHAR,
  1490.         error_value        = DCC_ABORTED_SWALLOWING,
  1491.         list_len        = 0,
  1492.         temp_str        = NIL        : PTR TO CHAR,
  1493.         i
  1494.  
  1495.       list_node := self.sending_port.ln
  1496.  
  1497.     IF modifiers AND RXFF_NONRET
  1498.         self.swallowRepliesQuick()
  1499.     ELSE
  1500.         VOID self.swallowReplies()
  1501.         IF self.unconfirmed_count > 0 THEN RETURN RC_FATAL, NIL, error_value
  1502.     ENDIF
  1503.  
  1504.     error_value    := DCC_MSG_NOT_CREATED
  1505.  
  1506.     rexx_msg    := CreateRexxMsg(    self.sending_port,
  1507.                                     self.default_extension,
  1508.                                     list_node.name )
  1509.  
  1510.       IF rexx_msg = NIL THEN JUMP clean_me_please
  1511.  
  1512.       rexx_args        := rexx_msg.args
  1513.  
  1514. -> -------------------------------------------------
  1515.  
  1516.     rexx_args[ 0 ]    := CreateArgstring( func_name, StrLen( func_name ) )
  1517.  
  1518.     IF modifiers AND RXFF_NONRET THEN rexx_args[ 15 ] :=
  1519.                             CreateArgstring( { no_reply_string },
  1520.                                                 StrLen( { no_reply_string } ) )
  1521.  
  1522.     IF func_args <> NIL
  1523.         list_len := Bounds( ListLen( func_args ), 0, 13  )
  1524.         FOR i := 0 TO list_len - 1
  1525.             temp_str            := func_args[ i ]
  1526.             rexx_args[ i + 1 ]    := CreateArgstring( temp_str, StrLen( temp_str ) )
  1527.         ENDFOR
  1528.     ENDIF
  1529.  
  1530.     rexx_msg.action    := ( modifiers OR RXFUNC ) AND Not( $FF )
  1531.  
  1532.     IF modifiers AND RXFF_NONRET
  1533.         rexx_msg.action    := rexx_msg.action OR 15
  1534.     ELSE
  1535.         rexx_msg.action    := rexx_msg.action OR list_len    -> arg # into low byte
  1536.     ENDIF
  1537.  
  1538.     IF FillRexxMsg( rexx_msg, 16, 0 ) = FALSE THEN JUMP clean_me_please
  1539.  
  1540.     ->
  1541.     -> fix I/O
  1542.     ->
  1543.     IF ( self.default_input <> NIL ) OR ( self.default_output <> NIL )
  1544.         rexx_msg.stdin    := self.default_input
  1545.         rexx_msg.stdout    := self.default_output
  1546.  
  1547.         rexx_msg.action    := rexx_msg.action OR MY_RXFF_NOIO
  1548.     ENDIF
  1549.  
  1550.     error_value := DCC_HOST_NOT_FOUND
  1551.  
  1552.     Forbid()
  1553.  
  1554.     ->
  1555.     -> send our message to the port if it exists
  1556.     ->
  1557.     arexx_port := FindPort( 'REXX' )
  1558.     IF arexx_port <> NIL THEN PutMsg( arexx_port, rexx_msg )
  1559.  
  1560.     Permit()
  1561.  
  1562.     ->
  1563.     -> this is written in this way in order to have Permit() earlier
  1564.     ->
  1565.     IF arexx_port <> NIL
  1566.         error_value := DCC_GOT_NO_REPLY
  1567.         IF ( modifiers AND RXFF_NONRET ) = FALSE
  1568.  
  1569.             self.unconfirmed_count    := self.unconfirmed_count + 1
  1570.  
  1571.             result_1, result_2        := self.handle_reply()
  1572.  
  1573.             RETURN result_1, result_2, DCC_NO_ERROR
  1574.  
  1575.         ELSE            -> it's RXFF_NONRET
  1576.  
  1577.             RETURN RC_OK, NIL, DCC_NO_ERROR    -> but nothing replied
  1578.  
  1579.         ENDIF
  1580.     ENDIF
  1581.  
  1582.     ClearRexxMsg( rexx_msg, 16 )
  1583.  
  1584.     DeleteRexxMsg( rexx_msg )
  1585.  
  1586. ENDPROC result_1, result_2, error_value
  1587. #endif
  1588.  
  1589. -> ---------------------------------------------------------------
  1590.  
  1591. ->
  1592. ->
  1593. ->
  1594. #ifdef NEED_do_function_string
  1595. PROC do_function_string( string : PTR TO CHAR, modifiers ) OF rexxC
  1596.  
  1597.     DEF    arexx_port        = NIL        : PTR TO mp,
  1598.         rexx_msg        = NIL        : PTR TO rexxmsg,
  1599.         rexx_args                    : PTR TO LONG,
  1600.         list_node        = NIL        : PTR TO ln,
  1601.         result_1        = RC_FATAL    : LONG,
  1602.         result_2        = NIL        : PTR TO CHAR,
  1603.         error_value        = DCC_ABORTED_SWALLOWING
  1604.  
  1605.       list_node := self.sending_port.ln
  1606.  
  1607.     IF modifiers AND RXFF_NONRET
  1608.         self.swallowRepliesQuick()
  1609.     ELSE
  1610.         VOID self.swallowReplies()
  1611.         IF self.unconfirmed_count > 0 THEN RETURN RC_FATAL, NIL, error_value
  1612.     ENDIF
  1613.  
  1614.     error_value    := DCC_MSG_NOT_CREATED
  1615.  
  1616.     rexx_msg    := CreateRexxMsg(    self.sending_port,
  1617.                                     self.default_extension,
  1618.                                     list_node.name )
  1619.  
  1620.       IF rexx_msg = NIL THEN JUMP clean_me_please
  1621.  
  1622.       rexx_args := rexx_msg.args
  1623.  
  1624. -> -------------------------------------------------
  1625.  
  1626.     rexx_args[ 0 ] := CreateArgstring( string, StrLen( string ) )
  1627.  
  1628.     IF modifiers AND RXFF_NONRET THEN
  1629.         rexx_args[ 15 ] := CreateArgstring( { no_reply_string },
  1630.                                             StrLen( { no_reply_string } ) )
  1631.  
  1632.     ->
  1633.     -> put 0 as # of arguments in the lowest byte of rexx_msg.action
  1634.     ->
  1635.     rexx_msg.action    := ( modifiers OR RXFUNC ) AND Not( $FF )
  1636.  
  1637.     IF FillRexxMsg( rexx_msg, 1, 0 ) = FALSE THEN JUMP clean_me_please
  1638.  
  1639.     ->
  1640.     -> fix default I/O
  1641.     ->
  1642.     IF ( self.default_input <> NIL ) OR ( self.default_output <> NIL )
  1643.         rexx_msg.stdin    := self.default_input
  1644.         rexx_msg.stdout    := self.default_output
  1645.  
  1646.         rexx_msg.action    := rexx_msg.action OR MY_RXFF_NOIO
  1647.     ENDIF
  1648.  
  1649.     error_value := DCC_HOST_NOT_FOUND
  1650.  
  1651.     Forbid()
  1652.  
  1653.     ->
  1654.     -> send our message to the port if it exists
  1655.     ->
  1656.     arexx_port := FindPort( 'REXX' )
  1657.     IF arexx_port <> NIL THEN PutMsg( arexx_port, rexx_msg )
  1658.  
  1659.     Permit()
  1660.  
  1661.     ->
  1662.     -> this is written in this way in order to have Permit() earlier
  1663.     ->
  1664.     IF arexx_port <> NIL
  1665.         error_value := DCC_GOT_NO_REPLY
  1666.         IF ( modifiers AND RXFF_NONRET ) = FALSE
  1667.  
  1668.             self.unconfirmed_count    := self.unconfirmed_count + 1
  1669.  
  1670.             result_1, result_2        := self.handle_reply()
  1671.  
  1672.             RETURN result_1, result_2, DCC_NO_ERROR
  1673.         ELSE
  1674.             RETURN RC_OK, NIL, DCC_NO_ERROR    -> but nothing replied
  1675.         ENDIF
  1676.     ENDIF
  1677.  
  1678. clean_me_please:
  1679.  
  1680.     ClearRexxMsg( rexx_msg, 16 )
  1681.  
  1682.     DeleteRexxMsg( rexx_msg )
  1683.  
  1684. ENDPROC result_1, result_2, error_value
  1685. #endif
  1686.  
  1687. -> ---------------------------------------------------------------
  1688.  
  1689. ->
  1690. ->    takes args[ 15 ] ! ! ! !
  1691. ->
  1692. #ifdef NEED_we_want_reply
  1693. PROC we_want_reply( str : PTR TO CHAR ) OF rexxC IS
  1694.                 Not( StrCmp( str, { no_reply_string } ) )
  1695. #endif
  1696.  
  1697. -> ---------------------------------------------------------------
  1698.  
  1699. no_reply_string:
  1700.     CHAR    '« NO REPLY! »'
  1701.  
  1702. -> =============== the is the end ================