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