Skip to Content
Author's profile photo Thomas Jung

Performing FTP Commands From ABAP

Introduction
The use of FTP from ABAP seems to have been a hot topic on the ABAP Forums of late. I thought I might sit down and document whatever I could find on this subject and share it as a weblog.

Over the years I have seen lots of different solutions for moving files on and off of a SAP system. I have seen external FTP scripts written in OS shell languages. I have seen full blown custom applications that are made to interface to the SAP system. However I think you will find that most of the technology you need to perform a simple FTP from ABAP is already contained in the standard system. All of my examples and screen shots will be coming from a 46C system.

SAP’s Solution
If you have ever taken a look at the kernel directory of your SAP system, you might have noticed an interesting little executable: sapftp.exe (the name of the file on Windows SAP Kernels). It is this part of the Kernel that exposes FTP functionality to the ABAP Programming language.

So you have a suspicion that there is FTP functionality in ABAP, but you’re not quite sure how to use it. Where do you start? I always turn to the Service Marketplace first. A quick search on SAPFTP reveals there is an entire component (BC-SRV-COM-FTP) on the subject. The most general note and our starting place is OSS Note 93042. This note starts off with a nice description of what SAPFTP is: A client RFC application that is accessed via RFC from ABAP. But we also find out that in addition to SAPFTP being part of the kernel, it is also part of the SAPGui. That means that we can perform FTP commands originating from our R/3 Server or from a Client Workstation.

Well if this solution is accessed via RFC, then we must have to setup some RFC destinations. In fact we have two that we need; SAPFTP for Front-end FTP and SAPFTPA for access on the application server. Luckily we don’t even have to mess with setting these RFC destinations up in SM59. SAP has supplied a program, RSFTP005, to generate the destinations for us.

Now before we go off and start written code on our own to hit these FTP functions, why don’t we make sure everything is setup and working. Once again SAP has helped us out by providing us with a test program, RSFTP002. (In case you are wondering the FTP functionality and many other test programs are all contained in SAP Development Class SFTP). When we run this test, we get a set input parameters for the server, username password, etc. We want to start out simple and just make sure we are getting a connection. Therefore we will just execute the pwd command (Print Working Directory).
image

Your answer back should look something like this:
image

If you are wanting to see a list of FTP commands, try using the command HELP in place of PWD:
image

If something did go wrong during the test, I suggest that you active the trace option in SM59 for the FTP Destination. You can then use program RSFTP001 to display the current trace file.

Programming the FTP
Not only does the RSFTP002 program give us a test environment, but it also provides us with a programming example. We can see that the FTP functionality is really provided by a set of function modules all within the SFTP Function Group. We have the basic commands such as FTP_CONNECT, FTP_COMMAND, and FTP_DISCONNECT that can be strung together to create a complete file operation action. The FTP_COMMAND Function allows you to issue arbitrary FTP commands as long as the SAPFTP function, the Host, and the Destination server all support the command. Then you have the specialized functions such as FTP_R3_TO_SERVER, FTP_R3_TO_CLIENT, and FTP_CLIENT_TO_R3. This lets you take some data in memory and transfer it someplace else. This has the advantage of not having to write the data to the file system first and not to have to issue any FTP commands. However these functions are also limited to the scope described.

If you are already familiar with FTP in general, working with these function modules should not seem to difficult. The Connect, Command, Disconnect actions would seem somewhat self explanatory. So instead of looking at the entire program in detail let’s focus on two things that may be unfamiliar. First the program starts off with an ABAP Kernel System call to AB_RFC_X_SCRAMBLE_STRING. Well we don’t want to pass a potentially sensitive password openly. Therefore the FTP_CONNECT function module requires that the password be encrypted before it receives it. It is this System call that performs that one-way encryption. Now I checked a 620 SP42 system and in this example, SAP has replace the AB_RFC_X_SCRAMBLE_STRING with a function call to HTTP_SCRAMBLE. Unfortunately HTTP_SCRAMBLE doesn’t even exist in my 46C system. The only other thing that I wanted to point out about these function calls is the exporting parameter on the FTP_CONNECT. It passes back a parameter called handle. This handle then becomes an importing parameter to all subsequent calls: FTP_COMMAND and FTP_CLOSE. This handle is the pointer to the instance of FTP that we started with the FTP_CONNECT. This assures that we get reconnected to the same FTP session with each command we issue.

FTP Development
I thought I would share a few of the things that can be built using this FTP functionality. First off I didn’t want a bunch of ABAP programs directly working with the SAP FTP Function modules. As you can see there is already a difference in the examples for encrypting the password between 46C and 620. Therefore I thought it would be best to encapsulate all the FTP function in one custom ABAP OO Class. Not only did I get the opportunity to hid the inner SAP functionality and make it easy to switch out during upgrades, but I also get consistent error handling as well. I accept the User Name, Password, Host, and RFC Destination in during the Constructor of the class. I then store these values away in Protected Attributes. Each function module is then implemented as a Instance Method. The Password encryption functionality is then all tucked away nicely in the class. Also the calling program doesn’t have to worry about keeping track of the FTP handle either since it is an instance attribute as well.
image

Next I got really carried away. I wanted a way to record entire FTP scripts that could be filled with values at runtime and ran as a step in a background job. My company used to have many interfaces that ran frequently sending files all over the place. We needed a mechanism to monitor and support these file moves. This was really the root of this tool, but it also gives you an idea of how powerful these functions can be.
image

Closing
I hope that anyone interested in FTP from ABAP will find this resource useful. If anyone has any other resources that should be included here, feel free to post them.

Assigned Tags

      40 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member
      On the other hand I have been using a local include of ZCL_FTP_BASE in my programs for some time. Here's the signature:


      *&-----------------------------------------------*
      *&  Include ZHR9_FTP_CLASSES
      *&-----------------------------------------------*
      *& Utility class ZCL_FTP_BASE having all the
      * functions to upload and download files from an
      * FTP server.                      
      *&-----------------------------------------------*

      CLASS zcl_ftp_base DEFINITION.
        PUBLIC SECTION.
      * Output file type
          TYPES: BEGIN OF t_scratch,
                   data(1024) TYPE c,
                 END OF t_scratch,
          t_str_tab TYPE STANDARD TABLE OF t_scratch.

          CONSTANTS: co_crlf(2) TYPE x VALUE '0D0A'.

          DATA: status TYPE c VALUE space.

          METHODS: constructor IMPORTING im_user TYPE string im_pwd    TYPE string
                                               im_server TYPE string,
                   send_table_data   IMPORTING im_file   TYPE string
                                               im_table  TYPE t_str_tab,
                   get_table_data    IMPORTING im_file   TYPE string
                                     EXPORTING ex_table  TYPE t_str_tab,
                   send_string_data  IMPORTING im_file   TYPE string
                                               im_string TYPE string,
                   get_string_data   IMPORTING im_file   TYPE string
                                     EXPORTING ex_string TYPE string,
                   disconnect.

        PRIVATE SECTION.
          DATA: v_user(64)    TYPE c,
                v_pwd_clear(30)   TYPE c,
                v_pwd(64)     TYPE c,
                v_server(30)  TYPE c,
                v_filename    TYPE rlgrap-filename,
                v_handle      TYPE i.

          METHODS:  pwd_scramble IMPORTING im_pwd TYPE c.

      ENDCLASS.     "ZCL_FTP_BASE DEFINITION

      Author's profile photo Former Member
      Former Member
      Thanks for this weblog, and I can be pretty sure there are some(many) more weblogs in the waiting.

      Regards,
      Subramanian V.

      Author's profile photo Former Member
      Former Member
      ...any chance you've used FTP via an HTTP proxy? 

      Any help using the HTTP* functions in the ZFTP function group will be greatly appreciated.  Any one?

      Thx

      Author's profile photo Thomas Jung
      Thomas Jung
      I'm afraid I haven't done either.  However I have used the HTTP client functionality in the WebAS 620 (if_http_client) along with an HTTP proxy.  I have an example of this in BSP a Developer's Journal Part XIV - Consuming WebServices with ABAP

      Author's profile photo Former Member
      Former Member
      I've been in IT for over 30 years as a mainframe contract programmer/analyst.  Recently a company hired me for my legacy knowledge of there business to become a developer on SAP for these same systems.

      My first task is to develop a generalized ftp application to send data to the mainframe and then on to financial institutions.  I have created an ABAP/4 test program with literals for the dest/host etc.  And it works fine.  I need more detail/guidance in creating the Class/Method/Function you have described to make this parameter driven and callable by other programs.  I know this is a lot to ask, any help in pointing me in the right direction would be greatly appreciated.  When I mention class creation to the existing staff they all say "Oh, we don't use or know anything about that object oriented stuff, we just right programs."

      Thanks,
      Tom

      Author's profile photo Former Member
      Former Member
      I just read what I typed, I meant "write programs" not "right programs" ... duh
      Author's profile photo Thomas Jung
      Thomas Jung
      "we don't use or know anything about that object oriented stuff"  That's something I might have expected to hear 4 years ago.  That's kind of like saying that you only want to use half of the programming lanuage (the old half at that).

      However it is true that you have to learn to walk before you run.  There are some fundamentals to ABAP that are usefull to have down before you start in with ABAP OO. But I wouldn't let that hold you back for long.

      I'm afraid that I wouldn't be able to teach you everything you would need to know to create a function module or a class in this posting.   There was a nice weblog that was just posted the other day that had the steps to create your first simple class.  I suggest you start there.

      As far as my FTP class goes, I don't mind sending you the code for the class.  My email address is already all over SDN (and spammers' lists) so just send me the address that you want the details sent to.  My email is tjung@kimball.com

      Author's profile photo Former Member
      Former Member
      When I pass the table blob with many lines, the file created in FTP Server only have 1 line with all information. The function doesn’t describe the lines of table.

      Do you have any experience about this problem?

      Cheers
      Carlos López(Spain)

      Author's profile photo Thomas Jung
      Thomas Jung
      I never use the FTP_R3_TO_SERVER function.  I like the control of creating my file local first and then FTPing it.  This also gives me an audit trail/backup copy of the data.
      Author's profile photo Former Member
      Former Member
      Hi Carlos,

      is it possible to pass it in parameter text, without length. This will help if you only have text in your table.

      Juergen Wachter

      Author's profile photo Manish Bhalla
      Manish Bhalla
      Hi Thomas,

      Do you know if the SAPFTP programs support secure FTP (over SSH or SSL) ?

      Cheers
      Manish

      Author's profile photo Thomas Jung
      Thomas Jung
      Blog Post Author
      As far as I know it does not. 
      Author's profile photo Former Member
      Former Member
      Manish,

      According to note 795131, it is recommended to create an SSH port forward to secure the FTP.

      If you haven't already worked out a solution good luck, I will be trying this soon as well.

      Regards,

      Rob

      Author's profile photo Former Member
      Former Member
      Hi,
      did you try to send a string table in text mode with sapftp.. It doesn't give any error.. even creates a file on the ftp server but cannot transfer the contents of the table..

      table definition:
      data: gt_file type standard table of string.

      regards.

      Author's profile photo Thomas Jung
      Thomas Jung
      Blog Post Author
      I can't say that I have ever tried to us a string table in a SAPFTP, but this doesn't seem like correct behavior. I would think that if the data type is not supported, you should at least get an exception.

      You should report this behavior through normal support channels (OSS) and see what they have to say.

      Author's profile photo Former Member
      Former Member
      Hi,

      Thanks 4 a Gr8 Blog helped me a lot.I am using FTP_CONNECT to ftp data from external server, to get data into internal table directly i used FTP_SERVER_TO_R3. when i am passing file path of external server to FNAME parameter i am getting error. Can u pls help with the flow of how to fetch data into internal table after ftp_connect.

      Regards,
      Krish

      Author's profile photo Thomas Jung
      Thomas Jung
      Blog Post Author
      The important thing to remember is that the FTP commands will be issued at the operating system level.  The first thing you should do is to try and have someone perform your FTP commands manually at the OS level.  THis will tell you if you have all the paths and FTP commands correctly defined. 
      Author's profile photo Former Member
      Former Member
      I read your blog on FTP. It is a great article and indeed is very helpful. I wanted to ask a query regarding FTP. I have my data in an internal table. i need to directly FTP that onto FTP server. The file format required is TAB-DELIMITED. So firstly can i upload a tab delimited file onto FTP server? and secondly how can i achieve this through my program.

      Thanks in anticipation.

      Author's profile photo Thomas Jung
      Thomas Jung
      Blog Post Author
      Well if you need a tab delimited file you are going to have to convert your internal table to that format before doing the FTP (regarless of if you FTP from memory or from the file system). 

      You will want to loop through your internal table and concatenate the fields together into string separated by CL_ABAP_CHAR_UTILITIES=>HORIZONTAL_TAB and CL_ABAP_CHAR_UTILITIES=>CR_LF.  The process is really the same as when you are preparing an internal table for download as an HTTP response object attachment:
      BSP Download to Excel in Unicode Format

      That example works fine if you know you fields at design time, but if you want a generic solution that also handles conversion exits have a look at this Blog in the section PROCESS_XLS_DOWNLOAD:
      Creating a BSP Extension for Downloading a Table

      Author's profile photo Former Member
      Former Member

      Hello,     Please let me know if you have any solution for this.

      Author's profile photo Thomas Jung
      Thomas Jung
      Blog Post Author
      I think you are going to have to find out why FTP didn't work at the OS level first.  I suspect that failure is certainly linked to the error when executing SAPFTPA.  For that I would turn to your Unix system administrators and your network administrators.
      Author's profile photo Former Member
      Former Member
      Hi Thomas..

      You mean to say...
      if a ftp command works in SM49/SM69 then it would work with FTP_CONNECT too !!

      Author's profile photo Thomas Jung
      Thomas Jung
      Blog Post Author
      No I didn't mean that at all.  I mean trying your FTP commands from the command line of the OS itself.  And no I don't guarentee that all comamnds at the OS will be support in the FTP_CONNECT.  However it is still a good idea to at least make sure it works at the OS at least before trying it in FTP_CONNECT.
      Author's profile photo Former Member
      Former Member
      Hello,
      We are testing program RSFTP002 to send files from a specific directory in our R/3 appl. server to a FTP server. We are interesting in defining this process in a job. We are using the program with RFC destination SAPFTPA (in order to be executed in the appl. server) but don't know where we can define the server path we want to use (the directory in our appl. server where the files are placed).
      Thanks in advance.
      Author's profile photo Thomas Jung
      Thomas Jung
      Blog Post Author
      Well you can either specify the full path in your put command or issue a LCD (Local Change Directory) command before the put. 

      But to pieces of advice.  First I don't believe that the RSFTP* programs are intended for productive usage.  They don't really have enough error trapping in them and their list of commands (lenght and number of commands) is restrictive.  You should probably only consider them as code samples for building your own FTP application.

      Second - try building the FTP "script" from the command line of the application server first.  Work out any problems with permissions, FTP command syntax, etc there before moving the commands into ABAP.  The smaller number of possible places that could be a problem, the better.

      Author's profile photo Former Member
      Former Member
      Hi,
      I am using the FM FTP_SERVER_TO_R3 to get the data from external application server to internal table in text mode. But the text line is greater than 255 characters and it gets truncated from 256 characters.
      Please do let me know if you have any solution for this.
      Author's profile photo Thomas Jung
      Thomas Jung
      Blog Post Author
      I can't say that I have personally ran into the problem, but you might try doing the import in Binary mode instead of text.  You will recieve the results in the BLOB object and you will have to parse it into individual lines yourself.
      Author's profile photo Former Member
      Former Member
      Hi,

      I have coded a program to connect and FTP a file.
      The programs works without any problems when run in foreground. Howvere, when run in backgound, the job fails with on FTP_CONNECT.
      Have you come across this issue before ?

      Regards,
      John W

      Author's profile photo Thomas Jung
      Thomas Jung
      Blog Post Author
      Which RFC destination are using using - SAPFTP or SAPFTPA?  Here is the section from the blog that describes the differences:

      Well if this solution is accessed via RFC, then we must have to setup some RFC destinations. In fact we have two that we need; SAPFTP for Front-end FTP and SAPFTPA for access on the application server. Luckily we don't even have to mess with setting these RFC destinations up in SM59. SAP has supplied a program, RSFTP005, to generate the destinations for us.

      If you are using SAPFTP that needs a connection to the SAPGUI.  That seems the mostly likely cause of your problem.  When running in the background you would have no connection to a client/SAPGUI.

      Author's profile photo Former Member
      Former Member
      Hi,
      I'm connecting to other system via FTP_connect ... and moving files from this system to SAP, but files are passed with incorrect format "DOS text" instead "UNIX text". Do you know if there is some command for that(command 'binary' is not working)? Or how can I solve it?

      Thanks in advanced and regards!

      Author's profile photo Thomas Jung
      Thomas Jung
      Blog Post Author
      No I don't know of the command.  However this is really a general FTP question and not specific to the ABAP FTP interface.  I'm far from a general FTP expert, so you are probably better seeking your answer elsewhere.
      Author's profile photo Former Member
      Former Member
      Hi I'm trying to connect to an external ftp-server via a proxy FTP-server using function ftp_connect.
      I'm using the gateway parameters to connect to the proxy, but the function always returns an error saying that the user doesn't have access to the external FTP-server. I know the users and passwords are correct. Is it the correct way to use the gateway parameters? What is the account parameter for?

      Thanks,
      Wim

      Author's profile photo Thomas Jung
      Thomas Jung
      Blog Post Author
      I'm afraid that I don't have any expertise to offer you on the topic of using a proxy.  I've never tried it myself.  I've seen the paramters and I always assumed their usage was pretty straight forward.  You should try posting your question in the forums to see if you can find someone with experience using proxies.  If no luck there - then a support ticket questioning the usage of those parameters would be appropriate.
      Author's profile photo Former Member
      Former Member
      Hi, we have some ABAPs which are using sapftp.
      Everytime they are executing there arise masses of logfiles in root directory from SAP Central Instance host(SXF193). Their name is a number (2,3,4,...) and the content is constantly:
      lcd \\SXF193\Daten\SAP_PROBIS
      local directory now \\SXF193\Daten\SAP_PROBIS

      What could be the cause of it and how we can prevent from it?

      Author's profile photo Thomas Jung
      Thomas Jung
      Blog Post Author
      It sounds like the FTP commands themselves are being logged.  You could activate logging on the SAPFTP connection, but then the logs would not be in the root director.  They would be in with the rest of our SAP logfiles.  I would have to see the FTP commands that are being executed, but I suspect that it is something specific in the commands or the applications that is doing the logging
      Author's profile photo Former Member
      Former Member
      The first step to make sure everything is setup and working using RSFTP002 was not succesful. for user and password i gave was of the remote server, for host i gave in the IP address of the remote server, for command1 i gave pwd and RFC destination the default value sapftpa and compress was the default value N. The rest of the few field were left blank.

      Please be kind enough to help me get this right. Thanks in advance.

      Author's profile photo Phillip Morgan
      Phillip Morgan

      Nice post!

      What about password storage and handling?

      I am going to set up a new program that will ftp files to several servers. Specification said to create a table to put all server information (the pgm will determine server based on functional information - a partner of sorts). This table is to include passwords to the servers.

      I pointed out this is not a good way to do it since anybody can see the passwords this way.

      What is the alternative?

      - store pwd encrypted; when I read the record, I have to decrypt it to use it. Not good. Anybody with access to function modules can decrypt it.

      - SAP's secure store cannot be used by custom applications

      - ...

      I have looked around SDN, but have not found a good solution.

      Any ideas?

      Author's profile photo Edgar Alonso Mendoza Ramírez
      Edgar Alonso Mendoza Ramírez

      It happened to me.. You are rigth... And DECRYPT FM doesn't work...

      Author's profile photo Edgar Alonso Mendoza Ramírez
      Edgar Alonso Mendoza Ramírez

      Hello everybody. Regarding to FM FTP_R3_TO_SAP . I'm facing a problem with XML files, the FM is working fine. But when I open the file migrated from FTP SERVER with CHROME, it throw me one error. 

      Extra content at the end of the document

      If I open XML with the note pad, I could correct  the error manually, it is due blank spaces at the end of XML, but I don´t know how the blank spaces arrive there!!! The original XML  doesn´t have any error neither blank spaces. If manually delete blank spaces and save file is possible to open XML file with any internet explorer.

      Do you have any ideas how to solve this??

      This is my implementation for the FM with some personal comments.

      *&---------------------------------------------------------------------*

      *&  FTP R3 TO SERVER

      *&---------------------------------------------------------------------*

      *   Transferring the data from internal table to FTP Server

      *&---------------------------------------------------------------------*

      FORM ftp_r3_to_server TABLES it_table TYPE table USING p_file.

         CLEAR: gv_code, gv_message.

         DATA: lv_char  TYPE i,

               lv_len   TYPE i,

               lv_table TYPE string.

         DESCRIBE TABLE it_table LINES  lv_char.

         lv_len = lv_char * 255.

         REFRESH: it_result.

         PERFORM ftp_command USING 'set passive on' CHANGING it_result.

         CALL FUNCTION 'FTP_R3_TO_SERVER'

           EXPORTING

             handle         = gv_dhdl

             fname          = p_file

             blob_length    = lv_len

      *      character_mode = space " Add blank spaces at end of file using TABLE BLOB

      *      character_mode = 'X'   "Split with newline some XML nodes using TABLE  TEXT

           TABLES

      *      text           = it_table " works only with CHARACTER MODE = X otherwise create empty files

             blob           = it_table

           EXCEPTIONS

             tcpip_error    = 1

             command_error  = 2

             data_error     = 3

             others         = 4.

         gv_code = sy-subrc.

         IF gv_code NE 0.

           CASE gv_code.

             WHEN 1. gv_message = 'tcpip_error'.

             WHEN 2. gv_message = 'command_error'.

             WHEN 3. gv_message = 'data_error'.

             WHEN OTHERS. gv_message = 'others'.

           ENDCASE.

           RAISE errorinfilecreation.

         ENDIF.

         CLEAR: gv_code, gv_command.

         REFRESH: it_result.

         CONCATENATE  'put' p_file INTO gv_command SEPARATED BY space.

         PERFORM ftp_command USING gv_command CHANGING it_result.

      ENDFORM.                    "ftp_r3_to_server

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      Edgar, you'll have better luck opening a discussion to ask this instead of waiting for answers in the comments on a blog that is 12 years old. Wild guess though - could this be a problem?

      lv_len = lv_char * 255

      Maybe your file length is inaccurate. Just simple logic...