FTP Server API -- describe FTP server API, callback and configuration
FTP Server API
The FTP server provides a single entry point:
#include <ftpserver.h>
__externC int cyg_ftpserver_start( cyg_ftpserver *server );
This function starts an FTP server running using parameters defined
in the server argument. It should be called
from a thread with a stack with at least
CYGNUM_NET_FTPSERVER_STACK_SIZE bytes
available. Under normal circumstances this function will not
return, so the application should create a thread dedicated to the
server. There are examples of this in the test programs.
The server argument contains a number of
fields that the user may set to control the behaviour of the FTP
server.
const char *address
This is a string giving the IP address on which the server will
listen. If not set this will default to listening on all
network interface, which is usually what is wanted. This option
is only useful if a target has more than one network interface
and the FTP server should only listen on one of them.
int port
This defines the port number on which the server will
listen. Leaving this value unset, zero, will cause the server
to choose the default FTP port of 21.
const char *greeting
This is the string that the server will use in its initial
response to a client connection. Leaving this NULL will cause
the server to use a default message: "Welcome to eCosPro FTP service.".
const char *root
This string defines a filesystem pathname to the root directory
of the FTP server. Files will only be transferred to and from
this directory or any subdirectories. A NULL pointer here will
cause the server to use "/" as the root.
int data_port
This defines the first port at which the server will create
passive data connections. It will try successive ports from
this value until a free port is found, limited to the following
20 ports. Leaving this value NULL will cause the server to
start from port 5000.
The normal idiom for use of the FTP server is to define the
cyg_ftpserver structure statically and to then call
cyg_ftpserver_start() with a pointer to
that. The following is a somewhat contrived example:
The defaults for the configuration parameters are such that
leaving them all zero or NULL will cause the server to configure
itself on the standard port serving files to/from the root of the
filesystem.
Callback Interface
The default server operates to and from a directory in a
filesystem, in the same way that most FTP servers
operate. However, not all embedded systems have filesystem
support. To allow such systems to provide an FTP service, all file
access operations go through a set of callback functions in the
cyg_ftpserver structure. The user can define these to
redirect file I/O operations to other devices such as memory
buffers or flash memory regions.
The callback interface defines a type,
ftpserver_cookie that is passed to the callback
functions. It is a word or pointer sized value and is typically
used by the callback functions to contain a data structure
pointer, or an index into a table that uniquely identifies an open
file.
The callbacks for a notional example
interface are defined as follows:
int example_open( const char *path, cyg_bool write, ftpserver_cookie *cookie );
Called to open a file for data transfer. The
path is a fully rooted path formed from
the root field of the server
configuration plus the client supplied path. The
write argument is true if the file is to
be opened for writing and false if for reading. If successful
the function may store a private value to
*cookie.
If the file is opened successfully this function should return
FTPSERVER_OK. If the file cannot be opened
for reading it should return FTPSERVER_NO_FILE.
If the file cannot be written to or created it should return
FTPSERVER_NOT_ALLOWED.
int example_write( ftpserver_cookie cookie, const cyg_uint8 *buf, cyg_uint32 size );
Called to write data to the file. The
cookie argument is the value stored by
the open callback. Arguments buf and
size define the data to be written.
If the data is successfully written this function should return
FTPSERVER_OK. If any error occurs it should
return FTPSERVER_WRITE_FAIL.
int example_read( ftpserver_cookie cookie, cyg_uint8 *buf, cyg_uint32 *size );
Called to read data from the file. The
cookie argument is the value stored by
the open callback. Arguments buf and
*size define a buffer into which the
data should be stored, *size should be
updated with the amount of data written to the buffer. If no
more data is available, *size should be
set to zero.
If the function is successful it should return
FTPSERVER_OK. If any error occurs it should
return FTPSERVER_READ_FAIL.
int example_close( ftpserver_cookie cookie );
Called to close the file for further data transfer. The
cookie argument is the value stored by
the open callback. After this call the cookie value will not be
used in further calls.
This function should return FTPSERVER_OK
under all circumstance, there are no error conditions of
interest to the FTP server.
int example_auth( const char *user, const char *passwd );
This function is called to authenticate a user ID and password
supplied by the client. The FTP server will only request a
password, by returning a 331 response, if a user supplied
authentication function is installed.
If the user and password are accepted, this function should
return FTPSERVER_LOGIN_OK; it should return
FTPSERVER_BADUSER if they do not.
int example_delete( const char *path );
Called to delete a file. The path is a
fully rooted path formed from the root
field of the server configuration plus the client supplied path.
If the file is deleted successfully this function should return
FTPSERVER_OPDONE. If the file cannot be deleted
or is not found, FTPSERVER_NO_FILE should be
returned.
Extending the previous example, the cyg_ftpserver
might look like this:
static cyg_ftpserver ftp_server =
{
.port = 2121, // Listen on port 2121
.root = "/fatfs/ftp", // FTP to/from here
.greeting = "Welcome to Fubar FTP service.", // Welcome string
.data_port = 40000, // Move data ports to 40000+
.open = example_open,
.read = example_read,
.write = example_write,
.close = example_close,
.auth = example_auth,
.delete = example_delete,
};
Configuration Options
The FTP server package contains a number of configuration options:
CYGNUM_NET_FTPSERVER_BUFFER_SIZE
This option defines the size of the buffer used for data
transfers. Buffer size is a tradeoff between memory use and
transfer speed. The default should be a reasonable compromise
between these two.
CYGNUM_NET_FTPSERVER_USER_SIZE
This option defines the size of the buffer used for storing the
user name supplied by the client.
CYGNUM_NET_FTPSERVER_PASSWD_SIZE
This option defines the size of the buffer used for storing the
password supplied by the client. The default reflects the habit
of using a user's email address as a password for anonymous
FTP.
CYGNUM_NET_FTPSERVER_CONTROL_TIMEOUT
This option defines the timeout applied to control streams. If
after this number of seconds the client has not interacted with
the server, the connection is closed down. Since the server
only allows a single client at a time, any client that fails to
close a control stream down will block it for others.
CYGNUM_NET_FTPSERVER_DATA_TIMEOUT
This option defines the timeout applied to data streams. If
after this number of seconds the client has not transferred
data to or from the server, the connection is closed
down. Clients are expected to use a data connection immediately
after it is created so this timeout can be considerably smaller
than the control timeout.