From 29e92b090c8bc35745aa5c89231ce806bcb11e57 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Mon, 31 May 2010 13:56:37 +0000 Subject: 2010-05-31 Chris Johns * libcsupport/Makefile.am: Add mount-mgr.c. * libcsupport/src/mount-mgr.c: New. * include/rtems/fs.h: Added rtems_filesystem_location_mount. * libcsupport/include/rtems/libio.h, libcsupport/src/mount.c: New mount interface. It is similar to Linux. * libcsupport/include/rtems/libio_.h: Remove the init_fs_mount_table call. * libcsupport/src/base_fs.c: Remove init_fs_mount_table_call. Use the new mount call. Remove setting the root node in the global pathloc. Mount does this now. * libcsupport/src/privateenv.c: Remove the hack to set the root mount table entry in the environment. * libcsupport/src/unmount.cL Free the target string. * libblock/src/bdpart-mount.c: New mount API. * libfs/src/devfs/devfs.h, libfs/src/devfs/devfs_init.c, libfs/src/dosfs/dosfs.h, libfs/src/dosfs/msdos.h, libfs/src/dosfs/msdos_init.c, libfs/src/imfs/imfs.h, libfs/src/imfs/imfs_eval.c, libfs/src/imfs/imfs_init.c, libfs/src/imfs/miniimfs_init.c, libfs/src/nfsclient/src/librtemsNfs.h, libfs/src/rfs/rtems-rfs-rtems.c, libfs/src/rfs/rtems-rfs.h, libnetworking/lib/ftpfs.c, libnetworking/rtems/ftpfs.h, libnetworking/rtems/tftp.h: New mount_h API. * libfs/src/devfs/devfs_eval.c: Local include of extern ops. * libfs/src/nfsclient/src/nfs.c: New mount API. Removed the mount me call and fixed the initialisation to happen when mounting. * libmisc/Makefile.am, libmisc/shell/shellconfig.h: Remove mount filesystem files. * libmisc/fsmount/fsmount.c, libmisc/fsmount/fsmount.h: Updated to the new mount table values. * libmisc/shell/main_mount_ftp.c, libmisc/shell/main_mount_msdos.c, libmisc/shell/main_mount_rfs.c, libmisc/shell/main_mount_tftp.c: Removed. * libmisc/shell/main_mount.c: Use the new mount API. Also access the file system table for the file system types. * libnetworking/lib/tftpDriver.c: Updated to the new mount API. Fixed to allow mounting from any mount point. Also can now have more than file system mounted. * sapi/include/confdefs.h: Add file system configuration support. --- cpukit/libnetworking/lib/ftpfs.c | 23 +- cpukit/libnetworking/lib/tftpDriver.c | 489 +++++++++++++++++++--------------- cpukit/libnetworking/rtems/ftpfs.h | 19 +- cpukit/libnetworking/rtems/tftp.h | 8 +- 4 files changed, 295 insertions(+), 244 deletions(-) (limited to 'cpukit/libnetworking') diff --git a/cpukit/libnetworking/lib/ftpfs.c b/cpukit/libnetworking/lib/ftpfs.c index fb7b0d32b2..5e7f520990 100644 --- a/cpukit/libnetworking/lib/ftpfs.c +++ b/cpukit/libnetworking/lib/ftpfs.c @@ -130,6 +130,8 @@ static int rtems_ftpfs_set_connection_timeout( return 0; } +#if 0 +CCJ_REMOVE_MOUNT rtems_status_code rtems_ftpfs_mount(const char *mount_point) { int rv = 0; @@ -156,6 +158,7 @@ rtems_status_code rtems_ftpfs_mount(const char *mount_point) return RTEMS_SUCCESSFUL; } +#endif static rtems_status_code rtems_ftpfs_do_ioctl( const char *mount_point, @@ -234,19 +237,6 @@ rtems_status_code rtems_ftpfs_set_timeout( ); } -int rtems_bsdnet_initialize_ftp_filesystem(void) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - - sc = rtems_ftpfs_mount(NULL); - - if (sc == RTEMS_SUCCESSFUL) { - return 0; - } else { - return -1; - } -} - typedef void (*rtems_ftpfs_reply_parser)( const char * /* reply fragment */, size_t /* reply fragment length */, @@ -1232,8 +1222,9 @@ static rtems_filesystem_node_types_t rtems_ftpfs_node_type( return RTEMS_FILESYSTEM_MEMORY_FILE; } -static int rtems_ftpfs_mount_me( - rtems_filesystem_mount_table_entry_t *e +int rtems_ftpfs_initialize( + rtems_filesystem_mount_table_entry_t *e, + const void *d ) { rtems_ftpfs_mount_entry *me = malloc(sizeof(rtems_ftpfs_mount_entry)); @@ -1337,7 +1328,7 @@ const rtems_filesystem_operations_table rtems_ftpfs_ops = { .chown_h = NULL, .freenod_h = rtems_ftpfs_free_node, .mount_h = NULL, - .fsmount_me_h = rtems_ftpfs_mount_me, + .fsmount_me_h = rtems_ftpfs_initialize, .unmount_h = NULL, .fsunmount_me_h = rtems_ftpfs_unmount_me, .utime_h = NULL, diff --git a/cpukit/libnetworking/lib/tftpDriver.c b/cpukit/libnetworking/lib/tftpDriver.c index c8740ce21a..63c2247844 100644 --- a/cpukit/libnetworking/lib/tftpDriver.c +++ b/cpukit/libnetworking/lib/tftpDriver.c @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef RTEMS_TFTP_DRIVER_DEBUG int rtems_tftp_driver_debug = 1; @@ -43,18 +44,6 @@ int rtems_tftp_driver_debug = 1; */ #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 */ @@ -152,43 +141,49 @@ struct tftpStream { }; /* - * Number of streams open at the same time + * Flags for filesystem info. */ -static rtems_id tftp_mutex; -static int nStreams; -static struct tftpStream ** volatile tftpStreams; +#define TFTPFS_VERBOSE (1 << 0) -typedef const char *tftp_node; -extern rtems_filesystem_operations_table rtems_tftp_ops; -extern rtems_filesystem_file_handlers_r rtems_tftp_handlers; +/* + * Root node_access value + * By using the address of the file system + * we ensure a unique value for this identifier. + */ +#define ROOT_NODE_ACCESS(_fs) (_fs) /* - * Direct copy from the IMFS. Look at this. + * TFTP File system info. */ +typedef struct tftpfs_info_s { + uint32_t flags; + rtems_id tftp_mutex; + int nStreams; + struct tftpStream ** volatile tftpStreams; +} tftpfs_info_t; -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 */ -}; +#define tftpfs_info_mount_table(_mt) ((tftpfs_info_t*) ((_mt)->fs_info)) +#define tftpfs_info_pathloc(_pl) ((tftpfs_info_t*) ((_pl)->mt_entry->fs_info)) +#define tftpfs_info_iop(_iop) (tftpfs_info_pathloc (&((_iop)->pathinfo))) -static int rtems_tftp_mount_me( - rtems_filesystem_mount_table_entry_t *temp_mt_entry +/* + * Number of streams open at the same time + */ + +typedef const char *tftp_node; +extern rtems_filesystem_operations_table rtems_tftp_ops; +extern rtems_filesystem_file_handlers_r rtems_tftp_handlers; + +int rtems_tftpfs_initialize( + rtems_filesystem_mount_table_entry_t *mt_entry, + const void *data ) { + tftpfs_info_t *fs; rtems_status_code sc; - temp_mt_entry->mt_fs_root.handlers = &rtems_tftp_handlers; - temp_mt_entry->mt_fs_root.ops = &rtems_tftp_ops; + mt_entry->mt_fs_root.handlers = &rtems_tftp_handlers; + mt_entry->mt_fs_root.ops = &rtems_tftp_ops; /* * We have no tftp filesystem specific data to maintain. This @@ -197,16 +192,18 @@ static int rtems_tftp_mount_me( * 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; - - + fs = malloc (sizeof (tftpfs_info_t)); + if (!fs) + rtems_set_errno_and_return_minus_one (ENOMEM); + + fs->flags = 0; + fs->nStreams = 0; + fs->tftpStreams = 0; + + mt_entry->fs_info = fs; + mt_entry->mt_fs_root.node_access = ROOT_NODE_ACCESS (fs); + mt_entry->mt_fs_root.node_access_2 = NULL; + /* * Now allocate a semaphore for mutual exclusion. * @@ -222,40 +219,51 @@ static int rtems_tftp_mount_me( RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL, 0, - &tftp_mutex + &fs->tftp_mutex ); if (sc != RTEMS_SUCCESSFUL) - rtems_set_errno_and_return_minus_one( ENOMEM ); - + rtems_set_errno_and_return_minus_one (ENOMEM); + + if (data) { + char* config = (char*) data; + char* token; + char* saveptr; + token = strtok_r (config, " ", &saveptr); + while (token) { + if (strcmp (token, "verbose") == 0) + fs->flags |= TFTPFS_VERBOSE; + token = strtok_r (NULL, " ", &saveptr); + } + } + return 0; } /* - * Initialize the TFTP driver + * Release a stream and clear the pointer to it */ - -int rtems_bsdnet_initialize_tftp_filesystem (void) +static void +releaseStream (tftpfs_info_t *fs, int s) { - 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" ); + if (fs->tftpStreams[s] && (fs->tftpStreams[s]->socket >= 0)) + close (fs->tftpStreams[s]->socket); + rtems_semaphore_obtain (fs->tftp_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + free (fs->tftpStreams[s]); + fs->tftpStreams[s] = NULL; + rtems_semaphore_release (fs->tftp_mutex); +} - return status; +static int +rtems_tftpfs_shutdown (rtems_filesystem_mount_table_entry_t* mt_entry) +{ + tftpfs_info_t *fs = tftpfs_info_mount_table (mt_entry); + int s; + for (s = 0; s < fs->nStreams; s++) + releaseStream (fs, s); + rtems_semaphore_delete (fs->tftp_mutex); + free (fs); + return 0; } /* @@ -335,8 +343,8 @@ getPacket (struct tftpStream *tp, int retryCount) } from; socklen_t fromlen = sizeof from; len = recvfrom (tp->socket, &tp->pkbuf, - sizeof tp->pkbuf, 0, - &from.s, &fromlen); + sizeof tp->pkbuf, 0, + &from.s, &fromlen); if (len < 0) break; if (from.i.sin_addr.s_addr == tp->farAddress.sin_addr.s_addr) { @@ -410,18 +418,6 @@ sendAck (struct tftpStream *tp) 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 __attribute__((unused)), /* IN */ rtems_filesystem_location_info_t *pathloc, /* IN/OUT */ @@ -429,7 +425,8 @@ static int rtems_tftp_evaluate_for_make( ) { pathloc->node_access = NULL; - rtems_set_errno_and_return_minus_one( EIO ); + pathloc->node_access_2 = NULL; + rtems_set_errno_and_return_minus_one (EIO); } /* @@ -493,46 +490,54 @@ static int rtems_tftp_eval_path( rtems_filesystem_location_info_t *pathloc /* IN/OUT */ ) { - pathloc->handlers = &rtems_tftp_handlers; + tftpfs_info_t *fs; + char *cp; + + /* + * Get the file system info. + */ + fs = tftpfs_info_pathloc (pathloc); + + 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; + int nal = 0; + if (pathloc->node_access != ROOT_NODE_ACCESS (fs)) + nal = strlen(pathloc->node_access); + cp = malloc(nal + pathnamelen + 1); + if (cp == NULL) + rtems_set_errno_and_return_minus_one(ENOMEM); + if (nal) + memcpy (cp, pathloc->node_access, nal); + memcpy(cp + nal, pathname, pathnamelen); + cp[nal + pathnamelen] = '\0'; + fixPath (cp); + pathloc->node_access = cp; + } + else { + if (pathnamelen) { + /* + * 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); - /* - * 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); + cp = malloc(pathnamelen + 1); if (cp == NULL) - rtems_set_errno_and_return_minus_one( ENOMEM ); + rtems_set_errno_and_return_minus_one(ENOMEM); + memcpy(cp, pathname, pathnamelen); + cp[pathnamelen] = '\0'; + fixPath (cp); + pathloc->node_access_2 = cp; } - 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; } @@ -546,6 +551,7 @@ static int rtems_tftp_open_worker( uint32_t mode __attribute__((unused)) ) { + tftpfs_info_t *fs; struct tftpStream *tp; int retryCount; struct in_addr farAddress; @@ -558,72 +564,75 @@ static int rtems_tftp_open_worker( rtems_status_code sc; char *hostname; + /* + * Get the file system info. + */ + fs = tftpfs_info_iop (iop); + /* * Extract the host name component */ - cp2 = full_path_name; - while (*cp2 == '/') - cp2++; - hostname = cp2; - while (*cp2 != '/') { - if (*cp2 == '\0') - return ENOENT; - cp2++; + hostname = full_path_name; + cp1 = strchr (full_path_name, ':'); + if (!cp1) + hostname = "BOOTP_HOST"; + else { + *cp1 = '\0'; + ++cp1; } - *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 == INADDR_ANY) || (farAddress.s_addr == INADDR_BROADCAST)) + else if (inet_aton (hostname, &farAddress) == 0) { + struct hostent *he = gethostbyname(hostname); + if (he == NULL) + return ENOENT; + memcpy (&farAddress, he->h_addr, sizeof (farAddress)); + } else { 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 (strcmp (cp1, "BOOTP_FILE") == 0) { + cp1 = rtems_bsdnet_bootp_boot_file_name; } - if (*cp2 == '\0') + if (*cp1 == '\0') return ENOENT; - remoteFilename = cp2; + remoteFilename = cp1; if (strlen (remoteFilename) > (TFTP_BUFSIZE - 10)) return ENOENT; /* * Find a free stream */ - sc = rtems_semaphore_obtain (tftp_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + sc = rtems_semaphore_obtain (fs->tftp_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); if (sc != RTEMS_SUCCESSFUL) return EBUSY; - for (s = 0 ; s < nStreams ; s++) { - if (tftpStreams[s] == NULL) + for (s = 0 ; s < fs->nStreams ; s++) { + if (fs->tftpStreams[s] == NULL) break; } - if (s == nStreams) { + if (s == fs->nStreams) { /* * Reallocate stream pointers * Guard against the case where realloc() returns NULL. */ struct tftpStream **np; - np = realloc (tftpStreams, ++nStreams * sizeof *tftpStreams); + np = realloc (fs->tftpStreams, ++fs->nStreams * sizeof *fs->tftpStreams); if (np == NULL) { - rtems_semaphore_release (tftp_mutex); + rtems_semaphore_release (fs->tftp_mutex); return ENOMEM; } - tftpStreams = np; + fs->tftpStreams = np; } - tp = tftpStreams[s] = malloc (sizeof (struct tftpStream)); - rtems_semaphore_release (tftp_mutex); + tp = fs->tftpStreams[s] = malloc (sizeof (struct tftpStream)); + rtems_semaphore_release (fs->tftp_mutex); if (tp == NULL) return ENOMEM; iop->data0 = s; @@ -633,7 +642,7 @@ static int rtems_tftp_open_worker( * Create the socket */ if ((tp->socket = socket (AF_INET, SOCK_DGRAM, 0)) < 0) { - releaseStream (s); + releaseStream (fs, s); return ENOMEM; } @@ -646,13 +655,12 @@ static int rtems_tftp_open_worker( 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_port = htons (UDP_PORT_BASE + fs->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); + releaseStream (fs, s); return EBUSY; } } @@ -697,8 +705,7 @@ static int rtems_tftp_open_worker( if (sendto (tp->socket, (char *)&tp->pkbuf, len, 0, (struct sockaddr *)&tp->farAddress, sizeof tp->farAddress) < 0) { - close (tp->socket); - releaseStream (s); + releaseStream (fs, s); return EIO; } @@ -716,8 +723,7 @@ static int rtems_tftp_open_worker( tp->nleft = len - 2 * sizeof (uint16_t ); tp->eof = (tp->nleft < TFTP_BUFSIZE); if (sendAck (tp) != 0) { - close (tp->socket); - releaseStream (s); + releaseStream (fs, s); return EIO; } break; @@ -731,8 +737,7 @@ static int rtems_tftp_open_worker( } if (opcode == TFTP_OPCODE_ERROR) { int e = tftpErrno (tp); - close (tp->socket); - releaseStream (s); + releaseStream (fs, s); return e; } } @@ -741,8 +746,7 @@ static int rtems_tftp_open_worker( * Keep trying */ if (++retryCount >= OPEN_RETRY_LIMIT) { - close (tp->socket); - releaseStream (s); + releaseStream (fs, s); return EIO; } } @@ -759,36 +763,81 @@ static int rtems_tftp_open( uint32_t mode ) { - char *full_path_name; - char *s1; - int err; + tftpfs_info_t *fs; + const char *device; + char *full_path_name; + char *na; + char *na2; + int dlen; + int nalen; + int na2len; + int sep1; + int err; /* - * Tack the `current directory' on to relative paths. - * We know that the current directory ends in a / character. + * Get the file system info. */ - 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 = ""; - } + fs = tftpfs_info_iop (iop); + + /* + * Tack the prefix directory if one exists from the device name. + */ + device = + rtems_filesystem_mount_device (rtems_filesystem_location_mount (&iop->pathinfo)); + dlen = strlen (device); + if (dlen == 0) + rtems_set_errno_and_return_minus_one (ENOENT); + + if (iop->pathinfo.node_access_2 == NULL) + rtems_set_errno_and_return_minus_one (ENOENT); + + if (iop->pathinfo.node_access != ROOT_NODE_ACCESS (fs)) { + na = iop->pathinfo.node_access; + nalen = strlen (na); + } else { - s1 = rtems_filesystem_current.node_access; + na = NULL; + nalen = 0; + } + + na2 = iop->pathinfo.node_access_2; + + na2len = strlen (na2); + + if (nalen) { + sep1 = 1; + if (na[nalen] == '/') { + sep1 = 0; + if (na2[0] == '/') + ++na2; + } + else { + if (na2[0] == '/') + sep1 = 0; + else + sep1 = 1; + } } - full_path_name = malloc (strlen (s1) + strlen (new_name) + 1); + else + sep1 = 0; + + full_path_name = malloc (dlen + nalen + sep1 + na2len + 1); if (full_path_name == NULL) - return ENOMEM; - strcpy (full_path_name, s1); - strcat (full_path_name, new_name); + rtems_set_errno_and_return_minus_one(ENOMEM); + strcpy (full_path_name, device); + if (nalen) + strcat (full_path_name, na); + if (sep1) + strcat (full_path_name, "/"); + strcat (full_path_name, na2); fixPath (full_path_name); + + if (fs->flags & TFTPFS_VERBOSE) + printf ("TFTPFS: %s %s %s -> %s\n", device, na, na2, full_path_name); + err = rtems_tftp_open_worker (iop, full_path_name, flags, mode); free (full_path_name); - return err; + rtems_set_errno_and_return_minus_one(err); } /* @@ -805,7 +854,9 @@ static ssize_t rtems_tftp_read( int retryCount; int nwant; - + if (!tp) + rtems_set_errno_and_return_minus_one( EIO ); + /* * Read till user request is satisfied or EOF is reached */ @@ -841,24 +892,24 @@ static ssize_t rtems_tftp_read( if ((opcode == TFTP_OPCODE_DATA) && (ntohs (tp->pkbuf.tftpDATA.blocknum) == nextBlock)) { tp->nused = 0; - tp->nleft = len - 2 * sizeof (uint16_t ); + tp->nleft = len - 2 * sizeof (uint16_t); tp->eof = (tp->nleft < TFTP_BUFSIZE); tp->blocknum++; if (sendAck (tp) != 0) - rtems_set_errno_and_return_minus_one( EIO ); + rtems_set_errno_and_return_minus_one (EIO); break; } if (opcode == TFTP_OPCODE_ERROR) - rtems_set_errno_and_return_minus_one( tftpErrno (tp) ); + rtems_set_errno_and_return_minus_one (tftpErrno (tp)); } /* * Keep trying? */ if (++retryCount == IO_RETRY_LIMIT) - rtems_set_errno_and_return_minus_one( EIO ); + rtems_set_errno_and_return_minus_one (EIO); if (sendAck (tp) != 0) - rtems_set_errno_and_return_minus_one( EIO ); + rtems_set_errno_and_return_minus_one (EIO); } } return count - nwant; @@ -867,7 +918,7 @@ static ssize_t rtems_tftp_read( /* * Flush a write buffer and wait for acknowledgement */ -static int rtems_tftp_flush ( struct tftpStream *tp ) +static int rtems_tftp_flush (struct tftpStream *tp) { int wlen, rlen; int retryCount = 0; @@ -917,10 +968,20 @@ static int rtems_tftp_close( rtems_libio_t *iop ) { - struct tftpStream *tp = iop->data1;; - + tftpfs_info_t *fs; + struct tftpStream *tp = iop->data1; + int e = 0; + + /* + * Get the file system info. + */ + fs = tftpfs_info_iop (iop); + + if (!tp) + rtems_set_errno_and_return_minus_one (EIO); + if (tp->writing) - rtems_tftp_flush (tp); + e = rtems_tftp_flush (tp); if (!tp->eof && !tp->firstReply) { /* * Tell the other end to stop @@ -930,9 +991,8 @@ static int rtems_tftp_close( ticksPerSecond = rtems_clock_get_ticks_per_second(); rtems_task_wake_after (1 + ticksPerSecond / 10); } - close (tp->socket); - releaseStream (iop->data0); - return RTEMS_SUCCESSFUL; + releaseStream (fs, iop->data0); + rtems_set_errno_and_return_minus_one (e); } static ssize_t rtems_tftp_write( @@ -949,8 +1009,7 @@ static ssize_t rtems_tftp_write( * Bail out if an error has occurred */ if (!tp->writing) - return EIO; - + rtems_set_errno_and_return_minus_one (EIO); /* * Write till user request is satisfied @@ -997,8 +1056,10 @@ static rtems_filesystem_node_types_t rtems_tftp_node_type( rtems_filesystem_location_info_t *pathloc /* IN */ ) { + tftpfs_info_t *fs = tftpfs_info_pathloc (pathloc); if ((pathloc->node_access == NULL) - || (pathloc->node_access == ROOT_NODE_ACCESS)) + || (pathloc->node_access_2 != NULL) + || (pathloc->node_access == ROOT_NODE_ACCESS (fs))) return RTEMS_FILESYSTEM_MEMORY_FILE; return RTEMS_FILESYSTEM_DIRECTORY; } @@ -1007,10 +1068,16 @@ static int rtems_tftp_free_node_info( rtems_filesystem_location_info_t *pathloc /* IN */ ) { - if (pathloc->node_access && (pathloc->node_access != ROOT_NODE_ACCESS)) { + tftpfs_info_t *fs = tftpfs_info_pathloc (pathloc); + if (pathloc->node_access && \ + (pathloc->node_access != ROOT_NODE_ACCESS (fs))) { free (pathloc->node_access); pathloc->node_access = NULL; } + if (pathloc->node_access_2) { + free (pathloc->node_access_2); + pathloc->node_access_2 = NULL; + } return 0; } @@ -1025,9 +1092,9 @@ rtems_filesystem_operations_table rtems_tftp_ops = { NULL, /* chown */ rtems_tftp_free_node_info, /* freenodinfo */ NULL, /* mount */ - rtems_tftp_mount_me, /* initialize */ + rtems_tftpfs_initialize, /* initialize */ NULL, /* unmount */ - NULL, /* fsunmount */ + rtems_tftpfs_shutdown, /* fsunmount */ NULL, /* utime, */ NULL, /* evaluate_link */ NULL, /* symlink */ @@ -1035,18 +1102,18 @@ rtems_filesystem_operations_table rtems_tftp_ops = { }; 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_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 */ + NULL, /* fpathconf */ + NULL, /* fsync */ + NULL, /* fdatasync */ + NULL, /* fcntl */ + NULL /* rmnod */ }; diff --git a/cpukit/libnetworking/rtems/ftpfs.h b/cpukit/libnetworking/rtems/ftpfs.h index 0414f8e49d..a9d89d45ef 100644 --- a/cpukit/libnetworking/rtems/ftpfs.h +++ b/cpukit/libnetworking/rtems/ftpfs.h @@ -98,16 +98,6 @@ typedef enum { */ extern const rtems_filesystem_operations_table rtems_ftpfs_ops; -/** - * Creates the mount point @a mount_point and mounts the FTP file system. - * - * If @a mount_point is @c NULL the default mount point - * @ref RTEMS_FTPFS_MOUNT_POINT_DEFAULT will be used. - * - * It is mounted with read and write access. - */ -rtems_status_code rtems_ftpfs_mount( const char *mount_point); - /** * Returns in @a verbose if the verbose mode is enabled or disabled for the * file system at @a mount_point. @@ -160,15 +150,12 @@ rtems_status_code rtems_ftpfs_set_timeout( /** * Creates the default mount point @ref RTEMS_FTPFS_MOUNT_POINT_DEFAULT and - * mounts the FTP file system. + * mounts the FTP file system. Do not call directly, use mount.xs * * It is mounted with read and write access. - * - * On success, zero is returned. On error, -1 is returned. - * - * @deprecated Use rtems_ftpfs_mount() instead. */ -int rtems_bsdnet_initialize_ftp_filesystem( void); +int rtems_ftpfs_initialize(rtems_filesystem_mount_table_entry_t *e, + const void *d); #ifdef __cplusplus } diff --git a/cpukit/libnetworking/rtems/tftp.h b/cpukit/libnetworking/rtems/tftp.h index b6a1bb5e8f..7fb977ffa0 100644 --- a/cpukit/libnetworking/rtems/tftp.h +++ b/cpukit/libnetworking/rtems/tftp.h @@ -20,7 +20,8 @@ * To open `/bootfiles/image' on `hostname' for reading: * fd = open ("/TFTP/hostname/bootfiles/image", O_RDONLY); * - * The `hostname' must be four dot-separated decimal values. + * The 'TFTP' is the mount path and the `hostname' must be four dot-separated + * decimal values. */ #ifndef _RTEMS_TFTP_H @@ -32,6 +33,11 @@ extern "C" { #include +/* + * Filesystem Mount table entry. + */ +int rtems_tftpfs_initialize(rtems_filesystem_mount_table_entry_t *temp_mt_entry); + /* * Filesystem initialization routine */ -- cgit v1.2.3