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