FTP: Difference between revisions

41,641 bytes added ,  5 months ago
m
m (→‎{{header|Perl 6}}: Change to a still active FTP host)
m (→‎{{header|Wren}}: Minor tidy)
 
(32 intermediate revisions by 19 users not shown)
Line 4:
Connect to a server, change directory, list its contents and download a file as binary using the FTP protocol. Use passive mode if available.
<br/><br/>
 
=={{header|BASIC}}==
==={{header|BaCon}}===
Using libCURL.
<syntaxhighlight lang="bacon">OPTION PARSE FALSE
 
PRAGMA INCLUDE <curl/curl.h>
PRAGMA LDFLAGS -lcurl
 
DECLARE easyhandle TYPE CURL*
 
OPEN "data.txt" FOR WRITING AS download
 
easyhandle = curl_easy_init()
curl_easy_setopt(easyhandle, CURLOPT_URL, "ftp://localhost/pub/data.txt")
curl_easy_setopt(easyhandle, CURLOPT_WRITEDATA, download)
curl_easy_setopt(easyhandle, CURLOPT_USERPWD, "anonymous")
success = curl_easy_perform(easyhandle)
curl_easy_cleanup(easyhandle)
 
CLOSE FILE download</syntaxhighlight>
 
Full native implementation without dependency to external libraries.
<syntaxhighlight lang="bacon">FUNCTION interact$(command$, connection, use_pasv)
 
LOCAL pasv$, data$, response$
LOCAL port, passive
 
IF use_pasv THEN
SEND "PASV" & NL$ TO connection
RECEIVE data$ FROM connection
pasv$ = INBETWEEN$(data$, "(", ")")
port = VAL(TOKEN$(pasv$, 5, ","))*256 + VAL(TOKEN$(pasv$, 6, ","))
OPEN "localhost:" & STR$(port) FOR NETWORK AS passive
ENDIF
 
IF LEN(command$) THEN SEND command$ & NL$ TO connection
 
WHILE WAIT(connection, 50)
RECEIVE data$ FROM connection
IF LEN(data$) = 0 THEN BREAK
response$ = response$ & data$
WEND
 
IF use_pasv THEN
WHILE WAIT(passive, 50)
RECEIVE data$ FROM passive
IF LEN(data$) = 0 THEN BREAK
response$ = response$ & data$
WEND
CLOSE NETWORK passive
ENDIF
 
RETURN response$
 
ENDFUNC
 
OPEN "localhost:21" FOR NETWORK AS ftp
 
PRINT interact$("", ftp, 0)
PRINT interact$("USER anonymous", ftp, 0)
PRINT interact$("PASS ", ftp, 0)
PRINT interact$("CWD pub", ftp, 0)
PRINT interact$("LIST", ftp, 1)
PRINT interact$("TYPE I", ftp, 0)
PRINT interact$("RETR data.txt", ftp, 1)
PRINT interact$("QUIT", ftp, 0)
 
CLOSE NETWORK ftp</syntaxhighlight>
 
 
==={{header|FreeBASIC}}===
Original code programmed by PaulSquires
[https://www.freebasic.net/forum/viewtopic.php?f=7&t=23867]
{{libheader|clsFTP}}
{{works with|Windows}}
====clsFTP.bas====
<syntaxhighlight lang="vb">''
''
'' FTP class (Public Domain code - enjoy).
'' Windows only. Uses WinInet system functions.
'' Paul Squires of PlanetSquires Software (August 2015)
''
'' Compiler: FreeBASIC 1.03 (32-bit) (64-bit)
''
 
#Include Once "windows.bi"
#Include Once "\win\wininet.bi"
 
' //
' //
' //
Type clsFTP
Private:
m_hSession As HINTERNET
m_hConnection As HINTERNET
m_LastError As Integer
m_ServerPort As Integer
m_ServerName As String
m_UserName As String
m_Password As String
Public:
Declare Constructor
Declare Destructor
Declare Property hSession() As HINTERNET
Declare Property hSession(Byval nValue As HINTERNET)
Declare Property hConnection() As HINTERNET
Declare Property hConnection(Byval nValue As HINTERNET)
Declare Property LastError() As Integer
Declare Property ServerPort(Byval nValue As Integer)
Declare Property ServerPort() As Integer
Declare Property LastError(Byval nValue As Integer)
Declare Property ServerName() As String
Declare Property ServerName(Byval sValue As String)
Declare Property UserName() As String
Declare Property UserName(Byval sValue As String)
Declare Property Password() As String
Declare Property Password(Byval sValue As String)
Declare Function Connect Overload() As WINBOOL
Declare Function Connect Overload(Byval sServerName As String, _
Byval sServerPort As Integer, _
Byval sUserName As String, _
Byval sPassword As String) As WINBOOL
Declare Sub Disconnect()
Declare Function SetCurrentFolder(Byval sFolderName As String) As WINBOOL
Declare Function GetCurrentFolder() As String
Declare Function RenameFile(Byval sOldFilename As String, _
Byval sNewFilename As String) As WINBOOL
Declare Function UploadFile(Byval sLocal As String, _
Byval sRemote As String) As WINBOOL
Declare Function DownloadFile(Byval sLocal As String, _
Byval sRemote As String) As WINBOOL
Declare Function KillFile(Byval sRemote As String) As WINBOOL
End Type
 
 
''
'' Initialize the class
''
Constructor clsFTP
m_ServerPort = INTERNET_DEFAULT_FTP_PORT ' port 21
End Constructor
 
 
''
'' Close any open connection and session
''
Destructor clsFTP
this.Disconnect
End Destructor
 
 
''
'' hSession (Property)
''
Property clsFTP.hSession() As HINTERNET
Property = this.m_hSession
End Property
 
Property clsFTp.hSession(Byval nValue As HINTERNET)
this.m_hSession = nValue
End Property
 
 
''
'' hConnection (Property)
''
Property clsFTP.hConnection() As HINTERNET
Property = this.m_hConnection
End Property
 
Property clsFTp.hConnection(Byval nValue As HINTERNET)
this.m_hConnection = nValue
End Property
 
 
''
'' LastError (Property)
''
Property clsFTP.LastError() As Integer
Property = this.m_LastError
End Property
 
Property clsFTp.LastError(Byval nValue As Integer)
this.m_LastError = nValue
End Property
 
 
''
'' ServerPort (Property)
''
Property clsFTP.ServerPort() As Integer
Property = this.m_ServerPort
End Property
 
Property clsFTp.ServerPort(Byval nValue As Integer)
this.m_ServerPort = nValue
End Property
 
 
''
'' ServerName (Property)
''
Property clsFTP.ServerName() As String
Property = this.m_ServerName
End Property
 
Property clsFTp.ServerName(Byval sValue As String)
this.m_ServerName = sValue
End Property
 
 
''
'' UserName (Property)
''
Property clsFTP.UserName() As String
Property = this.m_UserName
End Property
 
Property clsFTp.UserName(Byval sValue As String)
this.m_UserName = sValue
End Property
 
 
''
'' Password (Property)
''
Property clsFTP.Password() As String
Property = this.m_Password
End Property
 
Property clsFTp.Password(Byval sValue As String)
this.m_Password = sValue
End Property
 
 
''
'' Close current connection and end session
''
Sub clsFTP.Disconnect()
InternetCloseHandle this.hConnection
InternetCloseHandle this.hSession
this.hConnection = 0: this.hSession = 0
End Sub
 
 
''
'' Connect to an ftp host (overload). Returns TRUE if successful.
''
Function clsFTP.Connect Overload() As WINBOOL
this.hSession = InternetOpen("ftpClass", INTERNET_OPEN_TYPE_DIRECT, "", "", 0)
If this.hSession = 0 Then
this.LastError = GetLastError
Function = False: Exit Function
End If
this.hConnection = InternetConnect(_
this.hSession, this.ServerName, this.ServerPort, _
this.UserName, this.Password, _
INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0)
If this.hConnection = 0 Then
this.LastError = GetLastError
InternetCloseHandle(this.hSession)
Function = False: Exit Function
End If
Function = True
End Function
 
 
''
'' Connect to an ftp host (overload). Returns TRUE if successful.
''
Function clsFTP.Connect Overload (Byval sServerName As String, _
Byval nServerPort As Integer, _
Byval sUserName As String, _
Byval sPassword As String) As WINBOOL
this.ServerName = sServerName
this.ServerPort = nServerPort
this.UserName = sUserName
this.Password = sPassword
Function = this.Connect
End Function
 
 
''
'' Change to a folder on the server. Returns TRUE if successful.
''
Function clsFTP.SetCurrentFolder(Byval sFolderName As String) As WINBOOL
Function = FtpSetCurrentDirectory(this.hConnection, sFolderName)
this.LastError = GetLastError
End Function
 
 
''
'' Retrieves the name of current folder on the server.
''
Function clsFTP.GetCurrentFolder() As String
Dim zBuffer As ZString * MAX_PATH
Dim nLength As Integer = MAX_PATH
FtpGetCurrentDirectory(this.hConnection, zBuffer, Cast(LPDWORD, @nLength))
this.LastError = GetLastError
Function = zBuffer
End Function
 
 
''
'' Rename a file on the server. Returns TRUE if successful.
''
Function clsFTP.RenameFile(Byval sOldFilename As String, Byval sNewFilename As String) As WINBOOL
Function = FtpRenameFile(this.hConnection, sOldFilename, sNewFilename)
this.LastError = GetLastError
End Function
 
 
''
'' Upload a file to the server. Returns TRUE if successful.
''
Function clsFTP.UploadFile(Byval sLocal As String, Byval sRemote As String) As WINBOOL
Function = FtpPutFile(this.hConnection, sLocal, sRemote, FTP_TRANSFER_TYPE_BINARY, 0)
this.LastError = GetLastError
End Function
 
 
''
'' Download a file from the server. Returns TRUE if successful.
''
Function clsFTP.DownloadFile(Byval sLocal As String, Byval sRemote As String) As WINBOOL
Function = FtpGetFile(this.hConnection, sRemote, sLocal, False, _
FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_BINARY Or INTERNET_FLAG_RELOAD, 0)
this.LastError = GetLastError
End Function
 
 
''
'' Remove a file from the server. Returns TRUE if successful.
''
Function clsFTP.KillFile(Byval sRemote As String) As WINBOOL
Function = FtpDeleteFile(this.hConnection, sRemote)
this.LastError = GetLastError
End Function</syntaxhighlight>
 
====simple_test.bas====
<syntaxhighlight lang="vb">#Include Once "windows.bi"
#Include Once "clsFTP.bas"
 
Dim ftp As clsFTP
 
If ftp.Connect("ftp.ed.ac.uk", 21, "anonymous", "aaa@gmail.com") = False Then
Print "Error connecting to server. LastError = "; ftp.LastError
End If
 
If ftp.SetCurrentFolder("pub/courses") = False Then
Print "Error setting current folder. LastError = "; ftp.LastError
End If
 
Print "Current folder = "; ftp.GetCurrentFolder()
 
If ftp.DownloadFile("make.notes.tar", "make.notes.tar") = False Then
Print "Error downloading file. LastError = "; ftp.LastError
End If
 
ftp.Disconnect
 
Print "Done."
 
Sleep</syntaxhighlight>
 
==={{header|FutureBasic}}===
FB for Mac easily interfaces with the terminal command line. NOTE: The curl command line tool used in this example offers upload and sending capabilities. It supports FTP, FTPS, HTTP, HTTPS, SCP, SFTP, TFTP, TELNET, DICT, LDAP, LDAPS, FILE, POP3, IMAP, SMTP, RTMP and RTSP.
<syntaxhighlight lang="futurebasic">
include "NSLog.incl"
 
#plist NSAppTransportSecurity @{NSAllowsArbitraryLoads:YES}
 
local fn RunTerminalCommand( cmd as CFStringRef ) as CFStringRef
CFStringRef outputStr = NULL
TaskRef task = fn TaskInit
TaskSetExecutableURL( task, fn URLFileURLWithPath( @"/bin/zsh" ) )
CFStringRef cmdStr = fn StringWithFormat( @"%@", cmd )
CFArrayRef args = fn ArrayWithObjects( @"-c", cmdStr, NULL )
TaskSetArguments( task, args )
PipeRef p = fn PipeInit
TaskSetStandardOutput( task, p )
TaskSetStandardError( task, p )
FileHandleRef fh = fn PipeFileHandleForReading( p )
fn TaskLaunch( task, NULL )
TaskWaitUntilExit( task )
ErrorRef err
CFDataRef dta = fn FileHandleReadDataToEndOfFile( fh, @err )
if err then NSLog( @"%@", fn ErrorLocalizedDescription( err ) ) : exit fn
outputStr = fn StringWithData( dta, NSUTF8StringEncoding )
end fn = outputStr
 
NSLog( @"%@", fn RunTerminalCommand( @"curl ftp://ftp.slackware.com/welcome.msg" ) )
 
HandleEvents
</syntaxhighlight>
{{output}}
<pre style="font-size: 12px">
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
 
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 754 100 754 0 0 1363 0 --:--:-- --:--:-- --:--:-- 1361
 
---------------------------------------------------------------------------
R S Y N C . O S U O S L . O R G
Oregon State University
Open Source Lab
 
Unauthorized use is prohibited - violators will be prosecuted
---------------------------------------------------------------------------
 
For more information about the OSL visit:
http://osuosl.org/services/hosting
 
This host is the home to the primary archives of several
projects. We would prefer that only primary/secondary
mirrors use this service. Thanks!
 
---------------------------------------------------------------------------
</pre>
 
=={{header|Go}}==
Using the FTP package from [https://godoc.org/github.com/stacktic/ftp github.com/stacktic/ftp].
<syntaxhighlight lang="go">package main
 
import (
"fmt"
"io"
"log"
"os"
 
"github.com/stacktic/ftp"
)
 
func main() {
// Hard-coded demonstration values
const (
hostport = "localhost:21"
username = "anonymous"
password = "anonymous"
dir = "pub"
file = "somefile.bin"
)
 
conn, err := ftp.Connect(hostport)
if err != nil {
log.Fatal(err)
}
defer conn.Quit()
fmt.Println(conn)
 
if err = conn.Login(username, password); err != nil {
log.Fatal(err)
}
if err = conn.ChangeDir(dir); err != nil {
log.Fatal(err)
}
fmt.Println(conn.CurrentDir())
files, err := conn.List(".")
if err != nil {
log.Fatal(err)
}
for _, f := range files {
fmt.Printf("%v %12d %v %v\n", f.Time, f.Size, f.Type, f.Name)
}
 
r, err := conn.Retr(file)
if err != nil {
log.Fatal(err)
}
defer r.Close()
 
f, err := os.Create(file)
if err != nil {
log.Fatal(err)
}
defer f.Close()
 
n, err := io.Copy(f, r)
if err != nil {
log.Fatal(err)
}
 
fmt.Println("Wrote", n, "bytes to", file)
}</syntaxhighlight>
 
=={{header|Batch File}}==
This uses the native FTP.EXE in Windows. I am not sure, but I think FTP.EXE client does not support passive mode.
<langsyntaxhighlight lang="dos">::Playing with FTP
::Batch File Implementation
 
Line 30 ⟶ 529:
echo.get %download%
echo.disconnect
)|ftp -n</langsyntaxhighlight>
{{Out}}
<pre>\Desktop>RCFTP
Line 62 ⟶ 561:
=={{header|C}}==
Using [http://nbpfaus.net/~pfau/ftplib/ ftplib]
<syntaxhighlight lang="c">
<lang c>
#include <ftplib.h>
 
Line 80 ⟶ 579:
return 0;
}
</syntaxhighlight>
</lang>
 
=={{header|C++}}==
{{works with|c++|11}}
 
Using [http://nbpfaus.net/~pfau/ftplib/ ftplib], [https://github.com/saur0n/libftpxx libftp++]
<syntaxhighlight lang="cpp"> /* client.cpp
libftp++ C++ classes for ftplib C ftp library
compile:
clang++ -std=c++11 -o client client.cpp -lftp++
*/
 
#include <iostream>
#include <string>
#include <cstring>
#include <fstream>
#include <sys/stat.h> // stat
#include <ftplib.h> // libftp
#include <ftp++.hpp> // libftp++
 
 
/* C++ classes:
Connection main ftp connection (user class)
 
ConnectionBase base class for Connection (internal)
DataConnection connection type, (internal)
read bytes from server,
write bytes to server
ConnectionException custom exception (thrown by Connection)
 
*/
 
 
/** ftp::Connection class API
data members:
A Connection instance contains only a pointer as a data member
{
protected:
netbuf * conn; // pointer to ftplib netbuf struct
}
 
member functions:
 
connect:
 
Connection(const char * host); // constructor
 
void setConnectionMode(Mode mode); // passive or port
 
void login(const char * user, const char * password); // Log in
 
info:
 
const char * getLastResponse(); // last server response
 
std::string getSystemType(); // server type
std::string getDirectory(); // remote pwd
void getList(const char * filename, const char * path); // short dir list
 
unsigned size(const char * path, TransferMode mode);
file transfer:
void get(const char * local, const char * remote, TransferMode mode);
 
void put(const char * local, const char * remote, TransferMode mode);
 
**/
 
// libc functions
int stat(const char *pathname, struct stat *buf); // local file info
char *strerror(int errnum); // explanation of error
char *basename(char *path); // filename at end of path
 
 
// STL classes and functions used
namespace stl
{
using std::cout; // stdout
using std::cerr; // stderr
using std::string; // string
using std::ifstream; // files on disk
using std::remove; // delete file on disk
};
 
using namespace stl;
 
 
// connection modes
using Mode = ftp::Connection::Mode;
Mode PASV = Mode::PASSIVE;
Mode PORT = Mode::PORT;
 
//file transfer modes
using TransferMode = ftp::Connection::TransferMode;
TransferMode BINARY = TransferMode::BINARY;
TransferMode TEXT = TransferMode::TEXT;
 
 
/* ********************** */
// ftp session parameters
struct session
{
const string server; // server name
const string port; // usually 21
const string user; // username
const string pass; // password
Mode mode; // PASV, PORT
TransferMode txmode; // BINARY, TEXT
string dir; // current or default dir
};
 
/* ********************** */
// local helper functions
 
ftp::Connection connect_ftp( const session& sess);
size_t get_ftp( ftp::Connection& conn, string const& path);
string readFile( const string& filename);
string login_ftp(ftp::Connection& conn, const session& sess);
string dir_listing( ftp::Connection& conn, const string& path);
 
 
/* ******************************** */
// Read a file into one long string
 
string readFile( const string& filename)
{
struct stat stat_buf;
string contents;
errno = 0;
if (stat(filename.c_str() , &stat_buf) != -1) // file stats
{
size_t len = stat_buf.st_size; // size of file
string bytes(len+1, '\0'); // string big enough
ifstream ifs(filename); // open for input
 
ifs.read(&bytes[0], len); // read all bytes as chars into string
 
if (! ifs.fail() ) contents.swap(bytes); // swap into contents
 
ifs.close();
}
else
{
cerr << "stat error: " << strerror(errno);
}
 
return contents;
}
 
/* *************** */
// start a session
 
ftp::Connection connect_ftp( const session& sess)
try
{
string constr = sess.server + ":" + sess.port;
cerr << "connecting to " << constr << " ...\n";
 
ftp::Connection conn{ constr.c_str() };
cerr << "connected to " << constr << "\n";
conn.setConnectionMode(sess.mode);
 
return conn;
}
catch (ftp::ConnectException e)
{
cerr << "FTP error: could not connect to server" << "\n";
}
 
/* ***** */
// login
 
string login_ftp(ftp::Connection& conn, const session& sess)
{
conn.login(sess.user.c_str() , sess.pass.c_str() );
 
return conn.getLastResponse();
}
 
/* ***************************** */
// get remote directory listing
 
// ftplib writes to file for dir contents
// convert file contents to string
 
string dir_listing( ftp::Connection& conn, const string& path)
try
{
// file on disk to write to
const char* dirdata = "/dev/shm/dirdata";
conn.getList(dirdata, path.c_str() );
// conn.getFullList(dirdata, path.c_str() );
// conn.getFullList(NULL, path.c_str() ); // to stdout
string dir_string = readFile(dirdata);
 
cerr << conn.getLastResponse() << "\n";
errno = 0;
if ( remove(dirdata) != 0 ) // delete file on disk
{
cerr << "error: " << strerror(errno) << "\n";
}
return dir_string;
}
catch (...) {
cerr << "error: getting dir contents: \n"
<< strerror(errno) << "\n";
}
 
/* ************************* */
// retrieve file from server
 
size_t get_ftp( ftp::Connection& conn, const string& r_path)
{
size_t received = 0;
 
const char* path = r_path.c_str();
 
unsigned remotefile_size = conn.size(path , BINARY);
const char* localfile = basename(path);
conn.get(localfile, path, BINARY); // get file
 
cerr << conn.getLastResponse() << "\n";
 
// get local file size
struct stat stat_buf;
 
errno = 0;
if (stat(localfile, &stat_buf) != -1)
received = stat_buf.st_size;
else
cerr << strerror(errno);
 
return received;
}
 
/* ******************** */
// default test session
const session sonic
{
"mirrors.sonic.net",
"21" ,
"anonymous",
"xxxx@nohost.org",
PASV,
BINARY,
"/pub/OpenBSD"
};
 
/* **** */
// main
 
int main(int argc, char* argv[], char * env[] )
{
const session remote = sonic; // copy session info
 
try
{
// open an ftp connection
ftp::Connection conn = connect_ftp(remote);
 
// login with username and passwd
cerr << login_ftp(conn, remote);
 
// what type system
cout << "System type: " << conn.getSystemType() << "\n";
cerr << conn.getLastResponse() << "\n";
 
// cd to default session dir
conn.cd(remote.dir.c_str()); // change to dir on server
cerr << conn.getLastResponse() << "\n";
 
// get current remote directory
string pwdstr = conn.getDirectory();
cout << "PWD: " << pwdstr << "\n";
cerr << conn.getLastResponse() << "\n";
 
 
// get file listing
string dirlist = dir_listing(conn, pwdstr.c_str() );
cout << dirlist << "\n";
string filename = "ftplist"; // small text file
 
auto pos = dirlist.find(filename); // find filename in dir list
 
auto notfound = string::npos;
 
if (pos != notfound) // found filename
{
// get file
size_t received = get_ftp(conn, filename.c_str() );
 
if (received == 0)
cerr << "got 0 bytes\n";
else
cerr << "got " << filename
<< " (" << received << " bytes)\n";
}
else
{
cerr << "file " << filename
<< "not found on server. \n";
}
}
catch (ftp::ConnectException e)
{
cerr << "FTP error: could not connect to server" << "\n";
}
catch (ftp::Exception e)
{
cerr << "FTP error: " << e << "\n";
}
catch (...)
{
cerr << "error: " << strerror(errno) << "\n";
}
 
// logout, connection closes automatically when conn destructs
 
return 0;
}
/* END */
</syntaxhighlight>
 
{{Out}}
<pre>
connecting to mirrors.sonic.net:21 ...
connected to mirrors.sonic.net:21
230 Anonymous access granted, restrictions apply
System type: UNIX
215 UNIX Type: L8
 
250 CWD command successful
 
PWD: /openbsd
257 "/openbsd" is the current directory
 
226 Transfer complete
 
/openbsd/.
/openbsd/..
/openbsd/Changelogs
/openbsd/LibreSSL
/openbsd/OpenBGPD
/openbsd/OpenNTPD
/openbsd/OpenSSH
/openbsd/doc
/openbsd/patches
/openbsd/snapshots
/openbsd/songs
/openbsd/syspatch
/openbsd/tools
/openbsd/ftplist
/openbsd/timestamp
/openbsd/rpki-client
/openbsd/6.7
/openbsd/6.8
 
226 Transfer complete
 
got ftplist (4992 bytes)
</pre>
 
 
=={{header|Common Lisp}}==
Line 86 ⟶ 970:
Using package [http://code.kepibu.org/cl-ftp/ cl-ftp].
 
<langsyntaxhighlight lang="lisp">(use-package :ftp)
 
(with-ftp-connection (conn :hostname "ftp.hq.nasa.gov"
Line 94 ⟶ 978:
(let ((filename "Gravity in the Brain.mp3"))
(retrieve-file conn filename filename :type :binary)))
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 110 ⟶ 994:
</pre>
 
=={{header|GoErlang}}==
Erlang implementation using ftp module.
Using the FTP package from [https://godoc.org/github.com/stacktic/ftp github.com/stacktic/ftp].
<syntaxhighlight lang="erlang">
<lang go>package main
%%%-------------------------------------------------------------------
%%% To execute in shell, Run the following commands:-
%%% >c("ftp_example").
%%% >ftp_example:run().
%%%-------------------------------------------------------------------
-module(ftp_example).
 
-export([run/0]).
import (
"fmt"
"io"
"log"
"os"
 
run() ->
"github.com/stacktic/ftp"
Host = "ftp.easynet.fr",
)
Opts = [{mode, passive}],
User = "anonymous",
Password = "",
 
Directory = "/debian/",
func main() {
File = "README.html",
// Hard-coded demonstration values
const (
%%% Open connection with FTP Server
hostport = "localhost:21"
io:format("Opening connection with host ~p ~n", [Host]),
username = "anonymous"
{ok, Pid} = ftp:open(Host, Opts),
password = "anonymous"
dir = "pub"
%%% Login as Anonymous user
file = "somefile.bin"
io:format("Logging in as user ~p ~n", [User]),
)
ftp:user(Pid, User, Password),
%%% Change Directory to "/debian/"
io:format("Changing Directory to ~p ~n", [Directory]),
ftp:cd(Pid, Directory),
%%% Listing contents of current Directory
io:format("Contents of Current Directory ~n"),
{ok, Listing} = ftp:ls(Pid),
io:format("~p ~n", [Listing]),
 
%%% Download file "README.html"
conn, err := ftp.Connect(hostport)
io:format("Downloading File ~p to current directory ~n", [File]),
if err != nil {
ftp:recv(Pid, File),
log.Fatal(err)
}
%%% Close connection
defer conn.Quit()
io:format("Closing connection to FTP Server"),
fmt.Println(conn)
ftp:close(Pid).
 
</syntaxhighlight>
if err = conn.Login(username, password); err != nil {
log.Fatal(err)
}
if err = conn.ChangeDir(dir); err != nil {
log.Fatal(err)
}
fmt.Println(conn.CurrentDir())
files, err := conn.List(".")
if err != nil {
log.Fatal(err)
}
for _, f := range files {
fmt.Printf("%v %12d %v %v\n", f.Time, f.Size, f.Type, f.Name)
}
 
r, err := conn.Retr(file)
if err != nil {
log.Fatal(err)
}
defer r.Close()
 
f, err := os.Create(file)
if err != nil {
log.Fatal(err)
}
defer f.Close()
 
n, err := io.Copy(f, r)
if err != nil {
log.Fatal(err)
}
 
fmt.Println("Wrote", n, "bytes to", file)
}</lang>
 
=={{header|Groovy}}==
Line 180 ⟶ 1,046:
Dependencies are automatically loaded with the @Grab annotation.
let's say the code is saved in the file ftpTest.groovy:
<syntaxhighlight lang="groovy">
<lang Groovy>
@Grab(group='commons-net', module='commons-net', version='2.0')
import org.apache.commons.net.ftp.FTPClient
Line 195 ⟶ 1,061:
}
println(" ...Done.");
</syntaxhighlight>
</lang>
By typing groovy ftpTest.groovy, you should see a README.html file on your directory.
<pre>
Line 216 ⟶ 1,082:
Example uses [https://hackage.haskell.org/package/ftphs <tt>ftphs</tt>] package:
 
<langsyntaxhighlight lang="haskell">module Main (main) where
 
import Control.Exception (bracket)
Line 246 ⟶ 1,112:
-- Download in binary mode
(fileData, _) <- getbinary h "linux-0.01.tar.gz.sign"
print fileData</langsyntaxhighlight>
 
=={{header|J}}==
 
<langsyntaxhighlight Jlang="j"> require 'web/gethttp'
gethttp 'ftp://anonymous:example@ftp.hq.nasa.gov/pub/issoutreach/Living%20in%20Space%20Stories%20(MP3%20Files)/'
-rw-rw-r-- 1 109 space-station 2327118 May 9 2005 09sept_spacepropulsion.mp3
Line 264 ⟶ 1,130:
-rw-rw-r-- 1 109 space-station 1134654 May 9 2005 When Space Makes you Dizzy.mp3
#file=: gethttp rplc&(' ';'%20') 'ftp://anonymous:example@ftp.hq.nasa.gov/pub/issoutreach/Living in Space Stories (MP3 Files)/We have a solution.mp3'
772075</langsyntaxhighlight>
 
=={{header|Java}}==
requires apache.commons.net
<langsyntaxhighlight lang="java">import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
Line 340 ⟶ 1,206:
}
}
}</langsyntaxhighlight>
 
Output:
Line 388 ⟶ 1,254:
{{works with|Julia|0.6}}
 
<langsyntaxhighlight lang="julia">using FTPClient
 
ftp = FTP(hostname = "ftp.ed.ac.uk", username = "anonymous")
Line 395 ⟶ 1,261:
bytes = read(download(ftp, "make.notes.tar"))
 
close(ftp)</langsyntaxhighlight>
 
=={{header|Kotlin}}==
Line 430 ⟶ 1,296:
</pre>
Next, you need to compile the following Kotlin program, linking against ftplib.klib.
<langsyntaxhighlight lang="scala">// Kotlin Native v0.6
 
import kotlinx.cinterop.*
Line 447 ⟶ 1,313:
FtpQuit(vnbuf)
nativeHeap.free(nbuf)
}</langsyntaxhighlight>
Finally, the resulting .kexe file should be executed producing something similar to the following output:
<pre>
Line 468 ⟶ 1,334:
=={{header|Lingo}}==
{{libheader|Curl Xtra}}
<langsyntaxhighlight lang="lingo">CURLOPT_URL = 10002
ch = xtra("Curl").new()
url = "ftp://domain.com"
Line 485 ⟶ 1,351:
ch.setOption(CURLOPT_URL, url & filename)
ch.setDestinationFile(_movie.path & filename)
res = ch.exec()</langsyntaxhighlight>
 
=={{header|LiveCode}}==
<langsyntaxhighlight LiveCodelang="livecode">libURLSetFTPMode "passive" --default is passive anyway
put url "ftp://ftp.hq.nasa.gov/" into listing
repeat for each line ftpln in listing
Line 526 ⟶ 1,392:
e.g. to know the working directory, issue "pwd", we could issue "list" for above too,
but using an url with slash on the end with the ftp protocol causes a dir listing by default.
put libURLftpCommand("PWD",ftp.example.org)</langsyntaxhighlight>
 
=={{header|PerlNim}}==
<lang Perl>
#!/usr/bin/perl
use strict;
use warnings;
use 5.020;
#This script is dependent upon the Net::FTP cpan module
use Net::FTP;
 
{{works with|Nim|1.4}}
#Put the name of the FTP server here
my $host = "kernel.org";
#Credentials go here
my $user = "anonymous";
my $password = "";
 
<syntaxhighlight lang="nim">import asyncdispatch, asyncftpclient
#Attempt to connect to the server using the credentials provided.
my $f = Net::FTP->new($host) or die("Something went wrong. Can't open $host\n");
$f->login($user, $password) or die("Something went wrong. Can't log $user in.\n");
 
const
#Set to passive mode
Host = "speedtest.tele2.net"
$f->passive();
Upload = "upload"
File = "1KB.zip"
 
proc main {.async.} =
#Change to whatever directory you want. If no args are passed to cwd(), it sets it to the root directory
$f->cwd("pub/linux/kernel");
#Print the current dir
my @dir = $f->ls();
foreach my $element (@dir)
{
say("$element");
}
 
# Create session and connect.
#Download the file and store locally. get() returns the local filename
let ftp = newAsyncFtpClient(Host, user = "anonymous", pass = "anything")
my $local = $f->get("README");
await ftp.connect()
say("Your file was stored as $local in the current directory! ");
echo "Connected."
</lang>
echo await ftp.send("PASV") # Switch to passive mode.
 
# Change directory and list its contents.
Output:
await ftp.cd(Upload)
<pre>
echo "Changed to directory: ", Upload
COPYING
echo "Contents of directory: ", Upload
CREDITS
for file in await ftp.listDirs():
Historic
echo " ", file
README
SillySounds
crypto
next
people
ports
projects
sha256sums.asc
testing
uemacs
v1.0
v1.1
v1.2
v1.3
v2.0
v2.1
v2.2
v2.3
v2.4
v2.5
v2.6
v3.0
v3.x
v4.x
Your file was stored as README in the current directory!
</pre>
 
# Download a file.
=={{header|Perl 6}}==
await ftp.cd("/")
{{works with|rakudo|2018.04}}
echo "Returned to root directory."
await ftp.retrFile(file = File, dest = File)
echo "Downloaded file: ", File
echo await ftp.send("QUIT") # Disconnect.
 
waitFor main()</syntaxhighlight>
<lang perl6>use Net::FTP;
 
{{out}}
my $host = 'speedtest.tele2.net';
<pre>Connected.
my $user = 'anonymous';
227 Entering Passive Mode (90,130,70,73,94,108).
Changed to directory: upload
Contents of directory: upload
1_2758858854070946631_17-9ULspeedtest.upt
2MB.zip
2_2758858854070946631_17-9ULspeedtest.upt
3_2758858854070946631_17-9ULspeedtest.upt
DCS-932LB1-WEBCAM-12021010316232001.jpg
DCS-932LB1-WEBCAM-12021010316292601.jpg
DCS-932LB1-WEBCAM-12021010316314601.jpg
speedtest_uplink_1.1G.zip
upload_file.txt
Returned to root directory.
Downloaded file: 1KB.zip
221 Goodbye.</pre>
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">use Net::FTP;
 
# set server and credentials
my $host = 'speedtest.tele2.net';
my $user = 'anonymous';
my $password = '';
 
# connect in passive mode
my $ftp = Net::FTP.new( host => $host, :passive );
my $f = Net::FTP->new($host) or die "Can't open $host\n";
$f->login($user, $password) or die "Can't login as $user\n";
$f->passive();
 
# change remote directory, list contents
$ftp.login( user => $user, pass => $password );
$f->cwd('upload');
@files = $f->ls();
printf "Currently %d files in the 'upload' directory.\n", @files;
 
# download file in binary mode
say $_<name> for $ftp.ls;
$f->cwd('/');
$f->type('binary');
$local = $f->get('512KB.zip');
print "Your file was stored as $local in the current directory\n";</syntaxhighlight>
{{out}}
<pre>Currently 20 files in the 'upload' directory
Your file was stored as 512KB.zip in the current directory!</pre>
 
=={{header|Phix}}==
$ftp.get( '5MB.zip', :binary );</lang>
{{libheader|Phix/libcurl}}
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- libcurl, allocate, file i/o</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">libcurl</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">url</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"ftp://speedtest.tele2.net/"</span>
<span style="color: #7060A8;">curl_global_init</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">curl</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">curl_easy_init</span><span style="color: #0000FF;">(),</span>
<span style="color: #000000;">pErrorBuffer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">allocate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">CURL_ERROR_SIZE</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">curl_easy_setopt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">curl</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">CURLOPT_ERRORBUFFER</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">pErrorBuffer</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">curl_easy_setopt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">curl</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CURLOPT_URL</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">url</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">curl_easy_perform_ex</span><span style="color: #0000FF;">(</span><span style="color: #000000;">curl</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #0000FF;">?{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">peek_string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pErrorBuffer</span><span style="color: #0000FF;">)}</span>
<span style="color: #008080;">else</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">filename</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"1KB.zip"</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">delete_file</span><span style="color: #0000FF;">(</span><span style="color: #000000;">filename</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">curl_easy_get_file</span><span style="color: #0000FF;">(</span><span style="color: #000000;">url</span><span style="color: #0000FF;">&</span><span style="color: #000000;">filename</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">""</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">filename</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">=</span><span style="color: #004600;">CURLE_OK</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"successfully downloaded %s (size %s)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">filename</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">get_file_size</span><span style="color: #0000FF;">(</span><span style="color: #000000;">filename</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">else</span>
<span style="color: #0000FF;">?{</span><span style="color: #008000;">"error"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
-rw-r--r-- 1 0 0 1073741824000 Feb 19 2016 1000GB.zip
-rw-r--r-- 1 0 0 107374182400 Feb 19 2016 100GB.zip
-rw-r--r-- 1 0 0 102400 Feb 19 2016 100KB.zip
-rw-r--r-- 1 0 0 104857600 Feb 19 2016 100MB.zip
-rw-r--r-- 1 0 0 10737418240 Feb 19 2016 10GB.zip
-rw-r--r-- 1 0 0 10485760 Feb 19 2016 10MB.zip
-rw-r--r-- 1 0 0 1073741824 Feb 19 2016 1GB.zip
-rw-r--r-- 1 0 0 1024 Feb 19 2016 1KB.zip
-rw-r--r-- 1 0 0 1048576 Feb 19 2016 1MB.zip
-rw-r--r-- 1 0 0 209715200 Feb 19 2016 200MB.zip
-rw-r--r-- 1 0 0 20971520 Feb 19 2016 20MB.zip
-rw-r--r-- 1 0 0 2097152 Feb 19 2016 2MB.zip
-rw-r--r-- 1 0 0 3145728 Feb 19 2016 3MB.zip
-rw-r--r-- 1 0 0 524288000 Feb 19 2016 500MB.zip
-rw-r--r-- 1 0 0 52428800 Feb 19 2016 50MB.zip
-rw-r--r-- 1 0 0 524288 Feb 19 2016 512KB.zip
-rw-r--r-- 1 0 0 5242880 Feb 19 2016 5MB.zip
drwxr-xr-x 2 105 108 561152 Jul 18 13:11 upload
successfully downloaded 1KB.zip (size 1KB)
</pre>
 
=={{header|PHP}}==
<syntaxhighlight lang="php">
$server = "speedtest.tele2.net";
$user = "anonymous";
$pass = "ftptest@example.com";
 
$conn = ftp_connect($server);
if (!$conn) {
die('unable to connect to: '. $server);
}
$login = ftp_login($conn, $user, $pass);
if (!$login) {
echo 'unable to log in to '. $server. ' with user: '.$user.' and pass: '. $pass;
} else{
echo 'connected successfully'.PHP_EOL;
$directory = ftp_nlist($conn,'');
print_r($directory);
}
if (ftp_get($conn, '1KB.zip', '1KB.zip', FTP_BINARY)) {
echo "Successfully downloaded file".PHP_EOL;
} else {
echo "failed to download file";
}</syntaxhighlight>
{{out}}
<pre>1000GB.zip
connected successfully
100GB.zip
Array
100KB.zip
(
100MB.zip
[0] => 1000GB.zip
10GB.zip
[1] => 100GB.zip
10MB.zip
[2] => 100KB.zip
1GB.zip
[3] => 100MB.zip
1KB.zip
1MB [4] => 10GB.zip
200MB [5] => 10MB.zip
20MB [6] => 1GB.zip
2MB [7] => 1KB.zip
3MB [8] => 1MB.zip
[9] => 200MB.zip
500MB.zip
[10] => 20MB.zip
50MB.zip
512KB [11] => 2MB.zip
5MB [12] => 3MB.zip
[13] => 500MB.zip
upload</pre>
[14] => 50MB.zip
[15] => 512KB.zip
[16] => 5MB.zip
[17] => upload
)
Successfully downloaded file
Done.
</pre>
 
=={{header|PicoLisp}}==
Passive is the default behavior of 'curl'
<langsyntaxhighlight PicoLisplang="picolisp">(in '(curl "-sl" "ftp://kernel.org/pub/site/")
(while (line)
(prinl @) ) )
(call "curl" "-s" "-o" "sha256sums.asc" "ftp://kernel.org/pub/site/sha256sums.asc")</langsyntaxhighlight>
Output:
<pre>README
Line 646 ⟶ 1,590:
=={{header|Python}}==
{{works with|Python|2.7.10}}
<syntaxhighlight lang="python">
<lang Python>
from ftplib import FTP
ftp = FTP('kernel.org')
Line 655 ⟶ 1,599:
print ftp.retrbinary('RETR README', open('README', 'wb').write)
ftp.quit()
</syntaxhighlight>
</lang>
 
=={{header|Racket}}==
Note: <tt>net/ftp</tt> in Racket uses passive mode exclusively.
<langsyntaxhighlight lang="racket">
#lang racket
(require net/ftp)
Line 675 ⟶ 1,619:
(ftp-download-file conn "." "README")
(ftp-close-connection conn))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|rakudo|2018.04}}
 
<syntaxhighlight lang="raku" line>use Net::FTP;
 
my $host = 'speedtest.tele2.net';
my $user = 'anonymous';
my $password = '';
 
my $ftp = Net::FTP.new( host => $host, :passive );
 
$ftp.login( user => $user, pass => $password );
 
$ftp.cwd( 'upload' );
 
$ftp.cwd( '/' );
 
say $_<name> for $ftp.ls;
 
$ftp.get( '1KB.zip', :binary );</syntaxhighlight>
 
{{out}}
<pre>1000GB.zip
100GB.zip
100KB.zip
100MB.zip
10GB.zip
10MB.zip
1GB.zip
1KB.zip
1MB.zip
200MB.zip
20MB.zip
2MB.zip
3MB.zip
500MB.zip
50MB.zip
512KB.zip
5MB.zip
upload</pre>
 
=={{header|REBOL}}==
<syntaxhighlight lang="rebol">
<lang REBOL>
system/schemes/ftp/passive: on
print read ftp://kernel.org/pub/linux/kernel/
write/binary %README read/binary ftp://kernel.org/pub/linux/kernel/README
</syntaxhighlight>
</lang>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">require 'net/ftp'
 
Net::FTP.open('ftp.ed.ac.uk', "anonymous","aaa@gmail.com" ) do |ftp|
ftp.passive = true # default since Ruby 2.3
ftp.chdir('pub/courses')
puts ftp.list.each{|e| puts e}
ftp.getbinaryfile("make.notes.tar")
end</langsyntaxhighlight>
The connection is closed automatically at the end of the block.
 
=={{header|Rust}}==
Using crate <code>ftp</code> version 3.0.1
<syntaxhighlight lang="rust">use std::{error::Error, fs::File, io::copy};
use ftp::FtpStream;
 
fn main() -> Result<(), Box<dyn Error>> {
let mut ftp = FtpStream::connect("ftp.easynet.fr:21")?;
ftp.login("anonymous", "")?;
ftp.cwd("debian")?;
for file in ftp.list(None)? {
println!("{}", file);
}
let mut stream = ftp.get("README")?;
let mut file = File::create("README")?;
copy(&mut stream, &mut file)?;
Ok(())
}</syntaxhighlight>
 
=={{header|Scala}}==
{{libheader|commons-net}}
<langsyntaxhighlight Scalalang="scala">import java.io.{File, FileOutputStream, InputStream}
 
import org.apache.commons.net.ftp.{FTPClient, FTPFile, FTPReply}
Line 773 ⟶ 1,778:
ftpClient.logout
}.isFailure) println(s"Failure.")
}</langsyntaxhighlight>
{{Out}}See it in running in your browser by [https://scastie.scala-lang.org/3Lq8ehzIQTCuAOPXWofNLw Scastie (JVM)].
 
=={{header|Seed7}}==
The library [http://seed7.sourceforge.net/libraries/ftp.htm ftp.s7i] contains functions to
[http://seed7.sourceforge.net/libraries/ftp.htm#openFtp(in_string) open] and handle an
[http://seed7.sourceforge.net/libraries/ftp.htm#ftpFileSys ftpFileSys].
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "ftp.s7i";
 
Line 796 ⟶ 1,802:
writeln(getFile(ftp, "README"));
close(ftp);
end func;</langsyntaxhighlight>
 
=={{header|Sidef}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="ruby">require('Net::FTP');
 
var ftp = %s'Net::FTP'.new('ftp.ed.ac.uk', Passive => 1);
Line 808 ⟶ 1,814:
ftp.binary; # set binary mode
ftp.get("make.notes.tar");
ftp.quit;</langsyntaxhighlight>
 
=={{header|Tcl}}==
===Using package ftp===
<syntaxhighlight lang="tcl">
<lang Tcl>
package require ftp
 
Line 822 ⟶ 1,828:
::ftp::Type $conn binary
::ftp::Get $conn README README
</syntaxhighlight>
</lang>
 
===Using a virtual file system===
An alternative approach that uses the package [http://sourceforge.net/projects/tclvfs/ TclVFS] to access ftp:// paths as a virtual file system.
 
<langsyntaxhighlight lang="tcl">
package require vfs::urltype
vfs::urltype::Mount ftp
Line 840 ⟶ 1,846:
}
file copy README [file join $dir README]
</syntaxhighlight>
</lang>
 
The file <tt>vfsftpfix.tcl</tt> with the passive mode patch (see http://wiki.tcl.tk/12837):
<langsyntaxhighlight lang="tcl">
# Replace vfs::ftp::Mount to enable vfs::ftp to work in passive
# mode and make that the default.
Line 894 ⟶ 1,900:
return $fd
}
</syntaxhighlight>
</lang>
 
=={{header|UNIX Shell}}==
Uses sftp which os available on all Linux distress by default. The commands are identical to ftp. This example uses the public free sftp server at test.rebex.net , the credentials are demo/password :
 
<syntaxhighlight lang="bash">
Aamrun $ sftp demo@test.rebex.net
Password:
Connected to test.rebex.net.
sftp> ls
pub readme.txt
sftp> cd pub
sftp> ls
example
sftp> ls example
example/KeyGenerator.png example/KeyGeneratorSmall.png example/ResumableTransfer.png example/WinFormClient.png example/WinFormClientSmall.png example/imap-console-client.png example/mail-editor.png example/mail-send-winforms.png
example/mime-explorer.png example/pocketftp.png example/pocketftpSmall.png example/pop3-browser.png example/pop3-console-client.png example/readme.txt example/winceclient.png example/winceclientSmall.png
sftp> cd example
sftp> get KeyGenerator.png
Fetching /pub/example/KeyGenerator.png to KeyGenerator.png
/pub/example/KeyGenerator.png 100% 36KB 146.4KB/s 00:00
sftp> exit
Aamrun$
</syntaxhighlight>
 
=={{header|V (Vlang)}}==
<syntaxhighlight lang="v (vlang)">
import net.ftp
 
fn main() {
result := ftp_client_test() or {println('Error: something went wrong') exit(1)}
println(result)
}
 
 
fn ftp_client_test() ?[]u8 {
mut zftp := ftp.new()
mut blob := []u8{}
defer {
zftp.close() or {
println('Error: failure to close ftp')
exit(10)
}
}
connect_result := zftp.connect('ftp.redhat.com') or {
println('Error: failed to connect')
exit(1)
}
login_result := zftp.login('ftp', 'ftp') or {
println('Error: failed to login')
exit(2)
}
pwd := zftp.pwd() or {
println('Error: failed to login')
exit(3)
}
if (connect_result == true) && (login_result == true) && (pwd.len > 0) {
zftp.cd('/') or {
println('Error: failed to get root directory')
exit(4)
}
}
dir_list1 := zftp.dir() or {
println('Error: failed to get directory listing')
exit(5)
}
if dir_list1.len > 0 {
zftp.cd('/suse/linux/enterprise/11Server/en/SAT-TOOLS/SRPMS/') or {
println('Error: failed to get directory listing')
exit(6)
}
}
dir_list2 := zftp.dir() or {
println('Error: failed to get directory listing')
exit(7)
}
if dir_list2.len > 0 {
if dir_list2.contains('katello-host-tools-3.3.5-8.sles11_4sat.src.rpm') == true {
blob = zftp.get('katello-host-tools-3.3.5-8.sles11_4sat.src.rpm') or {
println('Error: failed to get directory listing')
exit(8)
}
}
}
if blob.len <= 0 {
println('Error: failed to get data')
exit(9)
}
return blob
}
</syntaxhighlight>
 
=={{header|Wren}}==
{{trans|C}}
{{libheader|ftplib}}
An embedded program so we can ask the C host to communicate with ''ftplib'' for us.
<syntaxhighlight lang="wren">/* FTP.wren */
 
var FTPLIB_CONNMODE = 1
var FTPLIB_PASSIVE = 1
var FTPLIB_ASCII = 65 // 'A'
 
foreign class Ftp {
foreign static init()
 
construct connect(host) {}
 
foreign login(user, pass)
 
foreign options(opt, val)
 
foreign chdir(path)
 
foreign dir(outputFile, path)
 
foreign get(output, path, mode)
 
foreign quit()
}
 
Ftp.init()
var ftp = Ftp.connect("ftp.easynet.fr")
ftp.login("anonymous", "ftptest@example.com")
ftp.options(FTPLIB_CONNMODE, FTPLIB_PASSIVE)
ftp.chdir("/debian/")
ftp.dir("", ".")
ftp.get("ftp.README", "README", FTPLIB_ASCII)
ftp.quit()</syntaxhighlight>
<br>
We now embed this in the following C program, compile and run it.
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
#include <ftplib.h>
#include "wren.h"
 
/* C <=> Wren interface functions */
 
void C_init(WrenVM* vm) {
FtpInit();
}
 
void C_ftpAllocate(WrenVM* vm) {
netbuf *nbuf;
const char *host = wrenGetSlotString(vm, 1);
FtpConnect(host, &nbuf);
netbuf** pnbuf = (netbuf**)wrenSetSlotNewForeign(vm, 0, 0, sizeof(netbuf*));
*pnbuf = nbuf;
}
 
void C_login(WrenVM* vm) {
netbuf* nbuf = *(netbuf**)wrenGetSlotForeign(vm, 0);
const char *user = wrenGetSlotString(vm, 1);
const char *pass = wrenGetSlotString(vm, 2);
FtpLogin(user, pass, nbuf);
}
 
void C_options(WrenVM* vm) {
netbuf* nbuf = *(netbuf**)wrenGetSlotForeign(vm, 0);
int opt = (int)wrenGetSlotDouble(vm, 1);
long val = (long)wrenGetSlotDouble(vm, 2);
FtpOptions(opt, val, nbuf);
}
 
void C_chdir(WrenVM* vm) {
netbuf* nbuf = *(netbuf**)wrenGetSlotForeign(vm, 0);
const char *path = wrenGetSlotString(vm, 1);
FtpChdir(path, nbuf);
}
 
void C_dir(WrenVM* vm) {
netbuf* nbuf = *(netbuf**)wrenGetSlotForeign(vm, 0);
const char *outputFile = wrenGetSlotString(vm, 1);
if (strlen(outputFile) == 0) outputFile = NULL;
const char *path = wrenGetSlotString(vm, 2);
FtpDir(outputFile, path, nbuf);
}
 
void C_get(WrenVM* vm) {
netbuf* nbuf = *(netbuf**)wrenGetSlotForeign(vm, 0);
const char *output = wrenGetSlotString(vm, 1);
if (strlen(output) == 0) output = NULL;
const char *path = wrenGetSlotString(vm, 2);
char mode = (char)wrenGetSlotDouble(vm, 3);
FtpGet(output, path, mode, nbuf);
}
 
void C_quit(WrenVM* vm) {
netbuf* nbuf = *(netbuf**)wrenGetSlotForeign(vm, 0);
FtpQuit(nbuf);
}
 
WrenForeignClassMethods bindForeignClass(WrenVM* vm, const char* module, const char* className) {
WrenForeignClassMethods methods;
methods.finalize = NULL;
if (strcmp(module, "main") == 0) {
if (strcmp(className, "Ftp") == 0) {
methods.allocate = C_ftpAllocate;
}
}
return methods;
}
 
WrenForeignMethodFn bindForeignMethod(
WrenVM* vm,
const char* module,
const char* className,
bool isStatic,
const char* signature) {
if (strcmp(module, "main") == 0) {
if (strcmp(className, "Ftp") == 0) {
if ( isStatic && strcmp(signature, "init()") == 0) return C_init;
if (!isStatic && strcmp(signature, "login(_,_)") == 0) return C_login;
if (!isStatic && strcmp(signature, "options(_,_)") == 0) return C_options;
if (!isStatic && strcmp(signature, "chdir(_)") == 0) return C_chdir;
if (!isStatic && strcmp(signature, "dir(_,_)") == 0) return C_dir;
if (!isStatic && strcmp(signature, "get(_,_,_)") == 0) return C_get;
if (!isStatic && strcmp(signature, "quit()") == 0) return C_quit;
}
}
return NULL;
}
 
static void writeFn(WrenVM* vm, const char* text) {
printf("%s", text);
}
 
void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
switch (errorType) {
case WREN_ERROR_COMPILE:
printf("[%s line %d] [Error] %s\n", module, line, msg);
break;
case WREN_ERROR_STACK_TRACE:
printf("[%s line %d] in %s\n", module, line, msg);
break;
case WREN_ERROR_RUNTIME:
printf("[Runtime Error] %s\n", msg);
break;
}
}
 
char *readFile(const char *fileName) {
FILE *f = fopen(fileName, "r");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
rewind(f);
char *script = malloc(fsize + 1);
fread(script, 1, fsize, f);
fclose(f);
script[fsize] = 0;
return script;
}
 
int main(int argc, char **argv) {
WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = &writeFn;
config.errorFn = &errorFn;
config.bindForeignClassFn = &bindForeignClass;
config.bindForeignMethodFn = &bindForeignMethod;
WrenVM* vm = wrenNewVM(&config);
const char* module = "main";
const char* fileName = "FTP.wren";
char *script = readFile(fileName);
WrenInterpretResult result = wrenInterpret(vm, module, script);
switch (result) {
case WREN_RESULT_COMPILE_ERROR:
printf("Compile Error!\n");
break;
case WREN_RESULT_RUNTIME_ERROR:
printf("Runtime Error!\n");
break;
case WREN_RESULT_SUCCESS:
break;
}
wrenFreeVM(vm);
free(script);
return 0;
}</syntaxhighlight>
 
{{out}}
Sample output:
<pre>
drwxr-xr-x 25 1002 1002 4096 Aug 15 06:55 dists
drwxr-xr-x 4 1002 1002 4096 Sep 27 07:52 doc
-rw-r--r-- 1 1002 1002 254738 Sep 27 08:21 extrafiles
drwxr-xr-x 3 1002 1002 4096 Sep 27 08:15 indices
-rw-r--r-- 1 1002 1002 14538903 Sep 27 08:15 ls-lR.gz
drwxr-xr-x 5 1002 1002 4096 Dec 19 2000 pool
drwxr-xr-x 4 1002 1002 4096 Nov 17 2008 project
-rw-r--r-- 1 1002 1002 1320 Aug 14 09:28 README
-rw-r--r-- 1 1002 1002 1290 Jun 26 2010 README.CD-manufacture
-rw-r--r-- 1 1002 1002 3203 Aug 14 09:27 README.html
-rw-r--r-- 1 1002 1002 291 Mar 4 2017 README.mirrors.html
-rw-r--r-- 1 1002 1002 86 Mar 4 2017 README.mirrors.txt
drwxr-xr-x 3 1002 1002 4096 Oct 10 2012 tools
drwxr-xr-x 26 1002 1002 4096 Aug 14 13:55 zzz-dists
</pre>
 
=={{header|zkl}}==
Using the cURL library, doing this from the REPL. Moving around in the tree isn't supported.
<langsyntaxhighlight lang="zkl">zkl: var cURL=Import("zklCurl")
zkl: var d=cURL().get("ftp.hq.nasa.gov/pub/issoutreach/Living in Space Stories (MP3 Files)/")
L(Data(2,567),1630,23) // downloaded listing, 1630 bytes of header, 23 bytes of trailer
Line 909 ⟶ 2,213:
L(Data(1,136,358),1681,23)
zkl: File("foo.mp3","w").write(d[0][1681,-23])
1134654 // note that this matches size in listing</langsyntaxhighlight>
The resulting file foo.mp3 has a nice six minute description of what can happen when returning from space.
 
9,476

edits