On Mon, 23 Mar 2020 00:28:16 -0400, Bob Bridges <[email protected]> wrote:

>Gil, I can't tell whether you're suggesting more things that CLIST can do that 
>REXX cannot, or things that REXX can do even though I said it cannot.  a) I 
>don't know what CHAROUT is, but it sounds like the same issue as WRITENR.  Or 
>are you saying it's some sort of REXX function that can imitate CLIST's 
>WRITENR?  b) I don't know what "RYO" is either ("rite your own"?), but unless 
>I'm thinking of something different, RXSOCKET isn't trick CLIST can do that 
>REXX cannot; I used it to write a socket server (and a separate client) in 
>REXX.  And c) TSO EDIT isn't an exception to what I wrote, it's a perfect 
>example of #2 below, a subsystem that CLIST can interact with dynamically (if 
>that's the word) and REXX cannot.  Exactly what I was talking about, although 
>I used FTP as my example because FTP is what I've encountered most recently.  
>I haven't used TSO Edit in ... well, must be the early '80s at the latest, 
>maybe the late '70s.
>
>So what am I missing?
>
>---
>Bob Bridges, [email protected], cell 336 382-7313

Bob, for FTP there is a FTP Client API documented in the "IP Programmer's Guide 
and Reference" that is usable from REXX and other languages.  VM/CMS allows 
Assembler programs to easily create a Sub Command (SUBCOM) environment in CMS.  
Romney White (now with IBM VM support) wrote a SUBCOM environment for CMS, 
(Address VMFTP), that allowed VMFTP Macros to be written to issue FTP commands 
and process the results.  I used this to create several FTP applications.  The 
z/OS FTP Client API is not a sub command environment, it is a REXX Function 
that can be invoked to do FTP command processing.

I found a FTP Server that is apparently used for speed tests, so I wrote a 
sample REXX program that uses the FTP Client API to connect to it and list the 
files in the root directory (and displays the number of files in any sub 
directories).  This FTP Server has a single sub directory named "upload" that 
is used for upload speed tests.  (The files are generally erased in "upload" so 
it may or may not have any files in it.)  This example contains a hard coded 
server name, userid, and password.  I would certainly not suggest doing this 
for any real applications!  That info should be in a properly secured file or 
PDS(e) member and read by the REXX program with EXECIO or equivalent.  Gil, the 
FTP Client API does not require TSO and can run under IRXJCL, (of course you 
would probably need TSO for more complicated programs).

Here is the working sample code:

/*--------------------------- SAMPFTP REXX ---------------------------*/
/* Sample REXX Program to show basic usage of the FTP Client API.     */
/*--------------------------------------------------------------------*/
SAMPFTP:
   Parse Source . ctype ename eddname edsname . defcom .
   pgmvers   = 1        /* Program Version */
   server    = 'speedtest.tele2.net'
   userid    = 'anonymous'
   password  = 'anonymous'
   connected = 0        /* 0=Not Connected; 1=Connected to Server */
   apistem   = 'FCAI.'  /* FTP Client API Stem Name */
   traceid   = 'TST'    /* Three Character Trace Entry Identifier */
   scmd      = ''       /* Server Command */
   Numeric Digits 15

   Arg debug .          /* 0=No FTP Debugging; 1=Set FTP Debugging */
   If debug \= 1 Then debug = 0

/*--------------------------------------------------------------------*/
/* Create FTP Client API Environment.                                 */
/*--------------------------------------------------------------------*/
   Say 'Creating FTP Client API Environment...'
   src = 'FTPAPI'(apistem,'CREATE',traceid)
   If src < 0 Then
      Do
         Say 'Error Creating the FTP Client API Environment RC='src
         Exit src
      End

/*--------------------------------------------------------------------*/
/* Enable FTP Client API Tracing (if DEBUG parameter specified).      */
/*--------------------------------------------------------------------*/
   If debug Then
      Do
         Say 'Turn FTP Client API Tracing On...'
         src = 'FTPAPI'(apistem,'SET_TRACE','ON')
         If src < 0 Then
            Do
               Say 'Error Turning FTP Client API Tracing On RC='src
               Exit src
            End
      End

/*--------------------------------------------------------------------*/
/* Initialize FTP Client API Connection and Connect to Server.        */
/*--------------------------------------------------------------------*/
   Say 'Connecting to Server' server'...'
   src = 'FTPAPI'(apistem,'INIT',server)
   If src < 0 Then Call API_ERROR
/*--------------------------------------------------------------------*/
/* Enter the Userid                                                   */
/*--------------------------------------------------------------------*/
   scmd = 'USER' userid
   src = 'FTPAPI'(apistem,'SCMD',scmd)
   If src < 0 Then Call API_ERROR
/*--------------------------------------------------------------------*/
/* Enter Password (if Required)                                       */
/*--------------------------------------------------------------------*/
   If src = 2 Then
      Do
         scmd = 'PASS'
         src = 'FTPAPI'(apistem,'SCMD',scmd password)
         If src < 0 Then Call API_ERROR
      End
   connected = 1        /* Connected to Server */

/*--------------------------------------------------------------------*/
/* Get List of Files and Sub Directories in the Root Directory.       */
/*--------------------------------------------------------------------*/
   Say 'Get List of Entries in Root Directory...'
   scmd = 'DIR'
   src = 'FTPAPI'(apistem,'SCMD',scmd)   /* Issue DIR Command */
   If src < 0 Then Call API_ERROR
   src = 'FTPAPI'(apistem,'GETL_COPY','FILE.','L')  /* Get DIR Results*/
   If src < 0 Then Call API_ERROR

/*--------------------------------------------------------------------*/
/* Process List Returned by DIR Command.                              */
/*--------------------------------------------------------------------*/
   filehdr = Left('File-Name',20) Left('Date',12),
             Right('Size-in-Bytes',18)
   If file.0 > 0 Then
      Do
         Say 'Process' file.0 'Entries in Root Directory...'
         Say filehdr
      End
   Else
      Say 'No Entries Found in Root Directory!'
   curyear = Left(Date('S'),4)
   Parse Value 0 With =1 m =1 dirs.0 .
   Do n = 1 to file.0
      Parse Var file.n flags . . . size mon day year sfile
      sfile = Strip(sfile)
      key = Left(flags,1)
      If key = 'd' Then
         Do
            m = m + 1
            dirs.m = sfile
            Iterate n
         End
      If key \= '-' Then Iterate n
      If Pos(':',year) > 0 Then year = curyear
      Say Left(sfile,20) mon day',' year Right(size,18)
   End /* Do n = 1 to file.0 */
   dirs.0 = m
   Drop file.
/*--------------------------------------------------------------------*/
/* Just Show the Number of Entries in each Sub Directory for this Demo*/
/*--------------------------------------------------------------------*/
   Do n = 1 to dirs.0
      dir = dirs.n
      Say 'Accessing Sub Directory "'dir'"...'
      scmd = 'CD' dir
      src = 'FTPAPI'(apistem,'SCMD',scmd)
      If src < 0 Then Call API_ERROR
      Say 'Get List of Entries in "'dir'"...'
      scmd = 'DIR'
      src = 'FTPAPI'(apistem,'SCMD',scmd)
      If src < 0 Then Call API_ERROR
      src = 'FTPAPI'(apistem,'GETL_COPY','FILE.','L')
      If src < 0 Then Call API_ERROR
      If file.0 > 0 Then
         Say 'Found' file.0 'Entries in "'dir'" Directory...'
      Else
         Say 'No Entries Found in "'dir'" Directory!'
      Drop file.
      Say 'Return to Root Directory...'
      scmd = 'CD ..'
      src = 'FTPAPI'(apistem,'SCMD',scmd)
      If src < 0 Then Call API_ERROR
   End /* Do n = 1 to dirs.0 */

   Call CLEANUP
   Exit 0

/*---------------------------- API_ERROR -----------------------------*/
/* FTP Client API Error Handling Routine.                             */
/*--------------------------------------------------------------------*/
API_ERROR:
   Arg parm .
   Say 'FTP Client API Error:'
   Say '    Result      =' Value(apistem'FCAI_Result')
   Say '    Status      =' Value(apistem'FCAI_Status')
   Say '    IE          =' Value(apistem'FCAI_IE')
   Say '    CEC         =' Value(apistem'FCAI_CEC')
   Say '    ReplyCode   =' Value(apistem'FCAI_ReplyCode')
   Say '    ReturnCode  =' Value(apistem'FCAI_ReturnCode')
   Say '    ReasonCode  =' Value(apistem'FCAI_ReasonCode')
   Say '    TraceStatus =' Value(apistem'FCAI_TraceStatus')
   Say '    SCMD Code   =' Value(apistem'FCAI_SCMD')
   If scmd \= '' Then Say '    SCMD Value  =' scmd

   If parm = 'RETURN' Then Return

   Call CLEANUP
   Exit 16

/*----------------------------- CLEANUP ------------------------------*/
/* Enter "QUIT" Command and Terminate the FTP Client API Environment. */
/*--------------------------------------------------------------------*/
CLEANUP:
   If connected Then
      Do
         Say 'DisConnecting from Server' server'...'
         scmd = 'QUIT'
         src = 'FTPAPI'(apistem,'SCMD',scmd)
         If src < 0 Then Call API_ERROR 'RETURN'
         connected = 0
      End
   Say 'Terminating FTP Client API Environment...'
   src = 'FTPAPI'(apistem,'TERM')
   If src < 0 Then
      Say 'Error Terminating the FTP Client API Environment RC='src

   Return

-- 
Dale R. Smith 

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN

Reply via email to