Midrange News for the IBM i Community

Transfer Files or Save Files (SAVF) using FTP - FTPSNDFILE Published by: Bob Cozzi on 05 Jul 2011 view comments(1)
© 2011 Robert Cozzi, Jr. All rights reserved.

© Robert Cozzi, Jr. All rights reserved. Reproduction/Redistribution prohibited.
A midrangeNews.com Publication

FTP Files and Save File (SAVF) Between AS/400s (iSeries)

NOTE: A link to the companion source code for FTPSNDFILE is featured near the bottom of the article.

A few years back I wrote yet another popular CL command, FTPSNDFILE. This command simplifies FTP transfers between AS/400 systems. It was so popular with my readers and AS/400 developers that it is one of a growing package of tools that I've created that seem to be in just about every shop.

Basically, FTPSNDFILE allows you to transfer via FTP an AS/400 database file to another system. That other system does not need to be an AS/400, however. Sending the Customer Master file to another system in your own network is simply a matter of calling FTPSNDFILE like this:


For the last 7 years this command has been widely used and has "just worked". Recently however, I received a small number of requests to enhance FTPSNDFILE. This specifically focused on a request I received when I first published the command, but then heard nothing further. That request was to support the transfer of SAVF (save file) objects in addition to database files. Coincidentally, I also had a client who needed this capability so I decided to implement it.

Initially I thought it would take a lot of work and that I should create a separate command, perhaps FTPSNDSAVF, that would transfer only save file objects. I began looking at the old code and realized it was already doing most of what I needed it to do. So I worked a little magic, changed a few lines of code, and it worked the first time.

Sponsored by: DropBox.com
DropBox.com gives you a "sky drive" in the cloud that automatically syncs between your PCs, Mac, iPhone, Android, and just about everything (except IBM i). You can sign up for a free 2GB dropbox account here (that's what I use) . Purchase more space only when and if its needed. I've been using it for over a year and have had no issues. I highly recommend it. - Bob Cozzi

FTPSNDFILE - Source Code

The FTPSNDFILE command definition source code is listed below. It contains over a dozen parameter definitions and may be prompted both in a CLP program during SEU or RDp and from Command Entry.

 FTPSNDFILE: CMD        PROMPT('Send File Using FTP')

             /*  Command processing program is FTPSNDFILE  */
             /* (c) 2005 - 2011 by Robert Cozzi, Jr.       */
             /*  REQUIREMENTS:  FTP server must be active. */
             /*                 The FTP source file for    */
             /*                 the generated FTP script   */
             /*                 must exist, but the member */
             /*                 is automaticallyed added.  */
             /*                 The LOG file must exist    */
             /*                 and should be 79 or 80     */
             /*                 bytes in length--a typical */
             /*                 source file is acceptable. */

 IP:         PARM       KWD(RMTSYS) TYPE(*CHAR) LEN(128) MIN(1) +
                          EXPR(*YES) PROMPT('Remote IP or FTP server')

             PARM       KWD(MBR) TYPE(*GENERIC) LEN(10) DFT(*FIRST) +
                          SPCVAL((*FILE) (*FIRST) (*LAST) (*ALL)) +
                          EXPR(*YES) PROMPT('Local member')
 QUAL1:      QUAL       TYPE(*NAME) LEN(10) MIN(1) EXPR(*YES)
             QUAL       TYPE(*NAME) DFT(*LIBL) SPCVAL((*LIBL)) +
                          EXPR(*YES) PROMPT('Library')

 TOFILE:     PARM       KWD(TOFILE) TYPE(QUAL2) PROMPT('Remote file')
                          SPCVAL((*FROMMBR) (*TOFILE)) EXPR(*YES) +
                          PROMPT('Remote member')
 QUAL2:      QUAL       TYPE(*NAME) LEN(10) DFT(*FROMFILE) +
                          SPCVAL((*FROMFILE)) EXPR(*YES)
             QUAL       TYPE(*NAME) DFT(*FROMLIB) SPCVAL((*FROMLIB)) +
                          EXPR(*YES) PROMPT('Library')

                          DFT(*YES) SPCVAL((*YES '1') (*NO '0')) +
                          EXPR(*YES) PROMPT('Replace data on remote +

                          SPCVAL((*CURRENT)) EXPR(*YES) +
                          PROMPT('Remote FTP User ID')
 PWD:        PARM       KWD(PWD) TYPE(*CHAR) LEN(64) DFT(*USERID) +
                          EXPR(*YES) DSPINPUT(*PROMPT) +
                          PROMPT('Remote FTP Password')

 MODE:       PARM       KWD(MODE) TYPE(*CHAR) LEN(10) RSTD(*YES) +
                          DFT(*BINARY) SPCVAL((*BINARY BINARY) +
                          (*TEXT ASCII) (BINARY) (ASCII) (TEXT +
                          ASCII)) EXPR(*YES) PROMPT('Transfer mode')

                          to receive FTP script')
             PARM       KWD(SRCMBR) TYPE(*NAME) LEN(10) +
                          DFT(*FROMMBR) SPCVAL((*FROMMBR) (*GEN)) +
                          EXPR(*YES) PROMPT('Script source member')
             QUAL       TYPE(*NAME) DFT(QTEMP) SPCVAL((*LIBL)) +
                          EXPR(*YES) PROMPT('Library')

  /**  The LOG member can be a source or database file.        */
  /**  A record length of 79 or 80 or more than 80 is needed.  */
  /**  If the log file does not exist, it is created for you.  */
                          SNGVAL((*STDOUT) (*STDIO *STDOUT) +
                          (*SRCFILE) (*NONE)) PROMPT('FTP log file')
             PARM       KWD(LOGMBR) TYPE(*NAME) LEN(10) +
                          DFT(*FROMMBR) SPCVAL((*FROMMBR) (*SRCMBR +
                          *SCRIPT) (*SCRIPT)) EXPR(*YES) +
                          PROMPT('Log member')
             QUAL       TYPE(*NAME) DFT(QTEMP) SPCVAL((*LIBL)) +
                          EXPR(*YES) PROMPT('Library')

  /*  The follow parmaeter is ignored when LOG(*STDIO) is specified.  */
                          SPCVAL((*YES '1') (*NO '0')) EXPR(*YES) +
                          PROMPT('Display FTP transfer log')

When sending between AS/400's the RMTSYS, FILE and USER/PWD parameters are really all that's needed. The only time you would need to include, for example, the TOFILE parameter is when the file name on the target system should be different from the name on the originating system.

FTPSNDFILE defaults to the FTP transfer mode of BINARY. Normally you would never need to change this when sending between AS/400's. If sending a source file to a PC platform, then you may want to use the ASCII option for the MODE parameter.


FTP Script and Log

FTPSNDFILE generates a source file member to perform the FTP. This is called an "FTP Script". I use QFTPSRC as the source file name, and add a source member name that receives the script named the same as the member name of the file being transferred. The default QFTPSRC file's library is QTEMP. This means that FTPSNDFILE creates the source file at runtime, adds the source member, and then writes the generated FTP script out to that member. If you want to preserve the script you may want to create a QFTPSRC source file in your own library. Please use a record length of 112, RCDLEN(112) for all new source files you create.


Unlike the safety net of IBM i CL commands, FTP originated on a non-i platform, so it isn't as safe to use as, for example. the MOVOBJ command. There are few checks and definitely no "Are you sure?" prompts. So while there is a REPLACE keyword parameter on the FTPSNDFILE, its purpose is to include the (Replace clause on the PUT command. It does NOT insure that specifying REPLACE(*NO) will avoid replacing the target object. For example, when you send a save file to another AS/400, the target save file is replaced with the contents of the new save file regardless of the REPLACE parameter.

So make sure you are doing what you intend to do before using any non-IBM i interface, such as FTP.


In a previous issue of RPG Report, I wrote about D/R (disaster recovery) and a recent experience I had with a client of mine. The feedback I received was 99% positive, and I thank you for that. I did, however, receive one comment that basically said:

 "Bob, I've been reading your technical stuff for years, but this non-technical article on D/R bored me."

I do understand that people want continuous technical content that they can "take home and use immediately". That has sort of become a theme of mine over the last 28 years of writing this kind of material. Yes, I started writing in 1983.

So I've come up with a use for the FTPSNDFILE command (which is technical) that applies to the boring article I wrote last time on Disaster/Recovery. This use advocates saving your data and other objects to a traditional savefile, and then using FTPSNDFILE to copy those savefiles to a remote location.

I've added a Job Scheduler Entry that automatically backs up today's work to a save file and then using FTPSNDFILE and its new SAVF support, I send it to a remote AS/400 (in another country) for backup purposes. I even wrap it all in a CL program that retrieves the JOB DATE and uses that as the savefile name so that I get a fresh copy every time it is run, along with an archive of prior backups, just in case.

Yes I know that will fill up the remote system with backups, but I also know how to use the WRKOBJ command, and type in option 4 on the unwanted savefile archives.


Premium MidrangeNews.com members can download a ZIP file containing the FTPSNDFILE CMD and RPG IV source code. Simply transfer it up to a source file on your AS/400 using RDp or FTP and compile them with PDM option 14 or the right-click thing in RDp.

Download FTPSNDFILE.ZIP here

Make sure your FTP server is started, to do that use the STRTCPSVR *FTP command.

Then go ahead and transfer a file to another AS/400 using FTPSNDFILE. Be sure to prompt it (F4) so you specify all the parameters you need.

You're Welcome!

Call Me

Bob Cozzi is available for consulting or on-site training in RPG IV, SQL, and CGI/Web as well as perform contract programming. Currently many shops are asking Cozzi to join them for 1 to 3 days of Q&A and consulting with their RPG staff. The Staff gets to ask real-world questions that apply to their unique situations. Contact Cozzi by sending him an email at: bob at rpgworld.com

Look for Bob in the upcoming STARZ network TV production of "BOSS" a continuing TV series staring Kelsey Grammer of "Frasier" and "Cheers". Coming this fall only on the STARZ network. (First NASA, then CNN, now STARZ, what'll Cozzi do next?)

Bob also accepts your questions for use in future RPG Report articles or content for midrangeNews.com. Topics of interest include: RPG IV, Web development with RPG IV, APIs, C/C++ or anything else IBM i development related (except subfiles, data areas and RPGII/III because Bob doesn't care about that stuff) write your questions using the Feedback link on the midrangeNews.com website. 

You can subscribe to RPG Report (we call it "follow") by visiting the RPG Report page on midrangeNews.com and then click the FOLLOW link in the table of contents for that page. To unsubscribe, simply click that same link. You must be signed up and signed in to midrangeNews.com to start following RPG Report.

Follow Bob Cozzi on Twitter

Return to midrangenews.com home page.
Sort Ascend | Descend


(Sign in to Post a Comment)
Posted by: bobcozzi
Site Admin ****
Comment on: RPG Report - 05 JULY 2011
Posted: 7 years 5 months 19 hours 2 minutes ago

Please note that this command has been replaced with the FTPFILE command found in COZTOOLS. Visit www.cozTools.com for details.