ZFTP is a file transfer program which supports the transfer of formatted, unformatted and ZEBRA RZ files (CMZ, HBOOK, etc.). Formatted files are typically KUIP macros, command or EXEC files, source code or even FZ ALPHA exchange format files. Unformatted files may be FZ binary exchange format or EPIO files, or any other binary file with fixed length records. ZFTP also provides LS, CD, PWD and RSHELL commands. It provides a common interface on all systems and the possibility of macros (via KUIP). It avoids the problems of file format conversion that occur when transferring binary files to UNIX systems.
PAM files may be transferred in CARD, CETA, CMZ or even compact binary PAM format. (In the first release this last format is limited to 32 bit machines.) This is particularly convenient for software distribution amongst disparate hardware types.
The advantages of using ZFTP are best explained via examples. Suppose one creates an HBOOK file (which is stored in ZEBRA RZ format) on the IBM and that is required on a VAX. Without ZFTP, the file must first be converted to sequential format using the RTOX utility. The output file can then be transferred to the VAX via Interlink or standard FTP but must then be reconverted to RZ format using the RFRX utility. This requires extra disk space on both sides for the sequential file and a three-step process. On some UNIX systems the situation is even worse as the file transferred by FTP cannot be read by RFRX but must be converted for a second time.
The same operation using ZFTP is much simpler:
1 The user issues the command ZFTP nodename and provides the remote
username and password much like with standard FTP.
2 The command PUTRZ local-file remote-file is issued.
Using this single stage operation the file is transferred with automatic conversion from IBM to VAX format. As the user interface of ZFTP is based on KUIP, the power of ZFTP may be extended using macros.
Data transfer rates are currently about 2/3 of those obtainable with standard FTP, but the effective transfer rate achieved by the elimination of the conversion to sequential format and back is much higher.
Example of a ZFTP session
VXST? zftp crnvmc
system 'crnvmc' service 'zserv'
Remote host/port = crnvmc/17303
Name (crnvmc:jamie):
fmsn201
Password (crnvmc:fmsn201):
crnvmc: loading zserv exec (30 sec timeout)...
Connected to crnvmc on TCP port 1305 at Wed Sep 19 12:43:49 1990
ZFTP>
ZFTP> pwd # Show current working directory
Current working directory is FMSN201 191
ZFTP>
ZFTP> cd fat3.192 # Change to FAT3 192
Remote directory changed to FAT3 192
ZFTP>
ZFTP> ls cspack.cards -l # Directory listing
CSPACK CARDS A1 F 80 10406 204 9/17/90 14:33:37 ZEBRA
ZFTP>
ZFTP> geta cspack.cards = s # Transfer file displaying statistics
File transfer completed
Transferred 261512 bytes, transfer rate = 4.636364 KB/S
Elapsed time = 00:00:55 CP time = 6.590000 sec.
ZFTP>
ZFTP> cd fmsn201 # Back to home directory
Remote directory changed to FMSN201
ZFTP>
ZFTP> ls
FATSENDR EXEC A1
FMCHARM2 KUMAC A1
FXFILE BIG A1
FXFILE DAT A1
GETZS EXEC A1
LASTING GLOBALV A0
PROFILE EXEC A1
ZSERV MODULE A1
ZFTP>
ZFTP> getb fxfile.dat = 32400 s # Transfer a ZEBRA FZ exchange file
File transfer completed
Transferred 10 records, transfer rate = 31.60000 KB/S
Elapsed time = 00:00:10 CP time = 0.9100000 sec.
ZFTP>
ZFTP> rm fmcharm2.kumac # Delete a remote file
ZFTP>
ZFTP>
ZFTP> cd fmcndiv
Remote directory changed to FMCNDIV
ZFTP>
ZFTP> getrz cern.fatrz = s
File transfer completed
NREC NWORDS QUOTA(%) FILE(%) DIR. NAME
2 1187 0.00 0.00 //RZ/CNDIV/CERNLIB/SUN
3 2211 0.00 0.00 //RZ/CNDIV/CERNLIB
2 1350 0.00 0.00 //RZ/CNDIV/JUDY
2 1839 0.00 0.00 //RZ/CNDIV/JAMIE
8 6424 0.01 0.01 //RZ/CNDIV
12 10520 0.01 0.01 //RZ
Transferred 41 KB, rate = 8.200000 KB/S
Elapsed time = 00:00:05 CP time = 0.6700000 sec.
ZFTP>
ZFTP> q
Table 4.1: ZFTP commands
+--------------+-------------------------+-----------------------------------+
| | | |
+-Command------+-Function----------------+-Description-----------------------+
| OPEN | Open connection | Establish connection to |
| | | specified host |
| | | |
| CLOSE | Close connection | Close connection with current |
| | | host |
| | | |
| GETA/PUTA | Text file transfer | Text file transfer, e.g. |
| | | scripts, EXECs, CARD pams etc. |
| | | |
| GETB/PUTB | Binary file transfer | Binary file transfer (fixed |
| | | length records only) e.g. ZEBRA |
| | | FZ binary exchange format, EPIO, |
| | | CETA files |
| | | |
| GETD/PUTD | Direct-access file | Direct-access file transfer e.g. |
| | transfer | ZEBRA RZ file between like |
| | | machines. |
| | | |
| GETRZ/PUTRZ | ZEBRA RZ file transfer | RZ file transfer with automatic |
| | | conversion between different |
| | | data representations, e.g. HBOOK |
| | | |
| | | histogram or ntuple files, CMZ |
| | | files. |
| GETFZ/PUTFZ | ZEBRA FZ file transfer | FZ file transfer with automatic |
| | | |
| | | conversion between different |
| | | data representations (currently |
| | | in preparation) |
| | | |
| GETP/PUTP | Compact binary PAM | Transfer a compact binary PAM |
| | transfer | file (not yet to Cray) |
| | | |
| CD | Change working | Set working directory on remote |
| | directory | node |
| LCD | Change working | Set working directory on local |
| | | |
| | directory | node |
| LS | Remote LS command | Make remote directory listing |
| | | |
| LLS | Local LS command | Make local directory listing |
| | | |
| MPUT | Put multiple files | Send all files matching the |
| | | specified pattern to the remote |
| | | machine. The mode of transfer is |
| | | determined by the file type: |
| | | .CET, .CETA = PUTB, .CMZ = |
| | | PUTRZ, other = PUTA |
+--------------+-------------------------+-----------------------------------+
The following example shows how individual records of a FORTRAN direct-access file may be accessed remotely. Example of remote access of records in direct-access file
common/pawc/paw(50000)
parameter (lrecl=4096)
dimension buff(lrecl)
*
* Initialise ZEBRA the easy way (get HBOOK to do it for us...)
*
call hlimit(50000)
*
* Open the file /fatmen/fmopal/cern.fatrz on node fatcat
* The record length is 4096 bytes
*
call xzopen(80,'/fatmen/fmopal/cern.fatrz','fatcat',
+ lrecl,'D',irc)
open(81,file='opal.fatrz',access='direct',recl=lrecl)
nrec = 0
*
* Now read each record in turn. Error is assumed to be end of file
*
10 continue
nrec = nrec + 1
call xzread(80,buff,nrec,lrecl,ngot,' ',irc)
if(irc.eq.0) then
write(81,rec=nrec) buff
goto 10
endif
*
* Terminate
*
call xzclos(80,' ',irc)
close (81)
end
The following program demonstrates file transfer using the FORTRAN callable routines. This program is used to transfer updates to the FATMEN catalogue, which are distributed as ZEBRA FZ files in ASCII exchange format, between CERNVM and the FATMEN server. It performs the following functions:
Table 4.1: ZFTP commands (continued)
+--------------+-------------------------+-----------------------------------+
| | | |
+-Command------+-Function----------------+-Description-----------------------+
| MGET | Get multiple files | Retrieve all files matching the |
| | | specified pattern from the |
| | | |
| | | remote machine. The mode of |
| | | transfer is determined by the |
| | | file type: .CET, .CETA = GETB, |
| | | .CMZ = GETRZ, other = GETA |
| | | |
| MV | Move (rename) remote | |
| | file | |
| | | |
| PWD | Print remote directory | Display current remote directory |
| LPWD | Print local directory | Display current local directory |
| | | |
| RM | Remove remote file | Remote file deletion |
| | | |
| LRM | Remove local file | Local file deletion |
| | | |
| RSH | Remote shell | Issue command to the remote |
| | | shell |
| VERSION | Version of ZFTP | Print version of the ZFTP |
| | | |
| | | program |
| SVERSION | Version of server | Print version of the remote |
| | | server (if connected) |
+--------------+-------------------------+-----------------------------------+
Example of file transfer using FORTRAN callable routines
PROGRAM FATCAT
*CMZ : 21/02/91 16.24.17 by Jamie Shiers
*-- Author : Jamie Shiers 21/02/91
* Program to move updates between CERNVM and FATCAT
*
PARAMETER (NMAX=100)
CHARACTER*64 FILES(NMAX)
CHARACTER*8 FATUSR,FATNOD,REMUSR,REMNOD
CHARACTER*64 REMOTE
CHARACTER*12 CHTIME
CHARACTER*8 CHUSER,CHPASS
CHARACTER*80 CHMAIL,LINE
COMMON/PAWC/PAW(50000)
PARAMETER (IPRINT=6)
PARAMETER (IDEBUG=3)
PARAMETER (LUNI=1)
PARAMETER (LUNO=2)
COMMON /QUEST/ IQUEST(100)
COMMON/SLATE/IS(6),IDUMM(34)
*
* Initialise ZEBRA
*
CALL HLIMIT(50000)
*
* Initialise XZ
*
CALL XZINIT(IPRINT,IDEBUG,LUNI,LUNO)
*
* Open connection to FATCAT...
*
CALL CZOPEN('zserv','FATCAT',IRC)
1 CALL VMCMS('EXEC FATSERV',IRC)
IF(IRC.EQ.3) GOTO 2
IF(IRC.NE.0) THEN
PRINT *,'FATCAT. error ',IRC,' from FATSERV. Stopping...'
GOTO 99
ENDIF
*
* Get the user and node name for this file...
*
CALL VMCMS('GLOBALV SELECT *EXEC STACK FATADDR',IC)
CALL VMRTRM(LINE,IEND)
ISTART = ICFNBL(LINE,1,IEND)
CALL FMWORD(FATUSR,0,' ',LINE(ISTART:IEND),IC)
LFAT = LENOCC(FATUSR)
CALL FMWORD(FATNOD,1,' ',LINE(ISTART:IEND),IC)
LNOD = LENOCC(FATNOD)
PRINT *,'FATCAT. Update received from ',FATUSR(1:LFAT), ' at ',
+ FATNOD(1:LNOD)
CALL DATIME(ID,IT)
WRITE(CHTIME,'(I6.6,I4.4,I2.2)') ID,IT,IS(6)
*
* Now put this file...
* This assumes the FATCAT naming convention: /fatmen/fmgroup,
* e.g. /fatmen/fml3
*
REMOTE = '/fatmen/'//FATUSR(1:LFAT)//
+ '/todo/'//FATUSR(1:LFAT)//'_'
+ //FATNOD(1:LNOD)//'.'//CHTIME
LREM = LENOCC(REMOTE)
CALL XZPUTA('FATMEN.RDRFILE.A',REMOTE(1:LREM),' ',IC)
IF(IC.NE.0) THEN
PRINT *,'FATCAT. error ',IC,' sending update from ',
+ FATUSR,' at ',FATNOD,' to FATCAT'
CALL VMCMS('#CP LOGOFF',IC)
ENDIF
CALL VMCMS('ERASE FATMEN RDRFILE A',IC)
*
* Are there any files for us to get?
*
2 CONTINUE
ICONT = 0
NFILES = 0
CALL XZLS('/fatmen/fm*/tovm/*',FILES,NMAX,NFILES,ICONT,' ',IC)
IF(ICONT.NE.0) THEN
PRINT *,'FATSRV. too many files - excess names ',
+ 'will be flushed'
*
10 CONTINUE
CALL CZGETA(CHMAIL,ISTAT)
LCH = LENOCC(CHMAIL)
IF(CHMAIL(1:1).EQ.'0') THEN
*
* Nop
*
ELSEIF(CHMAIL(1:1).EQ.'1') THEN
ELSEIF(CHMAIL(1:1).EQ.'2') THEN
GOTO 10
ELSEIF(CHMAIL(1:1).EQ.'3') THEN
IQUEST(1) = 1
IRC = 1
ELSEIF(CHMAIL(1:1).EQ.'E') THEN
IQUEST(1) = -1
IRC = -1
ELSEIF(CHMAIL(1:1).EQ.'V') THEN
GOTO 10
ELSE
IQUEST(1) = 1
IRC = 1
ENDIF
*
ENDIF
DO 3 I=1,NFILES
LF = LENOCC(FILES(I))
CALL CLTOU(FILES(I))
*
* Fix for the case when there are no files...
*
IF((NFILES.EQ.1).AND.
+ (INDEX(FILES(I)(1:LF),'DOES NOT EXIST').NE.0)) GOTO 1
*
* Remote file syntax is /fatmen/fm*/tovm
*
ISLASH = INDEXB(FILES(I)(1:LF),'/')
IF(INDEX(FILES(I)(ISLASH+1:LF),FATNOD(1:LNOD)).NE.0) THEN
PRINT *,'FATCAT. skipping update for ',FATNOD(1:LNOD),
+ '(',FILES(I)(1:LF),')'
GOTO 3
ENDIF
*
* Get the name of the server for whom this update is intended...
*
ISTART = INDEX(FILES(I)(1:LF),'/FM') + 1
IEND = INDEX(FILES(I)(ISTART:LF),'/')
REMUSR = FILES(I)(ISTART:ISTART+IEND-2)
LREM = LENOCC(REMUSR)
PRINT *,'FATCAT. update found for ',REMUSR(1:LREM),
+ '(',FILES(I)(1:LF),')'
CALL XZGETA('FATMEN.UPDATE.B',FILES(I)(1:LF),' ',IC)
IF(IC.NE.0) THEN
PRINT *,'FATCAT. error ',IC,' retrieving update'
GOTO 99
ENDIF
CALL VMCMS('EXEC SENDFILE FATMEN UPDATE B TO '
+ //REMUSR(1:LREM),IC)
CALL XZRM(FILES(I)(1:LF),IC)
IF(IC.NE.0) PRINT *,'FATCAT. error ',IC,' deleting file ',
+ '(',FILES(I)(1:LF),')'
3 CONTINUE
*
* Wait for some action...
*
GOTO 1
99 CALL CZCLOS(ISTAT)
END