home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / the25.zip / thesrc251.zip / rexx.c < prev    next >
C/C++ Source or Header  |  1998-07-29  |  80KB  |  2,173 lines

  1. /***********************************************************************/
  2. /* REXX.C - REXX interface routines.                                   */
  3. /***********************************************************************/
  4. /*
  5.  * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
  6.  * Copyright (C) 1991-1997 Mark Hessling
  7.  *
  8.  * This program is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU General Public License as
  10.  * published by the Free Software Foundation; either version 2 of
  11.  * the License, or any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16.  * General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to:
  20.  *
  21.  *    The Free Software Foundation, Inc.
  22.  *    675 Mass Ave,
  23.  *    Cambridge, MA 02139 USA.
  24.  *
  25.  *
  26.  * If you make modifications to this software that you feel increases
  27.  * it usefulness for the rest of the community, please email the
  28.  * changes, enhancements, bug fixes as well as any and all ideas to me.
  29.  * This software is going to be maintained and enhanced as deemed
  30.  * necessary by the community.
  31.  *
  32.  * Mark Hessling                 Email:             M.Hessling@qut.edu.au
  33.  * PO Box 203                    Phone:                    +617 3802 0800
  34.  * Bellara                       http://www.gu.edu.au/gext/the/markh.html
  35.  * QLD 4507                      **** Maintainer PDCurses & REXX/SQL ****
  36.  * Australia                     ************* Author of THE ************
  37.  */
  38.  
  39. /*
  40. $Id: rexx.c 2.1 1995/06/24 16:31:04 MH Rel MH $
  41. */
  42.  
  43. #if defined(__EMX__) && defined(USE_REGINA) && !defined(MSDOS)
  44. # include <os2.h>
  45. #else
  46. /*--------------------------- global data -----------------------------*/
  47. /* these are here because EMX include REXX definitions from within os2.h */
  48. /*---------------------------------------------------------------------*/
  49. #  define INCL_RXSUBCOM       /* Subcommand handler values */
  50. #  define INCL_RXSHV          /* Shared variable support */
  51. #  define INCL_RXSYSEXIT      /* System exit routines */
  52. #  define INCL_DOSPROCESS     /* Process/Thread Info */
  53. #  define INCL_RXFUNC         /* External functions */
  54. #endif
  55. #include <the.h>
  56. #include <proto.h>
  57.  
  58. LINE *rexxout_first_line=NULL;
  59. LINE *rexxout_last_line=NULL;
  60. LINE *rexxout_curr=NULL;
  61. LINETYPE rexxout_number_lines=0L;
  62.  
  63. #if (defined(HAVE_PROTO) && !defined(NOREXX)) || defined(USE_REXXIMC)
  64.  
  65. /*
  66.  * Because Rexx interpreters include <windows.h> on Windows platforms
  67.  * and it defines MOUSE_MOVED, we have to undef it here to avoid
  68.  * conflict.
  69.  */
  70. #undef MOUSE_MOVED
  71. #include <query.h>
  72. #if defined(__EMX__) && defined(USE_REGINA) && !defined(MSDOS)
  73. #  define INCL_RXSUBCOM       /* Subcommand handler values */
  74. #  define INCL_RXSHV          /* Shared variable support */
  75. #  define INCL_RXSYSEXIT      /* System exit routines */
  76. #  define INCL_DOSPROCESS     /* Process/Thread Info */
  77. #  define INCL_RXFUNC         /* External functions */
  78. #endif
  79. #include <therexx.h>
  80.  
  81. #if defined(HAVE_SYS_WAIT_H)
  82. # include <sys/wait.h>
  83. #endif
  84.  
  85. #define BUF_SIZE 512
  86.  
  87. #if defined(USE_REXX6000)
  88. LONG THE_Commands( RSH_ARG0_TYPE, RSH_ARG1_TYPE, RSH_ARG2_TYPE );
  89. LONG THE_Exit_Handler( REH_ARG0_TYPE, REH_ARG1_TYPE, REH_ARG2_TYPE );
  90. USHORT THE_Function_Handler( RFH_ARG0_TYPE, RFH_ARG1_TYPE, RFH_ARG2_TYPE, RFH_ARG3_TYPE, RFH_ARG4_TYPE );
  91. #else
  92. RexxSubcomHandler THE_Commands;
  93. RexxExitHandler THE_Exit_Handler;
  94. RexxFunctionHandler THE_Function_Handler;
  95. #endif
  96.  
  97. #if defined(HAVE_PROTO)
  98. static RXSTRING *get_compound_rexx_variable(CHARTYPE *,RXSTRING *,short);
  99. static short valid_target_function(ULONG, RXSTRING []);
  100. static short run_os_function(ULONG, RXSTRING []);
  101. static int run_os_command(CHARTYPE *,CHARTYPE *,CHARTYPE *,CHARTYPE *);
  102. static CHARTYPE *MakeAscii(RXSTRING *);
  103. static char *get_a_line(FILE *, char *, int *, int *);
  104. static short set_rexx_variables_from_file(char *,CHARTYPE *);
  105. #else
  106. static RXSTRING *get_compound_rexx_variable();
  107. static short valid_target_function();
  108. static short run_os_function();
  109. static int run_os_command();
  110. static CHARTYPE *MakeAscii();
  111. static char *get_a_line();
  112. static short set_rexx_variables_from_file();
  113. #endif
  114.  
  115. static LINETYPE captured_lines;
  116. static bool rexx_halted;
  117.  
  118. #define LVL_GLOB  1
  119. #define LVL_FILE  2
  120. #define LVL_VIEW  3
  121.  
  122. struct function_item
  123.  {
  124.   CHARTYPE *name;                                      /* name of item */
  125.   char  name_length;                        /* length of function name */
  126.   short item_number;                         /* unique number for item */
  127.   short item_index;                  /* index value for the whole item */
  128.   short level;                    /* level of item; global, file, view */
  129.  };
  130. typedef struct function_item FUNCTION_ITEM;
  131.  
  132.  static FUNCTION_ITEM function_item[] =
  133.   {
  134.    {(CHARTYPE *)"ALT.0",5,ITEM_ALT,0,LVL_FILE},
  135.    {(CHARTYPE *)"ALT.1",5,ITEM_ALT,1,LVL_FILE},
  136.    {(CHARTYPE *)"ALT.2",5,ITEM_ALT,2,LVL_FILE},
  137.    {(CHARTYPE *)"ARBCHAR.0",9,ITEM_ARBCHAR,0,LVL_VIEW},
  138.    {(CHARTYPE *)"ARBCHAR.1",9,ITEM_ARBCHAR,1,LVL_VIEW},
  139.    {(CHARTYPE *)"ARBCHAR.2",9,ITEM_ARBCHAR,2,LVL_VIEW},
  140.    {(CHARTYPE *)"AUTOSAVE.0",10,ITEM_AUTOSAVE,0,LVL_FILE},
  141.    {(CHARTYPE *)"AUTOSAVE.1",10,ITEM_AUTOSAVE,1,LVL_FILE},
  142.    {(CHARTYPE *)"BACKUP.0",8,ITEM_BACKUP,0,LVL_FILE},
  143.    {(CHARTYPE *)"BACKUP.1",8,ITEM_BACKUP,1,LVL_FILE},
  144.    {(CHARTYPE *)"BEEP.0",6,ITEM_BEEP,0,LVL_GLOB},
  145.    {(CHARTYPE *)"BEEP.1",6,ITEM_BEEP,1,LVL_GLOB},
  146.    {(CHARTYPE *)"BLOCK.0",7,ITEM_BLOCK,0,LVL_VIEW},
  147.    {(CHARTYPE *)"BLOCK.1",7,ITEM_BLOCK,1,LVL_VIEW},
  148.    {(CHARTYPE *)"BLOCK.2",7,ITEM_BLOCK,2,LVL_VIEW},
  149.    {(CHARTYPE *)"BLOCK.3",7,ITEM_BLOCK,3,LVL_VIEW},
  150.    {(CHARTYPE *)"BLOCK.4",7,ITEM_BLOCK,4,LVL_VIEW},
  151.    {(CHARTYPE *)"BLOCK.5",7,ITEM_BLOCK,5,LVL_VIEW},
  152.    {(CHARTYPE *)"BLOCK.6",7,ITEM_BLOCK,6,LVL_VIEW},
  153.    {(CHARTYPE *)"CASE.0",6,ITEM_CASE,0,LVL_VIEW},
  154.    {(CHARTYPE *)"CASE.1",6,ITEM_CASE,1,LVL_VIEW},
  155.    {(CHARTYPE *)"CASE.2",6,ITEM_CASE,2,LVL_VIEW},
  156.    {(CHARTYPE *)"CASE.3",6,ITEM_CASE,3,LVL_VIEW},
  157.    {(CHARTYPE *)"CASE.4",6,ITEM_CASE,4,LVL_VIEW},
  158.    {(CHARTYPE *)"CLEARSCREEN.0",13,ITEM_CLEARSCREEN,0,LVL_GLOB},
  159.    {(CHARTYPE *)"CLEARSCREEN.1",13,ITEM_CLEARSCREEN,1,LVL_GLOB},
  160.    {(CHARTYPE *)"CLOCK.0",7,ITEM_CLOCK,0,LVL_GLOB},
  161.    {(CHARTYPE *)"CLOCK.1",7,ITEM_CLOCK,1,LVL_GLOB},
  162.    {(CHARTYPE *)"CMDARROWS.0",11,ITEM_CMDARROWS,0,LVL_GLOB},
  163.    {(CHARTYPE *)"CMDARROWS.1",11,ITEM_CMDARROWS,1,LVL_GLOB},
  164.    {(CHARTYPE *)"CMDLINE.0",9,ITEM_CMDLINE,0,LVL_VIEW},
  165.    {(CHARTYPE *)"CMDLINE.1",9,ITEM_CMDLINE,1,LVL_VIEW},
  166.    {(CHARTYPE *)"CMDLINE.2",9,ITEM_CMDLINE,2,LVL_VIEW},
  167.    {(CHARTYPE *)"CMDLINE.3",9,ITEM_CMDLINE,3,LVL_VIEW},
  168.    {(CHARTYPE *)"COLOR.0",7,ITEM_COLOR,0,LVL_FILE},
  169.    {(CHARTYPE *)"COLOR.1",7,ITEM_COLOR,1,LVL_FILE},
  170.    {(CHARTYPE *)"COLOR.2",7,ITEM_COLOR,2,LVL_FILE},
  171.    {(CHARTYPE *)"COLOR.3",7,ITEM_COLOR,3,LVL_FILE},
  172.    {(CHARTYPE *)"COLOR.4",7,ITEM_COLOR,4,LVL_FILE},
  173.    {(CHARTYPE *)"COLOR.5",7,ITEM_COLOR,5,LVL_FILE},
  174.    {(CHARTYPE *)"COLOR.6",7,ITEM_COLOR,6,LVL_FILE},
  175.    {(CHARTYPE *)"COLOR.7",7,ITEM_COLOR,7,LVL_FILE},
  176.    {(CHARTYPE *)"COLOR.8",7,ITEM_COLOR,8,LVL_FILE},
  177.    {(CHARTYPE *)"COLOR.9",7,ITEM_COLOR,9,LVL_FILE},
  178.    {(CHARTYPE *)"COLOR.10",8,ITEM_COLOR,10,LVL_FILE},
  179.    {(CHARTYPE *)"COLOR.11",8,ITEM_COLOR,11,LVL_FILE},
  180.    {(CHARTYPE *)"COLOR.12",8,ITEM_COLOR,12,LVL_FILE},
  181.    {(CHARTYPE *)"COLOR.13",8,ITEM_COLOR,13,LVL_FILE},
  182.    {(CHARTYPE *)"COLOR.14",8,ITEM_COLOR,14,LVL_FILE},
  183.    {(CHARTYPE *)"COLOR.15",8,ITEM_COLOR,15,LVL_FILE},
  184.    {(CHARTYPE *)"COLOR.16",8,ITEM_COLOR,16,LVL_FILE},
  185.    {(CHARTYPE *)"COLOR.17",8,ITEM_COLOR,17,LVL_FILE},
  186.    {(CHARTYPE *)"COLOR.18",8,ITEM_COLOR,18,LVL_FILE},
  187.    {(CHARTYPE *)"COLOR.19",8,ITEM_COLOR,19,LVL_FILE},
  188.    {(CHARTYPE *)"COLOR.20",8,ITEM_COLOR,20,LVL_FILE},
  189.    {(CHARTYPE *)"COLOR.21",8,ITEM_COLOR,21,LVL_FILE},
  190.    {(CHARTYPE *)"COLOR.22",8,ITEM_COLOR,22,LVL_FILE},
  191.    {(CHARTYPE *)"COLOR.23",8,ITEM_COLOR,23,LVL_FILE},
  192.    {(CHARTYPE *)"COLOUR.0",7,ITEM_COLOUR,0,LVL_FILE},
  193.    {(CHARTYPE *)"COLOUR.1",7,ITEM_COLOUR,1,LVL_FILE},
  194.    {(CHARTYPE *)"COLOUR.2",7,ITEM_COLOUR,2,LVL_FILE},
  195.    {(CHARTYPE *)"COLOUR.3",7,ITEM_COLOUR,3,LVL_FILE},
  196.    {(CHARTYPE *)"COLOUR.4",7,ITEM_COLOUR,4,LVL_FILE},
  197.    {(CHARTYPE *)"COLOUR.5",7,ITEM_COLOUR,5,LVL_FILE},
  198.    {(CHARTYPE *)"COLOUR.6",7,ITEM_COLOUR,6,LVL_FILE},
  199.    {(CHARTYPE *)"COLOUR.7",7,ITEM_COLOUR,7,LVL_FILE},
  200.    {(CHARTYPE *)"COLOUR.8",7,ITEM_COLOUR,8,LVL_FILE},
  201.    {(CHARTYPE *)"COLOUR.9",7,ITEM_COLOUR,9,LVL_FILE},
  202.    {(CHARTYPE *)"COLOUR.10",8,ITEM_COLOUR,10,LVL_FILE},
  203.    {(CHARTYPE *)"COLOUR.11",8,ITEM_COLOUR,11,LVL_FILE},
  204.    {(CHARTYPE *)"COLOUR.12",8,ITEM_COLOUR,12,LVL_FILE},
  205.    {(CHARTYPE *)"COLOUR.13",8,ITEM_COLOUR,13,LVL_FILE},
  206.    {(CHARTYPE *)"COLOUR.14",8,ITEM_COLOUR,14,LVL_FILE},
  207.    {(CHARTYPE *)"COLOUR.15",8,ITEM_COLOUR,15,LVL_FILE},
  208.    {(CHARTYPE *)"COLOUR.16",8,ITEM_COLOUR,16,LVL_FILE},
  209.    {(CHARTYPE *)"COLOUR.17",8,ITEM_COLOUR,17,LVL_FILE},
  210.    {(CHARTYPE *)"COLOUR.18",8,ITEM_COLOUR,18,LVL_FILE},
  211.    {(CHARTYPE *)"COLOUR.19",8,ITEM_COLOUR,19,LVL_FILE},
  212.    {(CHARTYPE *)"COLOUR.20",8,ITEM_COLOUR,20,LVL_FILE},
  213.    {(CHARTYPE *)"COLOUR.21",8,ITEM_COLOUR,21,LVL_FILE},
  214.    {(CHARTYPE *)"COLOUR.22",8,ITEM_COLOUR,22,LVL_FILE},
  215.    {(CHARTYPE *)"COLOUR.23",8,ITEM_COLOUR,23,LVL_FILE},
  216.    {(CHARTYPE *)"COLUMN.0",8,ITEM_COLUMN,0,LVL_VIEW},
  217.    {(CHARTYPE *)"COLUMN.1",8,ITEM_COLUMN,1,LVL_VIEW},
  218.    {(CHARTYPE *)"COMPAT.0",8,ITEM_COMPAT,0,LVL_GLOB},
  219.    {(CHARTYPE *)"COMPAT.1",8,ITEM_COMPAT,1,LVL_GLOB},
  220.    {(CHARTYPE *)"COMPAT.2",8,ITEM_COMPAT,2,LVL_GLOB},
  221.    {(CHARTYPE *)"COMPAT.3",8,ITEM_COMPAT,3,LVL_GLOB},
  222.    {(CHARTYPE *)"CURLINE.0",9,ITEM_CURLINE,0,LVL_VIEW},
  223.    {(CHARTYPE *)"CURLINE.1",9,ITEM_CURLINE,1,LVL_VIEW},
  224.    {(CHARTYPE *)"CURLINE.2",9,ITEM_CURLINE,2,LVL_VIEW},
  225.    {(CHARTYPE *)"CURLINE.3",9,ITEM_CURLINE,3,LVL_VIEW},
  226.    {(CHARTYPE *)"CURLINE.4",9,ITEM_CURLINE,4,LVL_VIEW},
  227.    {(CHARTYPE *)"CURLINE.5",9,ITEM_CURLINE,5,LVL_VIEW},
  228.    {(CHARTYPE *)"CURLINE.6",9,ITEM_CURLINE,6,LVL_VIEW},
  229.    {(CHARTYPE *)"CURSOR.0",8,ITEM_CURSOR,0,LVL_VIEW},
  230.    {(CHARTYPE *)"CURSOR.1",8,ITEM_CURSOR,1,LVL_VIEW},
  231.    {(CHARTYPE *)"CURSOR.2",8,ITEM_CURSOR,2,LVL_VIEW},
  232.    {(CHARTYPE *)"CURSOR.3",8,ITEM_CURSOR,3,LVL_VIEW},
  233.    {(CHARTYPE *)"CURSOR.4",8,ITEM_CURSOR,4,LVL_VIEW},
  234.    {(CHARTYPE *)"CURSOR.5",8,ITEM_CURSOR,5,LVL_VIEW},
  235.    {(CHARTYPE *)"CURSOR.6",8,ITEM_CURSOR,6,LVL_VIEW},
  236.    {(CHARTYPE *)"CURSOR.7",8,ITEM_CURSOR,7,LVL_VIEW},
  237.    {(CHARTYPE *)"CURSOR.8",8,ITEM_CURSOR,8,LVL_VIEW},
  238.    {(CHARTYPE *)"CURSORSTAY.0",12,ITEM_CURSORSTAY,0,LVL_GLOB},
  239.    {(CHARTYPE *)"CURSORSTAY.1",12,ITEM_CURSORSTAY,1,LVL_GLOB},
  240.    {(CHARTYPE *)"DEFSORT.0",12,ITEM_DEFSORT,0,LVL_GLOB},
  241.    {(CHARTYPE *)"DEFSORT.1",12,ITEM_DEFSORT,1,LVL_GLOB},
  242.    {(CHARTYPE *)"DEFSORT.2",12,ITEM_DEFSORT,2,LVL_GLOB},
  243.    {(CHARTYPE *)"DIRFILEID.0",11,ITEM_DIRFILEID,0,LVL_FILE},
  244.    {(CHARTYPE *)"DIRFILEID.1",11,ITEM_DIRFILEID,1,LVL_FILE},
  245.    {(CHARTYPE *)"DIRFILEID.2",11,ITEM_DIRFILEID,2,LVL_FILE},
  246.    {(CHARTYPE *)"DISPLAY.0",9,ITEM_DISPLAY,0,LVL_VIEW},
  247.    {(CHARTYPE *)"DISPLAY.1",9,ITEM_DISPLAY,1,LVL_VIEW},
  248.    {(CHARTYPE *)"DISPLAY.2",9,ITEM_DISPLAY,2,LVL_VIEW},
  249.    {(CHARTYPE *)"EOF.0",5,ITEM_EOF,0,LVL_VIEW},
  250.    {(CHARTYPE *)"EOF.1",5,ITEM_EOF,1,LVL_VIEW},
  251.    {(CHARTYPE *)"EOLOUT.0",8,ITEM_EOLOUT,0,LVL_FILE},
  252.    {(CHARTYPE *)"EOLOUT.1",8,ITEM_EOLOUT,1,LVL_FILE},
  253.    {(CHARTYPE *)"ETMODE.0",8,ITEM_ETMODE,0,LVL_GLOB},
  254.    {(CHARTYPE *)"ETMODE.1",8,ITEM_ETMODE,1,LVL_GLOB},
  255.    {(CHARTYPE *)"ETMODE.2",8,ITEM_ETMODE,2,LVL_GLOB},
  256.    {(CHARTYPE *)"FEXT.0",6,ITEM_FEXT,0,LVL_FILE},
  257.    {(CHARTYPE *)"FEXT.1",6,ITEM_FEXT,1,LVL_FILE},
  258.    {(CHARTYPE *)"FIELD.0",7,ITEM_FIELD,0,LVL_VIEW},
  259.    {(CHARTYPE *)"FIELD.1",7,ITEM_FIELD,1,LVL_VIEW},
  260.    {(CHARTYPE *)"FIELD.2",7,ITEM_FIELD,2,LVL_VIEW},
  261.    {(CHARTYPE *)"FIELD.3",7,ITEM_FIELD,3,LVL_VIEW},
  262.    {(CHARTYPE *)"FIELD.4",7,ITEM_FIELD,4,LVL_VIEW},
  263.    {(CHARTYPE *)"FILENAME.0",10,ITEM_FILENAME,0,LVL_FILE},
  264.    {(CHARTYPE *)"FILENAME.1",10,ITEM_FILENAME,1,LVL_FILE},
  265.    {(CHARTYPE *)"FMODE.0",7,ITEM_FMODE,0,LVL_FILE},
  266.    {(CHARTYPE *)"FMODE.1",7,ITEM_FMODE,1,LVL_FILE},
  267.    {(CHARTYPE *)"FNAME.0",7,ITEM_FNAME,0,LVL_FILE},
  268.    {(CHARTYPE *)"FNAME.1",7,ITEM_FNAME,1,LVL_FILE},
  269.    {(CHARTYPE *)"FPATH.0",7,ITEM_FPATH,0,LVL_FILE},
  270.    {(CHARTYPE *)"FPATH.1",7,ITEM_FPATH,1,LVL_FILE},
  271.    {(CHARTYPE *)"FTYPE.0",7,ITEM_FTYPE,0,LVL_FILE},
  272.    {(CHARTYPE *)"FTYPE.1",7,ITEM_FTYPE,1,LVL_FILE},
  273.    {(CHARTYPE *)"FULLFNAME.0",11,ITEM_FULLFNAME,0,LVL_FILE},
  274.    {(CHARTYPE *)"FULLFNAME.1",11,ITEM_FULLFNAME,1,LVL_FILE},
  275.    {(CHARTYPE *)"GETENV.0",8,ITEM_GETENV,0,LVL_GLOB},
  276.    {(CHARTYPE *)"GETENV.1",8,ITEM_GETENV,1,LVL_GLOB},
  277.    {(CHARTYPE *)"HEX.0",5,ITEM_HEX,0,LVL_VIEW},
  278.    {(CHARTYPE *)"HEX.1",5,ITEM_HEX,1,LVL_VIEW},
  279.    {(CHARTYPE *)"HEXDISPLAY.0",12,ITEM_HEXDISPLAY,0,LVL_GLOB},
  280.    {(CHARTYPE *)"HEXDISPLAY.1",12,ITEM_HEXDISPLAY,1,LVL_GLOB},
  281.    {(CHARTYPE *)"HEXSHOW.0",9,ITEM_HEXSHOW,0,LVL_VIEW},
  282.    {(CHARTYPE *)"HEXSHOW.1",9,ITEM_HEXSHOW,1,LVL_VIEW},
  283.    {(CHARTYPE *)"HEXSHOW.2",9,ITEM_HEXSHOW,2,LVL_VIEW},
  284.    {(CHARTYPE *)"HIGHLIGHT.0",11,ITEM_HIGHLIGHT,0,LVL_VIEW},
  285.    {(CHARTYPE *)"HIGHLIGHT.1",11,ITEM_HIGHLIGHT,1,LVL_VIEW},
  286.    {(CHARTYPE *)"HIGHLIGHT.2",11,ITEM_HIGHLIGHT,2,LVL_VIEW},
  287.    {(CHARTYPE *)"HIGHLIGHT.3",11,ITEM_HIGHLIGHT,3,LVL_VIEW},
  288.    {(CHARTYPE *)"IDLINE.0",8,ITEM_IDLINE,0,LVL_VIEW},
  289.    {(CHARTYPE *)"IDLINE.1",8,ITEM_IDLINE,1,LVL_VIEW},
  290.    {(CHARTYPE *)"IMPMACRO.0",10,ITEM_IMPMACRO,0,LVL_VIEW},
  291.    {(CHARTYPE *)"IMPMACRO.1",10,ITEM_IMPMACRO,1,LVL_VIEW},
  292.    {(CHARTYPE *)"IMPMOS.0",8,ITEM_IMPOS,0,LVL_VIEW},
  293.    {(CHARTYPE *)"IMPMOS.1",8,ITEM_IMPOS,1,LVL_VIEW},
  294.    {(CHARTYPE *)"INPUTMODE.0",11,ITEM_INPUTMODE,0,LVL_VIEW},
  295.    {(CHARTYPE *)"INPUTMODE.1",11,ITEM_INPUTMODE,1,LVL_VIEW},
  296.    {(CHARTYPE *)"INSERTMODE.0",12,ITEM_INSERTMODE,0,LVL_GLOB},
  297.    {(CHARTYPE *)"INSERTMODE.1",12,ITEM_INSERTMODE,1,LVL_GLOB},
  298.    {(CHARTYPE *)"LASTMSG.0",9,ITEM_LASTMSG,0,LVL_GLOB},
  299.    {(CHARTYPE *)"LASTMSG.1",9,ITEM_LASTMSG,1,LVL_GLOB},
  300.    {(CHARTYPE *)"LASTRC.0",8,ITEM_LASTRC,0,LVL_GLOB},
  301.    {(CHARTYPE *)"LASTRC.1",8,ITEM_LASTRC,1,LVL_GLOB},
  302.    {(CHARTYPE *)"LENGTH.0",8,ITEM_LENGTH,0,LVL_FILE},
  303.    {(CHARTYPE *)"LENGTH.1",8,ITEM_LENGTH,1,LVL_FILE},
  304.    {(CHARTYPE *)"LINE.0",6,ITEM_LINE,0,LVL_VIEW},
  305.    {(CHARTYPE *)"LINE.1",6,ITEM_LINE,1,LVL_VIEW},
  306.    {(CHARTYPE *)"LINEFLAG.0",10,ITEM_LINEFLAG,0,LVL_FILE},
  307.    {(CHARTYPE *)"LINEFLAG.1",10,ITEM_LINEFLAG,1,LVL_FILE},
  308.    {(CHARTYPE *)"LINEFLAG.2",10,ITEM_LINEFLAG,2,LVL_FILE},
  309.    {(CHARTYPE *)"LINEFLAG.3",10,ITEM_LINEFLAG,3,LVL_FILE},
  310.    {(CHARTYPE *)"LINEND.0",8,ITEM_LINEND,0,LVL_VIEW},
  311.    {(CHARTYPE *)"LINEND.1",8,ITEM_LINEND,1,LVL_VIEW},
  312.    {(CHARTYPE *)"LINEND.2",8,ITEM_LINEND,2,LVL_VIEW},
  313.    {(CHARTYPE *)"LSCREEN.0",9,ITEM_LSCREEN,0,LVL_GLOB},
  314.    {(CHARTYPE *)"LSCREEN.1",9,ITEM_LSCREEN,1,LVL_GLOB},
  315.    {(CHARTYPE *)"LSCREEN.2",9,ITEM_LSCREEN,2,LVL_GLOB},
  316.    {(CHARTYPE *)"LSCREEN.3",9,ITEM_LSCREEN,3,LVL_GLOB},
  317.    {(CHARTYPE *)"LSCREEN.4",9,ITEM_LSCREEN,4,LVL_GLOB},
  318.    {(CHARTYPE *)"LSCREEN.5",9,ITEM_LSCREEN,5,LVL_GLOB},
  319.    {(CHARTYPE *)"LSCREEN.6",9,ITEM_LSCREEN,6,LVL_GLOB},
  320.    {(CHARTYPE *)"MACRO.0",7,ITEM_MACRO,0,LVL_VIEW},
  321.    {(CHARTYPE *)"MACRO.1",7,ITEM_MACRO,1,LVL_VIEW},
  322.    {(CHARTYPE *)"MACROEXT.0",10,ITEM_MACROEXT,0,LVL_GLOB},
  323.    {(CHARTYPE *)"MACROEXT.1",10,ITEM_MACROEXT,1,LVL_GLOB},
  324.    {(CHARTYPE *)"MACROPATH.0",11,ITEM_MACROPATH,0,LVL_GLOB},
  325.    {(CHARTYPE *)"MACROPATH.1",11,ITEM_MACROPATH,1,LVL_GLOB},
  326.    {(CHARTYPE *)"MARGINS.0",9,ITEM_MARGINS,0,LVL_VIEW},
  327.    {(CHARTYPE *)"MARGINS.1",9,ITEM_MARGINS,1,LVL_VIEW},
  328.    {(CHARTYPE *)"MARGINS.2",9,ITEM_MARGINS,2,LVL_VIEW},
  329.    {(CHARTYPE *)"MARGINS.3",9,ITEM_MARGINS,3,LVL_VIEW},
  330.    {(CHARTYPE *)"MONITOR.0",9,ITEM_MONITOR,0,LVL_GLOB},
  331.    {(CHARTYPE *)"MONITOR.1",9,ITEM_MONITOR,1,LVL_GLOB},
  332.    {(CHARTYPE *)"MONITOR.2",9,ITEM_MONITOR,2,LVL_GLOB},
  333.    {(CHARTYPE *)"MOUSE.0",7,ITEM_MOUSE,0,LVL_GLOB},
  334.    {(CHARTYPE *)"MOUSE.1",7,ITEM_MOUSE,1,LVL_GLOB},
  335.    {(CHARTYPE *)"MSGLINE.0",9,ITEM_MSGLINE,0,LVL_VIEW},
  336.    {(CHARTYPE *)"MSGLINE.1",9,ITEM_MSGLINE,1,LVL_VIEW},
  337.    {(CHARTYPE *)"MSGLINE.2",9,ITEM_MSGLINE,2,LVL_VIEW},
  338.    {(CHARTYPE *)"MSGLINE.3",9,ITEM_MSGLINE,3,LVL_VIEW},
  339.    {(CHARTYPE *)"MSGLINE.4",9,ITEM_MSGLINE,4,LVL_VIEW},
  340.    {(CHARTYPE *)"MSGMODE.0",9,ITEM_MSGMODE,0,LVL_VIEW},
  341.    {(CHARTYPE *)"MSGMODE.1",9,ITEM_MSGMODE,1,LVL_VIEW},
  342.    {(CHARTYPE *)"NBFILE.0",8,ITEM_NBFILE,0,LVL_GLOB},
  343.    {(CHARTYPE *)"NBFILE.1",8,ITEM_NBFILE,1,LVL_GLOB},
  344.    {(CHARTYPE *)"NEWLINES.0",10,ITEM_NEWLINES,0,LVL_VIEW},
  345.    {(CHARTYPE *)"NEWLINES.1",10,ITEM_NEWLINES,1,LVL_VIEW},
  346.    {(CHARTYPE *)"NONDISP.0",9,ITEM_NONDISP,0,LVL_GLOB},
  347.    {(CHARTYPE *)"NONDISP.1",9,ITEM_NONDISP,1,LVL_GLOB},
  348.    {(CHARTYPE *)"NUMBER.0",8,ITEM_NUMBER,0,LVL_VIEW},
  349.    {(CHARTYPE *)"NUMBER.1",8,ITEM_NUMBER,1,LVL_VIEW},
  350.    {(CHARTYPE *)"POSITION.0",10,ITEM_POSITION,0,LVL_VIEW},
  351.    {(CHARTYPE *)"POSITION.1",10,ITEM_POSITION,1,LVL_VIEW},
  352.    {(CHARTYPE *)"POSITION.2",10,ITEM_POSITION,2,LVL_VIEW},
  353.    {(CHARTYPE *)"POSITION.3",10,ITEM_POSITION,3,LVL_VIEW},
  354.    {(CHARTYPE *)"PREFIX.0",8,ITEM_PREFIX,0,LVL_VIEW},
  355.    {(CHARTYPE *)"PREFIX.1",8,ITEM_PREFIX,1,LVL_VIEW},
  356.    {(CHARTYPE *)"PREFIX.2",8,ITEM_PREFIX,2,LVL_VIEW},
  357.    {(CHARTYPE *)"PREFIX.3",8,ITEM_PREFIX,3,LVL_VIEW},
  358.    {(CHARTYPE *)"PREFIX.4",8,ITEM_PREFIX,4,LVL_VIEW},
  359.    {(CHARTYPE *)"PRINTER.0",9,ITEM_PRINTER,0,LVL_GLOB},
  360.    {(CHARTYPE *)"PRINTER.1",9,ITEM_PRINTER,1,LVL_GLOB},
  361.    {(CHARTYPE *)"REPROFILE.0",11,ITEM_REPROFILE,0,LVL_GLOB},
  362.    {(CHARTYPE *)"REPROFILE.1",11,ITEM_REPROFILE,1,LVL_GLOB},
  363.    {(CHARTYPE *)"RESERVED.0",10,ITEM_RESERVED,0,LVL_FILE},
  364.    {(CHARTYPE *)"RESERVED.1",10,ITEM_RESERVED,1,LVL_FILE},
  365.    {(CHARTYPE *)"REXXOUTPUT.0",12,ITEM_REXXOUTPUT,0,LVL_GLOB},
  366.    {(CHARTYPE *)"REXXOUTPUT.1",12,ITEM_REXXOUTPUT,1,LVL_GLOB},
  367.    {(CHARTYPE *)"REXXOUTPUT.2",12,ITEM_REXXOUTPUT,2,LVL_GLOB},
  368.    {(CHARTYPE *)"RING.0",6,ITEM_RING,0,LVL_GLOB},
  369.    {(CHARTYPE *)"SCALE.0",7,ITEM_SCALE,0,LVL_VIEW},
  370.    {(CHARTYPE *)"SCALE.1",7,ITEM_SCALE,1,LVL_VIEW},
  371.    {(CHARTYPE *)"SCALE.2",7,ITEM_SCALE,2,LVL_VIEW},
  372.    {(CHARTYPE *)"SCOPE.0",7,ITEM_SCOPE,0,LVL_VIEW},
  373.    {(CHARTYPE *)"SCOPE.1",7,ITEM_SCOPE,1,LVL_VIEW},
  374.    {(CHARTYPE *)"SCREEN.0",8,ITEM_SCREEN,0,LVL_GLOB},
  375.    {(CHARTYPE *)"SCREEN.1",8,ITEM_SCREEN,1,LVL_GLOB},
  376.    {(CHARTYPE *)"SCREEN.2",8,ITEM_SCREEN,2,LVL_GLOB},
  377.    {(CHARTYPE *)"SELECT.0",8,ITEM_SELECT,0,LVL_FILE},
  378.    {(CHARTYPE *)"SELECT.1",8,ITEM_SELECT,1,LVL_FILE},
  379.    {(CHARTYPE *)"SELECT.2",8,ITEM_SELECT,2,LVL_FILE},
  380.    {(CHARTYPE *)"SHADOW.0",8,ITEM_SHADOW,0,LVL_VIEW},
  381.    {(CHARTYPE *)"SHADOW.1",8,ITEM_SHADOW,1,LVL_VIEW},
  382.    {(CHARTYPE *)"SIZE.0",6,ITEM_SIZE,0,LVL_FILE},
  383.    {(CHARTYPE *)"SIZE.1",6,ITEM_SIZE,1,LVL_FILE},
  384.    {(CHARTYPE *)"STATUSLINE.0",12,ITEM_STATUSLINE,0,LVL_GLOB},
  385.    {(CHARTYPE *)"STATUSLINE.1",12,ITEM_STATUSLINE,1,LVL_GLOB},
  386.    {(CHARTYPE *)"STAY.0",6,ITEM_STAY,0,LVL_VIEW},
  387.    {(CHARTYPE *)"STAY.1",6,ITEM_STAY,1,LVL_VIEW},
  388.    {(CHARTYPE *)"TABKEY.0",8,ITEM_TABKEY,0,LVL_GLOB},
  389.    {(CHARTYPE *)"TABKEY.1",8,ITEM_TABKEY,1,LVL_GLOB},
  390.    {(CHARTYPE *)"TABKEY.2",8,ITEM_TABKEY,2,LVL_GLOB},
  391.    {(CHARTYPE *)"TABLINE.0",9,ITEM_TABLINE,0,LVL_VIEW},
  392.    {(CHARTYPE *)"TABLINE.1",9,ITEM_TABLINE,1,LVL_VIEW},
  393.    {(CHARTYPE *)"TABLINE.2",9,ITEM_TABLINE,2,LVL_VIEW},
  394.    {(CHARTYPE *)"TABS.0",6,ITEM_TABS,0,LVL_VIEW},
  395.    {(CHARTYPE *)"TABS.1",6,ITEM_TABS,1,LVL_VIEW},
  396.    {(CHARTYPE *)"TABSIN.0",8,ITEM_TABSIN,0,LVL_GLOB},
  397.    {(CHARTYPE *)"TABSIN.1",8,ITEM_TABSIN,1,LVL_GLOB},
  398.    {(CHARTYPE *)"TABSIN.2",8,ITEM_TABSIN,2,LVL_GLOB},
  399.    {(CHARTYPE *)"TABSOUT.0",9,ITEM_TABSOUT,0,LVL_FILE},
  400.    {(CHARTYPE *)"TABSOUT.1",9,ITEM_TABSOUT,1,LVL_FILE},
  401.    {(CHARTYPE *)"TABSOUT.2",9,ITEM_TABSOUT,2,LVL_FILE},
  402.    {(CHARTYPE *)"TERMINAL.0",10,ITEM_TERMINAL,0,LVL_GLOB},
  403.    {(CHARTYPE *)"TERMINAL.1",10,ITEM_TERMINAL,1,LVL_GLOB},
  404.    {(CHARTYPE *)"TOF.0",5,ITEM_TOF,0,LVL_VIEW},
  405.    {(CHARTYPE *)"TOF.1",5,ITEM_TOF,1,LVL_VIEW},
  406.    {(CHARTYPE *)"UNDOING.0",9,ITEM_UNDOING,0,LVL_FILE},
  407.    {(CHARTYPE *)"UNDOING.1",9,ITEM_UNDOING,1,LVL_FILE},
  408.    {(CHARTYPE *)"UNTAA.0",7,ITEM_UNTAA,0,LVL_GLOB},
  409.    {(CHARTYPE *)"UNTAA.1",7,ITEM_UNTAA,1,LVL_GLOB},
  410.    {(CHARTYPE *)"VERIFY.0",8,ITEM_VERIFY,0,LVL_VIEW},
  411.    {(CHARTYPE *)"VERIFY.1",8,ITEM_VERIFY,1,LVL_VIEW},
  412.    {(CHARTYPE *)"VERSHIFT.0",10,ITEM_VERSHIFT,0,LVL_VIEW},
  413.    {(CHARTYPE *)"VERSHIFT.1",10,ITEM_VERSHIFT,1,LVL_VIEW},
  414.    {(CHARTYPE *)"VERSION.0",9,ITEM_VERSION,0,LVL_GLOB},
  415.    {(CHARTYPE *)"VERSION.1",9,ITEM_VERSION,1,LVL_GLOB},
  416.    {(CHARTYPE *)"VERSION.2",9,ITEM_VERSION,2,LVL_GLOB},
  417.    {(CHARTYPE *)"VERSION.3",9,ITEM_VERSION,3,LVL_GLOB},
  418.    {(CHARTYPE *)"VERSION.4",9,ITEM_VERSION,4,LVL_GLOB},
  419.    {(CHARTYPE *)"WIDTH.0",7,ITEM_WIDTH,0,LVL_GLOB},
  420.    {(CHARTYPE *)"WIDTH.1",7,ITEM_WIDTH,1,LVL_GLOB},
  421.    {(CHARTYPE *)"WORD.0",6,ITEM_WORD,0,LVL_VIEW},
  422.    {(CHARTYPE *)"WORD.1",6,ITEM_WORD,1,LVL_VIEW},
  423.    {(CHARTYPE *)"WORDWRAP.0",10,ITEM_WORDWRAP,0,LVL_VIEW},
  424.    {(CHARTYPE *)"WORDWRAP.1",10,ITEM_WORDWRAP,1,LVL_VIEW},
  425.    {(CHARTYPE *)"WRAP.0",6,ITEM_WRAP,0,LVL_VIEW},
  426.    {(CHARTYPE *)"WRAP.1",6,ITEM_WRAP,1,LVL_VIEW},
  427.    {(CHARTYPE *)"ZONE.0",6,ITEM_ZONE,0,LVL_VIEW},
  428.    {(CHARTYPE *)"ZONE.1",6,ITEM_ZONE,1,LVL_VIEW},
  429.    {(CHARTYPE *)"ZONE.2",6,ITEM_ZONE,2,LVL_VIEW},
  430.    {(CHARTYPE *)"AFTER",5,ITEM_AFTER_FUNCTION,1,LVL_VIEW},
  431.    {(CHARTYPE *)"BATCH",5,ITEM_BATCH_FUNCTION,1,LVL_GLOB},
  432.    {(CHARTYPE *)"BEFORE",6,ITEM_BEFORE_FUNCTION,1,LVL_VIEW},
  433.    {(CHARTYPE *)"BLANK",5,ITEM_BLANK_FUNCTION,1,LVL_VIEW},
  434.    {(CHARTYPE *)"BLOCK",5,ITEM_BLOCK_FUNCTION,1,LVL_VIEW},
  435.    {(CHARTYPE *)"BOTTOMEDGE",10,ITEM_BOTTOMEDGE_FUNCTION,1,LVL_VIEW},
  436.    {(CHARTYPE *)"COMMAND",7,ITEM_COMMAND_FUNCTION,1,LVL_VIEW},
  437.    {(CHARTYPE *)"CURRENT",7,ITEM_CURRENT_FUNCTION,1,LVL_VIEW},
  438.    {(CHARTYPE *)"DIR",3,ITEM_DIR_FUNCTION,1,LVL_FILE},
  439.    {(CHARTYPE *)"END",3,ITEM_END_FUNCTION,1,LVL_VIEW},
  440.    {(CHARTYPE *)"EOF",3,ITEM_EOF_FUNCTION,1,LVL_VIEW},
  441.    {(CHARTYPE *)"FIRST",5,ITEM_FIRST_FUNCTION,1,LVL_VIEW},
  442.    {(CHARTYPE *)"FOCUSEOF",8,ITEM_FOCUSEOF_FUNCTION,1,LVL_VIEW},
  443.    {(CHARTYPE *)"FOCUSTOF",8,ITEM_FOCUSTOF_FUNCTION,1,LVL_VIEW},
  444.    {(CHARTYPE *)"INBLOCK",7,ITEM_INBLOCK_FUNCTION,1,LVL_VIEW},
  445.    {(CHARTYPE *)"INCOMMAND",9,ITEM_INCOMMAND_FUNCTION,1,LVL_VIEW},
  446.    {(CHARTYPE *)"INITIAL",7,ITEM_INITIAL_FUNCTION,1,LVL_GLOB},
  447.    {(CHARTYPE *)"INPREFIX",8,ITEM_INPREFIX_FUNCTION,1,LVL_VIEW},
  448.    {(CHARTYPE *)"LEFTEDGE",8,ITEM_LEFTEDGE_FUNCTION,1,LVL_VIEW},
  449.    {(CHARTYPE *)"MODIFIABLE",10,ITEM_MODIFIABLE_FUNCTION,1,LVL_VIEW},
  450.    {(CHARTYPE *)"RIGHTEDGE",9,ITEM_RIGHTEDGE_FUNCTION,1,LVL_VIEW},
  451.    {(CHARTYPE *)"SHADOW",6,ITEM_SHADOW_FUNCTION,1,LVL_VIEW},
  452.    {(CHARTYPE *)"SPACECHAR",9,ITEM_SPACECHAR_FUNCTION,1,LVL_VIEW},
  453.    {(CHARTYPE *)"TOF",3,ITEM_TOF_FUNCTION,1,LVL_VIEW},
  454.    {(CHARTYPE *)"TOPEDGE",7,ITEM_TOPEDGE_FUNCTION,1,LVL_VIEW},
  455.    {(CHARTYPE *)"VERONE",6,ITEM_VERONE_FUNCTION,1,LVL_VIEW},
  456.    {(CHARTYPE *)"VALID_TARGET",12,ITEM_VALID_TARGET_FUNCTION,1,LVL_VIEW},
  457.    {(CHARTYPE *)"RUN_OS",6,ITEM_RUN_OS_FUNCTION,1,LVL_GLOB},
  458.    {NULL,0,0,0,0},
  459.   };
  460.  
  461. /***********************************************************************/
  462. RSH_RETURN_TYPE THE_Commands
  463. #if defined(HAVE_PROTO)
  464.    (
  465.    RSH_ARG0_TYPE Command,    /* Command string passed from the caller    */
  466.    RSH_ARG1_TYPE Flags,      /* pointer to short for return of flags     */
  467.    RSH_ARG2_TYPE Retstr)     /* pointer to RXSTRING for RC return        */
  468. #else
  469.    ( Command, Flags, Retstr )
  470.    RSH_ARG0_TYPE Command;    /* Command string passed from the caller    */
  471.    RSH_ARG1_TYPE Flags;      /* pointer to short for return of flags     */
  472.    RSH_ARG2_TYPE Retstr;     /* pointer to RXSTRING for RC return        */
  473. #endif
  474. /***********************************************************************/
  475. {
  476. /*-------------------------- external data ----------------------------*/
  477.  extern CHARTYPE *temp_cmd;
  478. /*--------------------------- local data ------------------------------*/
  479.  short rc=RC_OK;
  480.  SHVBLOCK shv;
  481.  RXSTRING argstr;
  482. /*--------------------------- processing ------------------------------*/
  483.  if (allocate_temp_space(Command->strlength,TEMP_TEMP_CMD) != RC_OK)
  484.    {
  485.     display_error(30,(CHARTYPE *)"",FALSE);
  486.     *Flags = RXSUBCOM_ERROR;             /* raise an error condition   */
  487.     sprintf((DEFCHAR *)Retstr->strptr, "%d", rc);   /* format return code string  */
  488.                                          /* and set the correct length */
  489.     Retstr->strlength = strlen((DEFCHAR *)Retstr->strptr);
  490.     return 0L;                           /* processing completed       */
  491.    }
  492.  memcpy(temp_cmd,Command->strptr,Command->strlength);
  493.  temp_cmd[Command->strlength] = '\0';
  494.  
  495.  if (strcmp("XXYYZZ",(DEFCHAR *)temp_cmd) == 0)
  496.    {
  497.     shv.shvnext=NULL;                                /* only one block */
  498.     shv.shvcode=RXSHV_NEXTV;                             /* direct set */
  499.  
  500.     argstr.strptr=NULL;
  501.     argstr.strlength=0;
  502.     shv.shvname=argstr;
  503.     rc = 0;
  504.     while(rc != 2)
  505.      {
  506.       rc = RexxVariablePool(&shv);            /* get the next variable */
  507.       if (rc != 2)
  508.         {
  509.          sprintf((DEFCHAR *)temp_cmd,"i <%s> <%s> <%ld>",
  510.              shv.shvname.strptr,shv.shvvalue.strptr,shv.shvvalue.strlength);
  511.          command_line(temp_cmd,COMMAND_ONLY_FALSE);
  512.         }
  513.      }
  514.    }
  515.  else
  516.    rc = command_line(temp_cmd,COMMAND_ONLY_FALSE);
  517.  if (rc < 0)
  518.     *Flags = RXSUBCOM_ERROR;             /* raise an error condition   */
  519.  else
  520.     *Flags = RXSUBCOM_OK;                /* not found is not an error  */
  521.  
  522.  sprintf((DEFCHAR *)Retstr->strptr, "%d", rc); /* format return code string  */
  523.                                          /* and set the correct length */
  524.  Retstr->strlength = strlen((DEFCHAR *)Retstr->strptr);
  525.  return 0L;                              /* processing completed       */
  526. }
  527. /***********************************************************************/
  528. REH_RETURN_TYPE THE_Exit_Handler
  529. #if defined(HAVE_PROTO)
  530.    (
  531.    REH_ARG0_TYPE ExitNumber,    /* code defining the exit function    */
  532.    REH_ARG1_TYPE Subfunction,   /* code defining the exit subfunction */
  533.    REH_ARG2_TYPE ParmBlock      /* function dependent control block   */
  534.    )
  535. #else
  536.    ( ExitNumber, Subfunction, ParmBlock )
  537.    REH_ARG0_TYPE ExitNumber;    /* code defining the exit function    */
  538.    REH_ARG1_TYPE Subfunction;   /* code defining the exit subfunction */
  539.    REH_ARG2_TYPE ParmBlock;     /* function dependent control block   */
  540. #endif
  541. /***********************************************************************/
  542. {
  543. /*-------------------------- external data ----------------------------*/
  544. #ifndef XCURSES
  545.  extern WINDOW *statarea;
  546.  extern bool batch_only;
  547. #endif
  548. #if !defined(MULTIPLE_PSEUDO_FILES)
  549.  extern CHARTYPE rexx_filename[10];
  550.  extern CHARTYPE rexx_pathname[MAX_FILE_NAME+1];
  551. #endif
  552.  extern LINETYPE CAPREXXMAXx;
  553.  extern bool CAPREXXOUTx;
  554.  extern bool rexx_output;
  555. /*--------------------------- local data ------------------------------*/
  556.  RXSIOTRC_PARM *trc_parm = (RXSIOTRC_PARM *)ParmBlock;
  557.  LONG rc=0L;
  558.  char rexxout_temp[60];
  559.  VIEW_DETAILS *found_view=NULL;
  560. /*--------------------------- processing ------------------------------*/
  561.  if (Subfunction != RXSIOSAY   /* ignore all but RXSIOSAY and RXSIOTRC */
  562.  &&  Subfunction != RXSIOTRC)
  563.     return(RXEXIT_NOT_HANDLED);
  564. /*---------------------------------------------------------------------*/
  565. /* If this is the first time this exit handler is called, set up the   */
  566. /* handling of the result; either open the capture file, or set the    */
  567. /* terminal out of curses mode so scrolling etc. work.                 */
  568. /*---------------------------------------------------------------------*/
  569.  if (!rexx_output)
  570.    {
  571.     rexx_output = TRUE;
  572.     if (CAPREXXOUTx)
  573.       {
  574. /*---------------------------------------------------------------------*/
  575. /* Free up the existing linked list (if any)                           */
  576. /*---------------------------------------------------------------------*/
  577. #if !defined(MULTIPLE_PSEUDO_FILES)
  578.        rexxout_first_line = rexxout_last_line = lll_free(rexxout_first_line);
  579.        rexxout_number_lines = 0L;
  580.        if ((found_view = find_file(rexx_pathname,rexx_filename)) != (VIEW_DETAILS *)NULL)
  581.          {
  582.           found_view->file_for_view->first_line = found_view->file_for_view->last_line = NULL;
  583.           found_view->file_for_view->number_lines = 0L;
  584.          }
  585. #endif
  586. /*---------------------------------------------------------------------*/
  587. /* first_line is set to "Top of File"                                  */
  588. /*---------------------------------------------------------------------*/
  589.        if ((rexxout_first_line = add_line(rexxout_first_line,NULL,TOP_OF_FILE,
  590.             strlen((DEFCHAR *)TOP_OF_FILE),0,FALSE)) == NULL)
  591.           rc = RXEXIT_RAISE_ERROR;
  592. /*---------------------------------------------------------------------*/
  593. /* last line is set to "Bottom of File"                                */
  594. /*---------------------------------------------------------------------*/
  595.        if ((rexxout_last_line = add_line(rexxout_first_line,rexxout_first_line,BOTTOM_OF_FILE,
  596.             strlen((DEFCHAR *)BOTTOM_OF_FILE),0,FALSE)) == NULL)
  597.           rc = RXEXIT_RAISE_ERROR;
  598.        rexxout_curr = rexxout_first_line;
  599.        if (found_view != (VIEW_DETAILS *)NULL)
  600.          {
  601.           found_view->file_for_view->first_line = rexxout_first_line;
  602.           found_view->file_for_view->last_line = rexxout_last_line;
  603.          }
  604.       }
  605. #ifndef XCURSES
  606.     else
  607.       {
  608.        if (!batch_only)
  609.          {
  610.           wmove(statarea,0,COLS-1);
  611.           wrefresh(statarea);
  612.           suspend_curses();
  613.          }
  614.        printf("\n");                       /* scroll the screen 1 line */
  615.        fflush(stdout);
  616.       }
  617. #endif
  618.    }
  619. /*---------------------------------------------------------------------*/
  620. /* If the REXX interpreter has been halted by line limit exceeded, just*/
  621. /* return to the interpreter indicating that THE is hadnling the output*/
  622. /* of messages. This is done to stop the "clutter" that comes back as  */
  623. /* the interpreter tries to tell us that it is stopping.               */
  624. /*---------------------------------------------------------------------*/
  625.  if (rexx_halted)
  626.     return(RXEXIT_HANDLED);
  627. /*---------------------------------------------------------------------*/
  628. /* If we are capturing the rexx output, print the string to the file.  */
  629. /*---------------------------------------------------------------------*/
  630.  if (CAPREXXOUTx)
  631.    {
  632.     rexxout_number_lines++;
  633.     if ((rexxout_curr = add_line(rexxout_first_line,rexxout_curr,
  634.                                  (CHARTYPE *)trc_parm->rxsio_string.strptr,
  635.                                  (trc_parm->rxsio_string.strlength==(-1))?0:trc_parm->rxsio_string.strlength,0,FALSE)) == NULL)
  636.        rc = RXEXIT_RAISE_ERROR;
  637.     else
  638.        rc = RXEXIT_HANDLED;
  639.    }
  640.  else
  641.     rc = RXEXIT_NOT_HANDLED;
  642. /*---------------------------------------------------------------------*/
  643. /* If the number of lines processed exceeds the line limit, display our*/
  644. /* own message telling what has happened and exit with                 */
  645. /* RXEXIT_RAISE_ERROR. This tells the interpreter that it is to stop.  */
  646. /*---------------------------------------------------------------------*/
  647.  if (++captured_lines > CAPREXXMAXx)
  648.    {
  649.     if (CAPREXXOUTx)
  650.       {
  651.        rexxout_number_lines++;
  652.        sprintf(rexxout_temp,"THE: REXX macro halted - line limit (%ld) exceeded",CAPREXXMAXx);
  653.        rexxout_curr = add_line(rexxout_first_line,rexxout_curr,
  654.                                (CHARTYPE *)rexxout_temp,
  655.                                strlen((DEFCHAR *)rexxout_temp),0,FALSE);
  656.       }
  657.     else
  658.        printf("THE: REXX macro halted - line limit (%ld) exceeded\n",CAPREXXMAXx);
  659.     rc = RXEXIT_RAISE_ERROR;
  660.     rexx_halted = TRUE;
  661.    }
  662.  return(rc);
  663. }
  664. /***********************************************************************/
  665. RFH_RETURN_TYPE THE_Function_Handler
  666. #if defined(HAVE_PROTO)
  667.    (
  668.    RFH_ARG0_TYPE FunctionName,  /* name of function */
  669.    RFH_ARG1_TYPE Argc,          /* number of arguments    */
  670.    RFH_ARG2_TYPE Argv,          /* array of arguments in RXSTRINGs */
  671.    RFH_ARG3_TYPE QueueName,     /* name of queue */
  672.    RFH_ARG4_TYPE Retstr         /* return string   */
  673.    )
  674. #else
  675.    ( FunctionName, Argc, Argv, QueueName, Retstr )
  676.    RFH_ARG0_TYPE FunctionName;  /* name of function */
  677.    RFH_ARG1_TYPE Argc;          /* number of arguments    */
  678.    RFH_ARG2_TYPE Argv;          /* array of arguments in RXSTRINGs */
  679.    RFH_ARG3_TYPE QueueName;     /* name of queue */
  680.    RFH_ARG4_TYPE Retstr;        /* return string   */
  681. #endif
  682.  
  683. /***********************************************************************/
  684. {
  685. /*-------------------------- external data ----------------------------*/
  686.  extern VALUE item_values[MAX_VARIABLES_RETURNED];
  687.  extern CHARTYPE number_of_files;
  688. /*--------------------------- local data ------------------------------*/
  689.  register short i=0;
  690.  int functionname_length = strlen((DEFCHAR*)FunctionName);
  691. /*--------------------------- processing ------------------------------*/
  692. /*---------------------------------------------------------------------*/
  693. /* Find the external function name in the array. Error if not found.   */
  694. /*---------------------------------------------------------------------*/
  695.  for (i=0;function_item[i].name != NULL;i++)
  696.    {
  697.     if (memcmpi((CHARTYPE *)FunctionName,
  698.                 function_item[i].name,
  699.                 (int)function_item[i].name_length) == 0
  700.     &&  (int)function_item[i].name_length == functionname_length)
  701.       {
  702.        switch(function_item[i].item_number)
  703.          {
  704.           case ITEM_VALID_TARGET_FUNCTION:
  705.                if (number_of_files == 0)
  706.                  {
  707.                   display_error(83,(CHARTYPE *)"",FALSE);
  708.                   return(1);
  709.                  }
  710.                valid_target_function(Argc,Argv);
  711.                break;
  712.           case ITEM_RUN_OS_FUNCTION:
  713.                run_os_function(Argc,Argv);
  714.                break;
  715.           default:
  716.                if (number_of_files == 0
  717.                &&  function_item[i].level != LVL_GLOB)
  718.                  {
  719.                   display_error(83,(CHARTYPE *)"",FALSE);
  720.                   return(1);
  721.                  }
  722.               if ((Argv == NULL) || (Argc == 0)) /* FGC */
  723.                   (void)get_item_values(function_item[i].item_number,
  724.                         (CHARTYPE *)"",QUERY_FUNCTION,(LINETYPE)Argc,NULL,0L);
  725.                else
  726.                   (void)get_item_values(function_item[i].item_number,
  727.                         (CHARTYPE *)"",QUERY_FUNCTION,(LINETYPE)Argc,
  728.                         (CHARTYPE *)Argv[0].strptr,(LINETYPE)Argv[0].strlength);
  729.                break;
  730.          }
  731.        if (item_values[function_item[i].item_index].len > 256)
  732.          {
  733.           if ((Retstr->strptr = (RXSTRING_STRPTR_TYPE)(*the_malloc)(item_values[function_item[i].item_index].len)) == NULL)
  734.             {
  735.              display_error(30,(CHARTYPE *)"",FALSE);
  736.              return(1);
  737.             }
  738.          }
  739.        memcpy(Retstr->strptr,item_values[function_item[i].item_index].value,
  740.                              item_values[function_item[i].item_index].len);
  741.        Retstr->strlength = item_values[function_item[i].item_index].len;
  742.        return(0);
  743.       }
  744.    }
  745.  return(1);                                    /* fatal error for REXX */
  746. }
  747. /***********************************************************************/
  748. short initialise_rexx
  749. #if defined(HAVE_PROTO)
  750.       (void)
  751. #else
  752.       ()
  753. #endif
  754. /***********************************************************************/
  755. {
  756. /*--------------------------- local data ------------------------------*/
  757.  ULONG rc;
  758.  register short i=0;
  759. /*--------------------------- processing ------------------------------*/
  760. #ifdef TRACE
  761.  trace_function("rexx.c:    initialise_rexx");
  762. #endif
  763.  
  764. #if defined(MSWIN)
  765.  if (RexxThread(GetCurrentTask(),THREAD_ATTACH) != THREAD_ATTACH_AOK)
  766.    {
  767. #ifdef TRACE
  768.     trace_return();
  769. #endif
  770.     return(RC_INVALID_ENVIRON);
  771.    }
  772. #endif
  773.  
  774. #ifdef TRACE
  775.     trace_string("before Subcom\n");
  776. #endif
  777. #if defined(USE_REXX6000)
  778.  rc = RexxRegisterSubcom((RRSE_ARG0_TYPE)"THE",
  779.                          (RRSE_ARG1_TYPE)THE_Commands,
  780.                          (RRSE_ARG2_TYPE)NULL);
  781. #else
  782.  rc = RexxRegisterSubcomExe((RRSE_ARG0_TYPE)"THE",
  783.                             (RRSE_ARG1_TYPE)THE_Commands,
  784.                             (RRSE_ARG2_TYPE)NULL);
  785. #endif
  786.  if (rc != RXSUBCOM_OK)
  787.    {
  788. #ifdef TRACE
  789.     trace_return();
  790. #endif
  791.     return((short)rc);
  792.    }
  793. #ifdef TRACE
  794.     trace_string("before exits\n");
  795. #endif
  796.  
  797. #if !defined(USE_REXX6000)
  798.  rc = RexxRegisterExitExe((RREE_ARG0_TYPE)"THE_EXIT",
  799.                           (RREE_ARG1_TYPE)THE_Exit_Handler,
  800.                           (RREE_ARG2_TYPE)NULL);
  801.  if (rc != RXEXIT_OK)
  802.    {
  803. #ifdef TRACE
  804.     trace_return();
  805. #endif
  806.     return((short)rc);
  807.    }
  808. #endif
  809.  
  810.  for (i=0;function_item[i].name != NULL;i++)
  811.    {
  812. #ifdef TRACE
  813.     trace_string("before function: %d\n",i);
  814. #endif
  815. #if defined(USE_REXX6000)
  816.     rc = RexxRegisterFunction((RRFE_ARG0_TYPE)function_item[i].name,
  817.                               (RRFE_ARG1_TYPE)THE_Function_Handler,
  818.                               NULL);
  819. #else
  820.     rc = RexxRegisterFunctionExe((RRFE_ARG0_TYPE)function_item[i].name,
  821.                                  (RRFE_ARG1_TYPE)THE_Function_Handler);
  822. #endif
  823.     if (rc != RXFUNC_OK)
  824.       {
  825. #ifdef TRACE
  826.        trace_return();
  827. #endif
  828.        return((short)rc);
  829.       }
  830.    }
  831.  
  832. #ifdef TRACE
  833.     trace_constant("before returning\n");
  834. #endif
  835. #ifdef TRACE
  836.  trace_return();
  837. #endif
  838.  return((short)rc);
  839. }
  840. /***********************************************************************/
  841. short finalise_rexx
  842. #if defined(HAVE_PROTO)
  843.     (void)
  844. #else
  845.     ()
  846. #endif
  847. /***********************************************************************/
  848. {
  849. /*--------------------------- local data ------------------------------*/
  850.  ULONG rc;
  851.  register short i=0;
  852. /*--------------------------- processing ------------------------------*/
  853. #ifdef TRACE
  854.  trace_function("rexx.c:    finalise_rexx");
  855. #endif
  856.  
  857. #if defined(USE_REXX6000)
  858.  rc = RexxDeregisterSubcom((RDS_ARG0_TYPE)"THE");
  859. #else
  860.  rc = RexxDeregisterSubcom((RDS_ARG0_TYPE)"THE",
  861.                            (RDS_ARG1_TYPE)NULL);
  862.  rc = RexxDeregisterExit((RDE_ARG0_TYPE)"THE_EXIT",
  863.                          (RDE_ARG1_TYPE)NULL);
  864. #endif
  865.  for (i=0;function_item[i].name != NULL;i++)
  866.    {
  867.     rc = RexxDeregisterFunction((RDF_ARG0_TYPE)function_item[i].name);
  868.    }
  869.  
  870. #if defined(MSWIN)
  871.  (void)RexxThread(GetCurrentTask(),THREAD_DETACH);
  872. #endif
  873.  
  874. #ifdef TRACE
  875.  trace_return();
  876. #endif
  877.  return((short)rc);
  878. }
  879. /***********************************************************************/
  880. short execute_macro_file
  881. #if defined(HAVE_PROTO)
  882.       (CHARTYPE *filename,CHARTYPE *params,short *macrorc)
  883. #else
  884.       (filename,params,macrorc)
  885.        CHARTYPE *filename;
  886.        CHARTYPE *params;
  887.        short *macrorc;
  888. #endif
  889. /***********************************************************************/
  890. {
  891. /*-------------------------- external data ----------------------------*/
  892.  extern bool batch_only;
  893.  extern bool error_on_screen;
  894. #ifndef XCURSES
  895.  extern CHARTYPE number_of_files;
  896. #endif
  897. #if !defined(MULTIPLE_PSEUDO_FILES)
  898.  extern CHARTYPE rexx_filename[10];
  899.  extern CHARTYPE rexx_pathname[MAX_FILE_NAME+1];
  900. #endif
  901.  extern CHARTYPE rexx_macro_name[MAX_FILE_NAME+1];
  902.  extern CHARTYPE rexx_macro_parameters[MAX_FILE_NAME+1];
  903.  extern CHARTYPE *temp_cmd;
  904.  extern bool CAPREXXOUTx;
  905.  extern bool rexx_output;
  906. /*--------------------------- local data ------------------------------*/
  907. #if defined(USE_REXX6000)
  908.  LONG rexxrc=0L;
  909. #elif defined(__EMX__) || defined(USE_REGINA)
  910.  SHORT rexxrc=0;
  911. #else
  912.  USHORT rexxrc=0L;
  913. #endif
  914.  RXSTRING retstr;
  915.  RXSTRING argstr;
  916.  ULONG rc=0;
  917.  CHAR retbuf[260];
  918.  LONG num_params=0L;
  919.  CHARTYPE *rexx_args=NULL;
  920.  RXSYSEXIT exit_list[2];                /* system exit list           */
  921. /*--------------------------- processing ------------------------------*/
  922. #ifdef TRACE
  923.  trace_function("rexx.c:    execute_macro_file");
  924. #endif
  925. /*---------------------------------------------------------------------*/
  926. /* Determine how many parameters are to be passed to the interpreter.  */
  927. /* Only 0 or 1 are valid values.                                       */
  928. /*---------------------------------------------------------------------*/
  929.  if (params == NULL
  930.  || strcmp((DEFCHAR *)params,"") == 0)
  931.    {
  932.     num_params = 0;
  933.     MAKERXSTRING(argstr,"",0);
  934.     strcpy((DEFCHAR *)rexx_macro_parameters,"");
  935.    }
  936.  else
  937.    {
  938.     num_params = 1;
  939.     if ((rexx_args = (CHARTYPE *)(*the_malloc)(strlen((DEFCHAR *)params)+1)) == (CHARTYPE *)NULL)
  940.       {
  941.        display_error(30,(CHARTYPE *)"",FALSE);
  942. #ifdef TRACE
  943.        trace_return();
  944. #endif
  945.        return(RC_OUT_OF_MEMORY);
  946.       }
  947.     strcpy((DEFCHAR *)rexx_macro_parameters,(DEFCHAR *)params);
  948.     strcpy((DEFCHAR *)rexx_args,(DEFCHAR *)params);
  949.     MAKERXSTRING(argstr,(DEFCHAR *)rexx_args,strlen((DEFCHAR *)rexx_args));
  950.    }
  951.  
  952.  MAKERXSTRING(retstr,retbuf,sizeof(retbuf));
  953.  
  954.  strcpy((DEFCHAR *)rexx_macro_name,(DEFCHAR *)filename);
  955. /*---------------------------------------------------------------------*/
  956. /* Set up pointer to REXX Exit Handler.                                */
  957. /*---------------------------------------------------------------------*/
  958. #if defined(USE_REXX6000)
  959.  exit_list[0].sysexit_func = THE_Exit_Handler;
  960. #else
  961.  exit_list[0].sysexit_name = "THE_EXIT";
  962. #endif
  963.  exit_list[0].sysexit_code = RXSIO;
  964.  exit_list[1].sysexit_code = RXENDLST;
  965.  
  966. /*---------------------------------------------------------------------*/
  967. /* Under OS/2 use of interactive trace in a macro only works if an OS  */
  968. /* command has been run before executing the macro, so we run a REM    */
  969. /*---------------------------------------------------------------------*/
  970. #if defined(OS2) || defined(WIN32)
  971.  execute_os_command((CHARTYPE*)"REM",TRUE,FALSE);
  972. #endif
  973. #ifdef UNIX
  974.  execute_os_command((CHARTYPE*)"echo",TRUE,FALSE);
  975. #endif
  976.  
  977.  captured_lines = 0L;
  978.  rexx_output = FALSE;
  979.  rexx_halted = FALSE;
  980. /*---------------------------------------------------------------------*/
  981. /* Call the REXX interpreter.                                          */
  982. /*---------------------------------------------------------------------*/
  983.  rc = RexxStart((RS_ARG0_TYPE)num_params,
  984.                 (RS_ARG1_TYPE)&argstr,
  985.                 (RS_ARG2_TYPE)filename,
  986.                 (RS_ARG3_TYPE)NULL,
  987.                 (RS_ARG4_TYPE)"THE",
  988.                 (RS_ARG5_TYPE)RXCOMMAND,
  989.                 (RS_ARG6_TYPE)exit_list,
  990.                 (RS_ARG7_TYPE)&rexxrc,
  991.                 (RS_ARG8_TYPE)&retstr);
  992.  
  993. /*---------------------------------------------------------------------*/
  994. /* Edit the captured file or clean up after REXX output displays.      */
  995. /*---------------------------------------------------------------------*/
  996.  if (rexx_output)
  997.    {
  998.     rexx_output = FALSE;
  999.     if (CAPREXXOUTx)
  1000.       {
  1001. #if defined(MULTIPLE_PSEUDO_FILES)
  1002.        Xedit((CHARTYPE *)"***REXXOUT***");
  1003. #else
  1004.        strcpy((DEFCHAR *)temp_cmd,(DEFCHAR *)rexx_pathname);
  1005.        strcat((DEFCHAR *)temp_cmd,(DEFCHAR *)rexx_filename);
  1006.        Xedit(temp_cmd);
  1007. #endif
  1008.       }
  1009.     else
  1010.       {
  1011.        if (batch_only)
  1012.           error_on_screen = TRUE;
  1013. #ifndef XCURSES
  1014.        else
  1015. /*---------------------------------------------------------------------*/
  1016. /* Pause for operator intervention and restore the screen to the       */
  1017. /* current screen if there are still file(s) in the ring.              */
  1018. /*---------------------------------------------------------------------*/
  1019.          {
  1020.           printf("\n%s",HIT_ANY_KEY);
  1021.           fflush(stdout);
  1022.           resume_curses();
  1023.           (void)my_getch(stdscr);
  1024.           if (number_of_files > 0)
  1025.             {
  1026. #if defined(HAVE_BROKEN_SYSVR4_CURSES)
  1027.              short x=0,y=0;
  1028.              getyx(CURRENT_WINDOW,y,x);
  1029.              force_curses_background();
  1030.              wmove(CURRENT_WINDOW,y,x);
  1031.              refresh();
  1032. #endif
  1033.              restore_THE();
  1034.             }
  1035.          }
  1036. #endif
  1037.       }
  1038.    }
  1039. #if defined(WIN32) && defined(HAVE_RESET_PROG_MODE)
  1040.  else
  1041.     reset_prog_mode();
  1042. #endif
  1043.  
  1044.  if (rexx_args != NULL)
  1045.     (*the_free)(rexx_args);
  1046. #ifdef TRACE
  1047.  trace_return();
  1048. #endif
  1049.  *macrorc = (short)rexxrc;
  1050.  return((short)rc);
  1051. }
  1052. /***********************************************************************/
  1053. short execute_macro_instore
  1054. #if defined(HAVE_PROTO)
  1055.       (CHARTYPE *commands,short *macrorc)
  1056. #else
  1057.       (commands, macrorc)
  1058.        CHARTYPE *commands;
  1059.        short *macrorc;
  1060. #endif
  1061. /***********************************************************************/
  1062. {
  1063. /*-------------------------- external data ----------------------------*/
  1064.  extern bool batch_only;
  1065.  extern bool error_on_screen;
  1066. #ifndef XCURSES
  1067.  extern CHARTYPE number_of_files;
  1068. #endif
  1069. #if !defined(MULTIPLE_PSEUDO_FILES)
  1070.  extern CHARTYPE rexx_filename[10];
  1071.  extern CHARTYPE rexx_pathname[MAX_FILE_NAME+1];
  1072. #endif
  1073.  extern CHARTYPE *temp_cmd;
  1074.  extern bool CAPREXXOUTx;
  1075.  extern bool rexx_output;
  1076.  extern bool in_macro;
  1077. /*--------------------------- local data ------------------------------*/
  1078. #if defined(__EMX__) || defined(USE_REGINA)
  1079.  SHORT rexxrc=0;
  1080. #elif defined(USE_REXX6000)
  1081.  LONG rexxrc=0L;
  1082. #else
  1083.  USHORT rexxrc=0L;
  1084. #endif
  1085.  RXSTRING instore[2];
  1086.  RXSTRING retstr;
  1087.  CHAR retbuf[260];
  1088.  ULONG rc=0;
  1089.  LONG num_params=0L;
  1090.  RXSYSEXIT exit_list[2];                /* system exit list           */
  1091.  bool save_in_macro=in_macro;
  1092. /*--------------------------- processing ------------------------------*/
  1093. #ifdef TRACE
  1094.  trace_function("rexx.c:    execute_macro_instore");
  1095. #endif
  1096.  in_macro = TRUE;
  1097. /*---------------------------------------------------------------------*/
  1098. /* Set up pointer to REXX Exit Handler.                                */
  1099. /*---------------------------------------------------------------------*/
  1100. #if defined(USE_REXX6000)
  1101.  exit_list[0].sysexit_func = THE_Exit_Handler;
  1102. #else
  1103.  exit_list[0].sysexit_name = "THE_EXIT";
  1104. #endif
  1105.  exit_list[0].sysexit_code = RXSIO;
  1106.  exit_list[1].sysexit_code = RXENDLST;
  1107.  
  1108.  captured_lines = 0L;
  1109.  rexx_output = FALSE;
  1110.  rexx_halted = FALSE;
  1111.  instore[0].strptr = (RXSTRING_STRPTR_TYPE)commands;
  1112.  instore[0].strlength = strlen((DEFCHAR *)commands);
  1113.  instore[1].strptr = NULL;
  1114.  instore[1].strlength = 0;
  1115.  MAKERXSTRING(retstr,retbuf,sizeof(retbuf));
  1116. /*---------------------------------------------------------------------*/
  1117. /* Call the REXX interpreter.                                          */
  1118. /*---------------------------------------------------------------------*/
  1119.  rc = RexxStart((RS_ARG0_TYPE)num_params,
  1120.                 (RS_ARG1_TYPE)NULL,
  1121.                 (RS_ARG2_TYPE)"INSTORE",
  1122.                 (RS_ARG3_TYPE)instore,
  1123.                 (RS_ARG4_TYPE)"THE",
  1124.                 (RS_ARG5_TYPE)RXCOMMAND,
  1125.                 (RS_ARG6_TYPE)exit_list,
  1126.                 (RS_ARG7_TYPE)&rexxrc,
  1127.                 (RS_ARG8_TYPE)&retstr);
  1128.  if (instore[1].strptr)
  1129. #if defined(WIN32) && (defined(USE_OREXX) || defined(USE_WINREXX) || defined(USE_QUERCUS))
  1130.     GlobalFree( instore[1].strptr );
  1131. #elif defined(USE_OS2REXX)
  1132.     DosFreeMem(instore[1].strptr);
  1133. #else
  1134.     (*the_free)(instore[1].strptr);
  1135. #endif
  1136. /*---------------------------------------------------------------------*/
  1137. /* Edit the captured file or clean up after REXX output displays.      */
  1138. /*---------------------------------------------------------------------*/
  1139.  if (rexx_output)
  1140.    {
  1141.     rexx_output = FALSE;
  1142.     if (CAPREXXOUTx)
  1143.       {
  1144. #if defined(MULTIPLE_PSEUDO_FILES)
  1145.        Xedit((CHARTYPE *)"***REXXOUT***");
  1146. #else
  1147.        strcpy((DEFCHAR *)temp_cmd,(DEFCHAR *)rexx_pathname);
  1148.        strcat((DEFCHAR *)temp_cmd,(DEFCHAR *)rexx_filename);
  1149.        Xedit(temp_cmd);
  1150. #endif
  1151.       }
  1152.     else
  1153.       {
  1154.        if (batch_only)
  1155.           error_on_screen = TRUE;
  1156. #ifndef XCURSES
  1157.        else
  1158. /*---------------------------------------------------------------------*/
  1159. /* Pause for operator intervention and restore the screen to the       */
  1160. /* current screen if there are still file(s) in the ring.              */
  1161. /*---------------------------------------------------------------------*/
  1162.          {
  1163.           printf("\n%s",HIT_ANY_KEY);
  1164.           fflush(stdout);
  1165.           resume_curses();
  1166.           (void)my_getch(stdscr);
  1167.           if (number_of_files > 0)
  1168.             {
  1169. #if defined(HAVE_BROKEN_SYSVR4_CURSES)
  1170.              short x=0,y=0;
  1171.              getyx(CURRENT_WINDOW,y,x);
  1172.              force_curses_background();
  1173.              wmove(CURRENT_WINDOW,y,x);
  1174.              refresh();
  1175. #endif
  1176.              restore_THE();
  1177.             }
  1178.          }
  1179. #endif
  1180.       }
  1181.    }
  1182. #if defined(WIN32) && defined(HAVE_RESET_PROG_MODE)
  1183.  else
  1184.     reset_prog_mode();
  1185. #endif
  1186.  in_macro = save_in_macro;
  1187. #ifdef TRACE
  1188.  trace_return();
  1189. #endif
  1190.  *macrorc = (short)rexxrc;
  1191.  return((short)rc);
  1192. }
  1193.  
  1194. /***********************************************************************/
  1195. short get_rexx_variable
  1196. #if defined(HAVE_PROTO)
  1197.       (CHARTYPE *name,CHARTYPE **value,int *value_length)
  1198. #else
  1199.       (name,value,value_length)
  1200.        CHARTYPE *name;
  1201.        CHARTYPE **value;
  1202.        int *value_length;
  1203. #endif
  1204. /***********************************************************************/
  1205. {
  1206. /*-------------------------- external data ----------------------------*/
  1207. /*--------------------------- local data ------------------------------*/
  1208.  RXSTRING retstr;
  1209.  short rc=RC_OK;
  1210. /*--------------------------- processing ------------------------------*/
  1211. #ifdef TRACE
  1212.  trace_function("rexx.c:    get_rexx_variable");
  1213. #endif
  1214.  MAKERXSTRING(retstr,"",0);
  1215.  (void)get_compound_rexx_variable(name,&retstr,(-1));
  1216.  if (retstr.strptr == NULL)
  1217.     rc = RC_INVALID_ENVIRON;
  1218.  *value = (CHARTYPE*)retstr.strptr;
  1219.  *value_length = retstr.strlength;
  1220. #ifdef TRACE
  1221.  trace_return();
  1222. #endif
  1223.  return(rc);
  1224. }
  1225.  
  1226. /***********************************************************************/
  1227. short set_rexx_variable
  1228. #if defined(HAVE_PROTO)
  1229.       (CHARTYPE *name,CHARTYPE *value,short value_length,short suffix)
  1230. #else
  1231.       (name,value,value_length,suffix)
  1232.        CHARTYPE *name;
  1233.        CHARTYPE *value;
  1234.        short value_length;
  1235.        short suffix;
  1236. #endif
  1237. /***********************************************************************/
  1238. {
  1239. /*-------------------------- external data ----------------------------*/
  1240. /*--------------------------- local data ------------------------------*/
  1241.  SHVBLOCK shv;
  1242.  CHAR variable_name[250];
  1243.  short rc=0;
  1244. /*--------------------------- processing ------------------------------*/
  1245. #ifdef TRACE
  1246.  trace_function("rexx.c:    set_rexx_variable");
  1247. #endif
  1248.  
  1249.  shv.shvnext=NULL;                                   /* only one block */
  1250. #if defined(USE_REGINA)
  1251.  shv.shvcode=RXSHV_SYSET; /* for Regina (no direct set) use symbolic set */
  1252. #else
  1253.  shv.shvcode=RXSHV_SET;               /* ... for others use direct set */
  1254. #endif
  1255. /*---------------------------------------------------------------------*/
  1256. /* This calls the RexxVariablePool() function for each value. This is  */
  1257. /* not the most efficient way of doing this.                           */
  1258. /*---------------------------------------------------------------------*/
  1259.  if (suffix == (-1))
  1260.     strcpy(variable_name,(DEFCHAR*)name);
  1261.  else
  1262.     sprintf(variable_name,"%s.%-d",name,suffix);
  1263.  (void)make_upper((CHARTYPE *)variable_name);/* make variable name uppercase */
  1264. /*---------------------------------------------------------------------*/
  1265. /* Now (attempt to) set the REXX variable                              */
  1266. /* Add name/value to SHVBLOCK                                          */
  1267. /*---------------------------------------------------------------------*/
  1268.  MAKERXSTRING(shv.shvname, variable_name, strlen(variable_name));
  1269.  MAKERXSTRING(shv.shvvalue,(DEFCHAR *)value,value_length);
  1270. /*---------------------------------------------------------------------*/
  1271. /* One or both of these is needed, too <sigh>                          */
  1272. /*---------------------------------------------------------------------*/
  1273.  shv.shvnamelen=strlen(variable_name);
  1274.  shv.shvvaluelen=value_length;
  1275.  
  1276. #if defined(USE_OS2REXX) || defined(USE_REXX6000)
  1277.  rc=(short)RexxVariablePool(&shv);              /* Set the REXX variable */
  1278. #else
  1279.  rc = RexxVariablePool(&shv);                 /* Set the REXX variable */
  1280. /* rc = RXSHV_OK;*/
  1281. #endif
  1282.  if (rc != RXSHV_OK 
  1283.  &&  rc != RXSHV_NEWV)
  1284.    {
  1285.     display_error(25,(CHARTYPE *)"",FALSE);
  1286.     rc = RC_SYSTEM_ERROR;
  1287.    }
  1288.  else
  1289.     rc = RC_OK;
  1290. #ifdef TRACE
  1291.  trace_return();
  1292. #endif
  1293.  return(rc);
  1294. }
  1295. /***********************************************************************/
  1296. static RXSTRING *get_compound_rexx_variable
  1297. #if defined(HAVE_PROTO)
  1298.       (CHARTYPE *name,RXSTRING *value,short suffix)
  1299. #else
  1300.       (name,value,suffix)
  1301.        CHARTYPE *name;
  1302.        RXSTRING *value;
  1303.        short suffix;
  1304. #endif
  1305. /***********************************************************************/
  1306. {
  1307. /*-------------------------- external data ----------------------------*/
  1308. /*--------------------------- local data ------------------------------*/
  1309.  static SHVBLOCK shv;
  1310.  CHAR variable_name[250];
  1311.  short rc=0;
  1312. /*--------------------------- processing ------------------------------*/
  1313. #ifdef TRACE
  1314.  trace_function("rexx.c:    get_compound_rexx_variable");
  1315. #endif
  1316.  shv.shvnext=NULL;                                   /* only one block */
  1317. #if defined(USE_REGINA)
  1318.  shv.shvcode=RXSHV_SYFET; /* for Regina (no direct set) use symbolic set */
  1319. #else
  1320.  shv.shvcode=RXSHV_FETCH;             /* ... for others use direct set */
  1321. #endif
  1322. /*---------------------------------------------------------------------*/
  1323. /* This calls the RexxVariablePool() function for each value. This is  */
  1324. /* not the most efficient way of doing this.                           */
  1325. /*---------------------------------------------------------------------*/
  1326.  if (suffix == (-1))
  1327.     strcpy(variable_name,(DEFCHAR*)name);
  1328.  else
  1329.     sprintf(variable_name,"%s.%-d",name,suffix);
  1330.  (void)make_upper((CHARTYPE *)variable_name);/* make variable name uppercase */
  1331. /*---------------------------------------------------------------------*/
  1332. /* Now (attempt to) get the REXX variable                              */
  1333. /* Set shv.shvvalue to NULL to force interpreter to allocate memory.   */
  1334. /*---------------------------------------------------------------------*/
  1335.  MAKERXSTRING(shv.shvname, variable_name, strlen(variable_name));
  1336.  shv.shvvalue.strptr = NULL;
  1337.  shv.shvvalue.strlength = 0;
  1338. /*---------------------------------------------------------------------*/
  1339. /* One or both of these is needed, too <sigh>                          */
  1340. /*---------------------------------------------------------------------*/
  1341.  shv.shvnamelen=strlen(variable_name);
  1342.  shv.shvvaluelen=0;
  1343. #if defined(USE_OS2REXX) || defined(USE_REXX6000)
  1344.  rc=(short)RexxVariablePool(&shv);              /* Set the REXX variable */
  1345. #else
  1346.  rc = RexxVariablePool(&shv);                 /* Set the REXX variable */
  1347. #endif
  1348.  switch(rc)
  1349.    {
  1350.     case RXSHV_OK:
  1351. #ifdef USE_REXX6000
  1352.          value->strptr = (PUCHAR)(*the_malloc)((sizeof(char)*shv.shvvalue.strlength)+1);
  1353. #else
  1354.          value->strptr = (char *)(*the_malloc)((sizeof(char)*shv.shvvalue.strlength)+1);
  1355. #endif
  1356.          if (value->strptr != NULL)
  1357.            {
  1358.             value->strlength = shv.shvvalue.strlength;
  1359.             memcpy(value->strptr,shv.shvvalue.strptr,value->strlength);
  1360.             *(value->strptr+value->strlength) = '\0';
  1361.            }
  1362. #if defined(WIN32) && (defined(USE_OREXX) || defined(USE_WINREXX) || defined(USE_QUERCUS))
  1363.          GlobalFree( shv.shvvalue.strptr );
  1364. #elif defined(USE_OS2REXX)
  1365.          DosFreeMem( shv.shvvalue.strptr );
  1366. #else
  1367.          free( shv.shvvalue.strptr );
  1368. #endif
  1369.          break;
  1370.    case RXSHV_NEWV:
  1371. #ifdef USE_REXX6000
  1372.          value->strptr = (PUCHAR)(*the_malloc)((sizeof(char)*shv.shvname.strlength)+1);
  1373. #else
  1374.          value->strptr = (char *)(*the_malloc)((sizeof(char)*shv.shvname.strlength)+1);
  1375. #endif
  1376.          if (value->strptr != NULL)
  1377.            {
  1378.             value->strlength = shv.shvname.strlength;
  1379.             memcpy(value->strptr,shv.shvname.strptr,value->strlength);
  1380.             *(value->strptr+value->strlength) = '\0';
  1381.            }
  1382.          break;
  1383.    default:
  1384.          value->strptr = NULL;
  1385.          value->strlength = 0;
  1386.          break;
  1387.    }
  1388. #ifdef TRACE
  1389.  trace_return();
  1390. #endif
  1391.  return(value);
  1392. }
  1393. /***********************************************************************/
  1394. static short valid_target_function
  1395. #if defined(HAVE_PROTO)
  1396.       (ULONG Argc,RXSTRING Argv[])
  1397. #else
  1398.      (Argc,Argv)
  1399.       ULONG Argc;
  1400.       RXSTRING Argv[];
  1401. #endif
  1402. /***********************************************************************/
  1403. {
  1404. /*-------------------------- external data ----------------------------*/
  1405.  extern bool in_prefix_macro;
  1406.  extern LINETYPE prefix_current_line;
  1407.  extern VALUE item_values[MAX_VARIABLES_RETURNED];
  1408.  extern CHARTYPE *target_buffer;
  1409.  extern short target_buffer_len;
  1410. /*--------------------------- local data ------------------------------*/
  1411.  static TARGET target={NULL,0L,0L,0L,NULL,0,0,FALSE};
  1412.  short target_type=TARGET_NORMAL|TARGET_BLOCK_CURRENT|TARGET_ALL;
  1413.  LINETYPE true_line=0L;
  1414.  short rc=0;
  1415. /*--------------------------- processing ------------------------------*/
  1416. #ifdef TRACE
  1417.  trace_function("rexx.c:    valid_target_function");
  1418. #endif
  1419.  switch(1)
  1420.    {
  1421.     case 1:
  1422.          if (Argc < 1 || Argc > 2)  /* incorrect no of arguments - error */
  1423.            {
  1424.             item_values[1].value = (CHARTYPE *)"ERROR";
  1425.             item_values[1].len = 5;
  1426.             break;
  1427.            }
  1428.          if (Argc == 2)
  1429.             target_type = target_type | TARGET_SPARE;
  1430. /* allocate sufficient space for the spare string and 2 longs */
  1431.          if (target_buffer == NULL)
  1432.            {
  1433.             target_buffer = (CHARTYPE *)(*the_malloc)(sizeof(CHARTYPE)*(Argv[0].strlength+30));
  1434.             target_buffer_len = Argv[0].strlength+30;
  1435.            }
  1436.          else
  1437.            {
  1438.             if (target_buffer_len < Argv[0].strlength+30)
  1439.               {
  1440.                target_buffer = (CHARTYPE *)(*the_realloc)(target_buffer,sizeof(CHARTYPE)*(Argv[0].strlength+30));
  1441.                target_buffer_len = Argv[0].strlength+30;
  1442.               }
  1443.            }
  1444.          if (target_buffer == (CHARTYPE *)NULL)
  1445.            {
  1446.             item_values[1].value = (CHARTYPE *)"ERROR";
  1447.             item_values[1].len = 5;
  1448.             free_target(&target);
  1449.             break;
  1450.            }
  1451.          memcpy(target_buffer,Argv[0].strptr,Argv[0].strlength);
  1452.          *(target_buffer+Argv[0].strlength) = '\0';
  1453.          if (in_prefix_macro)
  1454.             true_line = prefix_current_line;
  1455.          else
  1456.             true_line = get_true_line(TRUE);
  1457.  
  1458.          initialise_target(&target);
  1459.          rc = validate_target(target_buffer,&target,target_type,true_line,FALSE,FALSE);
  1460.          if (rc == RC_TARGET_NOT_FOUND)
  1461.            {
  1462.             item_values[1].value = (CHARTYPE *)"NOTFOUND";
  1463.             item_values[1].len = 8;
  1464.             free_target(&target);
  1465.             break;
  1466.            }
  1467.          if (rc != RC_OK)
  1468.            {
  1469.             item_values[1].value = (CHARTYPE *)"ERROR";
  1470.             item_values[1].len = 5;
  1471.             free_target(&target);
  1472.             break;
  1473.            }
  1474.          if (Argc == 2
  1475.          &&  target.spare != (-1))
  1476.             sprintf((DEFCHAR *)target_buffer,"%ld %ld %s",target.true_line,target.num_lines,
  1477.                                         target.rt[target.spare].string);
  1478.          else
  1479.              sprintf((DEFCHAR *)target_buffer,"%ld %ld",target.true_line,target.num_lines);
  1480.          item_values[1].value = target_buffer;
  1481.          item_values[1].len = strlen((DEFCHAR *)target_buffer);
  1482.          free_target(&target);
  1483.          break;
  1484.    }
  1485.  item_values[0].value = (CHARTYPE *)"1";
  1486.  item_values[0].len = 1;
  1487. #ifdef TRACE
  1488.  trace_return();
  1489. #endif
  1490.  return(rc);
  1491. }
  1492. /***********************************************************************/
  1493. static short run_os_function
  1494. #if defined(HAVE_PROTO)
  1495.       (ULONG Argc,RXSTRING Argv[])
  1496. #else
  1497.      (Argc,Argv)
  1498.       ULONG Argc;
  1499.       RXSTRING Argv[];
  1500. #endif
  1501. /***********************************************************************/
  1502. {
  1503. /*-------------------------- external data ----------------------------*/
  1504.  extern VALUE item_values[MAX_VARIABLES_RETURNED];
  1505. /*--------------------------- local data ------------------------------*/
  1506.  int rc=0;
  1507.  static CHARTYPE num0[5];                  /* large enough for 1000+rc */
  1508.  CHARTYPE *cmd=NULL,*instem=NULL,*outstem=NULL,*errstem=NULL;
  1509. /*--------------------------- processing ------------------------------*/
  1510. #ifdef TRACE
  1511.  trace_function("rexx.c:    run_os_function");
  1512. #endif
  1513.  switch(Argc)
  1514.    {
  1515.     case 0:
  1516.          sprintf((DEFCHAR *)num0,"%d",RC_INVALID_OPERAND+1000);
  1517.          break;
  1518.     case 4:
  1519.          if ((errstem = (CHARTYPE *)MakeAscii(&Argv[3])) == NULL)
  1520.            {
  1521.             sprintf((DEFCHAR *)num0,"%d",RC_OUT_OF_MEMORY+1000);
  1522.             break;
  1523.            }
  1524.     case 3:
  1525.          if ((outstem = (CHARTYPE *)MakeAscii(&Argv[2])) == NULL)
  1526.            {
  1527.             sprintf((DEFCHAR *)num0,"%d",RC_OUT_OF_MEMORY+1000);
  1528.             break;
  1529.            }
  1530.     case 2:
  1531.          if ((instem = (CHARTYPE *)MakeAscii(&Argv[1])) == NULL)
  1532.            {
  1533.             sprintf((DEFCHAR *)num0,"%d",RC_OUT_OF_MEMORY+1000);
  1534.             break;
  1535.            }
  1536.     case 1:
  1537.          if ((cmd = (CHARTYPE *)MakeAscii(&Argv[0])) == NULL)
  1538.            {
  1539.             sprintf((DEFCHAR *)num0,"%d",RC_OUT_OF_MEMORY+1000);
  1540.             break;
  1541.            }
  1542.          rc = run_os_command(cmd,instem,outstem,errstem);
  1543.          sprintf((DEFCHAR *)num0,"%d",rc);
  1544.          break;
  1545.     default:
  1546.          sprintf((DEFCHAR *)num0,"%d",RC_INVALID_OPERAND+1000);
  1547.          break;
  1548.    }
  1549.  item_values[1].value = num0;
  1550.  item_values[1].len = strlen((DEFCHAR *)num0);
  1551.  item_values[0].value = (CHARTYPE *)"1";
  1552.  item_values[0].len = 1;
  1553.  if (cmd) (*the_free)(cmd);
  1554.  if (instem) (*the_free)(instem);
  1555.  if (outstem) (*the_free)(outstem);
  1556.  if (errstem) (*the_free)(errstem);
  1557. #ifdef TRACE
  1558.  trace_return();
  1559. #endif
  1560.  return(RC_OK);
  1561. }
  1562. /***********************************************************************/
  1563. static int run_os_command
  1564. #if defined(HAVE_PROTO)
  1565.       (CHARTYPE *cmd,CHARTYPE *instem,CHARTYPE *outstem,CHARTYPE *errstem)
  1566. #else
  1567.       (cmd,instem,outstem,errstem)
  1568.        CHARTYPE *cmd;
  1569.        CHARTYPE *instem;
  1570.        CHARTYPE *outstem;
  1571.        CHARTYPE *errstem;
  1572. #endif
  1573. /***********************************************************************/
  1574. {
  1575. /*-------------------------- external data ----------------------------*/
  1576. /*--------------------------- local data ------------------------------*/
  1577.  RXSTRING tmpstr;
  1578.  bool in=TRUE,out=TRUE,err=TRUE;
  1579.  bool out_and_err_same=FALSE;
  1580.  int inlen=0,outlen=0,errlen=0;
  1581.  int i=0;
  1582.  FILE *infp=NULL;
  1583.  char *infile="",*outfile="",*errfile="";
  1584.  long innum=0L;
  1585.  int rc=0,rcode=0;
  1586.  int save_stdin=0,save_stdout=0,save_stderr=0;
  1587.  int infd=0,outfd=0,errfd=0;
  1588. /*--------------------------- processing ------------------------------*/
  1589. #ifdef TRACE
  1590.  trace_function("rexx.c:    run_os_command");
  1591. #endif
  1592. /*---------------------------------------------------------------------*/
  1593. /* Determine if we are redirecting stdin, stdout or both and if the    */
  1594. /* values passed as stem variables end in '.'.                         */
  1595. /*---------------------------------------------------------------------*/
  1596.  if (instem == NULL
  1597.  ||  strcmp((DEFCHAR *)instem,"") == 0)
  1598.     in = FALSE;
  1599.  else
  1600.    {
  1601.     inlen = strlen((DEFCHAR *)instem);
  1602.     if (*(instem+inlen-1) == '.')
  1603.        *(instem+inlen-1) = '\0';
  1604.     else
  1605.       {
  1606. #ifdef TRACE
  1607.        trace_return();
  1608. #endif
  1609.        return(RC_INVALID_OPERAND+1000);
  1610.       }
  1611.    }
  1612.  if (outstem == NULL
  1613.  ||  strcmp((DEFCHAR *)outstem,"") == 0)
  1614.     out = FALSE;
  1615.  else
  1616.    {
  1617.     outlen = strlen((DEFCHAR *)outstem);
  1618.     if (*(outstem+outlen-1) == '.')
  1619.        *(outstem+outlen-1) = '\0';
  1620.     else
  1621.       {
  1622. #ifdef TRACE
  1623.        trace_return();
  1624. #endif
  1625.        return(RC_INVALID_OPERAND+1000);
  1626.       }
  1627.    }
  1628.  if (errstem == NULL
  1629.  ||  strcmp((DEFCHAR *)errstem,"") == 0)
  1630.     err = FALSE;
  1631.  else
  1632.    {
  1633.     errlen = strlen((DEFCHAR *)errstem);
  1634.     if (*(errstem+errlen-1) == '.')
  1635.        *(errstem+errlen-1) = '\0';
  1636.     else
  1637.       {
  1638. #ifdef TRACE
  1639.        trace_return();
  1640. #endif
  1641.        return(RC_INVALID_OPERAND+1000);
  1642.       }
  1643.    }
  1644. /*---------------------------------------------------------------------*/
  1645. /* Ensure that stdin stem is different to both stdout and stderr stems.*/
  1646. /*---------------------------------------------------------------------*/
  1647.  if (in)
  1648.    {
  1649.     if (out
  1650.     &&  strcmp((DEFCHAR *)instem,(DEFCHAR *)outstem) == 0)
  1651.       {
  1652. #ifdef TRACE
  1653.        trace_return();
  1654. #endif
  1655.        return(RC_INVALID_OPERAND+1000);
  1656.       }
  1657.     if (err
  1658.     &&  strcmp((DEFCHAR *)instem,(DEFCHAR *)errstem) == 0)
  1659.       {
  1660. #ifdef TRACE
  1661.        trace_return();
  1662. #endif
  1663.        return(RC_INVALID_OPERAND+1000);
  1664.       }
  1665.    }
  1666. /*---------------------------------------------------------------------*/
  1667. /* An extra check here to determine if stdout and stderr are to be     */
  1668. /* redirected to the same place.                                       */
  1669. /*---------------------------------------------------------------------*/
  1670.  if (out && err)
  1671.    {
  1672.     if (strcmp((DEFCHAR *)outstem,(DEFCHAR *)errstem)==0)
  1673.        out_and_err_same = TRUE;
  1674.    }
  1675. /*---------------------------------------------------------------------*/
  1676. /* If redirecting stdin, get the value of instem.0 to determine how    */
  1677. /* many variables to get...                                            */
  1678. /*---------------------------------------------------------------------*/
  1679.  if (in)
  1680.    {
  1681.     tmpstr.strptr = NULL;
  1682.     (void)get_compound_rexx_variable(instem,&tmpstr,0);
  1683.     if (tmpstr.strptr == NULL)
  1684.       {
  1685. #ifdef TRACE
  1686.        trace_return();
  1687. #endif
  1688.        return(RC_SYSTEM_ERROR+1000);
  1689.       }
  1690.     if (!valid_positive_integer((CHARTYPE *)tmpstr.strptr))
  1691.       {
  1692. #ifdef TRACE
  1693.        trace_return();
  1694. #endif
  1695.        return(RC_INVALID_OPERAND+1000);
  1696.       }
  1697.     innum = atol((DEFCHAR *)tmpstr.strptr);
  1698.     (*the_free)(tmpstr.strptr);
  1699. /*---------------------------------------------------------------------*/
  1700. /* Write the contents of the stdin stem to a temporary file...         */
  1701. /*---------------------------------------------------------------------*/
  1702.     infile = (char *)(*the_malloc)(L_tmpnam);
  1703.     if (infile == NULL)
  1704.       {
  1705. #ifdef TRACE
  1706.        trace_return();
  1707. #endif
  1708.        return(RC_OUT_OF_MEMORY+1000);
  1709.       }
  1710.     if ((infile = tmpnam(infile)) == NULL)
  1711.       {
  1712. #ifdef TRACE
  1713.        trace_return();
  1714. #endif
  1715.        return(RC_ACCESS_DENIED+1000);
  1716.       }
  1717. #if defined(GO32) || defined(__EMX__)
  1718. /*---------------------------------------------------------------------*/
  1719. /* For djgpp and emx convert all \ to / for internal file handling     */
  1720. /* functions.                                                          */
  1721. /*---------------------------------------------------------------------*/
  1722.     strrmdup(strtrans(infile,'\\','/'),'/');
  1723. #endif
  1724.     if ((infp = fopen(infile,"w")) == NULL)
  1725.       {
  1726. #ifdef TRACE
  1727.        trace_return();
  1728. #endif
  1729.        return(RC_ACCESS_DENIED+1000);
  1730.       }
  1731.     for (i=0;i<innum;i++)
  1732.       {
  1733.        tmpstr.strptr = NULL;
  1734.        (void)get_compound_rexx_variable(instem,&tmpstr,i+1);
  1735.        if (tmpstr.strptr == NULL)
  1736.          {
  1737. #ifdef TRACE
  1738.           trace_return();
  1739. #endif
  1740.           return(RC_SYSTEM_ERROR+1000);
  1741.          }
  1742.        fputs((DEFCHAR *)tmpstr.strptr,infp);
  1743.        fputs("\n",infp);
  1744.        (*the_free)(tmpstr.strptr);
  1745.       }
  1746.     if (fclose(infp))
  1747.       {
  1748. #ifdef TRACE
  1749.        trace_return();
  1750. #endif
  1751.        return(RC_ACCESS_DENIED+1000);
  1752.       }
  1753.    }
  1754. /*---------------------------------------------------------------------*/
  1755. /* If redirecting stdout, create the name of a temporary file for the  */
  1756. /* output.                                                             */
  1757. /*---------------------------------------------------------------------*/
  1758.  if (out)
  1759.    {
  1760.     outfile = (char *)(*the_malloc)(L_tmpnam);
  1761.     if (outfile == NULL)
  1762.       {
  1763. #ifdef TRACE
  1764.        trace_return();
  1765. #endif
  1766.        return(RC_OUT_OF_MEMORY+1000);
  1767.       }
  1768.     if ((outfile = tmpnam(outfile)) == NULL)
  1769.       {
  1770. #ifdef TRACE
  1771.        trace_return();
  1772. #endif
  1773.        return(RC_ACCESS_DENIED+1000);
  1774.       }
  1775.    }
  1776. /*---------------------------------------------------------------------*/
  1777. /* If redirecting stderr, create the name of a temporary file for the  */
  1778. /* output.                                                             */
  1779. /*---------------------------------------------------------------------*/
  1780.  if (err)
  1781.    {
  1782.     if (out_and_err_same)
  1783.       {
  1784.        errfile = outfile;
  1785.       }
  1786.     else
  1787.       {
  1788.        errfile = (char *)(*the_malloc)(L_tmpnam);
  1789.        if (errfile == NULL)
  1790.          {
  1791. #ifdef TRACE
  1792.           trace_return();
  1793. #endif
  1794.           return(RC_OUT_OF_MEMORY+1000);
  1795.          }
  1796.        if ((errfile = tmpnam(errfile)) == NULL)
  1797.          {
  1798. #ifdef TRACE
  1799.           trace_return();
  1800. #endif
  1801.           return(RC_ACCESS_DENIED+1000);
  1802.          }
  1803.       }
  1804.    }
  1805. /*---------------------------------------------------------------------*/
  1806. /* Save file ids for stdin, stdout and stderr, then reassign them to   */
  1807. /* the appropriate temporary files.                                    */
  1808. /*---------------------------------------------------------------------*/
  1809.  if (in) save_stdin = dup(fileno(stdin));
  1810.  if (out) save_stdout = dup(fileno(stdout));
  1811.  if (err) save_stderr = dup(fileno(stderr));
  1812.  if (in)
  1813.    {
  1814.     if ((infd = open(infile,O_RDONLY)) == (-1))
  1815.       {
  1816. #ifdef TRACE
  1817.        trace_return();
  1818. #endif
  1819.        return(RC_ACCESS_DENIED+1000);
  1820.       }
  1821.    }
  1822.  if (out)
  1823.    {
  1824. #if defined(UNIX)
  1825.     if ((outfd = open(outfile,O_RDWR|O_CREAT|O_TRUNC)) == (-1))
  1826. #else
  1827.     if ((outfd = open(outfile,O_RDWR|O_CREAT|O_TRUNC,S_IWRITE|S_IREAD)) == (-1))
  1828. #endif
  1829.       {
  1830. #ifdef TRACE
  1831.        trace_return();
  1832. #endif
  1833.        return(RC_ACCESS_DENIED+1000);
  1834.       }
  1835.    }
  1836.  if (out_and_err_same)
  1837.     errfd = outfd;
  1838.  else
  1839.    {
  1840.     if (err)
  1841.       {
  1842. #if defined(UNIX)
  1843.        if ((errfd = open(errfile,O_RDWR|O_CREAT|O_TRUNC)) == (-1))
  1844. #else
  1845.        if ((errfd = open(errfile,O_RDWR|O_CREAT|O_TRUNC,S_IWRITE|S_IREAD)) == (-1))
  1846. #endif
  1847.          {
  1848. #ifdef TRACE
  1849.           trace_return();
  1850. #endif
  1851.           return(RC_ACCESS_DENIED+1000);
  1852.          }
  1853.       }
  1854.    }
  1855. #if defined(UNIX)
  1856.   if (out)
  1857.      chmod(outfile,S_IWUSR|S_IRUSR);
  1858.   if (!out_and_err_same)
  1859.      if (err)
  1860.         chmod(errfile,S_IWUSR|S_IRUSR);
  1861. #endif
  1862.  if (in)  dup2(infd,fileno(stdin));
  1863.  if (out) dup2(outfd,fileno(stdout));
  1864.  if (err) dup2(errfd,fileno(stderr));
  1865.  if (in)  close(infd);
  1866.  if (out) close(outfd);
  1867.  if (!out_and_err_same)
  1868.     if (err) close(errfd);
  1869. /*---------------------------------------------------------------------*/
  1870. /* Execute the OS command supplied.                                    */
  1871. /*---------------------------------------------------------------------*/
  1872.  rcode = system((DEFCHAR *)cmd);
  1873. #if defined(HAVE_SYS_WAIT_H)
  1874.  if (rcode) rcode = WEXITSTATUS(rcode);
  1875. #endif
  1876. /*---------------------------------------------------------------------*/
  1877. /* Put all file ids back the way they were...                          */
  1878. /*---------------------------------------------------------------------*/
  1879.  if (in)  dup2(save_stdin,fileno(stdin));
  1880.  if (out) dup2(save_stdout,fileno(stdout));
  1881.  if (err) dup2(save_stderr,fileno(stderr));
  1882.  if (in)  close(save_stdin);
  1883.  if (out) close(save_stdout);
  1884.  if (err) close(save_stderr);
  1885. /*---------------------------------------------------------------------*/
  1886. /* If redirecting stdout, we now have to read the file and set a REXX  */
  1887. /* variable for each line read.                                        */
  1888. /*---------------------------------------------------------------------*/
  1889.  if (out)
  1890.     rc = set_rexx_variables_from_file(outfile,outstem);
  1891.  if (err)
  1892.    {
  1893.     if (!out_and_err_same)
  1894.        rc = set_rexx_variables_from_file(errfile,errstem);
  1895.    }
  1896. /*---------------------------------------------------------------------*/
  1897. /* Delete the temporary file(s) and free up any memory.                */
  1898. /*---------------------------------------------------------------------*/
  1899.  if (in)
  1900.    {
  1901.     unlink(infile);
  1902.     (*the_free)(infile);
  1903.    }
  1904.  if (out)
  1905.    {
  1906.     unlink(outfile);
  1907.     (*the_free)(outfile);
  1908.    }
  1909.  if (err)
  1910.    {
  1911.     if (!out_and_err_same)
  1912.       {
  1913.        unlink(errfile);
  1914.        (*the_free)(errfile);
  1915.       }
  1916.    }
  1917. /*---------------------------------------------------------------------*/
  1918. /* Return with, hopefully, return code from system() command.          */
  1919. /*---------------------------------------------------------------------*/
  1920. #ifdef TRACE
  1921.  trace_return();
  1922. #endif
  1923.  if (rc)
  1924.     return(rc+1000);
  1925.  else
  1926.     return(rcode);
  1927. }
  1928. /***********************************************************************/
  1929. static CHARTYPE *MakeAscii
  1930. #if defined(HAVE_PROTO)
  1931.       (RXSTRING *rxstring)
  1932. #else
  1933.      (rxstring)
  1934.       RXSTRING *rxstring;
  1935. #endif
  1936. /***********************************************************************/
  1937. {
  1938. /*-------------------------- external data ----------------------------*/
  1939. /*--------------------------- local data ------------------------------*/
  1940.  CHARTYPE *string=NULL;
  1941. /*--------------------------- processing ------------------------------*/
  1942. #ifdef TRACE
  1943.  trace_function("rexx.c:    MakeAscii");
  1944. #endif
  1945.  
  1946.  string = (CHARTYPE *)(*the_malloc)((sizeof(CHARTYPE)*rxstring->strlength)+1);
  1947.  if (string != NULL)
  1948.    {
  1949.     memcpy(string,rxstring->strptr,rxstring->strlength);
  1950.     *(string+(rxstring->strlength)) = '\0';
  1951.    }
  1952. #ifdef TRACE
  1953.  trace_return();
  1954. #endif
  1955.  return(string);
  1956. }
  1957. /***********************************************************************/
  1958. static char *get_a_line
  1959. #if defined(HAVE_PROTO)
  1960.       (FILE *fp,char *string,int *length,int *rcode)
  1961. #else
  1962.       (fp,string,length,rcode)
  1963.       FILE *fp;
  1964.       char *string;
  1965.       int *length;
  1966.       int *rcode;
  1967. #endif
  1968. /***********************************************************************/
  1969. {
  1970.  int ch;
  1971.  static int bufs = 1;
  1972.  register int i=0;
  1973. /*---------------------------------------------------------------------*/
  1974. /* Allocate the first block of memory.                                 */
  1975. /*---------------------------------------------------------------------*/
  1976.  if ((string = (char *)(*the_malloc)(BUF_SIZE+1)) == NULL)
  1977.    {
  1978.     *rcode = RC_OUT_OF_MEMORY;
  1979.     return(NULL);
  1980.    }
  1981.  while(1)
  1982.    {
  1983. /*---------------------------------------------------------------------*/
  1984. /* Read a character from the stream...                                 */
  1985. /*---------------------------------------------------------------------*/
  1986.     if ((ch = fgetc(fp)) == EOF)
  1987.       {
  1988. /*---------------------------------------------------------------------*/
  1989. /* If EOF is reached, check that it really is end of file.             */
  1990. /*---------------------------------------------------------------------*/
  1991.        if (feof(fp))
  1992.          {
  1993.           *length = i;
  1994.           *rcode = RC_TOF_EOF_REACHED;
  1995.           return(string);
  1996.          }
  1997.       }
  1998. /*---------------------------------------------------------------------*/
  1999. /* If end of line is reached, nul terminate string and return.         */
  2000. /*---------------------------------------------------------------------*/
  2001.     if ((char)ch == '\n')
  2002.       {
  2003.        *(string+i) = '\0';
  2004.        break;
  2005.       }
  2006. /*---------------------------------------------------------------------*/
  2007. /* All other characters, copy to string.                               */
  2008. /*---------------------------------------------------------------------*/
  2009.     *(string+i++) = (char)ch;
  2010. /*---------------------------------------------------------------------*/
  2011. /* If we have got to the end of the allocated memory, realloc some more*/
  2012. /*---------------------------------------------------------------------*/
  2013.     if (i == BUF_SIZE*bufs)
  2014.       {
  2015.        if ((string = (char *)realloc(string,(BUF_SIZE*(++bufs))+1)) == NULL)
  2016.          {
  2017.           *rcode = RC_OUT_OF_MEMORY;
  2018.           return(NULL);
  2019.          }
  2020.       }
  2021.    }
  2022. /*---------------------------------------------------------------------*/
  2023. /* Return a line read from the temporary file.                         */
  2024. /*---------------------------------------------------------------------*/
  2025.  *length = i;
  2026.  *rcode = 0;
  2027.  return(string);
  2028. }
  2029. /***********************************************************************/
  2030. static short set_rexx_variables_from_file
  2031. #if defined(HAVE_PROTO)
  2032.       (char *filename,CHARTYPE *stem)
  2033. #else
  2034.       (filename,stem)
  2035.        char *filename;
  2036.        CHARTYPE *stem;
  2037. #endif
  2038. /***********************************************************************/
  2039. {
  2040. /*-------------------------- external data ----------------------------*/
  2041. /*--------------------------- local data ------------------------------*/
  2042.  FILE *fp=NULL;
  2043.  register int i=0;
  2044.  char *string=NULL;
  2045.  int length=0,rcode=0,rc=0;
  2046.  char tmpnum[10];
  2047. /*--------------------------- processing ------------------------------*/
  2048. #ifdef TRACE
  2049.  trace_function("rexx.c:    set_rexx_variables_from_file");
  2050. #endif
  2051.  if ((fp = fopen(filename,"r")) == NULL)
  2052.    {
  2053. #ifdef TRACE
  2054.     trace_return();
  2055. #endif
  2056.     return(RC_ACCESS_DENIED);
  2057.    }
  2058.  for (i=0;;i++)
  2059.    {
  2060.     string = get_a_line(fp,string,&length,&rcode);
  2061.     if (rcode == RC_OUT_OF_MEMORY)
  2062.       {
  2063. #ifdef TRACE
  2064.        trace_return();
  2065. #endif
  2066.        return(rcode);
  2067.       }
  2068.     if (rcode == RC_TOF_EOF_REACHED
  2069.     && length == 0)
  2070.       {
  2071.        (*the_free)(string);
  2072.        break;
  2073.       }
  2074.     rc = set_rexx_variable(stem,(CHARTYPE *)string,strlen(string),i+1);
  2075.     (*the_free)(string);
  2076.     if (rcode == RC_TOF_EOF_REACHED)
  2077.        break;
  2078.    }
  2079.  sprintf(tmpnum,"%d",i);
  2080.  rc = set_rexx_variable(stem,(CHARTYPE *)tmpnum,strlen(tmpnum),0);
  2081.  if (fclose(fp))
  2082.     rc = RC_ACCESS_DENIED;
  2083. #ifdef TRACE
  2084.  trace_return();
  2085. #endif
  2086.  return(rc);
  2087. }
  2088. #else
  2089. /*---------------------------------------------------------------------*/
  2090. /* The following are dummy routines to enable the compliation of THE   */
  2091. /* with a nonANSI compiler.                                            */
  2092. /*---------------------------------------------------------------------*/
  2093. /***********************************************************************/
  2094. short initialise_rexx
  2095. #if defined(HAVE_PROTO)
  2096.       (void)
  2097. #else
  2098.       ()
  2099. #endif
  2100. /***********************************************************************/
  2101. {
  2102.  return(RC_INVALID_ENVIRON);                        /* force an error */
  2103. }
  2104. /***********************************************************************/
  2105. short finalise_rexx
  2106. #if defined(HAVE_PROTO)
  2107.       (void)
  2108. #else
  2109.       ()
  2110. #endif
  2111. /***********************************************************************/
  2112. {
  2113.  return(RC_OK);
  2114. }
  2115. /***********************************************************************/
  2116. short execute_macro_file
  2117. #if defined(HAVE_PROTO)
  2118.       (CHARTYPE *filename,CHARTYPE *params,short *macrorc)
  2119. #else
  2120.       (filename,params,macrorc)
  2121.       CHARTYPE *filename;
  2122.       CHARTYPE *params;
  2123.       short *macrorc;
  2124. #endif
  2125. /***********************************************************************/
  2126. {
  2127.  return(RC_OK);
  2128. }
  2129. /***********************************************************************/
  2130. short execute_macro_instore
  2131. #if defined(HAVE_PROTO)
  2132.       (CHARTYPE *commands,short *macrorc)
  2133. #else
  2134.       (commands,macrorc)
  2135.       CHARTYPE *commands;
  2136.       short *macrorc;
  2137. #endif
  2138. /***********************************************************************/
  2139. {
  2140.  return(RC_OK);
  2141. }
  2142. /***********************************************************************/
  2143. short set_rexx_variable
  2144. #if defined(HAVE_PROTO)
  2145.       (CHARTYPE *name,CHARTYPE *value,short value_length,short suffix)
  2146. #else
  2147.       (name,value,value_length,suffix)
  2148.       CHARTYPE *name;
  2149.       CHARTYPE *value;
  2150.       short value_length;
  2151.       short suffix;
  2152. #endif
  2153. /***********************************************************************/
  2154. {
  2155.  return(RC_OK);
  2156. }
  2157.  
  2158. /***********************************************************************/
  2159. short get_rexx_variable
  2160. #if defined(HAVE_PROTO)
  2161.       (CHARTYPE *name,CHARTYPE **value,int *value_length)
  2162. #else
  2163.       (name,value,value_length)
  2164.        CHARTYPE *name;
  2165.        CHARTYPE **value;
  2166.        int *value_length;
  2167. #endif
  2168. /***********************************************************************/
  2169. {
  2170.  return(RC_OK);
  2171. }
  2172. #endif
  2173.