ddname support with FTP

This section describes how the FTP client transfers a data set or file allocated in the JCL for a batch job or by an interactive user prior to the transfer. The FTP client refers to the data set with the ddname used on the allocation.

The FTP Client API does not support ddname transfers. The ddnames associated with a batch job that invokes an application program using the FTP Client API are not available to the created FTP client process.

The //DD: token prefixed before a 1–8 character local file name on a client file access command indicates that the token which follows is actually a ddname, rather than a local file name. This ddname must be allocated by the user (for example, in the JCL that started the FTP client). The server file name must be explicitly specified when a ddname is being used to access a local file for a put command.

Sometimes the client requires DCB information before it opens a data set. Among the situations where this is true are:
  • Reading and writing spanned records (RECFM=VS or VBS)
  • Reading and writing records that contain ASA control characters
  • Reading and writing variable-length records while preserving the RDW
  • Reading and writing fixed-length records while preserving trailing blanks

When a data set is allocated using a ddname and the DCB information is needed before open, the FTP client must be able to find the DCB information on the DD statement that was used to allocate the data set.

DCB attributes for a ddname allocation are acquired using the attributes or data set name specified in the DD statement DCB parameter. See the z/OS MVS JCL Reference for restrictions on using backward references in the DCB parameter.

If the DD statement refers to a cataloged DASD data set, any DCB attributes that are not specified are retrieved from the DSCB. DCB attributes on the DD statement override those found in the DSCB, except that LRECL=0 and BLKSIZE=0 do not override a different value in the DSCB.

If the DD statement refers to a tape data set that is to be opened for input (PUT //DD:), the record format that is specified on the DD statement is used instead of the READTAPEFormat setting. If no record format (RECFM) is specified on the DD statement, the READTAPEFormat setting (if any) is used.

Once the data set is opened by FTP, its attributes are set using the data returned in the DCB by open.

Restrictions:
  • If you pass a dynamically allocated ddname to a batch job, do not allocate the ddname using the XTIOT, UCB nocapture, or DSAB above the 16 MB line options.
  • The MVSGet subcommand does not support specifying the local data set as a ddname.
  • To prevent transferring data from an empty file, FTP checks whether the first file in a concatenation series is empty and allocates an empty data set. No data is transferred.

    If you use BSAM to transfer a series of concatenated files, each file in the series must not be empty. That is, they must have a valid end of file indicator set.

    For concatenated data sets, if any of the files are empty, you can use the PUT and APPEND commands to transfer the data sets. If one of the data sets is empty, the next command continues to run and the additional data is concatenated.

    put     //dd:infile1 target.ds
    append  //dd:infile2 target.ds   
    append  //dd:infile3 target.ds

    Following is a sample JCL that illustrates the problem where input consists of concatenated data sets with the first file USER35.GDG1 being empty and the remaining files not being empty. FTP checks an empty data set on the first file, resulting in the transfer of a null file.

    //STEP02 EXEC PGM=FTP,REGION=2048K,PARM='(TCP TCPCS TRACE'
    //STEPLIB DD DSN=USER33.LINKLIB,DISP=SHR 
    //SYSPRINT DD SYSOUT=* 
    //INFILE1 DD DSN=USER35.GDG1(+1),DISP=SHR          
    //        DD DSN=USER35.GDG2(+1),DISP=SHR
    //        DD DSN=USER34.FILE,DISP=SHR 
    //OUTPUT DD SYSOUT=* 
    //INPUT DD * 
    9.67.113.57 21 
    USER33 **pw** 
    put //DD:INFILE1 remote.file 
    quit  
    /*

    To resolve this problem, you can use the following sample JCL instead:

    //STEP02 EXEC PGM=FTP,REGION=2048K,PARM='(TCP TCPCS TRACE' 
    //STEPLIB DD DSN=USER33.LINKLIB,DISP=SHR 
    //SYSPRINT DD SYSOUT=* 
    //INFILE1 DD DSN=USER35.GDG1(+1),DISP=SHR
    //INFILE2 DD DSN=USER35.GDG2(+1),DISP=SHR
    //INFILE3 DD DSN=USER34.FILE,DISP=SHR 
    //OUTPUT DD SYSOUT=* 
    //INPUT DD * 
    9.67.113.57 21 
    USER33 **pw** 
    put //DD:INFILE1 remote.file 
    append //DD:INFILE2 remote.file 
    append //DD:INFILE3 remote.file 
    quit 
    /* 
    Note: This restriction applies to all types of data sets, not only GDG data sets.
Following is a sample job that shows usage of the //DD: token. In the sample job there are two data sets that use the local file specification with the //DD: token. One is a data set that is created as a new GDG data set in STEP01 (see the OUTSET DD statement). Note that STEP02 (the FTP step) uses a backward reference with the DD02 DD statement to locate the data set. Since the referenced DD statement contains explicit DCB attributes, FTP can access the attributes prior to opening the data set. The second data set is an old data set that existed before the job was executed.
 
	//USER33J  JOB  MSGLEVEL=1,MSGCLASS=H,USER=USER33,PASSWORD=**pw**
	//STEP01   EXEC PGM=IEBDG
	//SYSPRINT DD  SYSOUT=A
1	//OUTSET   DD  DSNAME=USER33.MYGDG(+1),DISP=(NEW,CATLG,CATLG),
 	//             VOLUME=SER=CPDLB1,SPACE=(TRK,(5,5)),UNIT=SYSDA,
	//             DCB=(RECFM=FB,LRECL=80,BLKSIZE=800)
	//SYSIN    DD  *
		< create statements >
	//STEP02   EXEC PGM=FTP,REGION=2048K,PARM='(TCP TCPCS TRACE'
	//STEPLIB  DD  DSN=USER33.LINKLIB,DISP=SHR
	//SYSPRINT DD  SYSOUT=*
2	//DD01     DD  DSNAME=USER33.TEST.S.A,DISP=OLD
3	//DD02     DD  DSNAME=*.STEP01.OUTSET,DISP=SHR
	//OUTPUT   DD  SYSOUT=*
	//INPUT    DD  *
	9.67.113.57 6321
	USER33 **pw**
4	put   //DD:DD02   data
5	get   data   //DD:DD01
	quit
	/*
Following are short descriptions of the numbered items in the example.
1
DD statement that allocates a new generation of a GDG data set
2
DD statement for an existing data set
3
Backward reference for the new data set in STEP01
4
Put subcommand using the //DD: token for the new data set created in STEP01
5
Get subcommand using the //DD: token for the existing data set
The FTP output for the above job is the following. Note that only a few selected FTP trace statements are shown.
	EZA1736I FTP (TCP TCPCS
	EZA1450I IBM FTP CS V1R5 2003 090 19:22 UTC
	EZA1466I FTP: using TCPCS
	EZA1456I Connect to ?
	EZA1736I 9.67.113.57 6321
	EZA1554I Connecting to:  9.67.113.57 port: 6321.
	220-FTPDJG1 IBM FTP CS V1R2 at MVS164, 14:58:36 on 2003-01-01.
	220 Connection will not timeout.
	EZA1459I NAME (9.67.113.57:USER33):
	EZA1701I >>> USER USER33
	331 Send password please.
	EZA1701I >>> PASS
	230 USER33 is logged on.  Working directory is "/u/user33".
	EZA1460I Command:
1 	EZA1736I put   //DD:DD02   data
2 	MF0680 seq_open_file: DDname DD02 has filename USER33.MYGDG.G0087V00
	EZA1701I >>> PORT 9,67,113,57,6,158
	200 Port request OK.
	EZA1701I >>> STOR data
	125 Storing data set /u/user33/data
	250 Transfer completed successfully.
	EZA1617I 820 bytes transferred in 0.020 seconds.  Transfer rate 41.00 Kbytes/sec.
	EZA1460I Command:
3 	EZA1736I get   data   //DD:DD01
4 	MF0680 seq_open_file: DDname DD01 has filename USER33.TEST.S.A
	EZA1701I >>> PORT 9,67,113,57,6,159
	200 Port request OK.
	EZA1701I >>> RETR data
	125 Sending data set /u/user33/data
	250 Transfer completed successfully.
	EZA1617I 820 bytes transferred in 0.030 seconds.  Transfer rate 27.33 Kbytes/sec.
	EZA1460I Command:
	EZA1736I quit
	EZA1701I >>> QUIT
	221 Quit command received. Goodbye.
1
Put subcommand using //DD: token for the local file
2
Trace statement showing that the local data set name is the new GDG data set that was created in STEP01
3
Get subcommand using //DD: token for the local file
4
Trace statement showing that the local data set name is the existing data set.