From 2b3e9d9b244e279ef5693a7cf5dacc7903164af5 Mon Sep 17 00:00:00 2001 From: Ralf Corsepius Date: Mon, 22 Jul 2002 09:46:48 +0000 Subject: Remove, moved to cpukit. --- c/src/exec/libnetworking/lib/.cvsignore | 2 - c/src/exec/libnetworking/lib/Makefile.am | 33 - c/src/exec/libnetworking/lib/README | 5 - c/src/exec/libnetworking/lib/ftpfs.c | 1159 ----------------------- c/src/exec/libnetworking/lib/getprotoby.c | 46 - c/src/exec/libnetworking/lib/rtems_bsdnet_ntp.c | 187 ---- c/src/exec/libnetworking/lib/syslog.c | 189 ---- c/src/exec/libnetworking/lib/tftpDriver.c | 1049 -------------------- 8 files changed, 2670 deletions(-) delete mode 100644 c/src/exec/libnetworking/lib/.cvsignore delete mode 100644 c/src/exec/libnetworking/lib/Makefile.am delete mode 100644 c/src/exec/libnetworking/lib/README delete mode 100644 c/src/exec/libnetworking/lib/ftpfs.c delete mode 100644 c/src/exec/libnetworking/lib/getprotoby.c delete mode 100644 c/src/exec/libnetworking/lib/rtems_bsdnet_ntp.c delete mode 100644 c/src/exec/libnetworking/lib/syslog.c delete mode 100644 c/src/exec/libnetworking/lib/tftpDriver.c (limited to 'c/src/exec/libnetworking/lib') diff --git a/c/src/exec/libnetworking/lib/.cvsignore b/c/src/exec/libnetworking/lib/.cvsignore deleted file mode 100644 index 282522db03..0000000000 --- a/c/src/exec/libnetworking/lib/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile -Makefile.in diff --git a/c/src/exec/libnetworking/lib/Makefile.am b/c/src/exec/libnetworking/lib/Makefile.am deleted file mode 100644 index a1cea1841b..0000000000 --- a/c/src/exec/libnetworking/lib/Makefile.am +++ /dev/null @@ -1,33 +0,0 @@ -## -## $Id$ -## - - -LIBNAME = lib.a -LIB = $(ARCH)/$(LIBNAME) - -C_FILES = getprotoby.c rtems_bsdnet_ntp.c ftpfs.c syslog.c tftpDriver.c -C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o) - -OBJS = $(C_O_FILES) - -include $(top_srcdir)/../automake/multilib.am -include $(top_srcdir)/../automake/compile.am -include $(top_srcdir)/../automake/lib.am - -# -# Add local stuff here using += -# - -AM_CPPFLAGS += -DNOPOLL -DNOSELECT - -$(LIB): $(OBJS) - $(make-library) - -all-local: $(ARCH) $(OBJS) $(LIB) - -.PRECIOUS: $(LIB) - -EXTRA_DIST = README getprotoby.c rtems_bsdnet_ntp.c syslog.c tftpDriver.c - -include $(top_srcdir)/../automake/local.am diff --git a/c/src/exec/libnetworking/lib/README b/c/src/exec/libnetworking/lib/README deleted file mode 100644 index 998bd5e708..0000000000 --- a/c/src/exec/libnetworking/lib/README +++ /dev/null @@ -1,5 +0,0 @@ -# -# $Id$ -# - -Sources from application-level (as opposed to kernel-level) libraries. 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 - * - * - * This code has been created after closly inspecting - * "tftpdriver.c" from Eric Norum. - * - * $Id$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#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 */ -}; diff --git a/c/src/exec/libnetworking/lib/getprotoby.c b/c/src/exec/libnetworking/lib/getprotoby.c deleted file mode 100644 index cefa5c1ff2..0000000000 --- a/c/src/exec/libnetworking/lib/getprotoby.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * $Id$ - */ - -#include -#include -#include -#include -#include - -static const struct protoent prototab[] = { - { "ip", NULL, IPPROTO_IP }, - { "icmp", NULL, IPPROTO_ICMP }, - { "tcp", NULL, IPPROTO_TCP }, - { "udp", NULL, IPPROTO_UDP }, - }; - -/* - * Dummy version of BSD getprotobyname() - */ -struct protoent * -getprotobyname_static (const char *name) -{ - int i; - - for (i = 0 ; i < (sizeof prototab / sizeof prototab[0]) ; i++) { - if (strcmp (name, prototab[i].p_name) == 0) - return (struct protoent *) &prototab[i]; - } - return NULL; -} - -/* - * Dummy version of BSD getprotobynumber() - */ -struct protoent * -getprotobynumber_static (int proto) -{ - int i; - - for (i = 0 ; i < (sizeof prototab / sizeof prototab[0]) ; i++) { - if (proto == prototab[i].p_proto) - return (struct protoent *) &prototab[i]; - } - return NULL; -} diff --git a/c/src/exec/libnetworking/lib/rtems_bsdnet_ntp.c b/c/src/exec/libnetworking/lib/rtems_bsdnet_ntp.c deleted file mode 100644 index 87514bd14c..0000000000 --- a/c/src/exec/libnetworking/lib/rtems_bsdnet_ntp.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Synchronize with an NTP server - * - * This program may be distributed and used for any purpose. - * I ask only that you: - * 1. Leave this author information intact. - * 2. Document any changes you make. - * - * W. Eric Norum - * Canadian Light Source - * University of Saskatchewan - * Saskatoon, Saskatchewan, CANADA - * eric@cls.usask.ca - * - * $Id$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * RTEMS base: 1988, January 1 - * UNIX base: 1970, January 1 - * NTP base: 1900, January 1 - */ -#define UNIX_BASE_TO_NTP_BASE (((70UL*365UL)+17UL) * (24*60*60)) - -struct timestamp { - rtems_unsigned32 integer; - rtems_unsigned32 fraction; -}; - -struct ntpPacketSmall { - rtems_unsigned8 li_vn_mode; - rtems_unsigned8 stratum; - rtems_signed8 poll_interval; - rtems_signed8 precision; - rtems_signed32 root_delay; - rtems_signed32 root_dispersion; - char reference_identifier[4]; - struct timestamp reference_timestamp; - struct timestamp originate_timestamp; - struct timestamp receive_timestamp; - struct timestamp transmit_timestamp; -}; - -struct ntpPacket { - struct ntpPacketSmall ntp; - char authenticator[96]; -}; - -static int -processPacket (struct ntpPacketSmall *p) -{ - time_t tbuf; - struct tm *lt; - rtems_time_of_day rt; - rtems_interval ticks_per_second; - - if (((p->li_vn_mode & (0x7 << 3)) != (3 << 3)) - || ((p->transmit_timestamp.integer == 0) && (p->transmit_timestamp.fraction == 0))) - return 0; - rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second); - tbuf = ntohl (p->transmit_timestamp.integer) - UNIX_BASE_TO_NTP_BASE - rtems_bsdnet_timeoffset; - lt = gmtime (&tbuf); - rt.year = lt->tm_year + 1900; - rt.month = lt->tm_mon + 1; - rt.day = lt->tm_mday; - rt.hour = lt->tm_hour; - rt.minute = lt->tm_min; - rt.second = lt->tm_sec; - rt.ticks = ntohl (p->transmit_timestamp.fraction) / (ULONG_MAX / ticks_per_second); - if (rt.ticks >= ticks_per_second) - rt.ticks = ticks_per_second - 1; - rtems_clock_set (&rt); - return 1; -} - -static int -tryServer (int i, int s) -{ - int l; - struct timeval tv; - int farlen; - struct sockaddr_in farAddr; - struct ntpPacketSmall packet; - - if (i < 0) - tv.tv_sec = 80; - else - tv.tv_sec = 5; - tv.tv_usec = 0; - if (setsockopt (s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv) < 0) { - printf ("Can't set socket receive timeout: %s\n", strerror (errno)); - close (s); - return -1; - } - if (i >= 0) { - memset (&farAddr, 0, sizeof farAddr); - farAddr.sin_family = AF_INET; - farAddr.sin_port = htons (123); - farAddr.sin_addr = rtems_bsdnet_ntpserver[i]; - memset (&packet, 0, sizeof packet); - packet.li_vn_mode = (3 << 3) | 3; /* NTP version 3, client */ - l = sendto (s, &packet, sizeof packet, 0, (struct sockaddr *)&farAddr, sizeof farAddr); - if (l != sizeof packet) { - printf ("Can't send: %s\n", strerror (errno)); - return -1; - } - } - farlen = sizeof farAddr; - i = recvfrom (s, &packet, sizeof packet, 0, (struct sockaddr *)&farAddr, &farlen); - if (i == 0) - printf ("Unexpected EOF"); - if (i < 0) { - if ((errno == EWOULDBLOCK) || (errno == EAGAIN)) - return -1; - printf ("Can't receive: %s\n", strerror (errno)); - } - if ((i >= sizeof packet) && processPacket (&packet)) - return 0; - return -1; -} - -int -rtems_bsdnet_synchronize_ntp (int interval, rtems_task_priority priority) -{ - int s; - int i; - int retry; - struct sockaddr_in myAddr; - int reuseFlag; - int ret; - - if (interval != 0) { - printf ("Daemon-mode note yet supported.\n"); - errno = EINVAL; - return -1; - } - s = socket (AF_INET, SOCK_DGRAM, 0); - if (s < 0) { - printf ("Can't create socket: %s\n", strerror (errno)); - return -1; - } - reuseFlag = 1; - if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseFlag, sizeof reuseFlag) < 0) { - printf ("Can't set socket reuse: %s\n", strerror (errno)); - close (s); - return -1; - } - memset (&myAddr, 0, sizeof myAddr); - myAddr.sin_family = AF_INET; - myAddr.sin_port = htons (123); - myAddr.sin_addr.s_addr = htonl (INADDR_ANY); - if (bind (s, (struct sockaddr *)&myAddr, sizeof myAddr) < 0) { - printf ("Can't bind socket: %s\n", strerror (errno)); - close (s); - return -1; - } - ret = -1; - for (retry = 0 ; (ret == -1) && (retry < 5) ; retry++) { - /* - * If there's no server we just have to wait - * and hope that there's an NTP broadcast - * server out there somewhere. - */ - if (rtems_bsdnet_ntpserver_count < 0) { - ret = tryServer (-1, s); - } - else { - for (i = 0 ; (ret == -1) && (i < rtems_bsdnet_ntpserver_count) ; i++) { - ret = tryServer (i, s); - } - } - } - close (s); - return ret; -} diff --git a/c/src/exec/libnetworking/lib/syslog.c b/c/src/exec/libnetworking/lib/syslog.c deleted file mode 100644 index 0bb15bc78e..0000000000 --- a/c/src/exec/libnetworking/lib/syslog.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * RTEMS version of syslog and associated routines - * - * $Id$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static int LogStatus = LOG_CONS; -static const char *LogTag = "syslog"; -static int LogFacility = LOG_USER; -static int LogMask = 0xff; - -static int LogFd = -1; -static rtems_id LogSemaphore; -extern struct in_addr rtems_bsdnet_log_host_address; - -#define SYSLOG_PORT 514 - -void -syslog (int pri, const char *fmt, ...) -{ - va_list ap; - - va_start (ap, fmt); - vsyslog (pri, fmt, ap); - va_end (ap); -} - -/* - * FIXME: Should cbuf be static? It could be if we put the mutex - * around the entire body of this routine. Then we wouldn't - * have to worry about blowing stacks with a local variable - * that large. Could make cbuf bigger, too. - */ -void -vsyslog (int pri, const char *fmt, va_list ap) -{ - int cnt; - char *cp; - char *msgp, cbuf[200]; - int sent; - - if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) { - syslog (LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID, - "syslog: unknown facility/priority: %#x", pri); - pri &= LOG_PRIMASK|LOG_FACMASK; - } - - if (!LOG_MASK(LOG_PRI(pri)) & LogMask) - return; - - if ((pri & LOG_FACMASK) == 0) - pri |= LogFacility; - - cnt = sprintf (cbuf, "<%d>", pri); - cp = msgp = cbuf + cnt; - if (LogTag) { - const char *lp = LogTag; - while ((*cp = *lp++) != '\0') - cp++; - } - if (LogStatus & LOG_PID) { - rtems_id tid; - rtems_task_ident (RTEMS_SELF, 0, &tid); - cnt = sprintf (cp, "[%#lx]", (unsigned long)tid); - cp += cnt; - } - if (LogTag) { - *cp++ = ':'; - *cp++ = ' '; - } - cnt = vsprintf (cp, fmt, ap); - cnt += cp - cbuf; - if (cbuf[cnt-1] == '\n') - cbuf[--cnt] = '\0'; - - if (LogStatus & LOG_PERROR) - printf ("%s\n", cbuf); - - /* - * Grab the mutex - */ - sent = 0; - if ((rtems_bsdnet_log_host_address.s_addr != INADDR_ANY) - && (LogFd >= 0) - && (rtems_semaphore_obtain (LogSemaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT) == RTEMS_SUCCESSFUL)) { - /* - * Set the destination address/port - */ - struct sockaddr_in farAddress; - farAddress.sin_family = AF_INET; - farAddress.sin_port = htons (SYSLOG_PORT); - farAddress.sin_addr = rtems_bsdnet_log_host_address; - memset (farAddress.sin_zero, '\0', sizeof farAddress.sin_zero); - - /* - * Send the message - */ - if (sendto (LogFd, cbuf, cnt, 0, (struct sockaddr *)&farAddress, sizeof farAddress) >= 0) - sent = 1; - rtems_semaphore_release (LogSemaphore); - } - if (!sent && (LogStatus & LOG_CONS) && !(LogStatus & LOG_PERROR)) - printf ("%s\n", msgp); -} - -void -openlog (const char *ident, int logstat, int logfac) -{ - rtems_status_code sc; - struct sockaddr_in myAddress; - - if (ident != NULL) - LogTag = ident; - LogStatus = logstat; - if (logfac != 0 && (logfac & ~LOG_FACMASK) == 0) - LogFacility = logfac; - - /* - * Create the socket - */ - if ((LogFd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) { - printf ("Can't create syslog socket: %d\n", errno); - return; - } - - /* - * Bind socket to name - */ - myAddress.sin_family = AF_INET; - myAddress.sin_addr.s_addr = INADDR_ANY; - myAddress.sin_port = 0; - memset (myAddress.sin_zero, '\0', sizeof myAddress.sin_zero); - if (bind (LogFd, (struct sockaddr *)&myAddress, sizeof (myAddress)) < 0) { - close (LogFd); - LogFd = -1; - printf ("Can't bind syslog socket: %d\n", errno); - return; - } - - /* - * Create the mutex - */ - sc = rtems_semaphore_create (rtems_build_name('s', 'L', 'o', 'g'), - 1, - RTEMS_PRIORITY | - RTEMS_BINARY_SEMAPHORE | - RTEMS_INHERIT_PRIORITY | - RTEMS_NO_PRIORITY_CEILING | - RTEMS_LOCAL, - 0, - &LogSemaphore); - if (sc != RTEMS_SUCCESSFUL) { - printf ("Can't create syslog seamphore: %d\n", sc); - close (LogFd); - LogFd = -1; - } -} - -void -closelog(void) -{ - if (LogFd >= 0) { - close (LogFd); - LogFd = -1; - rtems_semaphore_delete (LogSemaphore); - } -} - -int -setlogmask (int pmask) -{ - int omask; - - omask = LogMask; - if (pmask != 0) - LogMask = pmask; - return (omask); -} diff --git a/c/src/exec/libnetworking/lib/tftpDriver.c b/c/src/exec/libnetworking/lib/tftpDriver.c deleted file mode 100644 index 52f51748a5..0000000000 --- a/c/src/exec/libnetworking/lib/tftpDriver.c +++ /dev/null @@ -1,1049 +0,0 @@ -/* - * vim: set expandtab tabstop=4 shiftwidth=4 ai : - * - * Trivial File Transfer Protocol (RFC 1350) - * - * Transfer file to/from remote host - * - * W. Eric Norum - * Saskatchewan Accelerator Laboratory - * University of Saskatchewan - * Saskatoon, Saskatchewan, CANADA - * eric@skatter.usask.ca - * - * $Id$ - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef RTEMS_TFTP_DRIVER_DEBUG -int rtems_tftp_driver_debug = 1; -#endif - -/* - * Range of UDP ports to try - */ -#define UDP_PORT_BASE 3180 - -/* - * Pathname prefix - */ -#define TFTP_PATHNAME_PREFIX "/TFTP/" - -/* - * Root node_access value - * By using the address of a local static variable - * we ensure a unique value for this identifier. - */ -#define ROOT_NODE_ACCESS (&tftp_mutex) - -/* - * Default limits - */ -#define PACKET_FIRST_TIMEOUT_MILLISECONDS 400 -#define PACKET_TIMEOUT_MILLISECONDS 6000 -#define OPEN_RETRY_LIMIT 10 -#define IO_RETRY_LIMIT 10 - -/* - * TFTP opcodes - */ -#define TFTP_OPCODE_RRQ 1 -#define TFTP_OPCODE_WRQ 2 -#define TFTP_OPCODE_DATA 3 -#define TFTP_OPCODE_ACK 4 -#define TFTP_OPCODE_ERROR 5 - -/* - * Largest data transfer - */ -#define TFTP_BUFSIZE 512 - -/* - * Packets transferred between machines - */ -union tftpPacket { - /* - * RRQ/WRQ packet - */ - struct tftpRWRQ { - rtems_unsigned16 opcode; - char filename_mode[TFTP_BUFSIZE]; - } tftpRWRQ; - - /* - * DATA packet - */ - struct tftpDATA { - rtems_unsigned16 opcode; - rtems_unsigned16 blocknum; - rtems_unsigned8 data[TFTP_BUFSIZE]; - } tftpDATA; - - /* - * ACK packet - */ - struct tftpACK { - rtems_unsigned16 opcode; - rtems_unsigned16 blocknum; - } tftpACK; - - /* - * ERROR packet - */ - struct tftpERROR { - rtems_unsigned16 opcode; - rtems_unsigned16 errorCode; - char errorMessage[TFTP_BUFSIZE]; - } tftpERROR; -}; - -/* - * State of each TFTP stream - */ -struct tftpStream { - /* - * Buffer for storing most recently-received packet - */ - union tftpPacket pkbuf; - - /* - * Last block number transferred - */ - rtems_unsigned16 blocknum; - - /* - * Data transfer socket - */ - int socket; - struct sockaddr_in myAddress; - struct sockaddr_in farAddress; - - /* - * Indices into buffer - */ - int nleft; - int nused; - - /* - * Flags - */ - int firstReply; - int eof; - int writing; -}; - -/* - * Number of streams open at the same time - */ -static rtems_id tftp_mutex; -static int nStreams; -static struct tftpStream ** volatile tftpStreams; - -typedef const char *tftp_node; -extern rtems_filesystem_operations_table rtems_tftp_ops; -extern rtems_filesystem_file_handlers_r rtems_tftp_handlers; - -/* - * Direct copy from the IMFS. Look at this. - */ - -rtems_filesystem_limits_and_options_t rtems_tftp_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 */ -}; - -static int rtems_tftp_mount_me( - rtems_filesystem_mount_table_entry_t *temp_mt_entry -) -{ - rtems_status_code sc; - - temp_mt_entry->mt_fs_root.handlers = &rtems_tftp_handlers; - temp_mt_entry->mt_fs_root.ops = &rtems_tftp_ops; - - /* - * We have no tftp 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 = ROOT_NODE_ACCESS; - - /* - * These need to be looked at for full POSIX semantics. - */ - - temp_mt_entry->pathconf_limits_and_options = rtems_tftp_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('T', 'F', 'T', 'P'), - 1, - RTEMS_FIFO | - RTEMS_BINARY_SEMAPHORE | - RTEMS_NO_INHERIT_PRIORITY | - RTEMS_NO_PRIORITY_CEILING | - RTEMS_LOCAL, - 0, - &tftp_mutex - ); - - if (sc != RTEMS_SUCCESSFUL) - rtems_set_errno_and_return_minus_one( ENOMEM ); - - return 0; -} - -/* - * Initialize the TFTP driver - */ - -int rtems_bsdnet_initialize_tftp_filesystem () -{ - int status; - rtems_filesystem_mount_table_entry_t *entry; - - status = mkdir( TFTP_PATHNAME_PREFIX, S_IRWXU | S_IRWXG | S_IRWXO ); - if ( status == -1 ) - return status; - - status = mount( - &entry, - &rtems_tftp_ops, - RTEMS_FILESYSTEM_READ_WRITE, - NULL, - TFTP_PATHNAME_PREFIX - ); - - if ( status ) - perror( "TFTP mount failed" ); - - return status; -} - -/* - * Map error message - */ -static int -tftpErrno (struct tftpStream *tp) -{ - unsigned int tftpError; - static const int errorMap[] = { - EINVAL, - ENOENT, - EPERM, - ENOSPC, - EINVAL, - ENXIO, - EEXIST, - ESRCH, - }; - - tftpError = ntohs (tp->pkbuf.tftpERROR.errorCode); - if (tftpError < (sizeof errorMap / sizeof errorMap[0])) - return errorMap[tftpError]; - else - return 1000 + tftpError; -} - -/* - * Send a message to make the other end shut up - */ -static void -sendStifle (struct tftpStream *tp, struct sockaddr_in *to) -{ - int len; - struct { - rtems_unsigned16 opcode; - rtems_unsigned16 errorCode; - char errorMessage[12]; - } msg; - - /* - * Create the error packet (Unknown transfer ID). - */ - msg.opcode = htons (TFTP_OPCODE_ERROR); - msg.errorCode = htons (5); - len = sizeof msg.opcode + sizeof msg.errorCode + 1; - len += sprintf (msg.errorMessage, "GO AWAY"); - - /* - * Send it - */ - sendto (tp->socket, (char *)&msg, len, 0, (struct sockaddr *)to, sizeof *to); -} - -/* - * Wait for a data packet - */ -static int -getPacket (struct tftpStream *tp, int retryCount) -{ - int len; - struct timeval tv; - - if (retryCount == 0) { - tv.tv_sec = PACKET_FIRST_TIMEOUT_MILLISECONDS / 1000; - tv.tv_usec = (PACKET_FIRST_TIMEOUT_MILLISECONDS % 1000) * 1000; - } - else { - tv.tv_sec = PACKET_TIMEOUT_MILLISECONDS / 1000; - tv.tv_usec = (PACKET_TIMEOUT_MILLISECONDS % 1000) * 1000; - } - setsockopt (tp->socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv); - for (;;) { - union { - struct sockaddr s; - struct sockaddr_in i; - } from; - int fromlen = sizeof from; - len = recvfrom (tp->socket, (char *)&tp->pkbuf, - sizeof tp->pkbuf, 0, - &from.s, &fromlen); - if (len < 0) - break; - if (from.i.sin_addr.s_addr == tp->farAddress.sin_addr.s_addr) { - if (tp->firstReply) { - tp->firstReply = 0; - tp->farAddress.sin_port = from.i.sin_port; - } - if (tp->farAddress.sin_port == from.i.sin_port) - break; - } - - /* - * Packet is from someone with whom we are - * not interested. Tell them to go away. - */ - sendStifle (tp, &from.i); - } - tv.tv_sec = 0; - tv.tv_usec = 0; - setsockopt (tp->socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv); -#ifdef RTEMS_TFTP_DRIVER_DEBUG - if (rtems_tftp_driver_debug) { - if (len >= (int) sizeof tp->pkbuf.tftpACK) { - int opcode = ntohs (tp->pkbuf.tftpDATA.opcode); - switch (opcode) { - default: - printf ("TFTP: OPCODE %d\n", opcode); - break; - - case TFTP_OPCODE_DATA: - printf ("TFTP: RECV %d\n", ntohs (tp->pkbuf.tftpDATA.blocknum)); - break; - - case TFTP_OPCODE_ACK: - printf ("TFTP: GOT ACK %d\n", ntohs (tp->pkbuf.tftpACK.blocknum)); - break; - } - } - else { - printf ("TFTP: %d-byte packet\n", len); - } - } -#endif - return len; -} - -/* - * Send an acknowledgement - */ -static int -sendAck (struct tftpStream *tp) -{ -#ifdef RTEMS_TFTP_DRIVER_DEBUG - if (rtems_tftp_driver_debug) - printf ("TFTP: ACK %d\n", tp->blocknum); -#endif - - /* - * Create the acknowledgement - */ - tp->pkbuf.tftpACK.opcode = htons (TFTP_OPCODE_ACK); - tp->pkbuf.tftpACK.blocknum = htons (tp->blocknum); - - /* - * Send it - */ - if (sendto (tp->socket, (char *)&tp->pkbuf, sizeof tp->pkbuf.tftpACK, 0, - (struct sockaddr *)&tp->farAddress, - sizeof tp->farAddress) < 0) - return errno; - return 0; -} - -/* - * Release a stream and clear the pointer to it - */ -static void -releaseStream (int s) -{ - rtems_semaphore_obtain (tftp_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - free (tftpStreams[s]); - tftpStreams[s] = NULL; - rtems_semaphore_release (tftp_mutex); -} - -static int rtems_tftp_evaluate_for_make( - const char *path, /* IN */ - rtems_filesystem_location_info_t *pathloc, /* IN/OUT */ - const char **name /* OUT */ -) -{ - pathloc->node_access = NULL; - rtems_set_errno_and_return_minus_one( EIO ); -} - -/* - * Convert a path to canonical form - */ -static void -fixPath (char *path) -{ - char *inp, *outp, *base; - - outp = inp = path; - base = NULL; - for (;;) { - if (inp[0] == '.') { - if (inp[1] == '\0') - break; - if (inp[1] == '/') { - inp += 2; - continue; - } - if (inp[1] == '.') { - if (inp[2] == '\0') { - if ((base != NULL) && (outp > base)) { - outp--; - while ((outp > base) && (outp[-1] != '/')) - outp--; - } - break; - } - if (inp[2] == '/') { - inp += 3; - if (base == NULL) - continue; - if (outp > base) { - outp--; - while ((outp > base) && (outp[-1] != '/')) - outp--; - } - continue; - } - } - } - if (base == NULL) - base = inp; - while (inp[0] != '/') { - if ((*outp++ = *inp++) == '\0') - return; - } - *outp++ = '/'; - while (inp[0] == '/') - inp++; - } - *outp = '\0'; - return; -} - -static int rtems_tftp_eval_path( - const char *pathname, /* IN */ - int flags, /* IN */ - rtems_filesystem_location_info_t *pathloc /* IN/OUT */ -) -{ - pathloc->handlers = &rtems_tftp_handlers; - - /* - * Hack to provide the illusion of directories inside the TFTP file system. - * Paths ending in a / are assumed to be directories. - */ - if (pathname[strlen(pathname)-1] == '/') { - int isRelative = (pathloc->node_access != ROOT_NODE_ACCESS); - char *cp; - - /* - * Reject attempts to open() directories - */ - if (flags & RTEMS_LIBIO_PERMS_RDWR) - rtems_set_errno_and_return_minus_one( EISDIR ); - if (isRelative) { - cp = malloc (strlen(pathloc->node_access)+strlen(pathname)+1); - if (cp == NULL) - rtems_set_errno_and_return_minus_one( ENOMEM ); - strcpy (cp, pathloc->node_access); - strcat (cp, pathname); - } - else { - cp = strdup (pathname); - if (cp == NULL) - rtems_set_errno_and_return_minus_one( ENOMEM ); - } - fixPath (cp); - pathloc->node_access = cp; - return 0; - } - if (pathloc->node_access != ROOT_NODE_ACCESS) - pathloc->node_access = 0; - - /* - * Reject it if it's not read-only or write-only. - */ - flags &= RTEMS_LIBIO_PERMS_READ | RTEMS_LIBIO_PERMS_WRITE; - if ((flags != RTEMS_LIBIO_PERMS_READ) && (flags != RTEMS_LIBIO_PERMS_WRITE) ) - rtems_set_errno_and_return_minus_one( EINVAL ); - return 0; -} - -/* - * The routine which does most of the work for the IMFS open handler - */ -static int rtems_tftp_open_worker( - rtems_libio_t *iop, - char *full_path_name, - unsigned32 flags, - unsigned32 mode -) -{ - struct tftpStream *tp; - int retryCount; - struct in_addr farAddress; - int s; - int len; - char *cp1; - char *cp2; - char *remoteFilename; - rtems_interval now; - rtems_status_code sc; - char *hostname; - - /* - * Extract the host name component - */ - cp2 = full_path_name; - while (*cp2 == '/') - cp2++; - hostname = cp2; - while (*cp2 != '/') { - if (*cp2 == '\0') - return ENOENT; - cp2++; - } - *cp2++ = '\0'; - - /* - * Convert hostname to Internet address - */ - if (strcmp (hostname, "BOOTP_HOST") == 0) - farAddress = rtems_bsdnet_bootp_server_address; - else - farAddress.s_addr = inet_addr (hostname); - if ((farAddress.s_addr == 0) || (farAddress.s_addr == ~0)) - return ENOENT; - - /* - * Extract file pathname component - */ - while (*cp2 == '/') - cp2++; - if (strcmp (cp2, "BOOTP_FILE") == 0) { - cp2 = rtems_bsdnet_bootp_boot_file_name; - while (*cp2 == '/') - cp2++; - } - if (*cp2 == '\0') - return ENOENT; - remoteFilename = cp2; - if (strlen (remoteFilename) > (TFTP_BUFSIZE - 10)) - return ENOENT; - - /* - * Find a free stream - */ - sc = rtems_semaphore_obtain (tftp_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - return EBUSY; - for (s = 0 ; s < nStreams ; s++) { - if (tftpStreams[s] == NULL) - break; - } - if (s == nStreams) { - /* - * Reallocate stream pointers - * Guard against the case where realloc() returns NULL. - */ - struct tftpStream **np; - - np = realloc (tftpStreams, ++nStreams * sizeof *tftpStreams); - if (np == NULL) { - rtems_semaphore_release (tftp_mutex); - return ENOMEM; - } - tftpStreams = np; - } - tp = tftpStreams[s] = malloc (sizeof (struct tftpStream)); - rtems_semaphore_release (tftp_mutex); - if (tp == NULL) - return ENOMEM; - iop->data0 = s; - iop->data1 = tp; - - /* - * Create the socket - */ - if ((tp->socket = socket (AF_INET, SOCK_DGRAM, 0)) < 0) { - releaseStream (s); - return ENOMEM; - } - - /* - * Bind the socket to a local address - */ - retryCount = 0; - rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now); - for (;;) { - int try = (now + retryCount) % 10; - - tp->myAddress.sin_family = AF_INET; - tp->myAddress.sin_port = htons (UDP_PORT_BASE + nStreams * try + s); - tp->myAddress.sin_addr.s_addr = htonl (INADDR_ANY); - if (bind (tp->socket, (struct sockaddr *)&tp->myAddress, sizeof tp->myAddress) >= 0) - break; - if (++retryCount == 10) { - close (tp->socket); - releaseStream (s); - return EBUSY; - } - } - - /* - * Set the UDP destination to the TFTP server - * port on the remote machine. - */ - tp->farAddress.sin_family = AF_INET; - tp->farAddress.sin_addr = farAddress; - tp->farAddress.sin_port = htons (69); - - /* - * Start the transfer - */ - tp->firstReply = 1; - retryCount = 0; - for (;;) { - /* - * Create the request - */ - if ((flags & O_ACCMODE) == O_RDONLY) { - tp->writing = 0; - tp->pkbuf.tftpRWRQ.opcode = htons (TFTP_OPCODE_RRQ); - } - else { - tp->writing = 1; - tp->pkbuf.tftpRWRQ.opcode = htons (TFTP_OPCODE_WRQ); - } - cp1 = (char *) tp->pkbuf.tftpRWRQ.filename_mode; - cp2 = (char *) remoteFilename; - while ((*cp1++ = *cp2++) != '\0') - continue; - cp2 = "octet"; - while ((*cp1++ = *cp2++) != '\0') - continue; - len = cp1 - (char *)&tp->pkbuf.tftpRWRQ; - - /* - * Send the request - */ - if (sendto (tp->socket, (char *)&tp->pkbuf, len, 0, - (struct sockaddr *)&tp->farAddress, - sizeof tp->farAddress) < 0) { - close (tp->socket); - releaseStream (s); - return EIO; - } - - /* - * Get reply - */ - len = getPacket (tp, retryCount); - if (len >= (int) sizeof tp->pkbuf.tftpACK) { - int opcode = ntohs (tp->pkbuf.tftpDATA.opcode); - if (!tp->writing - && (opcode == TFTP_OPCODE_DATA) - && (ntohs (tp->pkbuf.tftpDATA.blocknum) == 1)) { - tp->nused = 0; - tp->blocknum = 1; - tp->nleft = len - 2 * sizeof (rtems_unsigned16); - tp->eof = (tp->nleft < TFTP_BUFSIZE); - if (sendAck (tp) != 0) { - close (tp->socket); - releaseStream (s); - return EIO; - } - break; - } - if (tp->writing - && (opcode == TFTP_OPCODE_ACK) - && (ntohs (tp->pkbuf.tftpACK.blocknum) == 0)) { - tp->nused = 0; - tp->blocknum = 1; - break; - } - if (opcode == TFTP_OPCODE_ERROR) { - int e = tftpErrno (tp); - close (tp->socket); - releaseStream (s); - return e; - } - } - - /* - * Keep trying - */ - if (++retryCount >= OPEN_RETRY_LIMIT) { - close (tp->socket); - releaseStream (s); - return EIO; - } - } - return 0; -} - -/* - * The IMFS open handler - */ -static int rtems_tftp_open( - rtems_libio_t *iop, - const char *new_name, - unsigned32 flags, - unsigned32 mode -) -{ - char *full_path_name; - char *s1; - int err; - - /* - * Tack the `current directory' on to relative paths. - * We know that the current directory ends in a / character. - */ - if (*new_name == '/') { - /* - * Skip the TFTP filesystem prefix. - */ - int len = strlen (TFTP_PATHNAME_PREFIX); - if (strncmp (new_name, TFTP_PATHNAME_PREFIX, len)) - return ENOENT; - new_name += len; - s1 = ""; - } - else { - s1 = rtems_filesystem_current.node_access; - } - full_path_name = malloc (strlen (s1) + strlen (new_name) + 1); - if (full_path_name == NULL) - return ENOMEM; - strcpy (full_path_name, s1); - strcat (full_path_name, new_name); - fixPath (full_path_name); - err = rtems_tftp_open_worker (iop, full_path_name, flags, mode); - free (full_path_name); - return err; -} - -/* - * Read from a TFTP stream - */ -static int rtems_tftp_read( - rtems_libio_t *iop, - void *buffer, - unsigned32 count -) -{ - char *bp; - struct tftpStream *tp = iop->data1; - int retryCount; - int nwant; - - - /* - * Read till user request is satisfied or EOF is reached - */ - bp = buffer; - nwant = count; - while (nwant) { - if (tp->nleft) { - int ncopy; - if (nwant < tp->nleft) - ncopy = nwant; - else - ncopy = tp->nleft; - memcpy (bp, &tp->pkbuf.tftpDATA.data[tp->nused], ncopy); - tp->nused += ncopy; - tp->nleft -= ncopy; - bp += ncopy; - nwant -= ncopy; - if (nwant == 0) - break; - } - if (tp->eof) - break; - - /* - * Wait for the next packet - */ - retryCount = 0; - for (;;) { - int len = getPacket (tp, retryCount); - if (len >= (int)sizeof tp->pkbuf.tftpACK) { - int opcode = ntohs (tp->pkbuf.tftpDATA.opcode); - rtems_unsigned16 nextBlock = tp->blocknum + 1; - if ((opcode == TFTP_OPCODE_DATA) - && (ntohs (tp->pkbuf.tftpDATA.blocknum) == nextBlock)) { - tp->nused = 0; - tp->nleft = len - 2 * sizeof (rtems_unsigned16); - tp->eof = (tp->nleft < TFTP_BUFSIZE); - tp->blocknum++; - if (sendAck (tp) != 0) - rtems_set_errno_and_return_minus_one( EIO ); - break; - } - if (opcode == TFTP_OPCODE_ERROR) - rtems_set_errno_and_return_minus_one( tftpErrno (tp) ); - } - - /* - * Keep trying? - */ - if (++retryCount == IO_RETRY_LIMIT) - rtems_set_errno_and_return_minus_one( EIO ); - if (sendAck (tp) != 0) - rtems_set_errno_and_return_minus_one( EIO ); - } - } - return count - nwant; -} - -/* - * Flush a write buffer and wait for acknowledgement - */ -static int rtems_tftp_flush ( struct tftpStream *tp ) -{ - int wlen, rlen; - int retryCount = 0; - - wlen = tp->nused + 2 * sizeof (rtems_unsigned16); - for (;;) { - tp->pkbuf.tftpDATA.opcode = htons (TFTP_OPCODE_DATA); - tp->pkbuf.tftpDATA.blocknum = htons (tp->blocknum); -#ifdef RTEMS_TFTP_DRIVER_DEBUG - if (rtems_tftp_driver_debug) - printf ("TFTP: SEND %d (%d)\n", tp->blocknum, tp->nused); -#endif - if (sendto (tp->socket, (char *)&tp->pkbuf, wlen, 0, - (struct sockaddr *)&tp->farAddress, - sizeof tp->farAddress) < 0) - return EIO; - rlen = getPacket (tp, retryCount); - /* - * Our last packet won't necessarily be acknowledged! - */ - if ((rlen < 0) && (tp->nused < sizeof tp->pkbuf.tftpDATA.data)) - return 0; - if (rlen >= (int)sizeof tp->pkbuf.tftpACK) { - int opcode = ntohs (tp->pkbuf.tftpACK.opcode); - if ((opcode == TFTP_OPCODE_ACK) - && (ntohs (tp->pkbuf.tftpACK.blocknum) == tp->blocknum)) { - tp->nused = 0; - tp->blocknum++; - return 0; - } - if (opcode == TFTP_OPCODE_ERROR) - return tftpErrno (tp); - } - - /* - * Keep trying? - */ - if (++retryCount == IO_RETRY_LIMIT) - return EIO; - } -} - -/* - * Close a TFTP stream - */ -static int rtems_tftp_close( - rtems_libio_t *iop -) -{ - struct tftpStream *tp = iop->data1;; - - if (tp->writing) - rtems_tftp_flush (tp); - if (!tp->eof && !tp->firstReply) { - /* - * Tell the other end to stop - */ - rtems_interval ticksPerSecond; - sendStifle (tp, &tp->farAddress); - rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticksPerSecond); - rtems_task_wake_after (1 + ticksPerSecond / 10); - } - close (tp->socket); - releaseStream (iop->data0); - return RTEMS_SUCCESSFUL; -} - -static int rtems_tftp_write( - rtems_libio_t *iop, - const void *buffer, - unsigned32 count -) -{ - const char *bp; - struct tftpStream *tp = iop->data1; - int nleft, nfree, ncopy; - - /* - * Bail out if an error has occurred - */ - if (!tp->writing) - return EIO; - - - /* - * Write till user request is satisfied - * Notice that the buffer is flushed as soon as it is filled rather - * than waiting for the next write or a close. This ensures that - * the flush in close writes a less than full buffer so the far - * end can detect the end-of-file condition. - */ - bp = buffer; - nleft = count; - while (nleft) { - nfree = sizeof tp->pkbuf.tftpDATA.data - tp->nused; - if (nleft < nfree) - ncopy = nleft; - else - ncopy = nfree; - memcpy (&tp->pkbuf.tftpDATA.data[tp->nused], bp, ncopy); - tp->nused += ncopy; - nleft -= ncopy; - bp += ncopy; - if (tp->nused == sizeof tp->pkbuf.tftpDATA.data) { - int e = rtems_tftp_flush (tp); - if (e) { - tp->writing = 0; - rtems_set_errno_and_return_minus_one (e); - } - } - } - return count; -} - -/* - * Dummy version to let fopen(xxxx,"w") work properly. - */ -static int rtems_tftp_ftruncate( - rtems_libio_t *iop, - off_t count -) -{ - return 0; -} - -static rtems_filesystem_node_types_t rtems_tftp_node_type( - rtems_filesystem_location_info_t *pathloc /* IN */ -) -{ - if ((pathloc->node_access == NULL) - || (pathloc->node_access == ROOT_NODE_ACCESS)) - return RTEMS_FILESYSTEM_MEMORY_FILE; - return RTEMS_FILESYSTEM_DIRECTORY; -} - -static int rtems_tftp_free_node_info( - rtems_filesystem_location_info_t *pathloc /* IN */ -) -{ - if (pathloc->node_access && (pathloc->node_access != ROOT_NODE_ACCESS)) { - free (pathloc->node_access); - pathloc->node_access = NULL; - } - return 0; -} - - -rtems_filesystem_operations_table rtems_tftp_ops = { - rtems_tftp_eval_path, /* eval_path */ - rtems_tftp_evaluate_for_make, /* evaluate_for_make */ - NULL, /* link */ - NULL, /* unlink */ - rtems_tftp_node_type, /* node_type */ - NULL, /* mknod */ - NULL, /* chown */ - rtems_tftp_free_node_info, /* freenodinfo */ - NULL, /* mount */ - rtems_tftp_mount_me, /* initialize */ - NULL, /* unmount */ - NULL, /* fsunmount */ - NULL, /* utime, */ - NULL, /* evaluate_link */ - NULL, /* symlink */ - NULL, /* readlin */ -}; - -rtems_filesystem_file_handlers_r rtems_tftp_handlers = { - rtems_tftp_open, /* open */ - rtems_tftp_close, /* close */ - rtems_tftp_read, /* read */ - rtems_tftp_write, /* write */ - NULL, /* ioctl */ - NULL, /* lseek */ - NULL, /* fstat */ - NULL, /* fchmod */ - rtems_tftp_ftruncate, /* ftruncate */ - NULL, /* fpathconf */ - NULL, /* fsync */ - NULL, /* fdatasync */ - NULL, /* fcntl */ - NULL /* rmnod */ -}; -- cgit v1.2.3