Practical Programming for AS/400 FTP Automated Interfaces

Back to Tylogix Home Page
Link to the Tylogix iSeries & AS/400 Q&A Page
AS400 Pro iSeries FTP Tips & Techniques
A more recent article, same topic: Automate Your File Transfers Using FTP on the IBM i
How the FTP protocol Challenges Firewall Security Exellent FTP and TCP/IP resource center from Tech Target


By Thibault Dambrine

See the new AS/400 FTP Question & Answer SheetAS/400 FTP Question & Answer Sheet
This brand-new page re-groups a number of user questions and answers related specifically to the use of FTP on the AS/400. You can find this page in the following link: AS/400 FTP Q&A

In this article, I will focus on File Transfer Protocol or FTP and programming techniques for this most convenient communication tool on the AS/400. A lot has been written on FTP and how convenient it is for communicating with virtually any other system now being built.

But how would you really go about using it in an application? Something built for real life work, happening every day in your shop, like an application that would run daily as part of your regular MIS Operations cycle.

Most of us have used FTP for the occasional file transfer here and there. When used like that, it really feels like a handy utility to have in a pinch. Something akin to DSPPFM in the field of Data Transfer.

Being able to do a manual transfer here and there is one thing, but to get some real use for this type of utility, you would need to be able to program it and control it using table-driven variables. How would you automate an FTP function? How would you go about creating a process to transfer a different file every day to different systems, the same file to different destinations or a combination of both?

In the next few paragraphs, you will get a good idea of how you can make FTP work for you, using everyday CL, RPG or any other high level language on the AS/400.

I will discuss configuration points to consider, FTP theory, the FTP command set and the practical aspects of how to implement FTP in a working program on the AS/400.

As mentioned before, FTP runs over TCP/IP. With the popularity of the Internet, this is probably the fastest growing communication protocol at this time. Since TCP/IP is all about communications between systems, the best way to start this article is to discuss the configuration aspects of TCP/IP on the AS/400.

If your AS/400 is not configured for TCP/IP communication, this is the place to start. You will need *IOSYSCFG authority on your own AS/400. You will also have to know some information about the system(s) you are aiming to connect to, and the specifics on how to get yourself connected to the destination(s) you are aiming to use (lines, configurations etc.)

AS/400 TCP/IP supports an extensive list of LAN and WAN connection types: Ethernet, token-ring, SDDI, FDDI, wireless LAN, X.25 SVC, PVC and frame relay. All this to say, it is flexible, but it requires attention to each individual situation. Documenting every situation would probably take a whole manual, and thus, I re-direct you to the IBM Manuals. In this case, the "TCP/IP Configuration and Reference, Document Number SC41-5420-00". Since this piece is about FTP, this is where I will stop for the configuration. From this point forward, the assumption is that you are configured for TCP/IP and your configuration is active.

How does FTP work?

To start with, here is a little bit of theory:

FTP consists of two parts: the Client and the Server. This Client/Server theme is common in the TCP/IP world.

The client has a user interface from which you can enter client FTP subcommands for making requests to an FTP server. The results of these requests are then displayed.

To transfer files between the client and the server, two connections are established: The control connection and the data connection. The control connection is used to request services from the server with FTP server subcommands. The server sends replies back to the client to indicate how the request was handled. The second connection, known as the data connection, is used for transferring lists of files and the actual file data.

Both the client and the server have a data transfer function that interfaces to the resident file systems. These functions read or write data to the local file systems and to and from the data connection.

Requests for transferring files originate from the client. The user makes these requests with the FTP client subcommands that are read by the client user interface function. The client subcommands are interpreted by the client protocol interpreter, which translates them into appropriate FTP server subcommands. The server protocol interpreter receives the subcommands from the control connection and processes it. The results of each server subcommand are transmitted back to the client in the form of an FTP server reply.

The distinction between FTP client and FTP server is from the viewpoint of where the FTP commands are initiated, not from the viewpoint of where the data resides. Thus, the commands are initiated from the FTP client session, while the files being transferred may initially reside on either system.

The File Transfer Protocol client function allows you to send and receive copies of files to or from remote systems across a TCP/IP network. In addition, FTP commands are provided for renaming, appending to and deleting files. I will concentrate on the basic functionality and usage, rather than the theory behind the protocol.

Getting familiar with the FTP Command Set:

You can start FTP on the AS/400 by simply typing the command "FTP" from the Command Entry Line. The system will prompt you for the remote system name you want to connect to, your user profile and your password. If you are not connected to any other system yet but are curious to experiment, you can use the name "LOOPBACK" as the remote system. This will effectively route your FTP command requests to the system you are on currently.

A LOOPBACK connection will yield a message that looks like "Connecting to host LOOPBACK at address using port XX", where XX is a port number. Note the address, This is an address referred to as a "Well Known Port". This means that in any machine supporting TCP/IP, there is a address that refers to itself. There are several Well Known Ports and they are covered in the TCP/IP configuration manual. Connecting to any other system will yield a similar message with the address of the system you are logging on to.

If you are a new TCP/IP user, to see how much you can use in this realm, simply type "HELP" on your FTP command line once you have logged on . By "logged on", I mean logged on to FTP rather than just "signed on" to the AS/400. This will work even if you have a local connection to LOOPBACK. This command will show the following menu:
 FTP Client Subcommands - Help 
 !______ ?______ ACCT___ APpend_ AScii__ Binary_ 
 CD_____ CDUp___ CLose__ DEBug__ DELete_ DIr____ 
 EBcdic_ Get____ Help___ LCd____ LOCstat LPwd___ 
 LS_____ LType__ MDelete MGet___ MKdir__ MOde___ 
 MPut___ NAmefmt NOop___ Open___ PAss___ PUt____ 
 PWd____ QUIt___ QUOte__ REInitialize______ REName_ 
 RESet__ RMDir__ SENDPort__________ SENDSite__________ 
 SIte___ STAtus_ STRuct_ SUnique SYSCmd_ SYSTem_ 
 TYpe___ User___ Verbose
 You can abbreviate subcommands to the most unique series of characters. 
 For example, you can type AP for the APPEND subcommand. 
 In addition to these subcommands the FTP client accepts synonyms for 
 certain subcommands. 
 If the remote system is an AS/400 system, some server subcommands are 
 F2=Extended help F3=Exit help F10=Move to top F12=Cancel 
 F13=Information Assistant F14=Print help F20=Enlarge 
Figure 1

The commands shown in Figure 1, starting with "!" and ending with "Verbose", are all colored yellow. If you position your cursor on top of any of these commands and hit ENTER, you will get a new screen with all the syntax details of the command you have selected and how to use it.

Here are some of the commands I use the most when dealing with FTP:

"PING", the PING command actually runs outside of the FTP realm. It is useful, in advance of connecting, to verify if the connection between your machine and the remote system is active. To verify the connection between two systems, the PING instruction, followed by the system name you are targeting will send a simple message that will be answered by the remote machine with an echo-like response. No password is necessary in this case, the aim of PING is simply to verify if the connection is alive between two systems. If it is, you will likely have no problems using FTP.

If for example, you do a "PING LOOPBACK" from your command line, you will get the following messages:

Verifying connection to host system LOOPBACK at address

and a communication status that will be verified 5 times:

Connection verification 1 took .001 seconds. 1 successful connection verifications.

After that, you will get the result of the test:

Round-trip (in milliseconds) min/avg/max = 0/0/1

Connection verification statistics: 5 of 5 successful (100 %)

"!" or "SYSCMD" lets you type in commands that will execute on the local AS/400 while you are in FTP mode. This is practical, as you can submit commands directed at your local system without having to leave the FTP mode. You could try "! PING REMOTESYSTEM" for example.

"DIR" lets the user see libraries and their entries (files and members) or the list of directories and directory entries on the remote system. This is practical to see if a file is there to be taken or to verify if a file has arrived after a "PUT".

"PUT" lets you send or "PUT" a file from your local AS/400 to the remote system.

"GET" lets you retrieve or "GET" a file from the remote system to the local AS/400.

"ASCII", "BINARY" and "EBCDIC" are ad-hoc commands that qualify your "PUT" or "GET" commands. IBM as a whole tends to work with EBCDIC. The rest of the world tends to work in ASCII. These commands help you manage the way the data is transmitted. The target file arrives in either ASCII, EBCDIC or as an exact (untranslated) replica of the original if you specify "BINARY". One note of caution, if you send files containing numeric data from your AS/400 to an ASCII-based system, ensure that all numeric fields are zoned and not packed. This will ensure the EBCDIC to ASCII table will recognize and translate all your numeric data correctly. If you try to use an ASCII to EBCDIC translation table on numeric packed fields, the results will be completely unpredictable.

"RENAME" lets the user rename a file on the remote system. This may be practical if, after successfully GETting a file, you wish to give it a new name to the original file on the remote system.

"QUOTE" lets the user send a command directly to the FTP server on the remote system, the command string is sent verbatim to the other system. This may be useful to trigger a process on the remote system after having transferred a file to or from it.

"STRUCT R" ensures records are transmitted record by record (as opposed to a continuous stream of bytes, the default). FTP by default transmits data as a continuous stream of bytes. If it encounters carriage return characters, it starts a new record on the destination file, regardless of the record length in the originating file. If for example you are transmitting binary coded decimal data, this may cause unpredictable record lengths in the destination file. Using "STRUCT R" as an option will ensure the original record lengths is respected, regardless of the presence of carriage return characters within the record.

To put this all into action, here is a practical example showing how to implement FTP in a program on the AS/400:

As explained earlier, FTP is a nifty tool to quickly transfer files by hand between systems but its real power can only be exploited by writing a program. The way to incorporate FTP into your programming is not very difficult. It does however take some knowledge of key elements.

FTP, on the AS/400, runs from the CL language environment. Here is the methodology:

The first step is to create a source member to contain your FTP instructions. This member can be left in a source file, or it can be re-built at the time of running the FTP Driver Application. This source file will contain your FTP logon and file transfer instructions. What ever you do, it is not desirable to store the user profile and password in an easily accessible source file. A hybrid solution consists of keeping a source member as a template and using an RPG or any other HLL program to replace the values that need to change. In Figure 2 example, we have a source member in which USRPRF, PASSWORD and the two LIBRARY/FILE.MEMBER combinations can be replaced by a program just before running the FTP command. Another solution would consist of writing each and every record in the source file member, in QTEMP, with an RPG (or any other HLL) program that would concatenate every element of each line as it goes.

The example below for TEMPLATE shows a simple scenario where we want to PUT our LOCALFILELIBRARY/LOCALFILENAME (from our AS/400) to a REMOTEFILENAME in REMOTEFILEDIR on a remote system The logon sequence is taken care of by the actual values replacing USRPRF and PASSWORD.

TEMPLATE Source Member:
0003.00  CLOSE
0004.00  QUIT
Figure 2

The second step is to create an FTP driver program that will actually run these commands. This will be done in a CL program. The following is a bare-bones program sample that will process the commands in the member TEMPLATE.

Here, in four points, is the methodology for FTP implementation on OS/400 :

Build the FTP commands in a temporary source member
Override the source member containing the FTP commands to INPUT
Override the source member that will receive the result of the FTP commands to OUTPUT
Use the command "FTP RMTSYS(REMOTESYS)", where REMOTESYS is the remote system, to process the FTP requests. FTP will automatically pick up the commands from the source member overridden to "INPUT" and write the results in the source member overridden to "OUTPUT". Note that REMOTESYS can also be a CL variable.
0001.00 BEGIN: PGM
0003.00 /* *---------------------------------------------------------------* */
0004.00 /* Copy The FTP input file & member in QTEMP                         */
0005.00 /* *---------------------------------------------------------------* */
0011.00 /* *---------------------------------------------------------------* */
0012.00 /* * Call the RPG program to update the FTP input member           * */
0013.00 /* *---------------------------------------------------------------* */
0016.00 MBR(TEMPLATE) /* Override to the +
0017.00 member containing input commands for the +
0018.00 FTP transmission so that it can be +
0019.00 updated with the proper parameters for +
0020.00 user profile, password, file to transfer +
0021.00 to & from and direction (put or get) of +
0022.00 the transfer. */
0025.00 CALL PGM(CUSTOMIZE) PARM(&PARMS) /* Update the +
0026.00 FTP input instructions member With the +
0027.00 proper UserProfile, Password, and file +
0028.00 characteristics. */
0031.00 /* * CREATE FTP OUTPUT file & member in QTEMP */
0034.00 TEXT('Output for FTP Result.')
0037.00 /* *---------------------------------------------------------------* */
0038.00 /* * Do the actual FTP transmission using the instructions in      * */
0039.00 /* * member INPUT and putting the result of the transmission in    * */
0040.00 /* * member OUTPUT. Note that INPUT and OUTPUT are overridden.     * */
0041.00 /* *---------------------------------------------------------------* */
0044.00 MBR(TEMPLATE) /* Override to the member +
0045.00 containing input commands for the FTP +
0046.00 transmission. */
0049.00 MBR(OUTPUT) /* Override to the +
0050.00 member that will contain the response +
0051.00 messages from FTP. They can be examined +
0052.00 after the transmission is finished. */
0054.00 FTP RMTSYS(REMOTESYS) /* This is the actual FTP Command Request      */
0057.00 results of this transmission. */
0059.00 /* *---------------------------------------------------------------* */
0060.00 /* * Call the RPG program to evaluate the result of the output file* */
0061.00 /* *---------------------------------------------------------------* */ 
0063.00 CALL PGM(EVALUATE) /* On a +
0064.00 "put", look at the result member for +
0065.00 succesful FTP completion. On a "get", +
0066.00 look at both the FTP completion messages +
0067.00 and compare the number of records in the +
0068.00 file received. */
0072.00 ENDPGM
Figure 3


As mentioned earlier, how you build the INPUT source member can be done in many ways. In this case, I have used a template that a program then changes. You can build it however you want, as long as the FTP syntax is correct. In this case, the INPUT member is in QTEMP. This way, when the job ends the customized file and member containing the user profile and password to the remote system disappear with the end of the job. Others may choose to create all the records at the last minute, not using a template.

This INPUT member example shows a PUT action. You can do a GET, a RENAME or any other legal FTP instruction and it will work the same way, provided the syntax is good.

What you want to do with the OUTPUT member is your choice. You don't have to do anything with it if you don't want to. I have found it convenient to read it in a program and analyze the FTP responses to figure out if the transfer was successful. As it turns out, you will notice in an automated process, knowing if you are successful in your transfer is just as important as transferring the data itself. The technique to figure out if the transfer went well is to read the OUTPUT member and look for certain FTP messages.

If you design a prototype application, you can run it with the address LOOPBACK. You can send a file for example from one library to another on the same system.

Note: When communicating with a UNIX operating system based system, the AS/400 file format notation "LIBRARY/FILE(MEMBER)" is translated as "DIRECTORY/FILE.MEMBER", where the member name becomes the extension. This relationship goes both ways, i.e. if you GET a file from a UNIX based remote system, the extension of that file will be used as the member name.

Note: Most times, having just the User Profile and the Password is enough. However, some operating systems and their FTP servers are more picky. You might have to provide explicit logon commands, as in "USER USERNAME" and then "PASSWORD USERPASSWORD". Another consideration, when it comes to communicating with systems other than AS/400 is lower-case passwords. If the system you are communicating with has a case-sensitive password, you could get frustrating experiences of not getting in even if you have the correct password (however in incorrect case, e.g. "Password" instead of "password"). The error message will not tell you anything too explicit.

Here are several examples of what you could get as an FTP OUTPUT.

This is an example of what you could get as an FTP output, note that the password used will not be transcribed into that OUTPUTmember by FTP, only the User Profile is showing. In this case, the transmission was successful. This transmission was done from an AS/400 system to an IBM MVS system. Here, the success message is 250, "File transfer completed successfully". An easy way to have a physical trace of the transfer is to do a simple CPYF to *PRINT of this member after the transfer has occurred.

Sample OUTPUT result for a successful FTP communication to MVS System
*************** Beginning of data ***************************************** 
0001.00   Output redirected to a file. 
0002.00   Input read from specified override file. 
0003.00   Connecting to host 999.999.99.9 using port 99. 
0004.00   220-FTP IBM MVS V3R2 at XXXX, 18:33:22 on 1998/08/01 
0005.00   220 Connection will close if idle more than 5 minutes. 
0006.00   MVS is the operating system of this server. 
0007.00   Enter login ID (TESTUSER): 
0008.00   331 Send Password Please. 
0009.00   230 TESTUSER logged on. Working Directory is "TESTUSER.". 
0010.00   Enter an FTP subcommand. 
0012.00   200 Port request OK. 
0013.00   125 Sending data set DATA.SET.NAME 
0014.00   250 Transfer completed successfully. 
0015.00   2530952 bytes transferred in 63.651 seconds. Transfer rate 39.763 KB/sec. 
0016.00   Enter an FTP subcommand. 
0017.00   > CLOSE 
0018.00   221 QUIT subcommand received. Goodbye. 
0019.00   Enter an FTP subcommand. 
0020.00   > QUIT 
Figure 4

Note:The text in the 250 code and other FTP return codes can vary depending on the system you are communicating with. It may say "Transfer completed successfully" in the case of an AS/400 to MVS system or "File transfer completed successfully" in the case of a transfer from AS/400 to AS/400. Also, in the case of a loopback to AS/400, the 250 message may appear twice. Once saying "Now using naming format "0" and once saying "File transfer completed successfully". These are subtle differences, but basically you should check the message number rather than the text with your error checking program.

When you write your error checking program it is a good idea to experiment first and check for the success messages that you can expect from what ever combination of systems you are transferring from and to.

Here is a sample of a transfer from an AS/400 to my own PC, using the Reflections 5250 emulator & FTP server product as a remote system. Note the differences in how the output can vary when communicating with one system or the other.

Sample OUTPUT result for a successful FTP communication to my own PC, using Reflections 5250 emulator and FTP server.
*************** Beginning of data ***************************************** 
0001.00 Output redirected to a file. 
0002.00 Input read from specified override file. 
0003.00 Connecting to host 999.999.99.9 using port 99. 
0004.00 220 Reflection FTP Server Version 6.20 Thursday 08/20/1998 15:07:44 
0005.00 Reflection FTP Server. 
0006.00 Enter login ID (TESTUSER): 
0007.00 Guest login OK 
0008.00 Welcome Message from Reflections PC Server 
0009.00 230 TESTUSER logged in. 
0010.00 Enter an FTP subcommand. 
0012.00 200 Port request successful. 
0013.00 150 Transfer started from file "C:\DATA.TXT" (46 bytes) 
0014.00 226 Transfer complete (0.00 KB/sec) 
0015.00 46 bytes transferred in 13.532 seconds. Transfer rate 0.03 KB/sec. 
0016.00 Enter an FTP subcommand. 
0017.00 > CLOSE 
0018.00 221 Goodbye. 
0019.00 Enter an FTP subcommand. 
0020.00 > QUIT 
Figure 5

Note that in this case, we did not receive the 250 message at all. Rather, we got a 226 message, its equivalent. This is another illustration of how different systems can respond. Again, a reminder to test and try the communication manually to see what you get message-wise when you transmit data between any two systems. Of course, you can code an FTP result checking application that can check for 250 and 226 return codes. This is probably the best thing to do. The Microsoft FTP Service (no example provided here but I did try it) also yields a 226 message rather than a 250.

Here is an example of a failed transmission. The easiest way to know that things went wrong is that you will not find in this OUTPUT member any successful completion message. Failing to find such a message, your program can notify you for failure.

Sample OUTPUT result for a failed FTP communication
*************** Beginning of data ***************************************** 
0001.00 Output redirected to a file. 
0002.00 Input read from specified override file. 
0003.00 Connecting to host ABCZZZ at address 999.999.99.9 using port 99. 
0004.00 220-QTCP at AAABBBCCC. 
0005.00 220 Connection will close if idle more than 10 minutes. 
0006.00 215 OS/400 is the remote operating system. The TCP/IP version is "V3R1M0". 
0007.00 Enter login ID (TESTUSER): 
0008.00 331 Enter password. 
0009.00 230 TESTUSER logged on. 
0010.00 250 Now using naming format "0". 
0011.00 257 "TESTUSER" is current library. 
0012.00 Enter an FTP subcommand. 
0015.00 501 Specified object name too long, limit is 10 characters: REMOTEFILENAME. 
0016.00 Enter an FTP subcommand. 
0017.00 > CLOSE 
0018.00 221 QUIT subcommand received. 
0019.00 Enter an FTP subcommand. 
0020.00 > QUIT 
Figure 6

As you can see, the results of the FTP commands are preceded by a reply code. The reply code list can be found in the TCP/IP Configuration and Reference manual, but in case you don't have it, here is a copy:

FTP Reply Codes
Code  Description 
110  Restart marker reply 
120  Service ready in nnn minutes 
125  Data connection already open; transfer starting 
150  File starting OK; about to open data connection 
200  Command OK 
202  Command not implemented; not used on this system 
211  System status, or system help reply 
212  Directory status 
213  File status 
214  Help message 
220 Service ready for new user 
226  Closing data connection; requested file action successful
230 User logged in 
250  Requested file action okay, completed 
257  Path name created 
331  Password required 
332  Account required 
425  Cannot open data connection 
426  Connection closed; transfer ended abnormally 
450  Requested file action not taken; file busy 
451  Requested action ended abnormally; local error in processing
452  Requested action not taken; insufficient storage in system space
500  Syntax error; command unrecognized 
501  Syntax error in parameters or arguments 
502  Command not implemented 
503  Bad sequence of commands 
504  Command not implemented for that parameter 
530  Logon attempt rejected 
532  Need account for storing files 
550  Requested action not taken; file not found or no access 
551  Requested action ended abnormally; page type unknown 
552  Requested file action ended abnormally; exceeded storage allocation 
553  Requested action not taken; file name not allowed 

The code examples supplied above are basic in nature. They do not include the RPG programs necessary to plug in user profiles, passwords and library/file names necessary to do actual transfers. They also do not include any example programs to read the OUTPUT result member and verify success or failure of a transfer. These programs can be coded in several languages and hopefully, there is enough information here to start a programmer on the path of FTP automation for your AS/400 applications. Another point to take note of is that all fatal errors have error numbers greater or equal to 331. This can be used as a method to check for failure rather than success (i.e. looking for 250 or 226 codes).

In Conclusion

More and more, rather than using a tape or any other physical media transfer, the IS user community is demanding file transfer solutions that are seamless and do not require physical intervention. In this respect, FTP is a simple, cost-effective solution. It is easy to implement and it comes built-in with OS/400.

The business of transferring data between different types of machines is growing in every direction. Competition for FTP's simple abilities abound. IBM's MQ series product, for example, promises guaranteed queued data delivery to virtually any type of remote system. Products like NDM, INFOPUMP and BEA's TUXEDO to name only a few, propose products that will transfer data seamlessly between systems with recovery features that help IS managers sleep more comfortably (at a cost!).

In this perspective, FTP is a simple product. It has some advantages, being bundled with OS/400 and is relatively easy to program & operate (read cheap). It does however have short-comings on the recovery side. This is an exposure to consider if you deal with sensitive data. If you decide to use FTP on a regular basis, especially in production mode, verification of the success of your transfer and recovery procedures will be an issue to look into. On the bright side, physical communication links these days are very reliable. My personal experience with FTP is that most times, a communication failure will usually come from a system problem rather than a "wire" link problem. Still, evaluating the best tool for transferring data between systems remains a case-by-case analysis.
This article has been published previously in the Toronto User Group for Midrange Systems Newsletter (

See the new AS/400 FTP Question & Answer SheetAS/400 FTP Question & Answer Sheet
This brand-new page re-groups a number of user questions and answers related specifically to the use of FTP on the AS/400. You can find this page in the following link: AS/400 FTP Q&A


Thibault Dambrine is a Computer Consultant, based in Calgary, Alberta (Canada). He can be reached at (403) 263-6556 or via e-mail at

Back to Tylogix Home Page