Uploading+files+to+an+FTP+server

//by Richard Russell, March 2010, amended June 2012//

This article describes how to upload one or more files to an FTP server. The first step is to define some constants: code format="bb4w" FTP_TRANSFER_TYPE_ASCII = 1 FTP_TRANSFER_TYPE_BINARY = 2 _INTERNET_DEFAULT_FTP_PORT = 21 : REM default port for FTP servers _INTERNET_SERVICE_FTP = 1 _INTERNET_FLAG_PASSIVE = &8000000 OPEN_TYPE_PRECONFIG = 0 : REM use registry configuration OPEN_TYPE_DIRECT = 1   : REM direct to net OPEN_TYPE_PROXY = 3    : REM via named proxy OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY = 4 : REM prevent using Java code Next, get the necessary function entry points: code format="bb4w" SYS "LoadLibrary", "WININET.DLL" TO wininet% SYS "GetProcAddress", wininet%, "InternetOpenA" TO `InternetOpen` SYS "GetProcAddress", wininet%, "InternetConnectA" TO `InternetConnect` SYS "GetProcAddress", wininet%, "FtpSetCurrentDirectoryA" TO `FtpSetCurrentDirectory` SYS "GetProcAddress", wininet%, "FtpPutFileA" TO `FtpPutFile` SYS "GetProcAddress", wininet%, "InternetCloseHandle" TO `InternetCloseHandle` code We are now ready to open an internet connection: code format="bb4w" REM Open an internet connection: SYS `InternetOpen`, "BBC BASIC for Windows", OPEN_TYPE_PRECONFIG, 0, 0, 0 TO hOpen% IF hOpen% = 0 ERROR 100, "Cannot open internet connection" code This code will normally be suitable, but in certain special circumstances an alternative OPEN_TYPE constant may need to be used (see the definitions above); details may be found in the [|Microsoft documentation].

Once a successful internet connection has been made, a connection must be made to the remote FTP server: code format="bb4w" REM Connect to the FTP server: SYS `InternetConnect`, hOpen%, "ServerName", _INTERNET_DEFAULT_FTP_PORT, \ \                     "Username", "Password", \ \                     _INTERNET_SERVICE_FTP, 0, 0 \ \                     TO hConnection% IF hConnection% = 0 ERROR 101, "Cannot open FTP connection" code Here **ServerName**, **Username** and **Password** have been shown as constant strings, but of course they could alternatively be string variables (e.g. ServerName$, Username$ and Password$). The Server Name should be either a valid host name (e.g. **ftp.bbc.co.uk**) or an IP address (e.g. **212.58.228.30**).

If the FTP server you are using requires a passive connection, specify the INTERNET_FLAG_PASSIVE flag in the **InternetConnect** function: code format="bb4w" REM Connect to the FTP server: SYS `InternetConnect`, hOpen%, "ServerName", _INTERNET_DEFAULT_FTP_PORT, \ \                     "Username", "Password", \ \                     _INTERNET_SERVICE_FTP, _INTERNET_FLAG_PASSIVE, 0 \ \                     TO hConnection% IF hConnection% = 0 ERROR 101, "Cannot open FTP connection" code

Optionally you can now navigate to a sub-directory in which you want to store the file(s): code format="bb4w" REM Set the current directory: SYS `FtpSetCurrentDirectory`, hConnection%, "testing" TO res% IF res% = 0 ERROR 102, "Cannot set current directory" code Once again the sub-directory name has been shown as a constant string, but it could be a variable.

Now we can transfer the file itself: code format="bb4w" REM Upload the file: SYS `FtpPutFile`, hConnection%, "C:\test.htm", "test.htm", \ \                FTP_TRANSFER_TYPE_ASCII, 0 TO res% IF res% = 0 ERROR 103, "Cannot upload file" code The location of the source file, and the name it should be given on the destination FTP server, are shown here as constant strings, but they could be variables.

As shown the file will be transferred in text format, which means the line terminations will automatically be converted as required (e.g. from CRLF to LF). If you want to transfer the file in binary format, for example it is an executable program or ZIP archive, then substitute **FTP_TRANSFER_TYPE_BINARY**.

You can transfer as many files as you like, by repeating the above code snippet. Once all the files have been successfully transferred, close the connection as follows: code format="bb4w" REM Close the FTP connection: SYS `InternetCloseHandle`, hConnection% REM Close the internet connection: SYS `InternetCloseHandle`, hOpen% code Ideally you should trap errors using **ON ERROR** and in the event of an error occurring close the connection, for example by copying the above code into a 'cleanup' routine called from your error handler.