Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do I transfer files using FTP?

Internet

How do I transfer files using FTP?

by  DSummZZZ  Posted    (Edited  )
A lot of folks have need of transferring files to and from an ftp server.
Well, you can end your search. I have (with a lot of help from news2news.com)
made some routines to utilize the ftp protocol using API calls. There is
always the MS Inet control, and there is the Winsock control, but if you all
you want is a command line transfer, you can use that API calls.

The first is FTPGet.PRG, followed by FTPPut.PRG, then FtpDelete.PRG.
Since none of the routines are really interactive or an end user interface,
there is not much error checking. It is up to you to put that in to suit your
needs.

I have also made an interactive FTP client form which also utilizes the API
calls above. It was a good lesson in FTP usage. It will browse both local
drives and remote servers, as well as transfer files back and forth. It isn't
totally refined, but it is a good starting point.

Go to my web site: http://www.davesummers.net/foxprolinks.htm
and download it. Have fun!

A couple things to point out here, notice that several of the the API calls are
common in these routines. The exceptions are of course, FtpGetFile, FtpPutFile
and FtpDeleteFile.
So they can all be declared early in your main program and not have to be
're'declared. Also note that the most common error is "Unable to find entry point"
or "Can't find entry point..." or something along those lines. That is caused by
not using the proper case for both the declare and execution on the API calls.
I.e., FtpPutFile must be written as "FtpPutFile", not "FTPPUTFILE" or "ftpputfile"
and so on. I point this out because if you're not careful, beautify can really
trash things.

Note that FtpGetFile, FtpPutFile and FtpDeleteFile have been made BOLD in this
faq. There is an issue here that when the code is posted, anything starting with
'ftp' that is not surrounded by quotes, will get converted to lowercase. That
causes an API error as stated in the previous paragraph.


**********************************************************************************
*... FTPGet.PRG ...*
Code:
PARAMETERS lcHost, lcUser, lcPwd, lcRemoteFile, lcNewFile, lnXFerType     

*.................................................................................
*:   Usage: DO ftpget WITH ;
*:         'ftp.host', 'name', 'password', 'source.file', 'target.file'[, 1 | 2]
*:
*:  Where:  lcHost       = Host computer IP address or name
*:          lcUser       = user name - anonymous may be used
*:          lcPwd        = password
*:          lcRemoteFile = source file name
*:          lcNewFile    = target file name
*:          lnXFerType   = 1 (default) for ascii, 2 for binary
*.................................................................................

*...set up API calls
DECLARE INTEGER InternetOpen IN wininet;
   STRING sAgent, INTEGER lAccessType, STRING sProxyName,;
   STRING sProxyBypass, STRING  lFlags

DECLARE INTEGER InternetCloseHandle IN wininet INTEGER hInet

DECLARE INTEGER InternetConnect IN wininet.DLL;
   INTEGER hInternetSession,;
   STRING  lcHost,;
   INTEGER nServerPort,;
   STRING  lcUser,;
   STRING  lcPassword,;
   INTEGER lService,;
   INTEGER lFlags,;
   INTEGER lContext

DECLARE INTEGER
FtpGetFile
Code:
 IN wininet;
   INTEGER hFtpSession, ;
   STRING  lcRemoteFile,;
   STRING  lcNewFile, ;
   INTEGER fFailIfExists,;
   INTEGER dwFlagsAndAttributes,;
   INTEGER dwFlags, ;
   INTEGER dwContext

lcHost       = ALLTRIM(lcHost) 
lcUser       = ALLTRIM(lcUser)
lcPwd        = ALLTRIM(lcPwd)
lcRemoteFile = ALLTRIM(lcRemoteFile)
lcNewFile    = ALLTRIM(lcNewFile)

sAgent = "vfp"

sProxyName = CHR(0)     &&... no proxy
sProxyBypass = CHR(0)   &&... nothing to bypass
lFlags = 0              &&... no flags used

*... initialize access to Inet functions
hOpen = InternetOpen (sAgent, 1,;
   sProxyName, sProxyBypass, lFlags)

IF hOpen = 0
   WAIT WINDOW  "Unable to get access to WinInet.Dll" TIMEOUT 2
   RETURN
ENDIF

*... The first '0' says use the default port, usually 21.
hFtpSession = InternetConnect (hOpen, lcHost,;
   0, lcUser, lcPwd, 1, 0, 0)   &&... 1 = ftp protocol

IF hFtpSession = 0
   *... close access to Inet functions and exit
   = InternetCloseHandle (hOpen)
   WAIT WINDOW "Unable to connect to " + lcHost + '.' TIMEOUT 2
   RETURN
ELSE
   WAIT WINDOW "Connected to " + lcHost + " as: [" + lcUser + "]"  TIMEOUT 1
ENDIF

*... 0 to automatically overwrite file
*... 1 to fail if file already exists
fFailIfExists  = 0  
dwContext      = 0  &&... used for callback

WAIT WINDOW 'Transferring ' + lcRemoteFile + ' to ' + lcNewFile + '...' NOWAIT 
lnResult =
FtpGetFile
Code:
 (hFtpSession, lcRemoteFile, lcNewFile,;
   fFailIfExists, 128, lnXFerType,;
   dwContext)

*... 128 = #define FILE_ATTRIBUTE_NORMAL     0x00000080 
*... See CreateFile for other attributes

* close handles
= InternetCloseHandle (hFtpSession)
= InternetCloseHandle (hOpen)

IF lnResult = 1
   *... successful download, do what you want here
   WAIT WINDOW 'Completed.' TIMEOUT 1
   MODI FILE (lcNewFile)
ELSE
   WAIT WINDOW  "Unable to download selected file" TIMEOUT 2
ENDIF

RETURN
*** End of FTPGet.PRG *************************************************************

**********************************************************************************
*... FTPPut.PRG ...*
Code:
PARAMETERS lcHost, lcUser, lcPassword, lcSource, lcTarget, lnXFerType

*.................................................................................
*:   Usage: DO ftpput WITH ;
*:         'ftp.host', 'name', 'password', 'source.file', 'target.file'[, 1 | 2]
*:
*:  Where:  lcHost     = Host computer IP address or name
*:          lcUser     = user name - anonymous may be used
*:          lcPassword = password
*:          lcSource   = source file name (remote)
*:          lcTarget   = target file name (local)
*:          lnXFerType = 1 (default) for ascii, 2 for binary
*.................................................................................

DECLARE INTEGER InternetOpen IN wininet.DLL;
   STRING  sAgent,;
   INTEGER lAccessType,;
   STRING  sProxyName,;
   STRING  sProxyBypass,;
   STRING  lFlags

DECLARE INTEGER InternetCloseHandle IN wininet.DLL INTEGER hInet

DECLARE INTEGER InternetConnect IN wininet.DLL;
   INTEGER hInternetSession,;
   STRING  lcHost,;
   INTEGER nServerPort,;
   STRING  lcUser,;
   STRING  lcPassword,;
   INTEGER lService,;
   INTEGER lFlags,;
   INTEGER lContext

DECLARE INTEGER
FtpPutFile
Code:
 IN wininet.DLL;
   INTEGER hConnect,;
   STRING  lpszLocalFile,;
   STRING  lpszNewRemoteFile,;
   INTEGER dwFlags,;
   INTEGER dwContext

PUBLIC hOpen, hFtpSession

lcHost     = ALLTRIM(lcHost) 
lcUser     = ALLTRIM(lcUser) 
lcPassword = ALLTRIM(lcPassword) 
lcSource   = ALLTRIM(lcSource)
lcTarget   = ALLTRIM(lcTarget)

IF connect2ftp (lcHost, lcUser, lcPassword)
   WAIT WINDOW 'Transferring....' NOWAIT
   IF
FtpPutFile
Code:
(hFtpSession, lcSource,;
         lcTarget, lnXFerType, 0) = 1
      WAIT WINDOW lcSource + ' transferred.' TIMEOUT 2
   ENDIF

   = InternetCloseHandle (hFtpSession)
   = InternetCloseHandle (hOpen)
ENDIF

*..................... connect2ftp .........................................
*...  Makes sure there is actually a valid connection to the host
FUNCTION  connect2ftp (lcHost, lcUser, lcPassword)   
   * open access to Inet functions    
   hOpen = InternetOpen ("vfp", 1, 0, 0, 0)    

   IF hOpen = 0    
      ? "Unable to get access to WinInet.Dll"   
      RETURN .F.   
   ENDIF   

   *... The first '0' says use the default port, usually 21.
   hFtpSession = InternetConnect (hOpen, lcHost,;
      0, lcUser, lcPassword, 1, 0, 0)   &&... 1 = ftp protocol

   IF hFtpSession = 0    
   * close access to Inet functions and exit    
      = InternetCloseHandle (hOpen)    
      ? "FTP " + lcHost + " is not available"   
      RETURN .F.   
   ELSE    
      ? "Connected to " + lcHost
   ENDIF    
RETURN .T.   
RETURN
*** End of FTPPut.PRG *************************************************************

Now if you want to delete the remote file after downloading it,
you can use FtpDelete.PRG:

**********************************************************************************
*... FtpDelete.PRG ...*
Code:
PARAMETERS lcHost, lcUser, lcPwd, lcRemoteFile

*.................................................................................
*:   Usage: DO ftpdelete WITH ;
*:         'ftpserver.host', 'name', 'password', 'delete.file'
*:
*:  Where:  lcHost       = Host computer IP address or name
*:          lcUser       = user name - anonymous may be used
*:          lcPwd        = password
*:          lcRemoteFile = file to delete
*.................................................................................

*...set up API calls
PUBLIC hOpen, hFtpSession
DECLARE INTEGER InternetOpen IN wininet.DLL;
   STRING  sAgent,;
   INTEGER lAccessType,;
   STRING  sProxyName,;
   STRING  sProxyBypass,;
   STRING  lFlags

DECLARE INTEGER InternetCloseHandle IN wininet.DLL INTEGER hInet

DECLARE INTEGER InternetConnect IN wininet.DLL;
   INTEGER hInternetSession,;
   STRING  sServerName,;
   INTEGER nServerPort,;
   STRING  sUsername,;
   STRING  sPassword,;
   INTEGER lService,;
   INTEGER lFlags,;
   INTEGER lContext

DECLARE INTEGER
FtpDeleteFile
Code:
 IN wininet.DLL;
   INTEGER hConnect,;
   STRING  lpszFileName

*... open access to Inet functions
hOpen = InternetOpen ("vfp", 1, 0, 0, 0)

IF hOpen = 0
   ? "Unable to get access to WinInet.Dll"
   RETURN .F.
ENDIF

*... connect to FTP host
hFtpSession = InternetConnect (hOpen, lcHost, 0,;
   lcUser, lcPwd, 1, 0, 0)

IF hFtpSession = 0
   * close access to Inet functions and exit
   = InternetCloseHandle (hOpen)
   WAIT WINDOW "FTP " + strHost + " is not available"  TIMEOUT 2
ELSE
   WAIT WINDOW "Connected to " + lcHost + " as: [" + lcUser + "]"  NOWAIT
   IF
FtpDeleteFile
Code:
(hFtpSession, lcRemoteFile) = 1
      WAIT WINDOW lcRemoteFile + ' deleted.' TIMEOUT 1
   ELSE
      WAIT WINDOW 'Error deleting ' + lcRemoteFile + "." TIMEOUT 1
   ENDIF
ENDIF
= InternetCloseHandle (hFtpSession)
= InternetCloseHandle (hOpen)
*** End of FTPDelete.PRG *************************************************************

Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top