diff options
Diffstat (limited to 'c/src/lib/libnetworking/lib')
-rw-r--r-- | c/src/lib/libnetworking/lib/Makefile.in | 57 | ||||
-rw-r--r-- | c/src/lib/libnetworking/lib/README | 5 | ||||
-rw-r--r-- | c/src/lib/libnetworking/lib/getprotoby.c | 46 | ||||
-rw-r--r-- | c/src/lib/libnetworking/lib/syslog.c | 189 | ||||
-rw-r--r-- | c/src/lib/libnetworking/lib/tftpDriver.c | 775 |
5 files changed, 0 insertions, 1072 deletions
diff --git a/c/src/lib/libnetworking/lib/Makefile.in b/c/src/lib/libnetworking/lib/Makefile.in deleted file mode 100644 index 829b2b25af..0000000000 --- a/c/src/lib/libnetworking/lib/Makefile.in +++ /dev/null @@ -1,57 +0,0 @@ -# -# $Id$ -# - -@SET_MAKE@ -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -top_builddir = .. -subdir = lib - -RTEMS_ROOT = @RTEMS_ROOT@ -PROJECT_ROOT = @PROJECT_ROOT@ - -VPATH = @srcdir@ - -LIBNAME = lib.a -LIB = ${ARCH}/${LIBNAME} - -# C and C++ source names, if any, go here -- minus the .c or .cc -C_PIECES = getprotoby syslog tftpDriver -C_FILES = $(C_PIECES:%=%.c) -C_O_FILES = $(C_PIECES:%=${ARCH}/%.o) - -SRCS = $(C_FILES) -OBJS = $(C_O_FILES) - -include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg -include $(RTEMS_ROOT)/make/lib.cfg - -INSTALL_CHANGE = @INSTALL_CHANGE@ - -# -# Add local stuff here using += -# - -DEFINES += -DNOPOLL -DNOSELECT -CPPFLAGS += -CFLAGS += - -# -# Add your list of files to delete here. The config files -# already know how to delete some stuff, so you may want -# to just run 'make clean' first to see what gets missed. -# 'make clobber' already includes 'make clean' -# - -CLEAN_ADDITIONS += $(LIB) -CLOBBER_ADDITIONS += - -all: ${ARCH} $(LIB) - -$(LIB): $(SRCS) ${OBJS} - $(make-library) - -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) \ - && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status diff --git a/c/src/lib/libnetworking/lib/README b/c/src/lib/libnetworking/lib/README deleted file mode 100644 index 998bd5e708..0000000000 --- a/c/src/lib/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/lib/libnetworking/lib/getprotoby.c b/c/src/lib/libnetworking/lib/getprotoby.c deleted file mode 100644 index fc8de6e402..0000000000 --- a/c/src/lib/libnetworking/lib/getprotoby.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * $Id$ - */ - -#include <netdb.h> -#include <string.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> - -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 (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 (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/lib/libnetworking/lib/syslog.c b/c/src/lib/libnetworking/lib/syslog.c deleted file mode 100644 index 0bb15bc78e..0000000000 --- a/c/src/lib/libnetworking/lib/syslog.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * RTEMS version of syslog and associated routines - * - * $Id$ - */ - -#include <rtems.h> -#include <stdio.h> -#include <stdarg.h> -#include <errno.h> -#include <syslog.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> - -#include <unistd.h> - -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/lib/libnetworking/lib/tftpDriver.c b/c/src/lib/libnetworking/lib/tftpDriver.c deleted file mode 100644 index 8e96c8d4a9..0000000000 --- a/c/src/lib/libnetworking/lib/tftpDriver.c +++ /dev/null @@ -1,775 +0,0 @@ -/* - * 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 <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <malloc.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.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> - -#ifndef set_errno_and_return_minus_one -#define set_errno_and_return_minus_one( _error ) \ - do { errno = (_error); return -1; } while(0) -#endif - - -/* - * Range of UDP ports to try - */ -#define UDP_PORT_BASE 3180 - -/* - * Pathname prefix - */ -#define TFTP_PATHNAME_PREFIX "/TFTP/" - -/* - * Default limits - */ -#define PACKET_REPLY_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 received - */ - 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; -}; - -/* - * 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 */ -}; - -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 = NULL; - - /* - * 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) - 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_ONLY, - NULL, - TFTP_PATHNAME_PREFIX - ); - - if ( status ) - perror( "TFTP mount failed" ); - - return status; -} - -/* - * Set error message - * This RTEMS/UNIX error mapping needs to be fixed! - */ -static void -tftpSetErrno (struct tftpStream *tp) -{ - unsigned int tftpError; - static const int errorMap[] = { - 0, - ENOENT, - EPERM, - ENOSPC, - EINVAL, - ENXIO, - EEXIST, - ESRCH, - 0, - }; - - tftpError = ntohs (tp->pkbuf.tftpERROR.errorCode); - if (tftpError < (sizeof errorMap / sizeof errorMap[0])) - errno = errorMap[tftpError]; - else - errno = 1000 + tftpError; -} - -/* - * Send a message to make the other end shut up - */ -static void -sendStifle (struct tftpStream *tp, struct sockaddr_in *to) -{ - int len; - - /* - * Create the error packet (Unknown transfer ID). - */ - tp->pkbuf.tftpERROR.opcode = htons (TFTP_OPCODE_ERROR); - tp->pkbuf.tftpERROR.errorCode = htons (5); - len = sizeof tp->pkbuf.tftpERROR.opcode + - sizeof tp->pkbuf.tftpERROR.errorCode + 1; - len += sprintf (tp->pkbuf.tftpERROR.errorMessage, "GO AWAY"); - - /* - * Send it - */ - sendto (tp->socket, (char *)&tp->pkbuf, len, 0, - (struct sockaddr *)to, sizeof *to); -} - -/* - * Wait for a data packet - */ -static int -getPacket (struct tftpStream *tp) -{ - int len; - struct timeval tv; - - tv.tv_sec = 6; - tv.tv_usec = 0; - 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; - setsockopt (tp->socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv); - return len; -} - -/* - * Send an acknowledgement - */ -static int -sendAck (struct tftpStream *tp) -{ - /* - * 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); -} - -int rtems_tftp_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_tftp_eval_path( - const char *pathname, /* IN */ - int flags, /* IN */ - rtems_filesystem_location_info_t *pathloc /* IN/OUT */ -) -{ - - /* - * Read-only for now - */ - - if ( (flags & O_WRONLY) == O_WRONLY ) - set_errno_and_return_minus_one( ENOENT ); - - /* - * The File system is mounted at TFTP_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_tftp_handlers; - - return 0; -} - - -int rtems_tftp_open( - rtems_libio_t *iop, - const char *new_name, - unsigned32 flag, - unsigned32 mode -) -{ - struct tftpStream *tp; - int retryCount; - rtems_unsigned32 farAddress; - int s; - int len; - char *cp1; - char *cp2; - char *remoteFilename; - rtems_interval now; - rtems_status_code sc; - char *hostname; - - /* - * This came from the evaluate path. - */ - - cp2 = iop->file_info; - - cp1 = cp2; - while (*cp2 != '/') { - if (*cp2 == '\0') - return ENOENT; - cp2++; - } - - len = cp2 - cp1; - hostname = malloc (len + 1); - if (hostname == NULL) - return ENOMEM; - - strncpy (hostname, cp1, len); - hostname[len] = '\0'; - farAddress = inet_addr (hostname); - free (hostname); - - if ((farAddress == 0) || (farAddress == ~0)) - return ENOENT; - - 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.s_addr = farAddress; - tp->farAddress.sin_port = htons (69); - - /* - * Start the transfer - */ - tp->firstReply = 1; - for (;;) { - /* - * Create the request - */ - tp->pkbuf.tftpRWRQ.opcode = htons (TFTP_OPCODE_RRQ); - 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); - if (len >= (int) sizeof tp->pkbuf.tftpACK) { - int opcode = ntohs (tp->pkbuf.tftpDATA.opcode); - if ((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 (opcode == TFTP_OPCODE_ERROR) { - tftpSetErrno (tp); - close (tp->socket); - releaseStream (s); - return EIO; - } - } - - /* - * Keep trying - */ - if (++retryCount >= OPEN_RETRY_LIMIT) { - close (tp->socket); - releaseStream (s); - return EIO; - } - } - - return 0; -} - -/* - * Read from a TFTP stream - */ - -int rtems_tftp_read( - rtems_libio_t *iop, - void *buffer, - unsigned32 count -) -{ - char *bp; - struct tftpStream *tp; - int retryCount; - int nwant; - - tp = iop->data1; - - /* - * Read till user request is satisfied or EOF is reached - */ - - bp = buffer; - nwant = count; - while (nwant) { - if (tp->nleft) { - int count; - if (nwant < tp->nleft) - count = nwant; - else - count = tp->nleft; - memcpy (bp, &tp->pkbuf.tftpDATA.data[tp->nused], count); - tp->nused += count; - tp->nleft -= count; - bp += count; - nwant -= count; - if (nwant == 0) - break; - } - if (tp->eof) - break; - - /* - * Wait for the next packet - */ - retryCount = 0; - for (;;) { - int len = getPacket (tp); - 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) - set_errno_and_return_minus_one( EIO ); - break; - } - if (opcode == TFTP_OPCODE_ERROR) { - tftpSetErrno (tp); - return RTEMS_INTERNAL_ERROR; - } - } - - /* - * Keep trying? - */ - if (++retryCount == IO_RETRY_LIMIT) - set_errno_and_return_minus_one( EIO ); - if (sendAck (tp) != 0) - set_errno_and_return_minus_one( EIO ); - } - } - - /* - * XXX - Eric is this right? - * - */ - return count - nwant; -} - -/* - * Close a TFTP stream - */ -int rtems_tftp_close( - rtems_libio_t *iop -) -{ - struct tftpStream *tp = iop->data1;; - - 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; -} - -int rtems_tftp_write( - rtems_libio_t *iop, - const void *buffer, - unsigned32 count -) -{ - return RTEMS_NOT_CONFIGURED; -} - -rtems_device_driver rtems_tftp_control( - rtems_device_major_number major, - rtems_device_minor_number minor, - void *pargp -) -{ - return RTEMS_NOT_CONFIGURED; -} - -rtems_filesystem_node_types_t rtems_tftp_node_type( - rtems_filesystem_location_info_t *pathloc /* IN */ -) -{ - return RTEMS_FILESYSTEM_MEMORY_FILE; -} - - -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, /* rmnod */ - NULL, /* chown */ - NULL, /* 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, - rtems_tftp_close, - rtems_tftp_read, - rtems_tftp_write, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -}; |