summaryrefslogtreecommitdiffstats
path: root/c/src/exec/libnetworking/lib/ftpfs.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--c/src/exec/libnetworking/lib/ftpfs.c1159
1 files changed, 0 insertions, 1159 deletions
diff --git a/c/src/exec/libnetworking/lib/ftpfs.c b/c/src/exec/libnetworking/lib/ftpfs.c
deleted file mode 100644
index 033c1b6bdf..0000000000
--- a/c/src/exec/libnetworking/lib/ftpfs.c
+++ /dev/null
@@ -1,1159 +0,0 @@
-/*
- * File Transfer Protocol client
- *
- * Transfer file to/from remote host
- *
- * This driver can be added to the RTEMS file system with a call to
- * "rtems_bsdnet_initialize_ftp_filesystem () ".
- * From then on, you can open, read and close files on a remote FTP server
- * using the following syntax:
- * To open a file "myfile.txt" in the directory "mydir" (relative to home
- * directory) on a server named "myserver" using the user id
- * "myuserid" and the password "my_very_secret_password" you must
- * specify the following path:
- *
- * /FTP/myuserid:my_very_secret_password/@myserver/mydirectory/myfile.txt
- *
- * If the server is the default server specified in BOOTP, it can be ommitted:
- *
- * /FTP/myuserid:my_very_secret_password/mydirectory/myfile.txt
- *
- * WARNING: write accesses have not yet been tested.
- *
- *
- * (c) Copyright 2002
- * Thomas Doerfler
- * IMD Ingenieurbuero fuer Microcomputertechnik
- * Herbststr. 8
- * 82178 Puchheim, Germany
- * <Thomas.Doerfler@imd-systems.de>
- *
- * This code has been created after closly inspecting
- * "tftpdriver.c" from Eric Norum.
- *
- * $Id$
- */
-
-#include <stdio.h>
-#include <errno.h>
-#include <malloc.h>
-#include <string.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <rtems.h>
-#include <rtems/libio.h>
-#include <rtems/rtems_bsdnet.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <rtems/ftpfs.h>
-
-
-#ifndef set_errno_and_return_minus_one
-#define set_errno_and_return_minus_one( _error ) \
- do { errno = (_error); return -1; } while(0)
-#endif
-
-/* #define DEBUG_OUT */
-
-/*
- * Well-known port for FTP
- */
-#define FTP_PORT_NUM 21
-
-/*
- * Pathname prefix
- */
-#define FTP_PATHNAME_PREFIX "/FTP/"
-/*
- * reply codes
- */
-#define FTP_REPLY_CONNECT 220 /* Connection established */
-#define FTP_REPLY_PASSREQ 331 /* user ok, password required */
-#define FTP_REPLY_LOGIN 230 /* login finished */
-#define FTP_REPLY_SUCCESS 200 /* xxx successful */
-#define FTP_REPLY_OPENCONN 150 /* opening connection for tfer */
-#define FTP_REPLY_TFERCMPL 226 /* transfer complete */
-
-extern rtems_filesystem_operations_table rtems_ftp_ops;
-extern rtems_filesystem_file_handlers_r rtems_ftp_handlers;
-
-/*
- * FTP command strings
- */
-#define FTP_USER_CMD "USER "
-#define FTP_PASS_CMD "PASS "
-#define FTP_BINARY_CMD "TYPE I"
-#define FTP_PORT_CMD "PORT "
-#define FTP_STOR_CMD "STOR "
-#define FTP_RETR_CMD "RETR "
-#define FTP_QUIT_CMD "QUIT"
-
-/*
- * State of each FTP stream
- */
-struct ftpStream {
- /*
- * Control connection socket
- */
- int ctrl_socket;
- struct sockaddr_in myCtrlAddress;
- struct sockaddr_in farCtrlAddress;
- /*
- * Data transfer socket
- */
- int port_socket;
- int data_socket;
- struct sockaddr_in myDataAddress;
- struct sockaddr_in farDataAddress;
- /*
- * other stuff to remember
- */
- boolean eof_reached;
-};
-
-/*
- * Number of streams open at the same time
- */
-static rtems_id ftp_mutex;
-static int nStreams;
-static struct ftpStream ** volatile ftpStreams;
-
-extern rtems_filesystem_operations_table rtems_tftp_ops;
-extern rtems_filesystem_file_handlers_r rtems_tftp_handlers;
-
-/*
- * Direct copy from the IMFS/TFTP. Look at this.
- */
-
-rtems_filesystem_limits_and_options_t rtems_ftp_limits_and_options = {
- 5, /* link_max */
- 6, /* max_canon */
- 7, /* max_input */
- 255, /* name_max */
- 255, /* path_max */
- 2, /* pipe_buf */
- 1, /* posix_async_io */
- 2, /* posix_chown_restrictions */
- 3, /* posix_no_trunc */
- 4, /* posix_prio_io */
- 5, /* posix_sync_io */
- 6 /* posix_vdisable */
-};
-
-int rtems_ftp_mount_me(
- rtems_filesystem_mount_table_entry_t *temp_mt_entry
-)
-{
- rtems_status_code sc;
-
- temp_mt_entry->mt_fs_root.handlers = &rtems_ftp_handlers;
- temp_mt_entry->mt_fs_root.ops = &rtems_ftp_ops;
-
- /*
- * We have no ftp filesystem specific data to maintain. This
- * filesystem may only be mounted ONCE.
- *
- * And we maintain no real filesystem nodes, so there is no real root.
- */
-
- temp_mt_entry->fs_info = NULL;
- temp_mt_entry->mt_fs_root.node_access = NULL;
-
- /*
- * These need to be looked at for full POSIX semantics.
- */
-
- temp_mt_entry->pathconf_limits_and_options = rtems_ftp_limits_and_options;
-
-
- /*
- * Now allocate a semaphore for mutual exclusion.
- *
- * NOTE: This could be in an fsinfo for this filesystem type.
- */
-
- sc = rtems_semaphore_create (rtems_build_name('F','T','P',' '),
- 1,
- RTEMS_FIFO |
- RTEMS_BINARY_SEMAPHORE |
- RTEMS_NO_INHERIT_PRIORITY |
- RTEMS_NO_PRIORITY_CEILING |
- RTEMS_LOCAL,
- 0,
- &ftp_mutex);
-
- if (sc != RTEMS_SUCCESSFUL)
- set_errno_and_return_minus_one( ENOMEM );
-
- return 0;
-}
-
-/*
- * Initialize the FTP driver
- */
-
-int rtems_bsdnet_initialize_ftp_filesystem ()
-{
- int status;
- rtems_filesystem_mount_table_entry_t *entry;
-
- status = mkdir( FTP_PATHNAME_PREFIX, S_IRWXU | S_IRWXG | S_IRWXO );
- if ( status == -1 )
- return status;
-
- status = mount(
- &entry,
- &rtems_ftp_ops,
- RTEMS_FILESYSTEM_READ_ONLY,
- NULL,
- FTP_PATHNAME_PREFIX
- );
-
- if ( status )
- perror( "FTP mount failed" );
-
- return status;
-}
-
-/*
- * read and return message code from ftp control connection
- */
-int rtems_ftp_get_message
-(
- const struct ftpStream *fsp, /* ptr to ftp control structure */
- int *msg_code /* ptr to return message code */
-)
-{
- char rd_buffer[4];
- size_t rd_size;
- size_t tmp_size;
- int eno = 0;
- rtems_boolean finished = FALSE;
- do {
- /*
- * fetch (at least) 4 characters from control connection
- * FIXME: how about a timeout?
- */
- rd_size = 0;
- while ((eno == 0) &&
- (rd_size < sizeof(rd_buffer))) {
- tmp_size = read(fsp->ctrl_socket,
- (&rd_buffer)+rd_size,
- sizeof(rd_buffer)-rd_size);
- if (tmp_size < 0) {
- eno = EIO;
- }
- else {
-#ifdef DEBUG_OUT
- write(1,(&rd_buffer)+rd_size,tmp_size);
-#endif
- rd_size += tmp_size;
- }
- }
- /*
- * check for 3 digits and space, otherwise not finished
- */
- if ((eno == 0) &&
- (isdigit((unsigned int)rd_buffer[0])) &&
- (isdigit((unsigned int)rd_buffer[1])) &&
- (isdigit((unsigned int)rd_buffer[2])) &&
- (rd_buffer[3] == ' ')) {
- finished = TRUE;
- rd_buffer[3] = '\0';
- *msg_code = atol(rd_buffer);
- }
- /*
- * skip rest until end-of-line
- */
- do {
- tmp_size = read(fsp->ctrl_socket,
- &rd_buffer,
- 1);
- if (tmp_size < 0) {
- eno = EIO;
- }
-#ifdef DEBUG_OUT
- else {
- write(1,(&rd_buffer),tmp_size);
- }
-#endif
- } while ((eno == 0) &&
- (rd_buffer[0] != '\n'));
- } while ((eno == 0) && !finished);
- return eno;
-}
-
-/*
- * split a pseudo file name into host, user, password, filename
- * NOTE: this function will allocate space for these strings,
- * the calling function should free the space, when no longer needed
- * exception: when we return any error, we will also cleanup
- * the strings
- * valid forms:
- * /FTP/user:pass/filepath
- * /FTP/user:pass@hostname/filepath
-
- * /FTP/user:pass/filepath
- * /FTP/user:pass/@hostname/filepath
- * NOTE: /FTP is already stripped from the name
- */
-int rtems_ftp_split_names
-( const char *pathname, /* total path name (including prefix) */
- char **usernamep, /* ptr to ptr to user name */
- char **passwordp, /* ptr to ptr to password */
- char **hostnamep, /* ptr to ptr to host name */
- char **filenamep) /* ptr to ptr to hostremaining file name */
-{
- const char *chunk_start;
- const char *chunk_end;
- size_t chunk_len;
- int rc = 0;
-
- /*
- * ensure, that result pointers are NULL...
- */
- *usernamep = NULL;
- *passwordp = NULL;
- *hostnamep = NULL;
- *filenamep = NULL;
-
-#if 1
- chunk_start = pathname;
-#else /* no longer needed with IMFS */
- /*
- * check, that total path is long enough, skip prefix
- */
- if (rc == 0) {
- if (strlen (pathname) <= strlen (FTP_PATHNAME_PREFIX)) {
- rc = ENOENT;
- }
- else {
- chunk_start = pathname + strlen (FTP_PATHNAME_PREFIX);
- }
- }
-#endif
- /*
- * fetch user name: terminated with ":"
- */
- if (rc == 0) {
- chunk_end = strchr(chunk_start,':');
- if ((chunk_end == NULL) || /* No ':' found or */
- (chunk_end == chunk_start)) { /* ':' is first character-> no name */
- rc = ENOENT;
- }
- else {
- chunk_len = chunk_end-chunk_start;
- *usernamep = malloc(chunk_len);
- if (*usernamep == NULL) {
- rc = ENOMEM;
- }
- else {
- memcpy(*usernamep,chunk_start,chunk_len);
- (*usernamep)[chunk_len] = '\0';
- }
- }
- }
- /*
- * fetch password: terminated with "/" or "@"
- */
- if (rc == 0) {
- chunk_start = chunk_end + 1; /* skip ":" after user name */
- chunk_end = strchr(chunk_start,'/');
- if ((chunk_end == NULL) || /* No '/' found or */
- (chunk_end == chunk_start)) { /* '/' is first character-> no pwd */
- rc = ENOENT;
- }
- else {
- /*
- * we have found a proper '/'
- * this is the end of the password
- */
- chunk_len = chunk_end-chunk_start;
- *passwordp = malloc(chunk_len);
- if (*passwordp == NULL) {
- rc = ENOMEM;
- }
- else {
- memcpy(*passwordp,chunk_start,chunk_len);
- (*passwordp)[chunk_len] = '\0';
- }
- }
- }
- /*
- * if first char after '/' is '@', then this is the hostname
- * fetch hostname terminated with "/"
- * if exists at all. otherwise take default server from bootp
- */
- if (rc == 0) {
- chunk_start = chunk_end+1;
- if (*chunk_start == '@') {
- /*
- * hostname follows
- */
- chunk_start = chunk_start + 1; /* skip "@" after password */
- chunk_end = strchr(chunk_start,'/');
- if ((chunk_end == NULL) || /* No '/' found or */
- (chunk_end == chunk_start)) { /* '/' is first character-> no host */
- rc = ENOENT;
- }
- else {
- /*
- * we have found a proper '/'
- */
- chunk_len = chunk_end-chunk_start;
- *hostnamep = malloc(chunk_len);
- if (*hostnamep == NULL) {
- rc = ENOMEM;
- }
- else {
- memcpy(*hostnamep,chunk_start,chunk_len);
- (*hostnamep)[chunk_len] = '\0';
- }
- }
- }
- else { /* chunk_start != '@' */
- /*
- * no host name given, keep string empty
- */
- *hostnamep = malloc(1);
- if (*hostnamep == NULL) {
- rc = ENOMEM;
- }
- else {
- (*hostnamep)[0] = '\0';
- }
- }
- }
- /*
- * fetch filename. This is all the rest...
- */
- if (rc == 0) {
- chunk_start = chunk_end+1;
- if (*chunk_start == '\0') { /* nothing left for filename */
- rc = ENOENT;
- }
- else {
- chunk_len = strlen(chunk_start);
- *filenamep = malloc(chunk_len);
- if (*filenamep == NULL) {
- rc = ENOMEM;
- }
- else {
- memcpy(*filenamep,chunk_start,chunk_len);
- (*filenamep)[chunk_len] = '\0';
- }
- }
- }
-
- /*
- * cleanup anything, if error occured
- */
- if (rc != 0) {
- if (*hostnamep != NULL) {
- free(*hostnamep);
- *hostnamep = NULL;
- }
- if (*usernamep != NULL) {
- free(*usernamep);
- *usernamep = NULL;
- }
- if (*passwordp != NULL) {
- free(*passwordp);
- *passwordp = NULL;
- }
- if (*filenamep != NULL) {
- free(*filenamep);
- *filenamep = NULL;
- }
- }
- return rc;
-}
-
-int rtems_ftp_evaluate_for_make(
- const char *path, /* IN */
- rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
- const char **name /* OUT */
-)
-{
- set_errno_and_return_minus_one( EIO );
-}
-
-/*
- * XXX - Fix return values.
- */
-
-int rtems_ftp_eval_path(
- const char *pathname, /* IN */
- int flags, /* IN */
- rtems_filesystem_location_info_t *pathloc /* IN/OUT */
-)
-{
-
- /*
- * Read-only for now
- */
-
- if ( ((flags & O_RDONLY) != O_RDONLY ) &&
- ((flags & O_WRONLY) != O_WRONLY )) {
- set_errno_and_return_minus_one( ENOENT );
- }
- /*
- * The File system is mounted at FTP_PATHNAME_PREFIX
- * the caller of this routine has striped off this part of the
- * name. Save the remainder of the name for use by the open routine.
- */
-
- pathloc->node_access = (void * ) pathname;
- pathloc->handlers = &rtems_ftp_handlers;
-
- return 0;
-}
-
-/*
- * Open a FTP stream
- */
-int rtems_ftp_open(
- rtems_libio_t *iop,
- const char *new_name,
- unsigned32 flag,
- unsigned32 mode
-)
-{
- int s = 0;
- char *filename = NULL;
- char *uname = NULL;
- char *upass = NULL;
- char *hostname = NULL;
- char port_buffer[sizeof(FTP_PORT_CMD)+6*4+1+1];
- rtems_unsigned32 my_ip;
- rtems_unsigned16 my_port;
- int eno = 0;
- rtems_status_code rc;
- rtems_boolean is_write = FALSE;
- rtems_boolean sema_obtained = FALSE;
- struct ftpStream *fsp = NULL;
- int msg_tmp;
- int sockaddr_size;
- /*
- * check for R/O or W/O flags
- */
- if (eno == 0) {
- if ((0 != (iop->flags & LIBIO_FLAGS_WRITE)) &&
- (0 != (iop->flags & LIBIO_FLAGS_READ))) {
- eno = ENOTSUP;
- }
- else {
- is_write = (0 != (iop->flags & LIBIO_FLAGS_WRITE));
- }
- }
- /*
- * split pathname into parts
- */
- if (eno == 0) {
- eno = rtems_ftp_split_names(iop->file_info,
- &uname,
- &upass,
- &hostname,
- &filename);
- }
-
- /*
- * Find a free stream
- */
- if (eno == 0) {
- rc = rtems_semaphore_obtain (ftp_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
- if (rc == RTEMS_SUCCESSFUL) {
- sema_obtained = TRUE;
- }
- else {
- eno = EBUSY;
- }
- }
- if (eno == 0) {
- for (s = 0 ; s < nStreams ; s++) {
- if (ftpStreams[s] == NULL)
- break;
- }
- if (s == nStreams) {
- /*
- * Reallocate stream pointers
- * Guard against the case where realloc() returns NULL.
- */
- struct ftpStream **np;
-
- np = realloc (ftpStreams, ++nStreams * sizeof *ftpStreams);
- if (np == NULL) {
- eno = ENOMEM;
- }
- else {
- ftpStreams = np;
- }
- }
- }
- if (eno == 0) {
- fsp = ftpStreams[s] = malloc (sizeof (struct ftpStream));
- rtems_semaphore_release (ftp_mutex);
- sema_obtained = FALSE;
- if (fsp == NULL) {
- eno = ENOMEM;
- }
- else {
- iop->data0 = s;
- iop->data1 = fsp;
- fsp->ctrl_socket = -1; /* mark, that sockets not yet created */
- fsp->port_socket = -1;
- fsp->data_socket = -1;
- fsp->eof_reached = FALSE;
- }
- }
- if (eno == 0) {
- /*
- * Create the socket for control connection
- */
- if ((fsp->ctrl_socket = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
- eno = ENOMEM;
- }
- }
-
- if (eno == 0) {
- /*
- * Set the destination to the FTP server
- * port on the remote machine.
- */
- memset(&(fsp->farCtrlAddress),sizeof(fsp->farCtrlAddress),0);
- fsp->farCtrlAddress.sin_family = AF_INET;
- if (*hostname == '\0') {
- fsp->farCtrlAddress.sin_addr.s_addr = rtems_bsdnet_bootp_server_address.s_addr;
- }
- else if (1 != inet_aton(hostname,&(fsp->farCtrlAddress.sin_addr))) {
- struct hostent *hent;
- struct hostent *gethostbyname(const char *name);
-
- hent = gethostbyname(hostname);
- if (hent != NULL) {
- bcopy(hent->h_addr,
- (char *)(&(fsp->farCtrlAddress.sin_addr)),
- sizeof(fsp->farCtrlAddress.sin_addr));
- }
- else {
- eno = ENOENT;
- }
- }
- if (eno == 0) {
- fsp->farCtrlAddress.sin_port = htons (FTP_PORT_NUM);
- fsp->farCtrlAddress.sin_len = sizeof(fsp->farCtrlAddress);
- if (0 > connect(fsp->ctrl_socket,
- (struct sockaddr *)&(fsp->farCtrlAddress),
- sizeof(fsp->farCtrlAddress))) {
- eno = ENOENT;
- }
- }
- if (eno == 0) {
- /*
- * fetch IP address of interface used
- */
- memset(&(fsp->myCtrlAddress),sizeof(fsp->myCtrlAddress),0);
- fsp->myCtrlAddress.sin_family = AF_INET;
- fsp->myCtrlAddress.sin_addr.s_addr = INADDR_ANY;
- fsp->myCtrlAddress.sin_port = 0;
- fsp->myCtrlAddress.sin_len = sizeof(fsp->myDataAddress);
- sockaddr_size = sizeof(fsp->myCtrlAddress);
- if (0 > getsockname(fsp->ctrl_socket,
- (struct sockaddr *)&(fsp->myCtrlAddress),
- &sockaddr_size)) {
- eno = ENOMEM;
- }
- }
- }
- if (eno == 0) {
- /*
- * now we should get a connect message from the FTP server
- */
- eno = rtems_ftp_get_message(fsp,&msg_tmp);
- if ((eno == 0) &&
- (msg_tmp != FTP_REPLY_CONNECT)) {
- eno = ENOENT;
- }
- }
- if (eno == 0) {
- /*
- * send user ID to server
- * NOTE: the following lines will be executed in order
- * and will be aborted whenever an error occures... (see your ANSI C book)
- */
- if ((0 > send(fsp->ctrl_socket,FTP_USER_CMD,strlen(FTP_USER_CMD),0)) ||
- (0 > send(fsp->ctrl_socket,uname, strlen(uname), 0)) ||
- (0 > send(fsp->ctrl_socket,"\n", 1, 0))) {
- eno = EIO;
- }
- }
- if (eno == 0) {
- /*
- * now we should get a request for the password or a login...
- */
- eno = rtems_ftp_get_message(fsp,&msg_tmp);
- if (eno == 0) {
- if (msg_tmp == FTP_REPLY_PASSREQ) {
- /*
- * send password to server
- */
-#ifdef DEBUG_OUT
- write(1,FTP_PASS_CMD,strlen(FTP_PASS_CMD));
- write(1,upass, strlen(upass) );
- write(1,"\n", 1 );
-#endif
- if ((0 > send(fsp->ctrl_socket,FTP_PASS_CMD,strlen(FTP_PASS_CMD),0)) ||
- (0 > send(fsp->ctrl_socket,upass, strlen(upass), 0)) ||
- (0 > send(fsp->ctrl_socket,"\n", 1, 0))) {
- eno = EIO;
- }
- /*
- * at least now a login reply should come up...
- * this is checked some lines downwards the code
- */
- if (eno == 0) {
- eno = rtems_ftp_get_message(fsp,&msg_tmp);
- }
- }
- }
- }
- if (eno == 0) {
- /*
- * check for a login reply. this should be present now...
- */
- if (msg_tmp != FTP_REPLY_LOGIN) {
- eno = EACCES; /* pseudo for wrong user/pass */
- }
- }
- if (eno == 0) {
- /*
- * set binary mode for all transfers
- */
-#ifdef DEBUG_OUT
- write(1,FTP_BINARY_CMD,strlen(FTP_BINARY_CMD));
- write(1,"\n", 1 );
-#endif
- if ((0 > send(fsp->ctrl_socket,FTP_BINARY_CMD,strlen(FTP_BINARY_CMD),0)) ||
- (0 > send(fsp->ctrl_socket,"\n", 1, 0))) {
- eno = EIO;
- }
- else {
- eno = rtems_ftp_get_message(fsp,&msg_tmp);
- }
- }
- if (eno == 0) {
- /*
- * check for a "BINARY TYPE command successful" reply
- */
- if (msg_tmp != FTP_REPLY_SUCCESS) {
- eno = EIO;
- }
- }
- if (eno == 0) {
- /*
- * create and bind socket for data connection
- */
- if ((fsp->port_socket = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
- eno = ENOMEM;
- }
- else {
- memset(&(fsp->myDataAddress),sizeof(fsp->myDataAddress),0);
- fsp->myDataAddress.sin_family = AF_INET;
- fsp->myDataAddress.sin_addr.s_addr = INADDR_ANY;
- fsp->myDataAddress.sin_port = 0; /* unique port will be assigned */
- fsp->myDataAddress.sin_len = sizeof(fsp->myDataAddress);
- if (0 > bind(fsp->port_socket,
- (struct sockaddr *)&(fsp->myDataAddress),
- sizeof(fsp->myDataAddress))) {
- eno = EBUSY;
- }
- else {
- /*
- * fetch port number of data socket
- */
- memset(&(fsp->myDataAddress),sizeof(fsp->myDataAddress),0);
- fsp->myDataAddress.sin_family = AF_INET;
- fsp->myDataAddress.sin_addr.s_addr = INADDR_ANY;
- fsp->myDataAddress.sin_port = 0;
- fsp->myDataAddress.sin_len = sizeof(fsp->myDataAddress);
- sockaddr_size = sizeof(fsp->myDataAddress);
- if (0 > getsockname(fsp->port_socket,
- (struct sockaddr *)&(fsp->myDataAddress),
- &sockaddr_size)) {
- eno = ENOMEM;
- }
- }
- }
- }
- if (eno == 0) {
- /*
- * propagate data connection port to server
- */
- my_ip = ntohl(fsp->myCtrlAddress.sin_addr.s_addr);
- my_port = ntohs(fsp->myDataAddress.sin_port);
- sprintf(port_buffer,"%s%u,%u,%u,%u,%u,%u\n",
- FTP_PORT_CMD,
- (my_ip >> 24) & 0x00ff,
- (my_ip >> 16) & 0x00ff,
- (my_ip >> 8) & 0x00ff,
- (my_ip >> 0) & 0x00ff,
- (my_port>> 8) & 0x00ff,
- (my_port>> 0) & 0x00ff);
-#ifdef DEBUG_OUT
- write(1,port_buffer,strlen(port_buffer));
-#endif
- if (0 > send(fsp->ctrl_socket,port_buffer,strlen(port_buffer),0)) {
- eno = EIO;
- }
- else {
- eno = rtems_ftp_get_message(fsp,&msg_tmp);
- }
- }
- if (eno == 0) {
- /*
- * check for a "PORT command successful" reply
- */
- if (msg_tmp != FTP_REPLY_SUCCESS) {
- eno = EBUSY;
- }
- }
- /*
- * prepare port socket to listen for incoming connections
- */
- if (eno == 0) {
- if (0 > listen(fsp->port_socket,1)) {
- eno = EBUSY;
- }
- }
- if (eno == 0) {
- /*
- * send retrive/store command with filename
- */
- if (is_write) {
-#ifdef DEBUG_OUT
- write(1,FTP_STOR_CMD,strlen(FTP_STOR_CMD));
- write(1,filename ,strlen(filename) );
- write(1,"\n",1);
-#endif
- if ((0 > send(fsp->ctrl_socket,FTP_STOR_CMD,strlen(FTP_STOR_CMD),0)) ||
- (0 > send(fsp->ctrl_socket,filename, strlen(filename), 0)) ||
- (0 > send(fsp->ctrl_socket,"\n", 1, 0))) {
- eno = EIO;
- }
- }
- else {
-#ifdef DEBUG_OUT
- write(1,FTP_RETR_CMD,strlen(FTP_RETR_CMD));
- write(1,filename ,strlen(filename) );
- write(1,"\n",1);
-#endif
- if ((0 > send(fsp->ctrl_socket,FTP_RETR_CMD,strlen(FTP_RETR_CMD),0)) ||
- (0 > send(fsp->ctrl_socket,filename, strlen(filename), 0)) ||
- (0 > send(fsp->ctrl_socket,"\n", 1, 0))) {
- eno = EIO;
- }
- }
- }
-#if 1
- if (eno == 0) {
- eno = rtems_ftp_get_message(fsp,&msg_tmp);
- }
- if (eno == 0) {
- /*
- * check for a "OPENING binary connection" reply
- */
- if (msg_tmp != FTP_REPLY_OPENCONN) {
- eno = EACCES;
- }
- }
-#endif
- /*
- * wait for connect on data connection
- * FIXME: this should become a select instead with a timeout
- */
- if (eno == 0) {
- sockaddr_size = sizeof(fsp->farDataAddress);
- fsp->data_socket = accept(fsp->port_socket,
- (struct sockaddr *)&(fsp->farDataAddress),
- &sockaddr_size);
- if (0 > fsp->data_socket) {
- eno = EIO;
- }
- }
- /*
- * FIXME: check, that fardataAddr is really from our ftp server
- */
-
- /*
- * clean up temp strings...
- */
- if (uname != NULL) {
- free(uname);
- uname = NULL;
- }
- if (upass != NULL) {
- free(upass);
- upass = NULL;
- }
- if (hostname != NULL) {
- free(hostname);
- hostname = NULL;
- }
- if (filename != NULL) {
- free(filename);
- filename = NULL;
- }
- /*
- * close part socket, no longer needed
- */
- if (fsp->port_socket != -1) {
- close(fsp->port_socket);
- fsp->port_socket = -1;
- }
- /*
- * if error, clean up everything
- */
- if (eno != 0) {
- if (fsp != NULL) {
- /*
- * check and close ctrl/data connection
- */
- if (fsp->data_socket != -1) {
- close(fsp->data_socket);
- fsp->data_socket = -1;
- }
- if (fsp->ctrl_socket != -1) {
- close(fsp->ctrl_socket);
- fsp->ctrl_socket = -1;
- }
- /*
- * free ftpStream structure
- */
- ftpStreams[s] = NULL;
- free(fsp);
- fsp = NULL;
- }
- }
- /*
- * return sema, if still occupied
- */
- if (sema_obtained) {
- rtems_semaphore_release (ftp_mutex);
- sema_obtained = FALSE;
- }
-#if 0
- if (eno != 0) {
- set_errno_and_return_minus_one(eno);
- }
- return 0;
-#else
- return eno;
-#endif
-}
-
-/*
- * Read from a FTP stream
- */
-int rtems_ftp_read(
- rtems_libio_t *iop,
- void *buffer,
- unsigned32 count
-)
-{
- int eno = 0;
- struct ftpStream *fsp;
- size_t want_cnt;
- ssize_t rd_cnt;
- int msg_tmp;
-
- fsp = iop->data1;
- want_cnt = count;
- /*
- * check, that data connection present
- */
- if (eno == 0) {
- if ((fsp == NULL) ||
- (fsp->data_socket < 0)) {
- eno = EBADF;
- }
- }
-
- /*
- * perform read from data socket
- * read multiple junks, if smaller than wanted
- */
- while ((eno == 0) &&
- (want_cnt > 0) &&
- !(fsp->eof_reached) ) {
- rd_cnt = read(fsp->data_socket,buffer,want_cnt);
- if (rd_cnt > 0) {
- buffer += rd_cnt;
- want_cnt -= rd_cnt;
- }
- else {
- eno = rtems_ftp_get_message(fsp,&msg_tmp);
- fsp->eof_reached = TRUE;
- if ((eno == 0) &&
- (msg_tmp != FTP_REPLY_TFERCMPL)) {
- eno = EIO;
- }
- if (rd_cnt < 0) {
- eno = EIO;
- }
- }
- }
- if (eno != 0) {
- set_errno_and_return_minus_one(eno);
- }
- return count - want_cnt;
-}
-
-int rtems_ftp_write(
- rtems_libio_t *iop,
- const void *buffer,
- unsigned32 count
-)
-{
- int eno = EIO;
- struct ftpStream *fsp;
- size_t want_cnt;
- ssize_t wr_cnt;
- int msg_tmp;
-
- fsp = iop->data1;
- want_cnt = count;
- /*
- * check, that data connection present
- */
- if (eno == 0) {
- if ((fsp == NULL) ||
- (fsp->data_socket < 0)) {
- eno = EBADF;
- }
- }
-
- /*
- * perform write to data socket
- */
- if (eno == 0) {
- wr_cnt = write(fsp->data_socket,buffer,want_cnt);
- if (wr_cnt > 0) {
- buffer += wr_cnt;
- want_cnt -= wr_cnt;
- }
- else {
- eno = rtems_ftp_get_message(fsp,&msg_tmp);
- if ((eno == 0) &&
- (msg_tmp != FTP_REPLY_TFERCMPL)) {
- eno = EIO;
- }
- if (wr_cnt < 0) {
- eno = EIO;
- }
- }
- }
- if (eno != 0) {
- set_errno_and_return_minus_one(eno);
- }
- return count - want_cnt;
-}
-
-/*
- * Close a FTP stream
- */
-int rtems_ftp_close(
- rtems_libio_t *iop
-)
-{
- int s = iop->data0;
- struct ftpStream *fsp = iop->data1;
-
- /*
- * close ctrl/data connection, if needed
- */
- if (fsp->data_socket >= 0) {
- close(fsp->data_socket);
- fsp->data_socket = -1;
- }
- if (fsp->ctrl_socket >= 0) {
- close(fsp->ctrl_socket);
- fsp->ctrl_socket = -1;
- }
- /*
- * free any used space...
- */
- rtems_semaphore_obtain (ftp_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
- free (ftpStreams[s]);
- ftpStreams[s] = NULL;
- rtems_semaphore_release (ftp_mutex);
-
- return 0;
-}
-
-rtems_device_driver rtems_ftp_control(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *pargp
-)
-{
- return RTEMS_NOT_CONFIGURED;
-}
-
-/*
- * Dummy version to let fopen(xxxx,"w") work properly.
- */
-static int rtems_ftp_ftruncate(
- rtems_libio_t *iop,
- off_t count
-)
-{
- return 0;
-}
-
-rtems_filesystem_node_types_t rtems_ftp_node_type(
- rtems_filesystem_location_info_t *pathloc /* IN */
-)
-{
- return RTEMS_FILESYSTEM_MEMORY_FILE;
-}
-
-rtems_filesystem_operations_table rtems_ftp_ops = {
- rtems_ftp_eval_path, /* eval_path */
- rtems_ftp_evaluate_for_make, /* evaluate_for_make */
- NULL, /* link */
- NULL, /* unlink */
- rtems_ftp_node_type, /* node_type */
- NULL, /* mknod */
- NULL, /* chown */
- NULL, /* freenodinfo */
- NULL, /* mount */
- rtems_ftp_mount_me, /* initialize */
- NULL, /* unmount */
- NULL, /* fsunmount */
- NULL, /* utime, */
- NULL, /* evaluate_link */
- NULL, /* symlink */
- NULL, /* readlin */
-};
-
-rtems_filesystem_file_handlers_r rtems_ftp_handlers = {
- rtems_ftp_open, /* open */
- rtems_ftp_close, /* close */
- rtems_ftp_read, /* read */
- rtems_ftp_write, /* write */
- NULL, /* ioctl */
- NULL, /* lseek */
- NULL, /* fstat */
- NULL, /* fchmod */
- rtems_ftp_ftruncate, /* ftruncate */
- NULL, /* fpathconf */
- NULL, /* fsync */
- NULL, /* fdatasync */
- NULL, /* fcntl */
- NULL /* rmnod */
-};