summaryrefslogtreecommitdiffstats
path: root/cpukit/libnetworking
diff options
context:
space:
mode:
authorThomas Doerfler <Thomas.Doerfler@embedded-brains.de>2009-05-07 14:40:55 +0000
committerThomas Doerfler <Thomas.Doerfler@embedded-brains.de>2009-05-07 14:40:55 +0000
commitd2ec6433fad6c8ebc942a5bf0142697dcdc7a881 (patch)
treeb5c785431b90beae450c3f32e9a43d6f16f57cc3 /cpukit/libnetworking
parentNew. (diff)
downloadrtems-d2ec6433fad6c8ebc942a5bf0142697dcdc7a881.tar.bz2
libnetworking/lib/ftpfs.c, libnetworking/rtems/ftpfs.h: Added
timeouts. Options are now per file system instance.
Diffstat (limited to 'cpukit/libnetworking')
-rw-r--r--cpukit/libnetworking/lib/ftpfs.c373
-rw-r--r--cpukit/libnetworking/rtems/ftpfs.h74
2 files changed, 366 insertions, 81 deletions
diff --git a/cpukit/libnetworking/lib/ftpfs.c b/cpukit/libnetworking/lib/ftpfs.c
index e51f88bf0d..65f651f5f5 100644
--- a/cpukit/libnetworking/lib/ftpfs.c
+++ b/cpukit/libnetworking/lib/ftpfs.c
@@ -1,7 +1,7 @@
/**
* @file
*
- * @brief File Transfer Protocol file system (FTP client).
+ * File Transfer Protocol file system (FTP client).
*/
/*
@@ -61,26 +61,70 @@
#endif
/**
- * @brief Connection entry for each open file stream.
+ * Connection entry for each open file stream.
*/
typedef struct {
/**
- * @brief Control connection socket.
+ * Control connection socket.
*/
int ctrl_socket;
/**
- * @brief Data transfer socket.
+ * Data transfer socket.
*/
int data_socket;
/**
- * @brief End of file flag.
+ * End of file flag.
*/
bool eof;
} rtems_ftpfs_entry;
-static bool rtems_ftpfs_verbose = false;
+/**
+ * Mount entry for each file system instance.
+ */
+typedef struct {
+ /**
+ * Verbose mode enabled or disabled.
+ */
+ bool verbose;
+
+ /**
+ * Timeout value
+ */
+ struct timeval timeout;
+} rtems_ftpfs_mount_entry;
+
+static const rtems_filesystem_file_handlers_r rtems_ftpfs_handlers;
+
+static const rtems_filesystem_file_handlers_r rtems_ftpfs_root_handlers;
+
+static bool rtems_ftpfs_use_timeout( const struct timeval *to)
+{
+ return to->tv_sec != 0 || to->tv_usec != 0;
+}
+
+static int rtems_ftpfs_set_connection_timeout(
+ int socket,
+ const struct timeval *to
+)
+{
+ if (rtems_ftpfs_use_timeout( to)) {
+ int rv = 0;
+
+ rv = setsockopt( socket, SOL_SOCKET, SO_SNDTIMEO, to, sizeof( *to));
+ if (rv != 0) {
+ return EIO;
+ }
+
+ rv = setsockopt( socket, SOL_SOCKET, SO_RCVTIMEO, to, sizeof( *to));
+ if (rv != 0) {
+ return EIO;
+ }
+ }
+
+ return 0;
+}
rtems_status_code rtems_ftpfs_mount( const char *mount_point)
{
@@ -109,22 +153,81 @@ rtems_status_code rtems_ftpfs_mount( const char *mount_point)
return RTEMS_SUCCESSFUL;
}
-rtems_status_code rtems_ftpfs_set_verbose( bool verbose)
+static rtems_status_code rtems_ftpfs_do_ioctl(
+ const char *mount_point,
+ int req,
+ ...
+)
{
- rtems_ftpfs_verbose = verbose;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ int rv = 0;
+ int fd = 0;
+ va_list ap;
- return RTEMS_SUCCESSFUL;
+ if (mount_point == NULL) {
+ mount_point = RTEMS_FTPFS_MOUNT_POINT_DEFAULT;
+ }
+
+ fd = open( mount_point, O_RDWR);
+ if (fd < 0) {
+ return RTEMS_INVALID_NAME;
+ }
+
+ va_start( ap, req);
+ rv = ioctl( fd, req, va_arg( ap, void *));
+ va_end( ap);
+ if (rv != 0) {
+ sc = RTEMS_INVALID_NUMBER;
+ }
+
+ rv = close( fd);
+ if (rv != 0 && sc == RTEMS_SUCCESSFUL) {
+ sc = RTEMS_IO_ERROR;
+ }
+
+ return sc;
}
-rtems_status_code rtems_ftpfs_get_verbose( bool *verbose)
+rtems_status_code rtems_ftpfs_get_verbose( const char *mount_point, bool *verbose)
{
- if (verbose == NULL) {
- return RTEMS_INVALID_ADDRESS;
- }
+ return rtems_ftpfs_do_ioctl(
+ mount_point,
+ RTEMS_FTPFS_IOCTL_GET_VERBOSE,
+ verbose
+ );
+}
- *verbose = rtems_ftpfs_verbose;
+rtems_status_code rtems_ftpfs_set_verbose( const char *mount_point, bool verbose)
+{
+ return rtems_ftpfs_do_ioctl(
+ mount_point,
+ RTEMS_FTPFS_IOCTL_SET_VERBOSE,
+ &verbose
+ );
+}
- return RTEMS_SUCCESSFUL;
+rtems_status_code rtems_ftpfs_get_timeout(
+ const char *mount_point,
+ struct timeval *timeout
+)
+{
+ return rtems_ftpfs_do_ioctl(
+ mount_point,
+ RTEMS_FTPFS_IOCTL_GET_TIMEOUT,
+ timeout
+ );
+}
+
+rtems_status_code rtems_ftpfs_set_timeout(
+ const char *mount_point,
+ const struct timeval *timeout
+)
+{
+ return rtems_ftpfs_do_ioctl(
+ mount_point,
+ RTEMS_FTPFS_IOCTL_SET_TIMEOUT,
+ timeout
+ );
}
int rtems_bsdnet_initialize_ftp_filesystem( void)
@@ -169,11 +272,11 @@ typedef enum {
static rtems_ftpfs_reply rtems_ftpfs_get_reply(
int socket,
rtems_ftpfs_reply_parser parser,
- void *parser_arg
+ void *parser_arg,
+ bool verbose
)
{
rtems_ftpfs_reply_state state = RTEMS_FTPFS_REPLY_START;
- bool verbose = rtems_ftpfs_verbose;
char reply_first [RTEMS_FTPFS_REPLY_SIZE] = { 'a', 'a', 'a' };
char reply_last [RTEMS_FTPFS_REPLY_SIZE] = { 'b', 'b', 'b' };
size_t reply_first_index = 0;
@@ -274,11 +377,11 @@ static rtems_ftpfs_reply rtems_ftpfs_send_command_with_parser(
const char *cmd,
const char *arg,
rtems_ftpfs_reply_parser parser,
- void *parser_arg
+ void *parser_arg,
+ bool verbose
)
{
const char *const eol = "\r\n";
- bool verbose = rtems_ftpfs_verbose;
int rv = 0;
/* Send command */
@@ -311,16 +414,24 @@ static rtems_ftpfs_reply rtems_ftpfs_send_command_with_parser(
}
/* Return reply */
- return rtems_ftpfs_get_reply( socket, parser, parser_arg);
+ return rtems_ftpfs_get_reply( socket, parser, parser_arg, verbose);
}
static rtems_ftpfs_reply rtems_ftpfs_send_command(
int socket,
const char *cmd,
- const char *arg
+ const char *arg,
+ bool verbose
)
{
- return rtems_ftpfs_send_command_with_parser( socket, cmd, arg, NULL, NULL);
+ return rtems_ftpfs_send_command_with_parser(
+ socket,
+ cmd,
+ arg,
+ NULL,
+ NULL,
+ verbose
+ );
}
typedef enum {
@@ -443,6 +554,8 @@ static int rtems_ftpfs_terminate( rtems_libio_t *iop, bool error)
int eno = 0;
int rv = 0;
rtems_ftpfs_entry *e = iop->data1;
+ rtems_ftpfs_mount_entry *me = iop->pathinfo.mt_entry->fs_info;
+ bool verbose = me->verbose;
if (e != NULL) {
/* Close data connection if necessary */
@@ -459,7 +572,7 @@ static int rtems_ftpfs_terminate( rtems_libio_t *iop, bool error)
&& !error
) {
rtems_ftpfs_reply reply =
- rtems_ftpfs_get_reply( e->ctrl_socket, NULL, NULL);
+ rtems_ftpfs_get_reply( e->ctrl_socket, NULL, NULL, verbose);
if (reply != RTEMS_FTPFS_REPLY_2) {
eno = EIO;
@@ -490,10 +603,13 @@ static int rtems_ftpfs_open_ctrl_connection(
const char *user,
const char *password,
const char *hostname,
- uint32_t *client_address
+ uint32_t *client_address,
+ bool verbose,
+ const struct timeval *timeout
)
{
int rv = 0;
+ int eno = 0;
rtems_ftpfs_reply reply = RTEMS_FTPFS_REPLY_ERROR;
struct in_addr address = { .s_addr = 0 };
struct sockaddr_in sa;
@@ -532,6 +648,12 @@ static int rtems_ftpfs_open_ctrl_connection(
return ENOENT;
}
+ /* Set control connection timeout */
+ eno = rtems_ftpfs_set_connection_timeout( e->ctrl_socket, timeout);
+ if (eno != 0) {
+ return eno;
+ }
+
/* Get client address */
size = rtems_ftpfs_create_address( &sa, INADDR_ANY, 0);
rv = getsockname(
@@ -546,16 +668,21 @@ static int rtems_ftpfs_open_ctrl_connection(
DEBUG_PRINTF( "client = %s\n", inet_ntoa( sa.sin_addr));
/* Now we should get a welcome message from the server */
- reply = rtems_ftpfs_get_reply( e->ctrl_socket, NULL, NULL);
+ reply = rtems_ftpfs_get_reply( e->ctrl_socket, NULL, NULL, verbose);
if (reply != RTEMS_FTPFS_REPLY_2) {
return ENOENT;
}
/* Send USER command */
- reply = rtems_ftpfs_send_command( e->ctrl_socket, "USER ", user);
+ reply = rtems_ftpfs_send_command( e->ctrl_socket, "USER ", user, verbose);
if (reply == RTEMS_FTPFS_REPLY_3) {
/* Send PASS command */
- reply = rtems_ftpfs_send_command( e->ctrl_socket, "PASS ", password);
+ reply = rtems_ftpfs_send_command(
+ e->ctrl_socket,
+ "PASS ",
+ password,
+ verbose
+ );
if (reply != RTEMS_FTPFS_REPLY_2) {
return EACCES;
}
@@ -566,7 +693,7 @@ static int rtems_ftpfs_open_ctrl_connection(
}
/* Send TYPE command to set binary mode for all data transfers */
- reply = rtems_ftpfs_send_command( e->ctrl_socket, "TYPE I", NULL);
+ reply = rtems_ftpfs_send_command( e->ctrl_socket, "TYPE I", NULL, verbose);
if (reply != RTEMS_FTPFS_REPLY_2) {
return EIO;
}
@@ -578,7 +705,9 @@ static int rtems_ftpfs_open_data_connection_active(
rtems_ftpfs_entry *e,
uint32_t client_address,
const char *file_command,
- const char *filename
+ const char *filename,
+ bool verbose,
+ const struct timeval *timeout
)
{
int rv = 0;
@@ -589,11 +718,6 @@ static int rtems_ftpfs_open_data_connection_active(
int port_socket = -1;
char port_command [] = "PORT 000,000,000,000,000,000";
uint16_t data_port = 0;
- fd_set fds;
- struct timeval timeout = {
- .tv_sec = 60,
- .tv_usec = 0
- };
/* Create port socket to establish a data data connection */
port_socket = socket( AF_INET, SOCK_STREAM, 0);
@@ -639,7 +763,12 @@ static int rtems_ftpfs_open_data_connection_active(
(data_port >> 8) & 0xffUL,
(data_port >> 0) & 0xffUL
);
- reply = rtems_ftpfs_send_command( e->ctrl_socket, port_command, NULL);
+ reply = rtems_ftpfs_send_command(
+ e->ctrl_socket,
+ port_command,
+ NULL,
+ verbose
+ );
if (reply != RTEMS_FTPFS_REPLY_2) {
eno = ENOTSUP;
goto cleanup;
@@ -653,19 +782,30 @@ static int rtems_ftpfs_open_data_connection_active(
}
/* Send RETR or STOR command with filename */
- reply = rtems_ftpfs_send_command( e->ctrl_socket, file_command, filename);
+ reply = rtems_ftpfs_send_command(
+ e->ctrl_socket,
+ file_command,
+ filename,
+ verbose
+ );
if (reply != RTEMS_FTPFS_REPLY_1) {
eno = EIO;
goto cleanup;
}
- /* Wait for connect on data connection */
- FD_ZERO( &fds);
- FD_SET( port_socket, &fds);
- rv = select( port_socket + 1, &fds, NULL, NULL, &timeout);
- if (rv <= 0) {
- eno = EIO;
- goto cleanup;
+ /* Wait for connect on data connection if necessary */
+ if (rtems_ftpfs_use_timeout( timeout)) {
+ struct timeval to = *timeout;
+ fd_set fds;
+
+ FD_ZERO( &fds);
+ FD_SET( port_socket, &fds);
+
+ rv = select( port_socket + 1, &fds, NULL, NULL, &to);
+ if (rv <= 0) {
+ eno = EIO;
+ goto cleanup;
+ }
}
/* Accept data connection */
@@ -755,7 +895,9 @@ static int rtems_ftpfs_open_data_connection_passive(
rtems_ftpfs_entry *e,
uint32_t client_address,
const char *file_command,
- const char *filename
+ const char *filename,
+ bool verbose,
+ const struct timeval *timeout
)
{
int rv = 0;
@@ -774,7 +916,8 @@ static int rtems_ftpfs_open_data_connection_passive(
"PASV",
NULL,
rtems_ftpfs_pasv_parser,
- &pe
+ &pe,
+ verbose
);
if (reply != RTEMS_FTPFS_REPLY_2) {
return ENOTSUP;
@@ -806,7 +949,12 @@ static int rtems_ftpfs_open_data_connection_passive(
}
/* Send RETR or STOR command with filename */
- reply = rtems_ftpfs_send_command( e->ctrl_socket, file_command, filename);
+ reply = rtems_ftpfs_send_command(
+ e->ctrl_socket,
+ file_command,
+ filename,
+ verbose
+ );
if (reply != RTEMS_FTPFS_REPLY_1) {
return EIO;
}
@@ -824,6 +972,9 @@ static int rtems_ftpfs_open(
int eno = 0;
bool ok = false;
rtems_ftpfs_entry *e = NULL;
+ rtems_ftpfs_mount_entry *me = iop->pathinfo.mt_entry->fs_info;
+ bool verbose = me->verbose;
+ const struct timeval *timeout = &me->timeout;
const char *user = NULL;
const char *password = NULL;
const char *hostname = NULL;
@@ -842,14 +993,6 @@ static int rtems_ftpfs_open(
rtems_set_errno_and_return_minus_one( ENOMEM);
}
- /* Check for either read-only or write-only flags */
- if (
- (iop->flags & LIBIO_FLAGS_WRITE) != 0
- && (iop->flags & LIBIO_FLAGS_READ) != 0
- ) {
- rtems_set_errno_and_return_minus_one( ENOTSUP);
- }
-
/* Split location into parts */
ok = rtems_ftpfs_split_names(
location,
@@ -859,7 +1002,17 @@ static int rtems_ftpfs_open(
&filename
);
if (!ok) {
- rtems_set_errno_and_return_minus_one( ENOENT);
+ if (strlen( location) == 0) {
+ /*
+ * This is an access to the root node that will be used for file system
+ * option settings.
+ */
+ iop->handlers = &rtems_ftpfs_root_handlers;
+
+ return 0;
+ } else {
+ rtems_set_errno_and_return_minus_one( ENOENT);
+ }
}
DEBUG_PRINTF(
"user = '%s', password = '%s', filename = '%s'\n",
@@ -868,6 +1021,14 @@ static int rtems_ftpfs_open(
filename
);
+ /* Check for either read-only or write-only flags */
+ if (
+ (iop->flags & LIBIO_FLAGS_WRITE) != 0
+ && (iop->flags & LIBIO_FLAGS_READ) != 0
+ ) {
+ rtems_set_errno_and_return_minus_one( ENOTSUP);
+ }
+
/* Allocate connection entry */
e = malloc( sizeof( *e));
if (e == NULL) {
@@ -888,7 +1049,9 @@ static int rtems_ftpfs_open(
user,
password,
hostname,
- &client_address
+ &client_address,
+ verbose,
+ timeout
);
if (eno != 0) {
goto cleanup;
@@ -899,7 +1062,9 @@ static int rtems_ftpfs_open(
e,
client_address,
file_command,
- filename
+ filename,
+ verbose,
+ timeout
);
if (eno == ENOTSUP) {
/* Open active data connection */
@@ -907,9 +1072,17 @@ static int rtems_ftpfs_open(
e,
client_address,
file_command,
- filename
+ filename,
+ verbose,
+ timeout
);
}
+ if (eno != 0) {
+ goto cleanup;
+ }
+
+ /* Set data connection timeout */
+ eno = rtems_ftpfs_set_connection_timeout( e->data_socket, timeout);
cleanup:
@@ -930,6 +1103,8 @@ static ssize_t rtems_ftpfs_read(
)
{
rtems_ftpfs_entry *e = iop->data1;
+ rtems_ftpfs_mount_entry *me = iop->pathinfo.mt_entry->fs_info;
+ bool verbose = me->verbose;
char *in = buffer;
size_t todo = count;
@@ -943,7 +1118,7 @@ static ssize_t rtems_ftpfs_read(
if (rv <= 0) {
if (rv == 0) {
rtems_ftpfs_reply reply =
- rtems_ftpfs_get_reply( e->ctrl_socket, NULL, NULL);
+ rtems_ftpfs_get_reply( e->ctrl_socket, NULL, NULL, verbose);
if (reply == RTEMS_FTPFS_REPLY_2) {
e->eof = true;
@@ -1036,19 +1211,25 @@ static rtems_filesystem_node_types_t rtems_ftpfs_node_type(
return RTEMS_FILESYSTEM_MEMORY_FILE;
}
-static const rtems_filesystem_file_handlers_r rtems_ftpfs_handlers;
-
static int rtems_ftpfs_mount_me(
rtems_filesystem_mount_table_entry_t *e
)
{
+ rtems_ftpfs_mount_entry *me = malloc( sizeof( rtems_ftpfs_mount_entry));
+
+ /* Mount entry for FTP file system instance */
+ e->fs_info = me;
+ if (e->fs_info == NULL) {
+ rtems_set_errno_and_return_minus_one( ENOMEM);
+ }
+ me->verbose = false;
+ me->timeout.tv_sec = 0;
+ me->timeout.tv_usec = 0;
+
/* Set handler and oparations table */
e->mt_fs_root.handlers = &rtems_ftpfs_handlers;
e->mt_fs_root.ops = &rtems_ftpfs_ops;
- /* We have no FTP file system specific data to maintain */
- e->fs_info = NULL;
-
/* We maintain no real file system nodes, so there is no real root */
e->mt_fs_root.node_access = NULL;
@@ -1058,11 +1239,54 @@ static int rtems_ftpfs_mount_me(
return 0;
}
+static int rtems_ftpfs_unmount_me(
+ rtems_filesystem_mount_table_entry_t *e
+)
+{
+ free( e->fs_info);
+
+ return 0;
+}
+
+static int rtems_ftpfs_ioctl(
+ rtems_libio_t *iop,
+ uint32_t command,
+ void *arg
+)
+{
+ rtems_ftpfs_mount_entry *me = iop->pathinfo.mt_entry->fs_info;
+ bool *verbose = arg;
+ struct timeval *timeout = arg;
+
+ if (arg == NULL) {
+ rtems_set_errno_and_return_minus_one( EINVAL);
+ }
+
+ switch (command) {
+ case RTEMS_FTPFS_IOCTL_GET_VERBOSE:
+ *verbose = me->verbose;
+ break;
+ case RTEMS_FTPFS_IOCTL_SET_VERBOSE:
+ me->verbose = *verbose;
+ break;
+ case RTEMS_FTPFS_IOCTL_GET_TIMEOUT:
+ *timeout = me->timeout;
+ break;
+ case RTEMS_FTPFS_IOCTL_SET_TIMEOUT:
+ me->timeout = *timeout;
+ break;
+ default:
+ rtems_set_errno_and_return_minus_one( EBADRQC);
+ }
+
+ return 0;
+}
+
/*
* The stat() support is intended only for the cp shell command. Each request
* will return that we have a regular file with read, write and execute
* permissions for every one. The node index uses a global counter to support
- * a remote to remote copy. Is not a very sophisticated method.
+ * a remote to remote copy. This is not a very sophisticated method.
*/
static int rtems_ftpfs_fstat(
rtems_filesystem_location_info_t *loc,
@@ -1094,7 +1318,7 @@ const rtems_filesystem_operations_table rtems_ftpfs_ops = {
.mount_h = NULL,
.fsmount_me_h = rtems_ftpfs_mount_me,
.unmount_h = NULL,
- .fsunmount_me_h = NULL,
+ .fsunmount_me_h = rtems_ftpfs_unmount_me,
.utime_h = NULL,
.eval_link_h = NULL,
.symlink_h = NULL,
@@ -1117,3 +1341,20 @@ static const rtems_filesystem_file_handlers_r rtems_ftpfs_handlers = {
.fcntl_h = NULL,
.rmnod_h = NULL
};
+
+static const rtems_filesystem_file_handlers_r rtems_ftpfs_root_handlers = {
+ .open_h = NULL,
+ .close_h = NULL,
+ .read_h = NULL,
+ .write_h = NULL,
+ .ioctl_h = rtems_ftpfs_ioctl,
+ .lseek_h = NULL,
+ .fstat_h = NULL,
+ .fchmod_h = NULL,
+ .ftruncate_h = NULL,
+ .fpathconf_h = NULL,
+ .fsync_h = NULL,
+ .fdatasync_h = NULL,
+ .fcntl_h = NULL,
+ .rmnod_h = NULL
+};
diff --git a/cpukit/libnetworking/rtems/ftpfs.h b/cpukit/libnetworking/rtems/ftpfs.h
index 3d48da2ca5..0414f8e49d 100644
--- a/cpukit/libnetworking/rtems/ftpfs.h
+++ b/cpukit/libnetworking/rtems/ftpfs.h
@@ -1,7 +1,7 @@
/**
* @file
*
- * @brief File Transfer Protocol file system (FTP client).
+ * File Transfer Protocol file system (FTP client).
*/
/*
@@ -34,6 +34,9 @@
#ifndef _RTEMS_FTPFS_H
#define _RTEMS_FTPFS_H
+#include <sys/time.h>
+#include <sys/ioctl.h>
+
#include <rtems/libio.h>
#ifdef __cplusplus
@@ -71,52 +74,93 @@ extern "C" {
*/
/**
- * @brief Well-known port number for FTP control connection.
+ * Well-known port number for FTP control connection.
*/
#define RTEMS_FTPFS_CTRL_PORT 21
/**
- * @brief Default mount point for FTP file system.
+ * Default mount point for FTP file system.
*/
#define RTEMS_FTPFS_MOUNT_POINT_DEFAULT "/FTP"
/**
- * @brief FTP file system operations table.
+ * FTP file system IO control requests.
+ */
+typedef enum {
+ RTEMS_FTPFS_IOCTL_GET_VERBOSE = _IOR( 'd', 1, bool *),
+ RTEMS_FTPFS_IOCTL_SET_VERBOSE = _IOW( 'd', 1, bool *),
+ RTEMS_FTPFS_IOCTL_GET_TIMEOUT = _IOR( 'd', 2, struct timeval *),
+ RTEMS_FTPFS_IOCTL_SET_TIMEOUT = _IOW( 'd', 2, struct timeval *)
+} rtems_ftpfs_ioctl_numbers;
+
+/**
+ * FTP file system operations table.
*/
extern const rtems_filesystem_operations_table rtems_ftpfs_ops;
/**
- * @brief Creates the mount point @a mount_point and mounts the FTP file
- * system.
+ * Creates the mount point @a mount_point and mounts the FTP file system.
*
* If @a mount_point is @c NULL the default mount point
* @ref RTEMS_FTPFS_MOUNT_POINT_DEFAULT will be used.
*
* It is mounted with read and write access.
- *
- * @note The parent directories of the mount point have to exist.
*/
rtems_status_code rtems_ftpfs_mount( const char *mount_point);
/**
- * @brief Enables or disables the verbose mode if @a verbose is @c true or
- * @c false respectively.
+ * Returns in @a verbose if the verbose mode is enabled or disabled for the
+ * file system at @a mount_point.
+ *
+ * If @a mount_point is @c NULL the default mount point
+ * @ref RTEMS_FTPFS_MOUNT_POINT_DEFAULT will be used.
+ */
+rtems_status_code rtems_ftpfs_get_verbose( const char *mount_point, bool *verbose);
+
+/**
+ * Enables or disables the verbose mode if @a verbose is @c true or
+ * @c false respectively for the file system at @a mount_point.
*
* In the enabled verbose mode the commands and replies of the FTP control
* connections will be printed to standard error.
+ *
+ * If @a mount_point is @c NULL the default mount point
+ * @ref RTEMS_FTPFS_MOUNT_POINT_DEFAULT will be used.
+ */
+rtems_status_code rtems_ftpfs_set_verbose( const char *mount_point, bool verbose);
+
+/**
+ * Returns the current timeout value in @a timeout for the file system at
+ * @a mount_point.
+ *
+ * If @a mount_point is @c NULL the default mount point
+ * @ref RTEMS_FTPFS_MOUNT_POINT_DEFAULT will be used.
*/
-rtems_status_code rtems_ftpfs_set_verbose( bool verbose);
+rtems_status_code rtems_ftpfs_get_timeout(
+ const char *mount_point,
+ struct timeval *timeout
+);
/**
- * @brief Returns in @a verbose if the verbose mode is enabled or disabled.
+ * Sets the timeout value to @a timeout for the file system at @a mount_point.
+ *
+ * The timeout value will be used during connection establishment of active
+ * data connections. It will be also used for send and receive operations on
+ * data and control connections.
+ *
+ * If @a mount_point is @c NULL the default mount point
+ * @ref RTEMS_FTPFS_MOUNT_POINT_DEFAULT will be used.
*/
-rtems_status_code rtems_ftpfs_get_verbose( bool *verbose);
+rtems_status_code rtems_ftpfs_set_timeout(
+ const char *mount_point,
+ const struct timeval *timeout
+);
/** @} */
/**
- * @brief Creates the default mount point @ref RTEMS_FTPFS_MOUNT_POINT_DEFAULT
- * and mounts the FTP file system.
+ * Creates the default mount point @ref RTEMS_FTPFS_MOUNT_POINT_DEFAULT and
+ * mounts the FTP file system.
*
* It is mounted with read and write access.
*