1 /*
2  *  Copyright (C) 2004  Mark Hessling   <M.Hessling@qut.com.au>
3  *
4  *  This library is free software; you can redistribute it and/or
5  *  modify it under the terms of the GNU Library General Public
6  *  License as published by the Free Software Foundation; either
7  *  version 2 of the License, or (at your option) any later version.
8  *
9  *  This library is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Library General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Library General Public
15  *  License along with this library; if not, write to the Free
16  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18 
19 /*
20  * $Id: rexxapi.c,v 1.3 2005/09/01 10:23:31 mark Exp $
21  */
22 #if defined(HAVE_CONFIG_H)
23 # include "config.h"
24 #endif
25 #include "configur.h"
26 
27 #include <stdio.h>
28 
29 #define INCL_REXXSAA
30 
31 #if defined(OS2)
32 # define INCL_DOSMODULEMGR
33 # define INCL_DOSMISC
34 # undef INCL_REXXSAA
35 # include <os2.h>
36 # define INCL_REXXSAA
37 # define DONT_TYPEDEF_PFN
38 # define DYNAMIC_OS2
39 #endif
40 
41 #if defined(HAVE_ERRNO_H)
42 # include <errno.h>
43 #endif
44 
45 #if defined(HAVE_MEMORY_H)
46 # include <memory.h>
47 #endif
48 
49 #if defined(HAVE_STDARG_H)
50 # include <stdarg.h>
51 #endif
52 
53 #if defined(HAVE_STDLIB_H)
54 # include <stdlib.h>
55 #endif
56 
57 #undef __USE_BSD
58 #if defined(HAVE_STRING_H)
59 # include <string.h>
60 #endif
61 
62 #if defined(HAVE_SYS_TYPES_H)
63 # include <sys/types.h>
64 #endif
65 
66 #if defined(HAVE_SYS_STAT_H)
67 # include <sys/stat.h>
68 #endif
69 
70 #if defined(HAVE_UNISTD_H)
71 # include <unistd.h>
72 #endif
73 
74 #include "rexxsaa.h"
75 
76 typedef HMODULE handle_type ;
77 
78 #define FUNCTION_REXXREGISTEREXITEXE           0
79 #define FUNCTION_REXXREGISTEREXITDLL           1
80 #define FUNCTION_REXXDEREGISTEREXIT            2
81 #define FUNCTION_REXXQUERYEXIT                 3
82 #define FUNCTION_REXXREGISTERSUBCOMEXE         4
83 #define FUNCTION_REXXDEREGISTERSUBCOM          5
84 #define FUNCTION_REXXREGISTERSUBCOMDLL         6
85 #define FUNCTION_REXXQUERYSUBCOM               7
86 #define FUNCTION_REXXREGISTERFUNCTIONEXE       8
87 #define FUNCTION_REXXREGISTERFUNCTIONDLL       9
88 #define FUNCTION_REXXDEREGISTERFUNCTION       10
89 #define FUNCTION_REXXQUERYFUNCTION            11
90 #define FUNCTION_REXXCREATEQUEUE              12
91 #define FUNCTION_REXXDELETEQUEUE              13
92 #define FUNCTION_REXXADDQUEUE                 14
93 #define FUNCTION_REXXPULLQUEUE                15
94 #define FUNCTION_REXXQUERYQUEUE               16
95 #define FUNCTION_REXXADDMACRO                 17
96 #define FUNCTION_REXXDROPMACRO                18
97 #define FUNCTION_REXXSAVEMACROSPACE           19
98 #define FUNCTION_REXXLOADMACROSPACE           20
99 #define FUNCTION_REXXQUERYMACRO               21
100 #define FUNCTION_REXXREORDERMACRO             22
101 #define FUNCTION_REXXCLEARMACROSPACE          23
102 
103 #define NUM_REXX_FUNCTIONS                    24
104 
105 static char *MyFunctionName[ NUM_REXX_FUNCTIONS ] =
106 {
107    /*  0 */  "RexxRegisterExitExe",
108    /*  1 */  "RexxRegisterExitDll",
109    /*  2 */  "RexxDeregisterExit",
110    /*  3 */  "RexxQueryExit",
111    /*  4 */  "RexxRegisterSubcomExe",
112    /*  5 */  "RexxDeregisterSubcom",
113    /*  6 */  "RexxRegisterSubcomDll",
114    /*  7 */  "RexxQuerySubcom",
115    /*  8 */  "RexxRegisterFunctionExe",
116    /*  9 */  "RexxRegisterFunctionDll",
117    /* 10 */  "RexxDeregisterFunction",
118    /* 11 */  "RexxQueryFunction",
119    /* 12 */  "RexxCreateQueue",
120    /* 13 */  "RexxDeleteQueue",
121    /* 14 */  "RexxQueryQueue",
122    /* 15 */  "RexxAddQueue",
123    /* 16 */  "RexxPullQueue",
124    /* 17 */  "RexxAddMacro",
125    /* 18 */  "RexxDropMacro",
126    /* 19 */  "RexxSaveMacroSpace",
127    /* 20 */  "RexxLoadMacroSpace",
128    /* 21 */  "RexxQueryMacro",
129    /* 22 */  "RexxReorderMacro",
130    /* 23 */  "RexxClearMacroSpace",
131 };
132 
133 /*
134  * Typedefs for Regina
135  */
136 typedef APIRET APIENTRY OREXXREGISTEREXITEXE(PSZ,PFN,PUCHAR ) ;
137 typedef APIRET APIENTRY OREXXREGISTEREXITDLL(PSZ,PSZ,PSZ,PUCHAR,ULONG ) ;
138 typedef APIRET APIENTRY OREXXDEREGISTEREXIT(PSZ,PSZ ) ;
139 typedef APIRET APIENTRY OREXXQUERYEXIT(PSZ,PSZ,PUSHORT,PUCHAR ) ;
140 typedef APIRET APIENTRY OREXXREGISTERSUBCOMEXE(PSZ,PFN,PUCHAR ) ;
141 typedef APIRET APIENTRY OREXXDEREGISTERSUBCOM(PSZ,PSZ ) ;
142 typedef APIRET APIENTRY OREXXREGISTERSUBCOMDLL(PSZ,PSZ,PSZ,PUCHAR,ULONG ) ;
143 typedef APIRET APIENTRY OREXXQUERYSUBCOM(PSZ,PSZ,PUSHORT,PUCHAR ) ;
144 typedef APIRET APIENTRY OREXXREGISTERFUNCTIONEXE(PSZ,PFN ) ;
145 typedef APIRET APIENTRY OREXXREGISTERFUNCTIONDLL(PSZ,PSZ,PSZ ) ;
146 typedef APIRET APIENTRY OREXXDEREGISTERFUNCTION(PSZ) ;
147 typedef APIRET APIENTRY OREXXQUERYFUNCTION(PSZ) ;
148 typedef APIRET APIENTRY OREXXCREATEQUEUE(PSZ,ULONG,PSZ,ULONG* ) ;
149 typedef APIRET APIENTRY OREXXDELETEQUEUE(PSZ ) ;
150 typedef APIRET APIENTRY OREXXQUERYQUEUE(PSZ,ULONG* ) ;
151 typedef APIRET APIENTRY OREXXADDQUEUE( PSZ,PRXSTRING,ULONG ) ;
152 typedef APIRET APIENTRY OREXXPULLQUEUE(PSZ,PRXSTRING,PDATETIME,ULONG );
153 typedef APIRET APIENTRY OREXXADDMACRO(PSZ,PSZ,ULONG );
154 typedef APIRET APIENTRY OREXXDROPMACRO(PSZ );
155 typedef APIRET APIENTRY OREXXSAVEMACROSPACE(ULONG,PSZ *,PSZ);
156 typedef APIRET APIENTRY OREXXLOADMACROSPACE(ULONG ,PSZ *,PSZ);
157 typedef APIRET APIENTRY OREXXQUERYMACRO(PSZ,PUSHORT );
158 typedef APIRET APIENTRY OREXXREORDERMACRO(PSZ,ULONG );
159 typedef APIRET APIENTRY OREXXCLEARMACROSPACE(VOID );
160 OREXXREGISTEREXITEXE     *ORexxRegisterExitExe=NULL;
161 OREXXREGISTEREXITDLL     *ORexxRegisterExitDll=NULL;
162 OREXXDEREGISTEREXIT      *ORexxDeregisterExit=NULL;
163 OREXXQUERYEXIT           *ORexxQueryExit=NULL;
164 OREXXREGISTERSUBCOMEXE   *ORexxRegisterSubcomExe=NULL;
165 OREXXDEREGISTERSUBCOM    *ORexxDeregisterSubcom=NULL;
166 OREXXREGISTERSUBCOMDLL   *ORexxRegisterSubcomDll=NULL;
167 OREXXQUERYSUBCOM         *ORexxQuerySubcom=NULL;
168 OREXXREGISTERFUNCTIONEXE *ORexxRegisterFunctionExe=NULL;
169 OREXXREGISTERFUNCTIONDLL *ORexxRegisterFunctionDll=NULL;
170 OREXXDEREGISTERFUNCTION  *ORexxDeregisterFunction=NULL;
171 OREXXQUERYFUNCTION       *ORexxQueryFunction=NULL;
172 OREXXCREATEQUEUE         *ORexxCreateQueue=NULL;
173 OREXXDELETEQUEUE         *ORexxDeleteQueue=NULL;
174 OREXXQUERYQUEUE          *ORexxQueryQueue=NULL;
175 OREXXADDQUEUE            *ORexxAddQueue=NULL;
176 OREXXPULLQUEUE           *ORexxPullQueue=NULL;
177 OREXXADDMACRO            *ORexxAddMacro=NULL;
178 OREXXDROPMACRO           *ORexxDropMacro=NULL;
179 OREXXSAVEMACROSPACE      *ORexxSaveMacroSpace=NULL;
180 OREXXLOADMACROSPACE      *ORexxLoadMacroSpace=NULL;
181 OREXXQUERYMACRO          *ORexxQueryMacro=NULL;
182 OREXXREORDERMACRO        *ORexxReorderMacro=NULL;
183 OREXXCLEARMACROSPACE     *ORexxClearMacroSpace=NULL;
184 
185 static char TraceFileName[256];
186 static int Trace = 0;
187 static int InterpreterIdx = -1;
188 
TraceString(char * fmt,...)189 static void TraceString( char *fmt, ... )
190 {
191    FILE *fp=NULL;
192    int using_stderr = 0;
193    va_list argptr;
194 
195    if ( strcmp( TraceFileName, "stderr" ) == 0 )
196       using_stderr = 1;
197    if ( using_stderr )
198       fp = stderr;
199    else
200       fp = fopen( TraceFileName, "a" );
201    if ( fp )
202    {
203       va_start( argptr, fmt );
204       vfprintf( fp, fmt, argptr );
205       va_end( argptr );
206       if ( !using_stderr )
207          fclose( fp );
208    }
209 }
210 
FindInterpreter(char * library)211 static handle_type FindInterpreter( char *library )
212 {
213    handle_type handle=(handle_type)NULL ;
214    CHAR LoadError[256];
215    PFN addr;
216    register int j=0;
217 
218    if ( Trace )
219    {
220       TraceString( "%s: Attempting to load \"%s\" using DosLoadModule()...",
221                    "FindInterpreter()",
222                    "REGINA");
223    }
224    if ( DosLoadModule( LoadError, sizeof(LoadError), library, &handle ) )
225    {
226       handle = (handle_type)NULL;
227    }
228    if ( handle != (handle_type)NULL )
229    {
230       if ( Trace )
231       {
232          TraceString( "found REGINA\n" );
233       }
234       for ( j = 0; j < NUM_REXX_FUNCTIONS; j++ )
235       {
236          if ( DosQueryProcAddr( handle, 0L, MyFunctionName[j], &addr) )
237          {
238             addr = NULL;
239          }
240          /*
241           * Log the function and address. This is useful if the module
242           * doesn't have an address for this procedure.
243           */
244          if (Trace)
245          {
246             TraceString( "%s: Address %x\n",
247                MyFunctionName[j],
248                (addr == NULL) ? 0 : addr );
249          }
250          /*
251           * Even if the function being processed is not in the module, its
252           * address is still stored.  In this case it will simply be set
253           * again to NULL.
254           */
255          switch ( j )
256          {
257             case FUNCTION_REXXREGISTERFUNCTIONEXE:  ORexxRegisterFunctionExe =   (OREXXREGISTERFUNCTIONEXE  *)addr; break;
258             case FUNCTION_REXXREGISTERFUNCTIONDLL:  ORexxRegisterFunctionDll =   (OREXXREGISTERFUNCTIONDLL  *)addr; break;
259             case FUNCTION_REXXDEREGISTERFUNCTION:   ORexxDeregisterFunction =    (OREXXDEREGISTERFUNCTION   *)addr; break;
260             case FUNCTION_REXXREGISTEREXITEXE:      ORexxRegisterExitExe =       (OREXXREGISTEREXITEXE      *)addr; break;
261             case FUNCTION_REXXREGISTEREXITDLL:      ORexxRegisterExitDll =       (OREXXREGISTEREXITDLL      *)addr; break;
262             case FUNCTION_REXXDEREGISTEREXIT:       ORexxDeregisterExit =        (OREXXDEREGISTEREXIT       *)addr; break;
263             case FUNCTION_REXXQUERYEXIT:            ORexxQueryExit =             (OREXXQUERYEXIT            *)addr; break;
264             case FUNCTION_REXXREGISTERSUBCOMEXE:    ORexxRegisterSubcomExe =     (OREXXREGISTERSUBCOMEXE    *)addr; break;
265             case FUNCTION_REXXDEREGISTERSUBCOM:     ORexxDeregisterSubcom =      (OREXXDEREGISTERSUBCOM     *)addr; break;
266             case FUNCTION_REXXREGISTERSUBCOMDLL:    ORexxRegisterSubcomDll =     (OREXXREGISTERSUBCOMDLL    *)addr; break;
267             case FUNCTION_REXXQUERYSUBCOM:          ORexxQuerySubcom =           (OREXXQUERYSUBCOM          *)addr; break;
268             case FUNCTION_REXXQUERYFUNCTION:        ORexxQueryFunction =         (OREXXQUERYFUNCTION        *)addr; break;
269             case FUNCTION_REXXCREATEQUEUE:          ORexxCreateQueue=            (OREXXCREATEQUEUE          *)addr; break;
270             case FUNCTION_REXXDELETEQUEUE:          ORexxDeleteQueue=            (OREXXDELETEQUEUE          *)addr; break;
271             case FUNCTION_REXXQUERYQUEUE:           ORexxQueryQueue=             (OREXXQUERYQUEUE           *)addr; break;
272             case FUNCTION_REXXADDQUEUE:             ORexxAddQueue=               (OREXXADDQUEUE             *)addr; break;
273             case FUNCTION_REXXPULLQUEUE:            ORexxPullQueue=              (OREXXPULLQUEUE            *)addr; break;
274             case FUNCTION_REXXADDMACRO:             ORexxAddMacro=               (OREXXADDMACRO             *)addr; break;
275             case FUNCTION_REXXDROPMACRO:            ORexxDropMacro=              (OREXXDROPMACRO            *)addr; break;
276             case FUNCTION_REXXSAVEMACROSPACE:       ORexxSaveMacroSpace=         (OREXXSAVEMACROSPACE       *)addr; break;
277             case FUNCTION_REXXLOADMACROSPACE:       ORexxLoadMacroSpace=         (OREXXLOADMACROSPACE       *)addr; break;
278             case FUNCTION_REXXQUERYMACRO:           ORexxQueryMacro=             (OREXXQUERYMACRO           *)addr; break;
279             case FUNCTION_REXXREORDERMACRO:         ORexxReorderMacro=           (OREXXREORDERMACRO         *)addr; break;
280             case FUNCTION_REXXCLEARMACROSPACE:      ORexxClearMacroSpace=        (OREXXCLEARMACROSPACE      *)addr; break;
281          }
282       }
283    }
284    else
285    {
286       if ( Trace )
287       {
288          TraceString( "not found: %s\n", LoadError );
289       }
290    }
291    return handle;
292 }
293 
LoadInterpreter(void)294 static void LoadInterpreter( void )
295 {
296    handle_type handle=(handle_type)NULL ;
297    char *ptr;
298 
299    if ( DosScanEnv( "REXXAPI_TRACEFILE", (PSZ *)&ptr ) )
300       ptr = NULL;
301    if ( ptr != NULL )
302    {
303       Trace = 1;
304       strcpy( TraceFileName, ptr );
305    }
306 
307    handle = (handle_type)FindInterpreter( "REGINA" );
308    if ( handle == (handle_type)NULL )
309    {
310       fprintf( stderr, "Could not find Regina DLL. Cannot continue.\n" );
311       exit( 11 );
312    }
313    if ( Trace )
314    {
315       TraceString( "----------- Initialisation Complete - Program Execution Begins -----------\n" );
316    }
317    InterpreterIdx = 0;
318    return;
319 }
320 
321 
322 /*
323  * System Exit functions
324  */
RexxRegisterExitExe(PCSZ EnvName,RexxExitHandler * EntryPoint,PUCHAR UserArea)325 APIRET APIENTRY RexxRegisterExitExe(
326    PCSZ EnvName,
327    RexxExitHandler *EntryPoint,
328    PUCHAR UserArea )
329 {
330    APIRET rc=RXEXIT_NOTREG;
331 
332    if ( InterpreterIdx == -1 )
333       LoadInterpreter();
334 
335    if (Trace)
336    {
337       TraceString( "%s: EnvName \"%s\" EntryPoint %x UserArea %x ",
338          "RexxRegisterExitExe()",
339          EnvName,
340          EntryPoint,
341          UserArea );
342    }
343    if (ORexxRegisterExitExe)
344    {
345       rc = (*ORexxRegisterExitExe)(
346          (PSZ)       EnvName,
347          (PFN)       EntryPoint,
348          (PUCHAR)    UserArea );
349    }
350    if ( Trace )
351    {
352       TraceString( "<=> Result: %d\n", rc );
353    }
354    return rc;
355 }
356 
RexxRegisterExitDll(PCSZ EnvName,PCSZ ModuleName,PCSZ ProcedureName,PUCHAR UserArea,ULONG DropAuth)357 APIRET APIENTRY RexxRegisterExitDll(
358    PCSZ EnvName,
359    PCSZ ModuleName,
360    PCSZ ProcedureName,
361    PUCHAR UserArea,
362    ULONG DropAuth )
363 {
364    APIRET rc=RXEXIT_NOTREG;
365 
366    if ( InterpreterIdx == -1 )
367       LoadInterpreter();
368 
369    if (Trace)
370    {
371       TraceString( "%s: EnvName \"%s\" ModuleName \"%s\" ProcedureName \"%s\" UserArea %x DropAuth %d ",
372          "RexxRegisterExitDll()",
373          EnvName,
374          ModuleName,
375          ProcedureName,
376          UserArea,
377          DropAuth );
378    }
379    if (ORexxRegisterExitDll)
380    {
381       rc = (*ORexxRegisterExitDll)(
382          (PSZ)       EnvName,
383          (PSZ)       ModuleName,
384          (PSZ)       ProcedureName,
385          (PUCHAR)    UserArea,
386          (ULONG)     DropAuth );
387    }
388    if ( Trace )
389    {
390       TraceString( "<=> Result: %d\n", rc );
391    }
392    return rc;
393 }
394 
RexxDeregisterExit(PCSZ EnvName,PCSZ ModuleName)395 APIRET APIENTRY RexxDeregisterExit(
396    PCSZ EnvName,
397    PCSZ ModuleName )
398 {
399    APIRET rc=RXEXIT_NOTREG;
400 
401    if ( InterpreterIdx == -1 )
402       LoadInterpreter();
403 
404    if (Trace)
405    {
406       TraceString( "%s: EnvName \"%s\" ModuleName \"%s\" ",
407          "RexxDeregisterExit()",
408          EnvName,
409          (ModuleName == NULL) ? "NULL" : ModuleName );
410    }
411    if (ORexxDeregisterExit)
412    {
413       rc = (*ORexxDeregisterExit)(
414          (PSZ)       EnvName,
415          (PSZ)       ModuleName );
416    }
417    if ( Trace )
418    {
419       TraceString( "<=> Result: %d\n", rc );
420    }
421    return rc;
422 }
423 
RexxQueryExit(PCSZ EnvName,PCSZ ModuleName,PUSHORT Flag,PUCHAR UserArea)424 APIRET APIENTRY RexxQueryExit(
425    PCSZ EnvName,
426    PCSZ ModuleName,
427    PUSHORT Flag,
428    PUCHAR UserArea )
429 {
430    APIRET rc=RXEXIT_NOTREG;
431 
432    if ( InterpreterIdx == -1 )
433       LoadInterpreter();
434 
435    if (Trace)
436    {
437       TraceString( "%s: EnvName \"%s\" ModuleName \"%s\" Flag %d UserArea %x ",
438          "RexxQueryExit()",
439          EnvName,
440          ModuleName,
441          Flag,
442          UserArea );
443    }
444    if (ORexxQueryExit)
445    {
446       rc = (*ORexxQueryExit)(
447          (PSZ)       EnvName,
448          (PSZ)       ModuleName,
449          (PUSHORT)   Flag,
450          (PUCHAR)    UserArea ) ;
451    }
452    if ( Trace )
453    {
454       TraceString( "<=> Result: %d\n", rc );
455    }
456    return rc;
457 }
458 
459 /*
460  * Subcommands
461  */
RexxRegisterSubcomExe(PCSZ EnvName,RexxSubcomHandler * EntryPoint,PUCHAR UserArea)462 APIRET APIENTRY RexxRegisterSubcomExe(
463    PCSZ EnvName,
464    RexxSubcomHandler *EntryPoint,
465    PUCHAR UserArea )
466 {
467    APIRET rc=RXSUBCOM_NOTREG;
468 
469    if ( InterpreterIdx == -1 )
470       LoadInterpreter();
471 
472    if (Trace)
473    {
474       TraceString( "%s: EnvName \"%s\" EntryPoint %x UserArea %x ",
475          "RexxRegisterSubcomExe()",
476          EnvName,
477          EntryPoint,
478          UserArea );
479    }
480    if (ORexxRegisterSubcomExe)
481    {
482       rc = (*ORexxRegisterSubcomExe)(
483          (PSZ)       EnvName,
484          (PFN)       EntryPoint,
485          (PUCHAR)    UserArea );
486    }
487    if ( Trace )
488    {
489       TraceString( "<=> Result: %d\n", rc );
490    }
491    return rc;
492 }
493 
RexxDeregisterSubcom(PCSZ EnvName,PCSZ ModuleName)494 APIRET APIENTRY RexxDeregisterSubcom(
495    PCSZ EnvName,
496    PCSZ ModuleName )
497 {
498    APIRET rc=RXSUBCOM_NOTREG;
499 
500    if ( InterpreterIdx == -1 )
501       LoadInterpreter();
502 
503    if (Trace)
504    {
505       TraceString( "%s: EnvName \"%s\" ModuleName \"%s\" ",
506          "RexxDeregisterSubcom()",
507          EnvName,
508          (ModuleName == NULL) ? "NULL" : ModuleName );
509    }
510    if (ORexxDeregisterSubcom)
511    {
512       rc = (*ORexxDeregisterSubcom)(
513          (PSZ)       EnvName,
514          (PSZ)       ModuleName );
515    }
516    if ( Trace )
517    {
518       TraceString( "<=> Result: %d\n", rc );
519    }
520    return rc;
521 }
522 
RexxRegisterSubcomDll(PCSZ EnvName,PCSZ ModuleName,PCSZ ProcedureName,PUCHAR UserArea,ULONG DropAuth)523 APIRET APIENTRY RexxRegisterSubcomDll(
524    PCSZ EnvName,
525    PCSZ ModuleName,
526    PCSZ ProcedureName,
527    PUCHAR UserArea,
528    ULONG DropAuth )
529 {
530    APIRET rc=RXSUBCOM_NOTREG;
531 
532    if ( InterpreterIdx == -1 )
533       LoadInterpreter();
534 
535    if (Trace)
536    {
537       TraceString( "%s: EnvName \"%s\" ModuleName \"%s\" ProcedureName \"%s\" UserArea %x DropAuth %d ",
538          "RexxQuerySubcom()",
539          EnvName,
540          ModuleName,
541          ProcedureName,
542          UserArea,
543          DropAuth );
544    }
545    if (ORexxRegisterSubcomDll)
546    {
547       rc = (*ORexxRegisterSubcomDll)(
548          (PSZ)       EnvName,
549          (PSZ)       ModuleName,
550          (PSZ)       ProcedureName,
551          (PUCHAR)    UserArea,
552          (ULONG)     DropAuth );
553    }
554    if ( Trace )
555    {
556       TraceString( "<=> Result: %d\n", rc );
557    }
558    return rc;
559 }
560 
RexxQuerySubcom(PCSZ Envname,PCSZ ModuleName,PUSHORT Flag,PUCHAR UserArea)561 APIRET APIENTRY RexxQuerySubcom(
562    PCSZ Envname,
563    PCSZ ModuleName,
564    PUSHORT Flag,
565    PUCHAR UserArea )
566 {
567    APIRET rc=RXSUBCOM_NOTREG;
568 
569    if ( InterpreterIdx == -1 )
570       LoadInterpreter();
571 
572    if (Trace)
573    {
574       TraceString( "%s: EnvName \"%s\" ModuleName \"%s\" Flag %d UserArea %x ",
575          "RexxQuerySubcom()",
576          Envname,
577          ModuleName,
578          Flag,
579          UserArea );
580    }
581    if (ORexxQuerySubcom)
582    {
583       rc = (*ORexxQuerySubcom)(
584          (PSZ)       Envname,
585          (PSZ)       ModuleName,
586          (PUSHORT)   Flag,
587          (PUCHAR)    UserArea );
588    }
589    if ( Trace )
590    {
591       TraceString( "<=> Result: %d\n", rc );
592    }
593    return rc;
594 }
595 
596 /*
597  * External functions
598  */
RexxRegisterFunctionExe(PCSZ name,RexxFunctionHandler * EntryPoint)599 APIRET APIENTRY RexxRegisterFunctionExe(
600    PCSZ name,
601    RexxFunctionHandler *EntryPoint )
602 {
603    APIRET rc=RXFUNC_NOTREG;
604 
605    if ( InterpreterIdx == -1 )
606       LoadInterpreter();
607 
608    if (Trace)
609    {
610       TraceString( "%s: Name \"%s\" Entrypoint %x ",
611          "RexxRegisterFunctionExe()",
612          name,
613          EntryPoint );
614 
615    }
616    if (ORexxRegisterFunctionExe)
617       rc = (*ORexxRegisterFunctionExe)(
618          (PSZ)       name,
619          (PFN)       EntryPoint );
620    if (Trace)
621    {
622       TraceString( "<=> Result: %d\n", rc );
623    }
624    return rc;
625 }
626 
RexxRegisterFunctionDll(PCSZ ExternalName,PCSZ LibraryName,PCSZ InternalName)627 APIRET APIENTRY RexxRegisterFunctionDll(
628    PCSZ ExternalName,
629    PCSZ LibraryName,
630    PCSZ InternalName )
631 {
632    APIRET rc=RXFUNC_NOTREG;
633 
634    if ( InterpreterIdx == -1 )
635       LoadInterpreter();
636 
637    if (Trace)
638    {
639       TraceString( "%s: External %s Library %s Internal %s ",
640          "RexxRegisterFunctionDll()",
641          ExternalName,
642          LibraryName,
643          InternalName );
644 
645    }
646    if (ORexxRegisterFunctionDll)
647       rc = (*ORexxRegisterFunctionDll)(
648          (PSZ)       ExternalName,
649          (PSZ)       LibraryName,
650          (PSZ)       InternalName );
651    if (Trace)
652    {
653       TraceString( "<=> Result: %d\n", rc );
654    }
655    return rc;
656 }
657 
RexxDeregisterFunction(PCSZ name)658 APIRET APIENTRY RexxDeregisterFunction(
659    PCSZ name )
660 {
661    APIRET rc=RXFUNC_NOTREG;
662 
663    if ( InterpreterIdx == -1 )
664       LoadInterpreter();
665 
666    if (Trace)
667    {
668       TraceString( "%s: %s ",
669          "RexxDeregisterFunction()",
670          name );
671 
672    }
673    if (ORexxDeregisterFunction)
674       rc = (*ORexxDeregisterFunction)(
675          (PSZ)       name );
676    if (Trace)
677    {
678       TraceString( "<=> Result: %d\n", rc );
679    }
680    return rc;
681 }
682 
RexxQueryFunction(PCSZ name)683 APIRET APIENTRY RexxQueryFunction(
684    PCSZ name )
685 {
686    APIRET rc=RXFUNC_NOTREG;
687 
688    if ( InterpreterIdx == -1 )
689       LoadInterpreter();
690 
691    if (Trace)
692    {
693       TraceString( "%s: %s ",
694          "RexxQueryFunction()",
695          name );
696 
697    }
698    if (ORexxQueryFunction)
699       rc = (*ORexxQueryFunction)(
700          (PSZ)       name );
701    if (Trace)
702    {
703       TraceString( "<=> Result: %d\n", rc );
704    }
705    return rc;
706 }
707 
708 /* ============================================================= */
709 /* Named queue interface */
710 
RexxCreateQueue(PSZ Buffer,ULONG BuffLen,PSZ RequestedName,ULONG * DupFlag)711 APIRET APIENTRY RexxCreateQueue( PSZ Buffer,
712                                  ULONG BuffLen,
713                                  PSZ RequestedName,
714                                  ULONG* DupFlag)
715 {
716    APIRET rc=RXQUEUE_NOTREG;
717 
718    if ( InterpreterIdx == -1 )
719       LoadInterpreter();
720 
721    if (Trace)
722    {
723       TraceString( "%s: Buffer: %x BuffLen: %d RequestedName: \"%s\" DupFlag: %ld ",
724          "RexxCreateQueue()",
725          Buffer,
726          BuffLen,
727          RequestedName,
728          DupFlag );
729 
730    }
731    if (ORexxCreateQueue)
732    {
733       rc = (*ORexxCreateQueue)(
734          (PSZ)       Buffer,
735          (ULONG)     BuffLen,
736          (PSZ)       RequestedName,
737          (ULONG*)    DupFlag );
738    }
739    if (Trace)
740    {
741       TraceString( "<=> Result: %d ", rc );
742       if ( rc == RXQUEUE_OK )
743          TraceString( "Buffer: \"%s\" DupFlag: %d\n", rc );
744       else
745          TraceString( "\n" );
746    }
747    return rc;
748 }
749 
RexxDeleteQueue(PSZ QueueName)750 APIRET APIENTRY RexxDeleteQueue( PSZ QueueName )
751 {
752    APIRET rc=RXQUEUE_NOTREG;
753 
754    if ( InterpreterIdx == -1 )
755       LoadInterpreter();
756 
757    if (Trace)
758    {
759       TraceString( "%s: QueueName: \"%s\" ",
760          "RexxDeleteQueue()",
761          QueueName );
762 
763    }
764    if (ORexxDeleteQueue)
765    {
766       rc = (*ORexxDeleteQueue)(
767          (PSZ)       QueueName );
768    }
769    if (Trace)
770    {
771       TraceString( "<=> Result: %d\n", rc );
772    }
773    return rc;
774 }
775 
RexxQueryQueue(PSZ QueueName,ULONG * Count)776 APIRET APIENTRY RexxQueryQueue( PSZ QueueName,
777                                 ULONG* Count)
778 {
779    APIRET rc=RXQUEUE_NOTREG;
780 
781    if ( InterpreterIdx == -1 )
782       LoadInterpreter();
783 
784    if (Trace)
785    {
786       TraceString( "%s: QueueName: \"%s\" Count: %x ",
787          "RexxQueryQueue()",
788          QueueName,
789          Count );
790 
791    }
792    if (ORexxQueryQueue)
793    {
794       rc = (*ORexxQueryQueue)(
795          (PSZ)       QueueName,
796          (ULONG*)    Count );
797    }
798    if (Trace)
799    {
800       TraceString( "<=> Result: %d ", rc );
801       if ( rc == RXQUEUE_OK )
802          TraceString( "Count: %ld\n", *Count );
803       else
804          TraceString( "\n" );
805    }
806    return rc;
807 }
808 
RexxAddQueue(PSZ QueueName,PRXSTRING EntryData,ULONG AddFlag)809 APIRET APIENTRY RexxAddQueue( PSZ QueueName,
810                               PRXSTRING EntryData,
811                               ULONG AddFlag)
812 {
813    APIRET rc=RXQUEUE_NOTREG;
814 
815    if ( InterpreterIdx == -1 )
816       LoadInterpreter();
817 
818    if (Trace)
819    {
820       TraceString( "%s: QueueName: \"%s\" AddFlag: %ld ",
821          "RexxAddQueue()",
822          QueueName,
823          AddFlag );
824 
825    }
826    if (ORexxAddQueue)
827    {
828       rc = (*ORexxAddQueue)(
829          (PSZ)       QueueName,
830          (PRXSTRING) EntryData,
831          (ULONG)     AddFlag );
832    }
833    if (Trace)
834    {
835       TraceString( "<=> Result: %d\n", rc );
836    }
837    return rc;
838 }
839 
RexxPullQueue(PSZ QueueName,PRXSTRING DataBuf,PDATETIME TimeStamp,ULONG WaitFlag)840 APIRET APIENTRY RexxPullQueue( PSZ QueueName,
841                                PRXSTRING DataBuf,
842                                PDATETIME TimeStamp,
843                                ULONG WaitFlag)
844 {
845    APIRET rc=RXQUEUE_NOTREG;
846 
847    if ( InterpreterIdx == -1 )
848       LoadInterpreter();
849 
850    if (Trace)
851    {
852       TraceString( "%s: QueueName: \"%s\" DataBuf: %x TimeStamp: %x WaitFlag: %ld ",
853          "RexxPullQueue()",
854          QueueName,
855          DataBuf,
856          TimeStamp,
857          WaitFlag );
858 
859    }
860    if (ORexxPullQueue)
861    {
862       rc = (*ORexxPullQueue)(
863          (PSZ)       QueueName,
864          (PRXSTRING) DataBuf,
865          (PDATETIME) TimeStamp,
866          (ULONG)     WaitFlag );
867    }
868    if (Trace)
869    {
870       TraceString( "<=> Result: %d\n", rc );
871       if ( rc == RXQUEUE_OK )
872          TraceString( "DataBuf->strlength: %ld DataBuf->strptr: \"%s\"\n",
873             DataBuf->strlength,
874             DataBuf->strptr );
875       else
876          TraceString( "\n" );
877    }
878    return rc;
879 }
880 
881 /* ============================================================= */
882 /* MacroSpace Rexx API interface */
883 
RexxAddMacro(PSZ FuncName,PSZ SourceFile,ULONG Position)884 APIRET APIENTRY RexxAddMacro( PSZ FuncName,
885                               PSZ SourceFile,
886                               ULONG Position )
887 {
888    APIRET rc=RXMACRO_NOT_FOUND;
889 
890    if ( InterpreterIdx == -1 )
891       LoadInterpreter();
892 
893    if (Trace)
894    {
895       TraceString( "%s: FuncName: \"%s\" SourceFile: \"%s\" Position: %ld ",
896          "RexxAddMacro()",
897          FuncName,
898          SourceFile,
899          Position );
900 
901    }
902    if (ORexxAddMacro)
903    {
904       rc = (*ORexxAddMacro)(
905          (PSZ)       FuncName,
906          (PSZ)       SourceFile,
907          (ULONG)     Position );
908    }
909    if (Trace)
910    {
911       TraceString( "<=> Result: %d\n", rc );
912    }
913    return rc;
914 }
915 
RexxDropMacro(PSZ FuncName)916 APIRET APIENTRY RexxDropMacro( PSZ FuncName)
917 {
918    APIRET rc=RXMACRO_NOT_FOUND;
919 
920    if ( InterpreterIdx == -1 )
921       LoadInterpreter();
922 
923    if (Trace)
924    {
925       TraceString( "%s: FuncName: \"%s\" ",
926          "RexxDropMacro()",
927          FuncName );
928 
929    }
930    if (ORexxDropMacro)
931    {
932       rc = (*ORexxDropMacro)(
933          (PSZ)       FuncName );
934    }
935    if (Trace)
936    {
937       TraceString( "<=> Result: %d\n", rc );
938    }
939    return rc;
940 }
941 
RexxSaveMacroSpace(ULONG FuncCount,PSZ * FuncNames,PSZ MacroLibFile)942 APIRET APIENTRY RexxSaveMacroSpace( ULONG FuncCount,
943                                     PSZ * FuncNames,
944                                     PSZ MacroLibFile)
945 {
946    APIRET rc=RXMACRO_NOT_FOUND;
947 
948    if ( InterpreterIdx == -1 )
949       LoadInterpreter();
950 
951    if (Trace)
952    {
953       unsigned int i;
954 
955       TraceString( "%s: FuncCount %d MacroLibFile \"%s\" ",
956          "RexxSaveMacroSpace()",
957          FuncCount, MacroLibFile );
958       if ( FuncCount && FuncNames )
959       {
960          for ( i = 0; i < FuncCount; i++ )
961          {
962             TraceString( "%s: FuncName \"%s\" ",
963                "RexxSaveMacroSpace()",
964                FuncNames[i] );
965          }
966       }
967    }
968    if (ORexxSaveMacroSpace)
969    {
970       rc = (*ORexxSaveMacroSpace)(
971          (ULONG)     FuncCount,
972          (PSZ*)      FuncNames,
973          (PSZ)       MacroLibFile
974           );
975    }
976    if (Trace)
977    {
978       TraceString( "<=> Result: %d\n", rc );
979    }
980    return rc;
981 }
982 
RexxLoadMacroSpace(ULONG FuncCount,PSZ * FuncNames,PSZ MacroLibFile)983 APIRET APIENTRY RexxLoadMacroSpace( ULONG FuncCount,
984                                     PSZ * FuncNames,
985                                     PSZ MacroLibFile)
986 {
987    APIRET rc=RXMACRO_NOT_FOUND;
988 
989    if ( InterpreterIdx == -1 )
990       LoadInterpreter();
991 
992    if (Trace)
993    {
994       unsigned int i;
995 
996       TraceString( "%s: FuncCount %d MacroLibFile \"%s\" ",
997          "RexxLoadMacroSpace()",
998          FuncCount, MacroLibFile );
999       if ( FuncCount && FuncNames )
1000       {
1001          for ( i = 0; i < FuncCount; i++ )
1002          {
1003             TraceString( "%s: FuncName \"%s\" ",
1004                "RexxLoadMacroSpace()",
1005                FuncNames[i] );
1006          }
1007       }
1008    }
1009    if (ORexxLoadMacroSpace)
1010    {
1011       rc = (*ORexxLoadMacroSpace)(
1012          (ULONG)     FuncCount,
1013          (PSZ*)      FuncNames,
1014          (PSZ)       MacroLibFile
1015           );
1016    }
1017    if (Trace)
1018    {
1019       TraceString( "<=> Result: %d\n", rc );
1020    }
1021    return rc;
1022 }
1023 
RexxQueryMacro(PSZ FuncName,PUSHORT Position)1024 APIRET APIENTRY RexxQueryMacro( PSZ FuncName,
1025                                 PUSHORT Position )
1026 {
1027    APIRET rc=RXMACRO_NOT_FOUND;
1028 
1029    if ( InterpreterIdx == -1 )
1030       LoadInterpreter();
1031 
1032    if (Trace)
1033    {
1034       TraceString( "%s: FuncName: \"%s\" Position: %x ",
1035          "RexxQueryMacro()",
1036          FuncName,
1037          Position );
1038 
1039    }
1040    if (ORexxQueryMacro)
1041    {
1042       rc = (*ORexxQueryMacro)(
1043          (PSZ)       FuncName,
1044          (PUSHORT)   Position );
1045    }
1046    if (Trace)
1047    {
1048       TraceString( "<=> Result: %d\n", rc );
1049       if ( rc == RXMACRO_OK )
1050          TraceString( "Position: %d\n",
1051             *Position );
1052       else
1053          TraceString( "\n" );
1054    }
1055    return rc;
1056 }
1057 
RexxReorderMacro(PSZ FuncName,ULONG Position)1058 APIRET APIENTRY RexxReorderMacro( PSZ FuncName,
1059                                   ULONG Position )
1060 {
1061    APIRET rc=RXMACRO_NOT_FOUND;
1062 
1063    if ( InterpreterIdx == -1 )
1064       LoadInterpreter();
1065 
1066    if (Trace)
1067    {
1068       TraceString( "%s: FuncName: \"%s\" Position: %ld",
1069          "RexxReorderMacro()",
1070          FuncName,
1071          Position );
1072 
1073    }
1074    if (ORexxReorderMacro)
1075    {
1076       rc = (*ORexxReorderMacro)(
1077          (PSZ)       FuncName,
1078          (ULONG)     Position );
1079    }
1080    if (Trace)
1081    {
1082       TraceString( "<=> Result: %d\n", rc );
1083    }
1084    return rc;
1085 }
1086 
RexxClearMacroSpace(VOID)1087 APIRET APIENTRY RexxClearMacroSpace( VOID )
1088 {
1089    APIRET rc=RXMACRO_NOT_FOUND;
1090 
1091    if ( InterpreterIdx == -1 )
1092       LoadInterpreter();
1093 
1094    if (Trace)
1095    {
1096       TraceString( "%s:",
1097          "RexxClearMacroSpace()" );
1098 
1099    }
1100    if (ORexxClearMacroSpace)
1101       rc = (*ORexxClearMacroSpace)(
1102            );
1103    if (Trace)
1104    {
1105       TraceString( ": Result: %x\n", rc );
1106    }
1107    return rc;
1108 }
1109