home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
rexxuuxx.zip
/
REXXUUXX.PLI
< prev
next >
Wrap
Text File
|
1997-05-13
|
15KB
|
379 lines
%PROCESS DLLINIT,M,NIS;
/*********************************************************************/
/* This program is freeware, distributed as is, without any warranty */
/* of its usefulness for any purpose. You may use it freely. You may */
/* also redistribute it, provided no charge is levied beyond the */
/* price of its distribution medium. However, the author retains all */
/* intellectual property rights. */
/* */
/* */
/* Copyright (C) David W. Noon, 1995, 1997 */
/* */
/*********************************************************************/
(NOOFL,NOUFL,NOFOFL,NOZDIV):
REXXUUXX:
PACKAGE OPTIONS(REENTRANT REORDER) EXPORTS(*);
DEFINE STRUCTURE
1 RXSTRING,
2 strlength BIN FIXED(31,0) UNSIGNED,
2 strptr PTR;
%DCL Thread_stack_size FIXED NOSCAN;
%Thread_stack_size = 4*1024*1024;
%ACT Thread_stack_size NORESCAN;
DCL RexxRegisterFunctionDll ENTRY(CHAR(*) VARZ NONASGN,
CHAR(*) VARZ NONASGN,
CHAR(*) VARZ NONASGN)
RETURNS(BIN FIXED(31,0) UNSIGNED OPTIONAL)
OPTIONS(BYADDR LINKAGE(SYSTEM) NODESCRIPTOR)
EXT('RexxRegisterFunctionDll');
DCL RexxDeregisterFunction ENTRY(CHAR(*) VARZ NONASGN)
RETURNS(BIN FIXED(31,0) UNSIGNED OPTIONAL)
OPTIONS(BYADDR LINKAGE(SYSTEM) NODESCRIPTOR)
EXT('RexxDeregisterFunction');
DCL UUXX_function_names(8) CHAR(17) VARZ NONASGN STATIC
INIT('UUXXREGISTER','UUXXDEREGISTER',
'UUDECODEFILES','UUENCODEFILES',
'XXDECODEFILES','XXENCODEFILES',
'BASE64DECODEFILES','BASE64ENCODEFILES');
UUXXREGISTER:
PROC(Func_name,argc,argv,Queue_name,ret_val)
RETURNS(BIN FIXED(31,0) UNSIGNED)
OPTIONS(BYADDR LINKAGE(SYSTEM) NODESCRIPTOR FROMALIEN);
DCL Func_name CHAR(32) VARZ NONASGN,
argc BIN FIXED(31,0) UNSIGNED BYVALUE,
argv(9999) TYPE RXSTRING CONN NONASGN,
Queue_name CHAR(32) VARZ NONASGN,
ret_val TYPE RXSTRING;
DCL i BIN FIXED(31,0),
Return_code CHAR(1) BASED,
(LBOUND,HBOUND) BUILTIN;
DO i = LBOUND(UUXX_function_names,1) + 1
UPTHRU HBOUND(UUXX_function_names,1);
CALL RexxRegisterFunctionDll(UUXX_function_names(i),'REXXUUXX',
UUXX_function_names(i));
END;
/* Set return value to zero */
ret_val.strptr->Return_code = '0';
ret_val.strlength = 1;
/* And we're done */
RETURN(0);
END UUXXREGISTER;
UUXXDEREGISTER:
PROC(Func_name,argc,argv,Queue_name,ret_val)
RETURNS(BIN FIXED(31,0) UNSIGNED)
OPTIONS(BYADDR LINKAGE(SYSTEM) NODESCRIPTOR FROMALIEN);
DCL Func_name CHAR(32) VARZ NONASGN,
argc BIN FIXED(31,0) UNSIGNED BYVALUE,
argv(9999) TYPE RXSTRING CONN NONASGN,
Queue_name CHAR(32) VARZ NONASGN,
ret_val TYPE RXSTRING;
DCL i BIN FIXED(31,0),
Return_code CHAR(1) BASED,
(LBOUND,HBOUND) BUILTIN;
DO i = LBOUND(UUXX_function_names,1) UPTHRU HBOUND(UUXX_function_names,1);
CALL RexxDeregisterFunction(UUXX_function_names(i));
END;
/* Set return value to zero */
ret_val.strptr->Return_code = '0';
ret_val.strlength = 1;
/* And we're done */
RETURN(0);
END UUXXDEREGISTER;
UUDECODEFILES:
PROC(Func_name,argc,argv,Queue_name,ret_val)
RETURNS(BIN FIXED(31,0) UNSIGNED)
OPTIONS(BYADDR LINKAGE(SYSTEM) NODESCRIPTOR FROMALIEN);
DCL Func_name CHAR(32) VARZ NONASGN,
argc BIN FIXED(31,0) UNSIGNED BYVALUE,
argv(9999) TYPE RXSTRING CONN NONASGN,
Queue_name CHAR(32) VARZ NONASGN,
ret_val TYPE RXSTRING;
%INCLUDE UUXXCODE;
DCL (i,istart) BIN FIXED(31,0) UNSIGNED,
Horton_fix BIT(1),
RX_chars CHAR(260) BASED,
Return_code CHAR(1) BASED,
Parm_ptr PTR,
DLL_subtask TASK,
SUBSTR BUILTIN;
/* Check that we have at least 1 input file */
IF argc = 0 THEN
RETURN(40); /* REX040 Invalid call to routine */
/* Check if we have to correct Horton's error */
IF argv(1).strlength = 6 &
SUBSTR(argv(1).strptr->RX_chars,1,6) = 'HORTON' THEN
DO;
/* Check that we have at least 1 input file */
IF argc = 1 THEN
RETURN(40); /* REX040 Invalid call to routine */
Horton_fix = '1'B;
istart = 2;
END;
ELSE
DO;
Horton_fix = '0'B;
istart = 1;
END;
/* Work out how much storage we need */
DO i = istart TO argc;
/* Null strings are not permitted */
IF argv(i).strlength = 0 THEN
RETURN(40);
Max_in += argv(i).strlength + 1;
END;
Max_in = Max_in - 1;
/* Allocate the storage */
ALLOC UUXX_Decode_struct SET(Parm_ptr);
Parm_ptr->UUXX_Decode_struct.Horton_bug = Horton_fix;
Parm_ptr->UUXX_Decode_struct.Msg_file = 'NUL:';
/* Build the list of file names */
Parm_ptr->UUXX_Decode_struct.Input_filename_list = '';
DO i = istart TO argc - 1;
Parm_ptr->UUXX_Decode_struct.Input_filename_list ||=
SUBSTR(argv(i).strptr->RX_chars,1,argv(i).strlength);
Parm_ptr->UUXX_Decode_struct.Input_filename_list ||= '+';
END;
Parm_ptr->UUXX_Decode_struct.Input_filename_list ||=
SUBSTR(argv(argc).strptr->RX_chars,1,argv(argc).strlength);
/* Call the decoder in its own thread */
IF Func_name = 'XXDECODEFILES' THEN
ATTACH XXDECODE_FILE(Parm_ptr) THREAD(DLL_subtask)
ENV(TSTACK(Thread_stack_size));
ELSE
ATTACH UUDECODE_FILE(Parm_ptr) THREAD(DLL_subtask)
ENV(TSTACK(Thread_stack_size));
/* Wait for that thread to finish */
WAIT THREAD(DLL_subtask);
DETACH THREAD(DLL_subtask);
/* Release the parameter area storage */
FREE Parm_ptr->UUXX_Decode_struct;
/* Set return value to zero */
ret_val.strptr->Return_code = '0';
ret_val.strlength = 1;
/* And we're done */
RETURN(0);
END UUDECODEFILES;
UUENCODEFILES:
PROC(Func_name,argc,argv,Queue_name,ret_val)
RETURNS(BIN FIXED(31,0) UNSIGNED)
OPTIONS(BYADDR LINKAGE(SYSTEM) NODESCRIPTOR FROMALIEN);
DCL Func_name CHAR(32) VARZ NONASGN,
argc BIN FIXED(31,0) UNSIGNED BYVALUE,
argv(9999) TYPE RXSTRING CONN NONASGN,
Queue_name CHAR(32) VARZ NONASGN,
ret_val TYPE RXSTRING;
%INCLUDE UUXXCODE;
DCL i BIN FIXED(31,0) UNSIGNED,
RX_chars CHAR(260) BASED,
Return_code CHAR(1) BASED,
Parm_ptr PTR,
DLL_subtask TASK,
SUBSTR BUILTIN;
/* Check that we have at least 1 input & 1 output file */
IF argc < 2 | argv(1).strlength = 0 THEN
RETURN(40); /* REX040 Invalid call to routine */
/* Work out how much storage we need */
Max_in = argc - 1;
/* Allocate the storage */
ALLOC UUXX_Encode_struct SET(Parm_ptr);
/* Asaign the output filename */
Parm_ptr->UUXX_Encode_struct.Output_filename =
SUBSTR(argv(1).strptr->RX_chars,1,argv(1).strlength);
/* Build the list of file names */
DO i = 2 UPTHRU argc;
/* Null strings are not permitted */
IF argv(i).strlength = 0 THEN
DO;
FREE Parm_ptr->UUXX_Encode_struct;
RETURN(40);
END;
Parm_ptr->UUXX_Encode_struct.Input_filename(i-1) =
SUBSTR(argv(i).strptr->RX_chars,1,argv(i).strlength);
END;
/* Call the encoder in its own thread */
IF Func_name = 'XXENCODEFILES' THEN
ATTACH XXENCODE_FILE(Parm_ptr) THREAD(DLL_subtask)
ENV(TSTACK(Thread_stack_size));
ELSE
ATTACH UUENCODE_FILE(Parm_ptr) THREAD(DLL_subtask)
ENV(TSTACK(Thread_stack_size));
/* Wait for that thread to finish */
WAIT THREAD(DLL_subtask);
DETACH THREAD(DLL_subtask);
/* Release the parameter area storage */
FREE Parm_ptr->UUXX_Encode_struct;
/* Set return value to zero */
ret_val.strptr->Return_code = '0';
ret_val.strlength = 1;
/* And we're done */
RETURN(0);
END UUENCODEFILES;
BASE64DECODEFILES:
PROC(Func_name,argc,argv,Queue_name,ret_val)
RETURNS(BIN FIXED(31,0) UNSIGNED)
OPTIONS(BYADDR LINKAGE(SYSTEM) NODESCRIPTOR FROMALIEN);
DCL Func_name CHAR(32) VARZ NONASGN,
argc BIN FIXED(31,0) UNSIGNED BYVALUE,
argv(9999) TYPE RXSTRING CONN NONASGN,
Queue_name CHAR(32) VARZ NONASGN,
ret_val TYPE RXSTRING;
%INCLUDE UUXXCODE;
DCL (i,istart) BIN FIXED(31,0) UNSIGNED,
RX_chars CHAR(260) BASED,
Return_code CHAR(1) BASED,
Parm_ptr PTR,
DLL_subtask TASK,
(SUBSTR,VERIFY) BUILTIN;
/* Check that we have at least 1 input & 1 output file,
with optional record length */
IF argc < 2 | argv(1).strlength = 0 THEN
RETURN(40); /* REX040 Invalid call to routine */
/* Check if first parameter is a maximum record length */
IF VERIFY(SUBSTR(argv(1).strptr->RX_chars,1,argv(1).strlength),
'0123456789') = 0 THEN /* It's a length */
DO;
/* Check that the output filename is not a null string */
IF argv(2).strlength = 0 THEN
RETURN(40); /* REX040 Invalid call to routine */
istart = 3;
END;
ELSE
istart = 2;
/* Work out how much storage we need */
DO i = istart TO argc;
/* Null strings are not permitted */
IF argv(i).strlength = 0 THEN
RETURN(40);
Max_in += argv(i).strlength + 1;
END;
Max_in = Max_in - 1;
/* Allocate the storage */
ALLOC B64_Decode_struct SET(Parm_ptr);
Parm_ptr->B64_Decode_struct.Msg_file = 'NUL:';
IF istart = 3 THEN
GET STRING(SUBSTR(argv(1).strptr->RX_chars,1,argv(1).strlength))
LIST(Parm_ptr->B64_Decode_struct.Valid_rec_len);
/* Build the list of file names */
Parm_ptr->B64_Decode_struct.Output_filename =
SUBSTR(argv(istart-1).strptr->RX_chars,1,argv(istart-1).strlength);
Parm_ptr->B64_Decode_struct.Input_filename_list = '';
DO i = istart TO argc - 1;
Parm_ptr->B64_Decode_struct.Input_filename_list ||=
SUBSTR(argv(i).strptr->RX_chars,1,argv(i).strlength);
Parm_ptr->B64_Decode_struct.Input_filename_list ||= '+';
END;
Parm_ptr->B64_Decode_struct.Input_filename_list ||=
SUBSTR(argv(argc).strptr->RX_chars,1,argv(argc).strlength);
/* Call the decoder in its own thread */
ATTACH BASE64_DECODE(Parm_ptr) THREAD(DLL_subtask)
ENV(TSTACK(Thread_stack_size));
/* Wait for that thread to finish */
WAIT THREAD(DLL_subtask);
DETACH THREAD(DLL_subtask);
/* Release the parameter area storage */
FREE Parm_ptr->B64_Decode_struct;
/* Set return value to zero */
ret_val.strptr->Return_code = '0';
ret_val.strlength = 1;
/* And we're done */
RETURN(0);
END BASE64DECODEFILES;
BASE64ENCODEFILES:
PROC(Func_name,argc,argv,Queue_name,ret_val)
RETURNS(BIN FIXED(31,0) UNSIGNED)
OPTIONS(BYADDR LINKAGE(SYSTEM) NODESCRIPTOR FROMALIEN);
DCL Func_name CHAR(32) VARZ NONASGN,
argc BIN FIXED(31,0) UNSIGNED BYVALUE,
argv(2) TYPE RXSTRING CONN NONASGN,
Queue_name CHAR(32) VARZ NONASGN,
ret_val TYPE RXSTRING;
%INCLUDE UUXXCODE;
DCL 1 Parm_struct,
2 Input_file CHAR(260) VAR,
2 Output_file CHAR(260) VAR,
RX_chars CHAR(260) BASED,
Return_code CHAR(1) BASED,
DLL_subtask TASK,
(ADDR,SUBSTR) BUILTIN;
/* Check that we have exactly 1 input & 1 output file */
IF argc ¬= 2 | argv(1).strlength = 0 | argv(2).strlength = 0 THEN
RETURN(40); /* REX040 Invalid call to routine */
/* Build the list of file names */
Output_file = SUBSTR(argv(1).strptr->RX_chars,1,argv(1).strlength);
Input_file = SUBSTR(argv(2).strptr->RX_chars,1,argv(2).strlength);
/* Call the encoder in its own thread */
ATTACH BASE64_ENCODE(ADDR(Parm_struct)) THREAD(DLL_subtask)
ENV(TSTACK(Thread_stack_size));
/* Wait for that thread to finish */
WAIT THREAD(DLL_subtask);
DETACH THREAD(DLL_subtask);
/* Set return value to zero */
ret_val.strptr->Return_code = '0';
ret_val.strlength = 1;
/* And we're done */
RETURN(0);
END BASE64ENCODEFILES;
END REXXUUXX;