home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / rexxuuxx.zip / REXXUUXX.PLI < prev    next >
Text File  |  1997-05-13  |  15KB  |  379 lines

  1. %PROCESS DLLINIT,M,NIS;
  2.  /*********************************************************************/
  3.  /* This program is freeware, distributed as is, without any warranty */
  4.  /* of its usefulness for any purpose. You may use it freely. You may */
  5.  /* also redistribute it, provided no charge is levied beyond the     */
  6.  /* price of its distribution medium. However, the author retains all */
  7.  /* intellectual property rights.                                     */
  8.  /*                                                                   */
  9.  /*                                                                   */
  10.  /*  Copyright (C) David W. Noon, 1995, 1997                          */
  11.  /*                                                                   */
  12.  /*********************************************************************/
  13.  
  14.  (NOOFL,NOUFL,NOFOFL,NOZDIV):
  15.  REXXUUXX:
  16.  PACKAGE OPTIONS(REENTRANT REORDER) EXPORTS(*);
  17.  
  18.      DEFINE STRUCTURE
  19.           1    RXSTRING,
  20.                2    strlength      BIN FIXED(31,0) UNSIGNED,
  21.                2    strptr         PTR;
  22.  
  23.      %DCL Thread_stack_size        FIXED NOSCAN;
  24.      %Thread_stack_size = 4*1024*1024;
  25.      %ACT Thread_stack_size        NORESCAN;
  26.  
  27.      DCL  RexxRegisterFunctionDll  ENTRY(CHAR(*) VARZ NONASGN,
  28.                                         CHAR(*) VARZ NONASGN,
  29.                                         CHAR(*) VARZ NONASGN)
  30.                                    RETURNS(BIN FIXED(31,0) UNSIGNED OPTIONAL)
  31.                                    OPTIONS(BYADDR LINKAGE(SYSTEM) NODESCRIPTOR)
  32.                                    EXT('RexxRegisterFunctionDll');
  33.  
  34.      DCL  RexxDeregisterFunction   ENTRY(CHAR(*) VARZ NONASGN)
  35.                                    RETURNS(BIN FIXED(31,0) UNSIGNED OPTIONAL)
  36.                                    OPTIONS(BYADDR LINKAGE(SYSTEM) NODESCRIPTOR)
  37.                                    EXT('RexxDeregisterFunction');
  38.  
  39.      DCL  UUXX_function_names(8)   CHAR(17) VARZ NONASGN STATIC
  40.                                    INIT('UUXXREGISTER','UUXXDEREGISTER',
  41.                                    'UUDECODEFILES','UUENCODEFILES',
  42.                                    'XXDECODEFILES','XXENCODEFILES',
  43.                                    'BASE64DECODEFILES','BASE64ENCODEFILES');
  44.  
  45.  UUXXREGISTER:
  46.  PROC(Func_name,argc,argv,Queue_name,ret_val)
  47.           RETURNS(BIN FIXED(31,0) UNSIGNED)
  48.           OPTIONS(BYADDR LINKAGE(SYSTEM) NODESCRIPTOR FROMALIEN);
  49.  
  50.      DCL  Func_name                CHAR(32) VARZ NONASGN,
  51.           argc                     BIN FIXED(31,0) UNSIGNED BYVALUE,
  52.           argv(9999)               TYPE RXSTRING CONN NONASGN,
  53.           Queue_name               CHAR(32) VARZ NONASGN,
  54.           ret_val                  TYPE RXSTRING;
  55.  
  56.      DCL  i                        BIN FIXED(31,0),
  57.           Return_code              CHAR(1) BASED,
  58.           (LBOUND,HBOUND)          BUILTIN;
  59.  
  60.      DO i = LBOUND(UUXX_function_names,1) + 1
  61.                UPTHRU HBOUND(UUXX_function_names,1);
  62.           CALL RexxRegisterFunctionDll(UUXX_function_names(i),'REXXUUXX',
  63.                     UUXX_function_names(i));
  64.      END;
  65.  
  66.      /* Set return value to zero */
  67.      ret_val.strptr->Return_code = '0';
  68.      ret_val.strlength = 1;
  69.  
  70.      /* And we're done */
  71.      RETURN(0);
  72.  END UUXXREGISTER;
  73.  
  74.  UUXXDEREGISTER:
  75.  PROC(Func_name,argc,argv,Queue_name,ret_val)
  76.           RETURNS(BIN FIXED(31,0) UNSIGNED)
  77.           OPTIONS(BYADDR LINKAGE(SYSTEM) NODESCRIPTOR FROMALIEN);
  78.  
  79.      DCL  Func_name                CHAR(32) VARZ NONASGN,
  80.           argc                     BIN FIXED(31,0) UNSIGNED BYVALUE,
  81.           argv(9999)               TYPE RXSTRING CONN NONASGN,
  82.           Queue_name               CHAR(32) VARZ NONASGN,
  83.           ret_val                  TYPE RXSTRING;
  84.  
  85.      DCL  i                        BIN FIXED(31,0),
  86.           Return_code              CHAR(1) BASED,
  87.           (LBOUND,HBOUND)          BUILTIN;
  88.  
  89.      DO i = LBOUND(UUXX_function_names,1) UPTHRU HBOUND(UUXX_function_names,1);
  90.           CALL RexxDeregisterFunction(UUXX_function_names(i));
  91.      END;
  92.  
  93.      /* Set return value to zero */
  94.      ret_val.strptr->Return_code = '0';
  95.      ret_val.strlength = 1;
  96.  
  97.      /* And we're done */
  98.      RETURN(0);
  99.  END UUXXDEREGISTER;
  100.  
  101.  UUDECODEFILES:
  102.  PROC(Func_name,argc,argv,Queue_name,ret_val)
  103.           RETURNS(BIN FIXED(31,0) UNSIGNED)
  104.           OPTIONS(BYADDR LINKAGE(SYSTEM) NODESCRIPTOR FROMALIEN);
  105.  
  106.      DCL  Func_name                CHAR(32) VARZ NONASGN,
  107.           argc                     BIN FIXED(31,0) UNSIGNED BYVALUE,
  108.           argv(9999)               TYPE RXSTRING CONN NONASGN,
  109.           Queue_name               CHAR(32) VARZ NONASGN,
  110.           ret_val                  TYPE RXSTRING;
  111.  
  112.      %INCLUDE UUXXCODE;
  113.  
  114.      DCL  (i,istart)               BIN FIXED(31,0) UNSIGNED,
  115.           Horton_fix               BIT(1),
  116.           RX_chars                 CHAR(260) BASED,
  117.           Return_code              CHAR(1) BASED,
  118.           Parm_ptr                 PTR,
  119.           DLL_subtask              TASK,
  120.           SUBSTR                   BUILTIN;
  121.  
  122.      /* Check that we have at least 1 input file */
  123.      IF argc = 0 THEN
  124.           RETURN(40); /* REX040 Invalid call to routine */
  125.  
  126.      /* Check if we have to correct Horton's error */
  127.      IF argv(1).strlength = 6 &
  128.                SUBSTR(argv(1).strptr->RX_chars,1,6) = 'HORTON' THEN
  129.      DO;
  130.           /* Check that we have at least 1 input file */
  131.           IF argc = 1 THEN
  132.                RETURN(40); /* REX040 Invalid call to routine */
  133.           Horton_fix = '1'B;
  134.           istart = 2;
  135.      END;
  136.      ELSE
  137.      DO;
  138.           Horton_fix = '0'B;
  139.           istart = 1;
  140.      END;
  141.  
  142.      /* Work out how much storage we need */
  143.      DO i = istart TO argc;
  144.           /* Null strings are not permitted */
  145.           IF argv(i).strlength = 0 THEN
  146.                RETURN(40);
  147.           Max_in += argv(i).strlength + 1;
  148.      END;
  149.      Max_in = Max_in - 1;
  150.  
  151.      /* Allocate the storage */
  152.      ALLOC UUXX_Decode_struct SET(Parm_ptr);
  153.      Parm_ptr->UUXX_Decode_struct.Horton_bug = Horton_fix;
  154.      Parm_ptr->UUXX_Decode_struct.Msg_file = 'NUL:';
  155.      /* Build the list of file names */
  156.      Parm_ptr->UUXX_Decode_struct.Input_filename_list = '';
  157.      DO i = istart TO argc - 1;
  158.           Parm_ptr->UUXX_Decode_struct.Input_filename_list ||=
  159.                     SUBSTR(argv(i).strptr->RX_chars,1,argv(i).strlength);
  160.           Parm_ptr->UUXX_Decode_struct.Input_filename_list ||= '+';
  161.      END;
  162.      Parm_ptr->UUXX_Decode_struct.Input_filename_list ||=
  163.                SUBSTR(argv(argc).strptr->RX_chars,1,argv(argc).strlength);
  164.  
  165.      /* Call the decoder in its own thread */
  166.      IF Func_name = 'XXDECODEFILES' THEN
  167.           ATTACH XXDECODE_FILE(Parm_ptr) THREAD(DLL_subtask)
  168.                     ENV(TSTACK(Thread_stack_size));
  169.      ELSE
  170.           ATTACH UUDECODE_FILE(Parm_ptr) THREAD(DLL_subtask)
  171.                     ENV(TSTACK(Thread_stack_size));
  172.      /* Wait for that thread to finish */
  173.      WAIT THREAD(DLL_subtask);
  174.      DETACH THREAD(DLL_subtask);
  175.  
  176.      /* Release the parameter area storage */
  177.      FREE Parm_ptr->UUXX_Decode_struct;
  178.  
  179.      /* Set return value to zero */
  180.      ret_val.strptr->Return_code = '0';
  181.      ret_val.strlength = 1;
  182.  
  183.      /* And we're done */
  184.      RETURN(0);
  185.  END UUDECODEFILES;
  186.  
  187.  UUENCODEFILES:
  188.  PROC(Func_name,argc,argv,Queue_name,ret_val)
  189.           RETURNS(BIN FIXED(31,0) UNSIGNED)
  190.           OPTIONS(BYADDR LINKAGE(SYSTEM) NODESCRIPTOR FROMALIEN);
  191.  
  192.      DCL  Func_name                CHAR(32) VARZ NONASGN,
  193.           argc                     BIN FIXED(31,0) UNSIGNED BYVALUE,
  194.           argv(9999)               TYPE RXSTRING CONN NONASGN,
  195.           Queue_name               CHAR(32) VARZ NONASGN,
  196.           ret_val                  TYPE RXSTRING;
  197.  
  198.      %INCLUDE UUXXCODE;
  199.  
  200.      DCL  i                        BIN FIXED(31,0) UNSIGNED,
  201.           RX_chars                 CHAR(260) BASED,
  202.           Return_code              CHAR(1) BASED,
  203.           Parm_ptr                 PTR,
  204.           DLL_subtask              TASK,
  205.           SUBSTR                   BUILTIN;
  206.  
  207.      /* Check that we have at least 1 input & 1 output file */
  208.      IF argc < 2 | argv(1).strlength = 0 THEN
  209.           RETURN(40); /* REX040 Invalid call to routine */
  210.  
  211.      /* Work out how much storage we need */
  212.      Max_in = argc - 1;
  213.      /* Allocate the storage */
  214.      ALLOC UUXX_Encode_struct SET(Parm_ptr);
  215.      /* Asaign the output filename */
  216.      Parm_ptr->UUXX_Encode_struct.Output_filename =
  217.                SUBSTR(argv(1).strptr->RX_chars,1,argv(1).strlength);
  218.      /* Build the list of file names */
  219.      DO i = 2 UPTHRU argc;
  220.           /* Null strings are not permitted */
  221.           IF argv(i).strlength = 0 THEN
  222.           DO;
  223.                FREE Parm_ptr->UUXX_Encode_struct;
  224.                RETURN(40);
  225.           END;
  226.           Parm_ptr->UUXX_Encode_struct.Input_filename(i-1) =
  227.                     SUBSTR(argv(i).strptr->RX_chars,1,argv(i).strlength);
  228.      END;
  229.  
  230.      /* Call the encoder in its own thread */
  231.      IF Func_name = 'XXENCODEFILES' THEN
  232.           ATTACH XXENCODE_FILE(Parm_ptr) THREAD(DLL_subtask)
  233.                     ENV(TSTACK(Thread_stack_size));
  234.      ELSE
  235.           ATTACH UUENCODE_FILE(Parm_ptr) THREAD(DLL_subtask)
  236.                     ENV(TSTACK(Thread_stack_size));
  237.      /* Wait for that thread to finish */
  238.      WAIT THREAD(DLL_subtask);
  239.      DETACH THREAD(DLL_subtask);
  240.  
  241.      /* Release the parameter area storage */
  242.      FREE Parm_ptr->UUXX_Encode_struct;
  243.  
  244.      /* Set return value to zero */
  245.      ret_val.strptr->Return_code = '0';
  246.      ret_val.strlength = 1;
  247.  
  248.      /* And we're done */
  249.      RETURN(0);
  250.  END UUENCODEFILES;
  251.  
  252.  BASE64DECODEFILES:
  253.  PROC(Func_name,argc,argv,Queue_name,ret_val)
  254.           RETURNS(BIN FIXED(31,0) UNSIGNED)
  255.           OPTIONS(BYADDR LINKAGE(SYSTEM) NODESCRIPTOR FROMALIEN);
  256.  
  257.      DCL  Func_name                CHAR(32) VARZ NONASGN,
  258.           argc                     BIN FIXED(31,0) UNSIGNED BYVALUE,
  259.           argv(9999)               TYPE RXSTRING CONN NONASGN,
  260.           Queue_name               CHAR(32) VARZ NONASGN,
  261.           ret_val                  TYPE RXSTRING;
  262.  
  263.      %INCLUDE UUXXCODE;
  264.  
  265.      DCL  (i,istart)               BIN FIXED(31,0) UNSIGNED,
  266.           RX_chars                 CHAR(260) BASED,
  267.           Return_code              CHAR(1) BASED,
  268.           Parm_ptr                 PTR,
  269.           DLL_subtask              TASK,
  270.           (SUBSTR,VERIFY)          BUILTIN;
  271.  
  272.      /* Check that we have at least 1 input & 1 output file,
  273.         with optional record length */
  274.      IF argc < 2 | argv(1).strlength = 0 THEN
  275.           RETURN(40); /* REX040 Invalid call to routine */
  276.  
  277.      /* Check if first parameter is a maximum record length */
  278.      IF VERIFY(SUBSTR(argv(1).strptr->RX_chars,1,argv(1).strlength),
  279.                '0123456789') = 0 THEN /* It's a length */
  280.      DO;
  281.           /* Check that the output filename is not a null string */
  282.           IF argv(2).strlength = 0 THEN
  283.                RETURN(40); /* REX040 Invalid call to routine */
  284.           istart = 3;
  285.      END;
  286.      ELSE
  287.           istart = 2;
  288.  
  289.      /* Work out how much storage we need */
  290.      DO i = istart TO argc;
  291.           /* Null strings are not permitted */
  292.           IF argv(i).strlength = 0 THEN
  293.                RETURN(40);
  294.           Max_in += argv(i).strlength + 1;
  295.      END;
  296.      Max_in = Max_in - 1;
  297.  
  298.      /* Allocate the storage */
  299.      ALLOC B64_Decode_struct SET(Parm_ptr);
  300.      Parm_ptr->B64_Decode_struct.Msg_file = 'NUL:';
  301.      IF istart = 3 THEN
  302.           GET STRING(SUBSTR(argv(1).strptr->RX_chars,1,argv(1).strlength))
  303.                LIST(Parm_ptr->B64_Decode_struct.Valid_rec_len);
  304.      /* Build the list of file names */
  305.      Parm_ptr->B64_Decode_struct.Output_filename =
  306.              SUBSTR(argv(istart-1).strptr->RX_chars,1,argv(istart-1).strlength);
  307.      Parm_ptr->B64_Decode_struct.Input_filename_list = '';
  308.      DO i = istart TO argc - 1;
  309.           Parm_ptr->B64_Decode_struct.Input_filename_list ||=
  310.                     SUBSTR(argv(i).strptr->RX_chars,1,argv(i).strlength);
  311.           Parm_ptr->B64_Decode_struct.Input_filename_list ||= '+';
  312.      END;
  313.      Parm_ptr->B64_Decode_struct.Input_filename_list ||=
  314.                SUBSTR(argv(argc).strptr->RX_chars,1,argv(argc).strlength);
  315.  
  316.      /* Call the decoder in its own thread */
  317.      ATTACH BASE64_DECODE(Parm_ptr) THREAD(DLL_subtask)
  318.                ENV(TSTACK(Thread_stack_size));
  319.      /* Wait for that thread to finish */
  320.      WAIT THREAD(DLL_subtask);
  321.      DETACH THREAD(DLL_subtask);
  322.  
  323.      /* Release the parameter area storage */
  324.      FREE Parm_ptr->B64_Decode_struct;
  325.  
  326.      /* Set return value to zero */
  327.      ret_val.strptr->Return_code = '0';
  328.      ret_val.strlength = 1;
  329.  
  330.      /* And we're done */
  331.      RETURN(0);
  332.  END BASE64DECODEFILES;
  333.  
  334.  BASE64ENCODEFILES:
  335.  PROC(Func_name,argc,argv,Queue_name,ret_val)
  336.           RETURNS(BIN FIXED(31,0) UNSIGNED)
  337.           OPTIONS(BYADDR LINKAGE(SYSTEM) NODESCRIPTOR FROMALIEN);
  338.  
  339.      DCL  Func_name                CHAR(32) VARZ NONASGN,
  340.           argc                     BIN FIXED(31,0) UNSIGNED BYVALUE,
  341.           argv(2)                  TYPE RXSTRING CONN NONASGN,
  342.           Queue_name               CHAR(32) VARZ NONASGN,
  343.           ret_val                  TYPE RXSTRING;
  344.  
  345.      %INCLUDE UUXXCODE;
  346.  
  347.      DCL  1    Parm_struct,
  348.                2    Input_file          CHAR(260) VAR,
  349.                2    Output_file         CHAR(260) VAR,
  350.           RX_chars                 CHAR(260) BASED,
  351.           Return_code              CHAR(1) BASED,
  352.           DLL_subtask              TASK,
  353.           (ADDR,SUBSTR)            BUILTIN;
  354.  
  355.      /* Check that we have exactly 1 input & 1 output file */
  356.      IF argc ¬= 2 | argv(1).strlength = 0 | argv(2).strlength = 0 THEN
  357.           RETURN(40); /* REX040 Invalid call to routine */
  358.  
  359.      /* Build the list of file names */
  360.      Output_file = SUBSTR(argv(1).strptr->RX_chars,1,argv(1).strlength);
  361.      Input_file = SUBSTR(argv(2).strptr->RX_chars,1,argv(2).strlength);
  362.  
  363.      /* Call the encoder in its own thread */
  364.      ATTACH BASE64_ENCODE(ADDR(Parm_struct)) THREAD(DLL_subtask)
  365.                ENV(TSTACK(Thread_stack_size));
  366.      /* Wait for that thread to finish */
  367.      WAIT THREAD(DLL_subtask);
  368.      DETACH THREAD(DLL_subtask);
  369.  
  370.      /* Set return value to zero */
  371.      ret_val.strptr->Return_code = '0';
  372.      ret_val.strlength = 1;
  373.  
  374.      /* And we're done */
  375.      RETURN(0);
  376.  END BASE64ENCODEFILES;
  377.  
  378.  END REXXUUXX;
  379.