From 2a7ec882706904df4851c044c736410e5e89eb88 Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Tue, 3 Feb 2026 10:22:17 -0700 Subject: [PATCH] cpukit/libfs/ftpfs: reformat fixes #5447 --- cpukit/include/rtems/ftpfs.h | 24 +- cpukit/include/rtems/tftp.h | 30 +- cpukit/libfs/src/ftpfs/ftpfs.c | 774 ++++++----- cpukit/libfs/src/ftpfs/tftpDriver.c | 1847 +++++++++++++------------- cpukit/libfs/src/ftpfs/tftp_driver.h | 8 +- cpukit/libfs/src/ftpfs/tftpfs.c | 647 ++++----- 6 files changed, 1671 insertions(+), 1659 deletions(-) diff --git a/cpukit/include/rtems/ftpfs.h b/cpukit/include/rtems/ftpfs.h index c21894a7fe..0f3ac74fc0 100644 --- a/cpukit/include/rtems/ftpfs.h +++ b/cpukit/include/rtems/ftpfs.h @@ -98,10 +98,10 @@ extern "C" { * @brief FTP file system IO control requests. */ typedef enum { - RTEMS_FTPFS_IOCTL_GET_VERBOSE = _IOR( 'd', 1, bool *), - RTEMS_FTPFS_IOCTL_SET_VERBOSE = _IOW( 'd', 1, bool *), - RTEMS_FTPFS_IOCTL_GET_TIMEOUT = _IOR( 'd', 2, struct timeval *), - RTEMS_FTPFS_IOCTL_SET_TIMEOUT = _IOW( 'd', 2, struct timeval *) + RTEMS_FTPFS_IOCTL_GET_VERBOSE = _IOR( 'd', 1, bool * ), + RTEMS_FTPFS_IOCTL_SET_VERBOSE = _IOW( 'd', 1, bool * ), + RTEMS_FTPFS_IOCTL_GET_TIMEOUT = _IOR( 'd', 2, struct timeval * ), + RTEMS_FTPFS_IOCTL_SET_TIMEOUT = _IOW( 'd', 2, struct timeval * ) } rtems_ftpfs_ioctl_numbers; /** @@ -111,7 +111,10 @@ typedef enum { * If @a mount_point is @c NULL the default mount point * @ref RTEMS_FTPFS_MOUNT_POINT_DEFAULT will be used. */ -rtems_status_code rtems_ftpfs_get_verbose( const char *mount_point, bool *verbose); +rtems_status_code rtems_ftpfs_get_verbose( + const char *mount_point, + bool *verbose +); /** * @brief Enables or disables the verbose mode if @a verbose is @c true or @@ -123,7 +126,10 @@ rtems_status_code rtems_ftpfs_get_verbose( const char *mount_point, bool *verbos * If @a mount_point is @c NULL the default mount point * @ref RTEMS_FTPFS_MOUNT_POINT_DEFAULT will be used. */ -rtems_status_code rtems_ftpfs_set_verbose( const char *mount_point, bool verbose); +rtems_status_code rtems_ftpfs_set_verbose( + const char *mount_point, + bool verbose +); /** * @brief Returns the current timeout value in @a timeout for the file system @@ -133,7 +139,7 @@ rtems_status_code rtems_ftpfs_set_verbose( const char *mount_point, bool verbose * @ref RTEMS_FTPFS_MOUNT_POINT_DEFAULT will be used. */ rtems_status_code rtems_ftpfs_get_timeout( - const char *mount_point, + const char *mount_point, struct timeval *timeout ); @@ -149,7 +155,7 @@ rtems_status_code rtems_ftpfs_get_timeout( * @ref RTEMS_FTPFS_MOUNT_POINT_DEFAULT will be used. */ rtems_status_code rtems_ftpfs_set_timeout( - const char *mount_point, + const char *mount_point, const struct timeval *timeout ); @@ -160,7 +166,7 @@ rtems_status_code rtems_ftpfs_set_timeout( */ int rtems_ftpfs_initialize( rtems_filesystem_mount_table_entry_t *mt_entry, - const void *data + const void *data ); #ifdef __cplusplus diff --git a/cpukit/include/rtems/tftp.h b/cpukit/include/rtems/tftp.h index 6df3866711..36f6e3007a 100644 --- a/cpukit/include/rtems/tftp.h +++ b/cpukit/include/rtems/tftp.h @@ -57,7 +57,7 @@ extern "C" { */ int rtems_tftpfs_initialize( rtems_filesystem_mount_table_entry_t *mt_entry, - const void *data + const void *data ); /** @@ -288,9 +288,7 @@ typedef struct tftp_net_config { * The values are set to the defaults defined in * @ref tftp_net_config "`type tftp_net_config`". */ -void tftp_initialize_net_config( - tftp_net_config *config -); +void tftp_initialize_net_config( tftp_net_config *config ); /** * @brief Opens and starts a TFTP client session to read or write a @@ -343,11 +341,11 @@ void tftp_initialize_net_config( * @return Returns a POSIX @c errno value in case an error occurred. */ int tftp_open( - const char *hostname, - const char *path, - bool is_for_reading, + const char *hostname, + const char *path, + bool is_for_reading, const tftp_net_config *config, - void **tftp_handle + void **tftp_handle ); /** @@ -373,11 +371,7 @@ int tftp_open( * into the buffer. If the return value is negative, an error occurred. * In this case the negated value is a POSIX @c errno value. */ -ssize_t tftp_read( - void *tftp_handle, - void *buffer, - size_t count -); +ssize_t tftp_read( void *tftp_handle, void *buffer, size_t count ); /** * @brief Write data to a TFTP server. @@ -403,11 +397,7 @@ ssize_t tftp_read( * If the return value is negative, an error occurred. In this case * the negated value is a POSIX @c errno value. */ -ssize_t tftp_write( - void *tftp_handle, - const void *buffer, - size_t count -); +ssize_t tftp_write( void *tftp_handle, const void *buffer, size_t count ); /** * @brief Close a TFTP client connection. @@ -431,9 +421,7 @@ ssize_t tftp_write( * @retval 0 When the client session was closed successfully. * @return Returns a POSIX @c errno value in case an error occurred. */ -int tftp_close( - void *tftp_handle -); +int tftp_close( void *tftp_handle ); /** @} */ diff --git a/cpukit/libfs/src/ftpfs/ftpfs.c b/cpukit/libfs/src/ftpfs/ftpfs.c index a9d1851aee..84f17eb644 100644 --- a/cpukit/libfs/src/ftpfs/ftpfs.c +++ b/cpukit/libfs/src/ftpfs/ftpfs.c @@ -58,9 +58,9 @@ #include #ifdef DEBUG - #define DEBUG_PRINTF(...) printf(__VA_ARGS__) + #define DEBUG_PRINTF( ... ) printf( __VA_ARGS__ ) #else - #define DEBUG_PRINTF(...) + #define DEBUG_PRINTF( ... ) #endif /** @@ -94,7 +94,7 @@ typedef struct { /** * Buffer for relpy data. */ - char reply_buffer [128]; + char reply_buffer[ 128 ]; /** * End of file flag. @@ -122,7 +122,7 @@ typedef struct { const char *filename; - char buffer []; + char buffer[]; } rtems_ftpfs_entry; /** @@ -151,26 +151,26 @@ static const rtems_filesystem_file_handlers_r rtems_ftpfs_handlers; static const rtems_filesystem_file_handlers_r rtems_ftpfs_root_handlers; -static bool rtems_ftpfs_use_timeout(const struct timeval *to) +static bool rtems_ftpfs_use_timeout( const struct timeval *to ) { return to->tv_sec != 0 || to->tv_usec != 0; } static int rtems_ftpfs_set_connection_timeout( - int socket, + int socket, const struct timeval *to ) { - if (rtems_ftpfs_use_timeout(to)) { + if ( rtems_ftpfs_use_timeout( to ) ) { int rv = 0; - rv = setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, to, sizeof(*to)); - if (rv != 0) { + rv = setsockopt( socket, SOL_SOCKET, SO_SNDTIMEO, to, sizeof( *to ) ); + if ( rv != 0 ) { return EIO; } - rv = setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, to, sizeof(*to)); - if (rv != 0) { + rv = setsockopt( socket, SOL_SOCKET, SO_RCVTIMEO, to, sizeof( *to ) ); + if ( rv != 0 ) { return EIO; } } @@ -179,41 +179,44 @@ static int rtems_ftpfs_set_connection_timeout( } static rtems_status_code rtems_ftpfs_do_ioctl( - const char *mount_point, + const char *mount_point, ioctl_command_t req, ... ) { rtems_status_code sc = RTEMS_SUCCESSFUL; - int rv = 0; - int fd = 0; - va_list ap; + int rv = 0; + int fd = 0; + va_list ap; - if (mount_point == NULL) { + if ( mount_point == NULL ) { mount_point = RTEMS_FTPFS_MOUNT_POINT_DEFAULT; } - fd = open(mount_point, O_RDWR); - if (fd < 0) { + fd = open( mount_point, O_RDWR ); + if ( fd < 0 ) { return RTEMS_INVALID_NAME; } - va_start(ap, req); - rv = ioctl(fd, req, va_arg(ap, void *)); - va_end(ap); - if (rv != 0) { + va_start( ap, req ); + rv = ioctl( fd, req, va_arg( ap, void * ) ); + va_end( ap ); + if ( rv != 0 ) { sc = RTEMS_INVALID_NUMBER; } - rv = close(fd); - if (rv != 0 && sc == RTEMS_SUCCESSFUL) { + rv = close( fd ); + if ( rv != 0 && sc == RTEMS_SUCCESSFUL ) { sc = RTEMS_IO_ERROR; } return sc; } -rtems_status_code rtems_ftpfs_get_verbose(const char *mount_point, bool *verbose) +rtems_status_code rtems_ftpfs_get_verbose( + const char *mount_point, + bool *verbose +) { return rtems_ftpfs_do_ioctl( mount_point, @@ -222,7 +225,10 @@ rtems_status_code rtems_ftpfs_get_verbose(const char *mount_point, bool *verbose ); } -rtems_status_code rtems_ftpfs_set_verbose(const char *mount_point, bool verbose) +rtems_status_code rtems_ftpfs_set_verbose( + const char *mount_point, + bool verbose +) { return rtems_ftpfs_do_ioctl( mount_point, @@ -232,7 +238,7 @@ rtems_status_code rtems_ftpfs_set_verbose(const char *mount_point, bool verbose) } rtems_status_code rtems_ftpfs_get_timeout( - const char *mount_point, + const char *mount_point, struct timeval *timeout ) { @@ -244,7 +250,7 @@ rtems_status_code rtems_ftpfs_get_timeout( } rtems_status_code rtems_ftpfs_set_timeout( - const char *mount_point, + const char *mount_point, const struct timeval *timeout ) { @@ -255,7 +261,7 @@ rtems_status_code rtems_ftpfs_set_timeout( ); } -typedef void (*rtems_ftpfs_reply_parser)( +typedef void ( *rtems_ftpfs_reply_parser )( const char * /* reply fragment */, size_t /* reply fragment length */, void * /* parser argument */ @@ -280,29 +286,30 @@ typedef enum { #define RTEMS_FTPFS_REPLY_SIZE 3 -static bool rtems_ftpfs_is_reply_code_valid(unsigned char *reply) +static bool rtems_ftpfs_is_reply_code_valid( unsigned char *reply ) { - return isdigit(reply [0]) && isdigit(reply [1]) && isdigit(reply [2]); + return isdigit( reply[ 0 ] ) && isdigit( reply[ 1 ] ) && + isdigit( reply[ 2 ] ); } static rtems_ftpfs_reply rtems_ftpfs_get_reply( - rtems_ftpfs_entry *e, + rtems_ftpfs_entry *e, rtems_ftpfs_reply_parser parser, - void *parser_arg, - bool verbose + void *parser_arg, + bool verbose ) { rtems_ftpfs_reply_state state = RTEMS_FTPFS_REPLY_START; - unsigned char reply_code [RTEMS_FTPFS_REPLY_SIZE] = { 'a', 'a', 'a' }; - size_t reply_code_index = 0; + unsigned char reply_code[ RTEMS_FTPFS_REPLY_SIZE ] = { 'a', 'a', 'a' }; + size_t reply_code_index = 0; - while (state != RTEMS_FTPFS_REPLY_DONE) { - char *buf = NULL; + while ( state != RTEMS_FTPFS_REPLY_DONE ) { + char *buf = NULL; size_t i = 0; size_t n = 0; /* Receive reply fragment from socket */ - if (e->reply_current == e->reply_end) { + if ( e->reply_current == e->reply_end ) { ssize_t rv = 0; e->reply_current = 0; @@ -310,37 +317,37 @@ static rtems_ftpfs_reply rtems_ftpfs_get_reply( rv = recv( e->ctrl_socket, - &e->reply_buffer [0], - sizeof(e->reply_buffer), + &e->reply_buffer[ 0 ], + sizeof( e->reply_buffer ), 0 ); - if (rv > 0) { + if ( rv > 0 ) { e->reply_end = (size_t) rv; } else { return RTEMS_FTPFS_REPLY_ERROR; } } - buf = &e->reply_buffer [e->reply_current]; + buf = &e->reply_buffer[ e->reply_current ]; n = e->reply_end - e->reply_current; /* Invoke parser if necessary */ - if (parser != NULL) { - parser(buf, n, parser_arg); + if ( parser != NULL ) { + parser( buf, n, parser_arg ); } /* Parse reply fragment */ - for (i = 0; i < n && state != RTEMS_FTPFS_REPLY_DONE; ++i) { - char c = buf [i]; + for ( i = 0; i < n && state != RTEMS_FTPFS_REPLY_DONE; ++i ) { + char c = buf[ i ]; - switch (state) { + switch ( state ) { case RTEMS_FTPFS_REPLY_START: - if (reply_code_index < RTEMS_FTPFS_REPLY_SIZE) { - reply_code [reply_code_index] = c; + if ( reply_code_index < RTEMS_FTPFS_REPLY_SIZE ) { + reply_code[ reply_code_index ] = c; ++reply_code_index; - } else if (rtems_ftpfs_is_reply_code_valid(reply_code)) { - if (c == '-') { + } else if ( rtems_ftpfs_is_reply_code_valid( reply_code ) ) { + if ( c == '-' ) { state = RTEMS_FTPFS_REPLY_MULTI_LINE; } else { state = RTEMS_FTPFS_REPLY_SINGLE_LINE; @@ -350,25 +357,25 @@ static rtems_ftpfs_reply rtems_ftpfs_get_reply( } break; case RTEMS_FTPFS_REPLY_SINGLE_LINE: - if (c == '\n') { + if ( c == '\n' ) { state = RTEMS_FTPFS_REPLY_DONE; } break; case RTEMS_FTPFS_REPLY_MULTI_LINE: - if (c == '\n') { + if ( c == '\n' ) { state = RTEMS_FTPFS_REPLY_MULTI_LINE_START; reply_code_index = 0; } break; case RTEMS_FTPFS_REPLY_MULTI_LINE_START: - if (reply_code_index < RTEMS_FTPFS_REPLY_SIZE) { - if (reply_code [reply_code_index] == c) { + if ( reply_code_index < RTEMS_FTPFS_REPLY_SIZE ) { + if ( reply_code[ reply_code_index ] == c ) { ++reply_code_index; } else { state = RTEMS_FTPFS_REPLY_MULTI_LINE; } } else { - if (c == ' ') { + if ( c == ' ' ) { state = RTEMS_FTPFS_REPLY_SINGLE_LINE; } else { state = RTEMS_FTPFS_REPLY_MULTI_LINE; @@ -381,54 +388,54 @@ static rtems_ftpfs_reply rtems_ftpfs_get_reply( } /* Be verbose if necessary */ - if (verbose) { - write(STDERR_FILENO, buf, i); + if ( verbose ) { + write( STDERR_FILENO, buf, i ); } /* Update reply index */ e->reply_current += i; } - return reply_code [0]; + return reply_code[ 0 ]; } static rtems_ftpfs_reply rtems_ftpfs_send_command_with_parser( - rtems_ftpfs_entry *e, - const char *cmd, - const char *arg, + rtems_ftpfs_entry *e, + const char *cmd, + const char *arg, rtems_ftpfs_reply_parser parser, - void *parser_arg, - bool verbose + void *parser_arg, + bool verbose ) { rtems_ftpfs_reply reply = RTEMS_FTPFS_REPLY_ERROR; - size_t cmd_len = strlen(cmd); - size_t arg_len = arg != NULL ? strlen(arg) : 0; - size_t len = cmd_len + arg_len + 2; - char *buf = malloc(len); + size_t cmd_len = strlen( cmd ); + size_t arg_len = arg != NULL ? strlen( arg ) : 0; + size_t len = cmd_len + arg_len + 2; + char *buf = malloc( len ); - if (buf != NULL) { + if ( buf != NULL ) { ssize_t n = 0; - char *buf_arg = buf + cmd_len; - char *buf_eol = buf_arg + arg_len; + char *buf_arg = buf + cmd_len; + char *buf_eol = buf_arg + arg_len; - memcpy(buf, cmd, cmd_len); - memcpy(buf_arg, arg, arg_len); - buf_eol [0] = '\r'; - buf_eol [1] = '\n'; + memcpy( buf, cmd, cmd_len ); + memcpy( buf_arg, arg, arg_len ); + buf_eol[ 0 ] = '\r'; + buf_eol[ 1 ] = '\n'; /* Send */ - n = send(e->ctrl_socket, buf, len, 0); - if (n == (ssize_t) len) { - if (verbose) { - write(STDERR_FILENO, buf, len); + n = send( e->ctrl_socket, buf, len, 0 ); + if ( n == (ssize_t) len ) { + if ( verbose ) { + write( STDERR_FILENO, buf, len ); } /* Reply */ - reply = rtems_ftpfs_get_reply(e, parser, parser_arg, verbose); + reply = rtems_ftpfs_get_reply( e, parser, parser_arg, verbose ); } - free(buf); + free( buf ); } return reply; @@ -436,9 +443,9 @@ static rtems_ftpfs_reply rtems_ftpfs_send_command_with_parser( static rtems_ftpfs_reply rtems_ftpfs_send_command( rtems_ftpfs_entry *e, - const char *cmd, - const char *arg, - bool verbose + const char *cmd, + const char *arg, + bool verbose ) { return rtems_ftpfs_send_command_with_parser( @@ -463,8 +470,8 @@ typedef enum { STATE_INVALID } split_state; -static int rtems_ftpfs_split_names ( - char *s, +static int rtems_ftpfs_split_names( + char *s, const char **user, const char **password, const char **hostname, @@ -472,63 +479,63 @@ static int rtems_ftpfs_split_names ( ) { split_state state = STATE_USER_NAME; - size_t len = strlen(s); - size_t i = 0; + size_t len = strlen( s ); + size_t i = 0; *user = s; - for (i = 0; i < len; ++i) { - char c = s [i]; + for ( i = 0; i < len; ++i ) { + char c = s[ i ]; - switch (state) { + switch ( state ) { case STATE_USER_NAME: - if (c == ':') { + if ( c == ':' ) { state = STATE_START_PASSWORD; - s [i] = '\0'; - } else if (c == '@') { + s[ i ] = '\0'; + } else if ( c == '@' ) { state = STATE_START_HOST_NAME; - s [i] = '\0'; - } else if (c == '/') { + s[ i ] = '\0'; + } else if ( c == '/' ) { state = STATE_START_HOST_NAME_OR_PATH; - s [i] = '\0'; + s[ i ] = '\0'; } break; case STATE_START_PASSWORD: state = STATE_PASSWORD; - *password = &s [i]; + *password = &s[ i ]; --i; break; case STATE_START_HOST_NAME: state = STATE_HOST_NAME; - *hostname = &s [i]; + *hostname = &s[ i ]; --i; break; case STATE_START_HOST_NAME_OR_PATH: - if (c == '@') { + if ( c == '@' ) { state = STATE_START_HOST_NAME; } else { state = STATE_DONE; - *path = &s [i]; + *path = &s[ i ]; goto done; } break; case STATE_START_PATH: state = STATE_DONE; - *path = &s [i]; + *path = &s[ i ]; goto done; case STATE_PASSWORD: - if (c == '@') { + if ( c == '@' ) { state = STATE_START_HOST_NAME; - s [i] = '\0'; - } else if (c == '/') { + s[ i ] = '\0'; + } else if ( c == '/' ) { state = STATE_START_HOST_NAME_OR_PATH; - s [i] = '\0'; + s[ i ] = '\0'; } break; case STATE_HOST_NAME: - if (c == '/') { + if ( c == '/' ) { state = STATE_START_PATH; - s [i] = '\0'; + s[ i ] = '\0'; } break; default: @@ -540,14 +547,14 @@ static int rtems_ftpfs_split_names ( done: /* This is a special case with no username and password */ - if (*hostname == NULL) { - *hostname = &s [0]; + if ( *hostname == NULL ) { + *hostname = &s[ 0 ]; *user = "anonymous"; *password = *user; } /* If we have no password use the user name */ - if (*password == NULL) { + if ( *password == NULL ) { *password = *user; } @@ -556,43 +563,43 @@ done: static socklen_t rtems_ftpfs_create_address( struct sockaddr_in *sa, - unsigned long address, - unsigned short port + unsigned long address, + unsigned short port ) { - memset(sa, 0, sizeof(*sa)); + memset( sa, 0, sizeof( *sa ) ); sa->sin_family = AF_INET; sa->sin_addr.s_addr = address; sa->sin_port = port; - sa->sin_len = sizeof(*sa); + sa->sin_len = sizeof( *sa ); - return sizeof(*sa); + return sizeof( *sa ); } static int rtems_ftpfs_close_data_connection( rtems_ftpfs_entry *e, - bool verbose, - bool error + bool verbose, + bool error ) { int eno = 0; /* Close data connection if necessary */ - if (e->data_socket >= 0) { - int rv = close(e->data_socket); + if ( e->data_socket >= 0 ) { + int rv = close( e->data_socket ); e->data_socket = -1; - if (rv != 0) { + if ( rv != 0 ) { eno = EIO; } /* For write connections we have to obtain the transfer reply */ - if (e->write && !error) { - rtems_ftpfs_reply reply = - rtems_ftpfs_get_reply(e, NULL, NULL, verbose); + if ( e->write && !error ) { + rtems_ftpfs_reply + reply = rtems_ftpfs_get_reply( e, NULL, NULL, verbose ); - if (reply != RTEMS_FTPFS_REPLY_2) { + if ( reply != RTEMS_FTPFS_REPLY_2 ) { eno = EIO; } } @@ -602,90 +609,86 @@ static int rtems_ftpfs_close_data_connection( } static int rtems_ftpfs_open_ctrl_connection( - rtems_ftpfs_entry *e, - bool verbose, + rtems_ftpfs_entry *e, + bool verbose, const struct timeval *timeout ) { - int rv = 0; - int eno = 0; - rtems_ftpfs_reply reply = RTEMS_FTPFS_REPLY_ERROR; - struct in_addr address = { .s_addr = 0 }; + int rv = 0; + int eno = 0; + rtems_ftpfs_reply reply = RTEMS_FTPFS_REPLY_ERROR; + struct in_addr address = { .s_addr = 0 }; struct sockaddr_in sa; - socklen_t size = 0; + socklen_t size = 0; /* Create the socket for the control connection */ - e->ctrl_socket = socket(AF_INET, SOCK_STREAM, 0); - if (e->ctrl_socket < 0) { + e->ctrl_socket = socket( AF_INET, SOCK_STREAM, 0 ); + if ( e->ctrl_socket < 0 ) { return ENOMEM; } /* Set up the server address from the hostname */ - if (inet_aton(e->hostname, &address) == 0) { + if ( inet_aton( e->hostname, &address ) == 0 ) { /* Try to get the address by name */ - struct hostent *he = gethostbyname(e->hostname); + struct hostent *he = gethostbyname( e->hostname ); - if (he != NULL) { - memcpy(&address, he->h_addr, sizeof(address)); + if ( he != NULL ) { + memcpy( &address, he->h_addr, sizeof( address ) ); } else { return ENOENT; } } - rtems_ftpfs_create_address(&sa, address.s_addr, htons(RTEMS_FTPFS_CTRL_PORT)); - DEBUG_PRINTF("server = %s\n", inet_ntoa(sa.sin_addr)); + rtems_ftpfs_create_address( + &sa, + address.s_addr, + htons( RTEMS_FTPFS_CTRL_PORT ) + ); + DEBUG_PRINTF( "server = %s\n", inet_ntoa( sa.sin_addr ) ); /* Open control connection */ - rv = connect( - e->ctrl_socket, - (struct sockaddr *) &sa, - sizeof(sa) - ); - if (rv != 0) { + rv = connect( e->ctrl_socket, (struct sockaddr *) &sa, sizeof( sa ) ); + if ( rv != 0 ) { return ENOENT; } /* Set control connection timeout */ - eno = rtems_ftpfs_set_connection_timeout(e->ctrl_socket, timeout); - if (eno != 0) { + eno = rtems_ftpfs_set_connection_timeout( e->ctrl_socket, timeout ); + if ( eno != 0 ) { return eno; } /* Get client address */ - size = rtems_ftpfs_create_address(&sa, INADDR_ANY, 0); - rv = getsockname( - e->ctrl_socket, - (struct sockaddr *) &sa, - &size - ); - if (rv != 0) { + size = rtems_ftpfs_create_address( &sa, INADDR_ANY, 0 ); + rv = getsockname( e->ctrl_socket, (struct sockaddr *) &sa, &size ); + if ( rv != 0 ) { return ENOMEM; } - e->client_address = ntohl(sa.sin_addr.s_addr); - DEBUG_PRINTF("client = %s\n", inet_ntoa(sa.sin_addr)); + e->client_address = ntohl( sa.sin_addr.s_addr ); + DEBUG_PRINTF( "client = %s\n", inet_ntoa( sa.sin_addr ) ); /* Now we should get a welcome message from the server */ - reply = rtems_ftpfs_get_reply(e, NULL, NULL, verbose); - if (reply != RTEMS_FTPFS_REPLY_2) { + reply = rtems_ftpfs_get_reply( e, NULL, NULL, verbose ); + if ( reply != RTEMS_FTPFS_REPLY_2 ) { return ENOENT; } /* Send USER command */ - reply = rtems_ftpfs_send_command(e, "USER ", e->user, verbose); - if (reply == RTEMS_FTPFS_REPLY_3) { + reply = rtems_ftpfs_send_command( e, "USER ", e->user, verbose ); + if ( reply == RTEMS_FTPFS_REPLY_3 ) { /* Send PASS command */ - reply = rtems_ftpfs_send_command(e, "PASS ", e->password, verbose); - if (reply != RTEMS_FTPFS_REPLY_2) { + reply = rtems_ftpfs_send_command( e, "PASS ", e->password, verbose ); + if ( reply != RTEMS_FTPFS_REPLY_2 ) { return EACCES; } /* TODO: Some server may require an account */ - } else if (reply != RTEMS_FTPFS_REPLY_2) { + } else if ( reply != RTEMS_FTPFS_REPLY_2 ) { return EACCES; } /* Send TYPE command to set binary mode for all data transfers */ - reply = rtems_ftpfs_send_command(e, "TYPE I", NULL, verbose); - if (reply != RTEMS_FTPFS_REPLY_2) { + reply = rtems_ftpfs_send_command( e, "TYPE I", NULL, verbose ); + if ( reply != RTEMS_FTPFS_REPLY_2 ) { return EIO; } @@ -693,108 +696,96 @@ static int rtems_ftpfs_open_ctrl_connection( } static int rtems_ftpfs_open_data_connection_active( - rtems_ftpfs_entry *e, - const char *file_command, - bool verbose, + rtems_ftpfs_entry *e, + const char *file_command, + bool verbose, const struct timeval *timeout ) { - int rv = 0; - int eno = 0; - rtems_ftpfs_reply reply = RTEMS_FTPFS_REPLY_ERROR; + int rv = 0; + int eno = 0; + rtems_ftpfs_reply reply = RTEMS_FTPFS_REPLY_ERROR; struct sockaddr_in sa; - socklen_t size = 0; - int port_socket = -1; - char port_command [] = "PORT 000,000,000,000,000,000"; - uint16_t data_port = 0; + socklen_t size = 0; + int port_socket = -1; + char port_command[] = "PORT 000,000,000,000,000,000"; + uint16_t data_port = 0; /* Create port socket to establish a data data connection */ - port_socket = socket(AF_INET, SOCK_STREAM, 0); - if (port_socket < 0) { + port_socket = socket( AF_INET, SOCK_STREAM, 0 ); + if ( port_socket < 0 ) { eno = ENOMEM; goto cleanup; } /* Bind port socket */ - rtems_ftpfs_create_address(&sa, INADDR_ANY, 0); - rv = bind( - port_socket, - (struct sockaddr *) &sa, - sizeof(sa) - ); - if (rv != 0) { + rtems_ftpfs_create_address( &sa, INADDR_ANY, 0 ); + rv = bind( port_socket, (struct sockaddr *) &sa, sizeof( sa ) ); + if ( rv != 0 ) { eno = EBUSY; goto cleanup; } /* Get port number for data socket */ - size = rtems_ftpfs_create_address(&sa, INADDR_ANY, 0); - rv = getsockname( - port_socket, - (struct sockaddr *) &sa, - &size - ); - if (rv != 0) { + size = rtems_ftpfs_create_address( &sa, INADDR_ANY, 0 ); + rv = getsockname( port_socket, (struct sockaddr *) &sa, &size ); + if ( rv != 0 ) { eno = ENOMEM; goto cleanup; } - data_port = ntohs(sa.sin_port); + data_port = ntohs( sa.sin_port ); /* Send PORT command to set data connection port for server */ snprintf( port_command, - sizeof(port_command), + sizeof( port_command ), "PORT %lu,%lu,%lu,%lu,%lu,%lu", - (e->client_address >> 24) & 0xffUL, - (e->client_address >> 16) & 0xffUL, - (e->client_address >> 8) & 0xffUL, - (e->client_address >> 0) & 0xffUL, - (data_port >> 8) & 0xffUL, - (data_port >> 0) & 0xffUL + ( e->client_address >> 24 ) & 0xffUL, + ( e->client_address >> 16 ) & 0xffUL, + ( e->client_address >> 8 ) & 0xffUL, + ( e->client_address >> 0 ) & 0xffUL, + ( data_port >> 8 ) & 0xffUL, + ( data_port >> 0 ) & 0xffUL ); - reply = rtems_ftpfs_send_command(e, port_command, NULL, verbose); - if (reply != RTEMS_FTPFS_REPLY_2) { + reply = rtems_ftpfs_send_command( e, port_command, NULL, verbose ); + if ( reply != RTEMS_FTPFS_REPLY_2 ) { eno = ENOTSUP; goto cleanup; } /* Listen on port socket for incoming data connections */ - rv = listen(port_socket, 1); - if (rv != 0) { + rv = listen( port_socket, 1 ); + if ( rv != 0 ) { eno = EBUSY; goto cleanup; } /* Send RETR or STOR command with filename */ - reply = rtems_ftpfs_send_command(e, file_command, e->filename, verbose); - if (reply != RTEMS_FTPFS_REPLY_1) { + reply = rtems_ftpfs_send_command( e, file_command, e->filename, verbose ); + if ( reply != RTEMS_FTPFS_REPLY_1 ) { eno = EIO; goto cleanup; } /* Wait for connect on data connection if necessary */ - if (rtems_ftpfs_use_timeout(timeout)) { + if ( rtems_ftpfs_use_timeout( timeout ) ) { struct timeval to = *timeout; - fd_set fds; + fd_set fds; - FD_ZERO(&fds); - FD_SET(port_socket, &fds); + FD_ZERO( &fds ); + FD_SET( port_socket, &fds ); - rv = select(port_socket + 1, &fds, NULL, NULL, &to); - if (rv <= 0) { + rv = select( port_socket + 1, &fds, NULL, NULL, &to ); + if ( rv <= 0 ) { eno = EIO; goto cleanup; } } /* Accept data connection */ - size = sizeof(sa); - e->data_socket = accept( - port_socket, - (struct sockaddr *) &sa, - &size - ); - if (e->data_socket < 0) { + size = sizeof( sa ); + e->data_socket = accept( port_socket, (struct sockaddr *) &sa, &size ); + if ( e->data_socket < 0 ) { eno = EIO; goto cleanup; } @@ -802,9 +793,9 @@ static int rtems_ftpfs_open_data_connection_active( cleanup: /* Close port socket if necessary */ - if (port_socket >= 0) { - rv = close(port_socket); - if (rv != 0) { + if ( port_socket >= 0 ) { + rv = close( port_socket ); + if ( rv != 0 ) { eno = EIO; } } @@ -821,43 +812,39 @@ typedef enum { typedef struct { rtems_ftpfs_pasv_state state; - size_t index; - uint8_t data [6]; + size_t index; + uint8_t data[ 6 ]; } rtems_ftpfs_pasv_entry; -static void rtems_ftpfs_pasv_parser( - const char* buf, - size_t len, - void *arg -) +static void rtems_ftpfs_pasv_parser( const char *buf, size_t len, void *arg ) { rtems_ftpfs_pasv_entry *pe = arg; - size_t i = 0; + size_t i = 0; - for (i = 0; i < len; ++i) { - int c = buf [i]; + for ( i = 0; i < len; ++i ) { + int c = buf[ i ]; - switch (pe->state) { + switch ( pe->state ) { case RTEMS_FTPFS_PASV_START: - if (!isdigit(c)) { + if ( !isdigit( c ) ) { pe->state = RTEMS_FTPFS_PASV_JUNK; pe->index = 0; } break; case RTEMS_FTPFS_PASV_JUNK: - if (isdigit(c)) { + if ( isdigit( c ) ) { pe->state = RTEMS_FTPFS_PASV_DATA; - pe->data [pe->index] = (uint8_t) (c - '0'); + pe->data[ pe->index ] = (uint8_t) ( c - '0' ); } break; case RTEMS_FTPFS_PASV_DATA: - if (isdigit(c)) { - pe->data [pe->index] = - (uint8_t) (pe->data [pe->index] * 10 + c - '0'); - } else if (c == ',') { + if ( isdigit( c ) ) { + pe->data[ pe->index ] = (uint8_t) ( pe->data[ pe->index ] * 10 + c - + '0' ); + } else if ( c == ',' ) { ++pe->index; - if (pe->index < sizeof(pe->data)) { - pe->data [pe->index] = 0; + if ( pe->index < sizeof( pe->data ) ) { + pe->data[ pe->index ] = 0; } else { pe->state = RTEMS_FTPFS_PASV_DONE; } @@ -872,22 +859,22 @@ static void rtems_ftpfs_pasv_parser( } static int rtems_ftpfs_open_data_connection_passive( - rtems_ftpfs_entry *e, - const char *file_command, - bool verbose, + rtems_ftpfs_entry *e, + const char *file_command, + bool verbose, const struct timeval *timeout ) { (void) timeout; - int rv = 0; - rtems_ftpfs_reply reply = RTEMS_FTPFS_REPLY_ERROR; - struct sockaddr_in sa; - uint32_t data_address = 0; - uint16_t data_port = 0; + int rv = 0; + rtems_ftpfs_reply reply = RTEMS_FTPFS_REPLY_ERROR; + struct sockaddr_in sa; + uint32_t data_address = 0; + uint16_t data_port = 0; rtems_ftpfs_pasv_entry pe; - memset(&pe, 0, sizeof(pe)); + memset( &pe, 0, sizeof( pe ) ); /* Send PASV command */ reply = rtems_ftpfs_send_command_with_parser( @@ -898,40 +885,36 @@ static int rtems_ftpfs_open_data_connection_passive( &pe, verbose ); - if (reply != RTEMS_FTPFS_REPLY_2) { + if ( reply != RTEMS_FTPFS_REPLY_2 ) { return ENOTSUP; } - data_address = ((uint32_t)(pe.data [0]) << 24) - + ((uint32_t)(pe.data [1]) << 16) - + ((uint32_t)(pe.data [2]) << 8) - + ((uint32_t)(pe.data [3])); - data_port = (uint16_t) ((pe.data [4] << 8) + pe.data [5]); - rtems_ftpfs_create_address(&sa, htonl(data_address), htons(data_port)); + data_address = ( (uint32_t) ( pe.data[ 0 ] ) << 24 ) + + ( (uint32_t) ( pe.data[ 1 ] ) << 16 ) + + ( (uint32_t) ( pe.data[ 2 ] ) << 8 ) + + ( (uint32_t) ( pe.data[ 3 ] ) ); + data_port = (uint16_t) ( ( pe.data[ 4 ] << 8 ) + pe.data[ 5 ] ); + rtems_ftpfs_create_address( &sa, htonl( data_address ), htons( data_port ) ); DEBUG_PRINTF( "server data = %s:%u\n", - inet_ntoa(sa.sin_addr), - (unsigned) ntohs(sa.sin_port) + inet_ntoa( sa.sin_addr ), + (unsigned) ntohs( sa.sin_port ) ); /* Create data socket */ - e->data_socket = socket(AF_INET, SOCK_STREAM, 0); - if (e->data_socket < 0) { + e->data_socket = socket( AF_INET, SOCK_STREAM, 0 ); + if ( e->data_socket < 0 ) { return ENOMEM; } /* Open data connection */ - rv = connect( - e->data_socket, - (struct sockaddr *) &sa, - sizeof(sa) - ); - if (rv != 0) { + rv = connect( e->data_socket, (struct sockaddr *) &sa, sizeof( sa ) ); + if ( rv != 0 ) { return EIO; } /* Send RETR or STOR command with filename */ - reply = rtems_ftpfs_send_command(e, file_command, e->filename, verbose); - if (reply != RTEMS_FTPFS_REPLY_1) { + reply = rtems_ftpfs_send_command( e, file_command, e->filename, verbose ); + if ( reply != RTEMS_FTPFS_REPLY_1 ) { return EIO; } @@ -947,46 +930,42 @@ typedef enum { typedef struct { rtems_ftpfs_size_state state; - size_t index; - off_t size; + size_t index; + off_t size; } rtems_ftpfs_size_entry; -static void rtems_ftpfs_size_parser( - const char* buf, - size_t len, - void *arg -) +static void rtems_ftpfs_size_parser( const char *buf, size_t len, void *arg ) { rtems_ftpfs_size_entry *se = arg; - size_t i = 0; + size_t i = 0; - for (i = 0; se->size >= 0 && i < len; ++i, ++se->index) { - int c = buf [i]; + for ( i = 0; se->size >= 0 && i < len; ++i, ++se->index ) { + int c = buf[ i ]; - switch (se->state) { + switch ( se->state ) { case RTEMS_FTPFS_SIZE_START: - if (se->index == 2) { + if ( se->index == 2 ) { se->state = RTEMS_FTPFS_SIZE_SPACE; } break; case RTEMS_FTPFS_SIZE_SPACE: - if (c == ' ') { + if ( c == ' ' ) { se->state = RTEMS_FTPFS_SIZE_NUMBER; } else { se->size = -1; } break; case RTEMS_FTPFS_SIZE_NUMBER: - if (isdigit(c)) { + if ( isdigit( c ) ) { se->size = 10 * se->size + c - '0'; - } else if (c == '\r') { + } else if ( c == '\r' ) { se->state = RTEMS_FTPFS_SIZE_NL; } else { se->size = -1; } break; case RTEMS_FTPFS_SIZE_NL: - if (c != '\n') { + if ( c != '\n' ) { se->size = -1; } break; @@ -997,16 +976,16 @@ static void rtems_ftpfs_size_parser( } } -static void rtems_ftpfs_get_file_size(rtems_ftpfs_entry *e, bool verbose) +static void rtems_ftpfs_get_file_size( rtems_ftpfs_entry *e, bool verbose ) { - if (e->file_size < 0) { - if (e->write) { + if ( e->file_size < 0 ) { + if ( e->write ) { e->file_size = 0; } else { rtems_ftpfs_size_entry se; - rtems_ftpfs_reply reply = RTEMS_FTPFS_REPLY_ERROR; + rtems_ftpfs_reply reply = RTEMS_FTPFS_REPLY_ERROR; - memset(&se, 0, sizeof(se)); + memset( &se, 0, sizeof( se ) ); reply = rtems_ftpfs_send_command_with_parser( e, @@ -1016,7 +995,7 @@ static void rtems_ftpfs_get_file_size(rtems_ftpfs_entry *e, bool verbose) &se, verbose ); - if (reply == RTEMS_FTPFS_REPLY_2 && se.size >= 0) { + if ( reply == RTEMS_FTPFS_REPLY_2 && se.size >= 0 ) { e->file_size = se.size; } else { e->file_size = 0; @@ -1027,36 +1006,35 @@ static void rtems_ftpfs_get_file_size(rtems_ftpfs_entry *e, bool verbose) static int rtems_ftpfs_open( rtems_libio_t *iop, - const char *path, - int oflag, - mode_t mode + const char *path, + int oflag, + mode_t mode ) { (void) path; (void) oflag; (void) mode; - int eno = 0; - rtems_ftpfs_entry *e = iop->pathinfo.node_access; + int eno = 0; + rtems_ftpfs_entry *e = iop->pathinfo.node_access; rtems_ftpfs_mount_entry *me = iop->pathinfo.mt_entry->fs_info; - bool verbose = me->verbose; - const struct timeval *timeout = &me->timeout; + bool verbose = me->verbose; + const struct timeval *timeout = &me->timeout; - e->write = rtems_libio_iop_is_writeable(iop); + e->write = rtems_libio_iop_is_writeable( iop ); /* Check for either read-only or write-only flags */ if ( - rtems_libio_iop_is_writeable(iop) - && rtems_libio_iop_is_readable(iop) + rtems_libio_iop_is_writeable( iop ) && rtems_libio_iop_is_readable( iop ) ) { eno = ENOTSUP; } - if (eno == 0) { - rtems_ftpfs_get_file_size(e, verbose); + if ( eno == 0 ) { + rtems_ftpfs_get_file_size( e, verbose ); } - if (eno == 0) { + if ( eno == 0 ) { const char *file_command = e->write ? "STOR " : "RETR "; /* Open passive data connection */ @@ -1066,7 +1044,7 @@ static int rtems_ftpfs_open( verbose, timeout ); - if (eno == ENOTSUP) { + if ( eno == ENOTSUP ) { /* Open active data connection */ eno = rtems_ftpfs_open_data_connection_active( e, @@ -1078,77 +1056,77 @@ static int rtems_ftpfs_open( } /* Set data connection timeout */ - if (eno == 0) { - eno = rtems_ftpfs_set_connection_timeout(e->data_socket, timeout); + if ( eno == 0 ) { + eno = rtems_ftpfs_set_connection_timeout( e->data_socket, timeout ); } - if (eno == 0) { + if ( eno == 0 ) { return 0; } else { - rtems_ftpfs_close_data_connection(e, verbose, true); + rtems_ftpfs_close_data_connection( e, verbose, true ); - rtems_set_errno_and_return_minus_one(eno); + rtems_set_errno_and_return_minus_one( eno ); } } static ssize_t rtems_ftpfs_read( rtems_libio_t *iop, - void *buffer, - size_t count + void *buffer, + size_t count ) { - rtems_ftpfs_entry *e = iop->pathinfo.node_access; + rtems_ftpfs_entry *e = iop->pathinfo.node_access; const rtems_ftpfs_mount_entry *me = iop->pathinfo.mt_entry->fs_info; - bool verbose = me->verbose; - char *in = buffer; - size_t todo = count; + bool verbose = me->verbose; + char *in = buffer; + size_t todo = count; - if (e->eof) { + if ( e->eof ) { return 0; } - while (todo > 0) { - ssize_t rv = recv(e->data_socket, in, todo, 0); + while ( todo > 0 ) { + ssize_t rv = recv( e->data_socket, in, todo, 0 ); - if (rv <= 0) { - if (rv == 0) { - rtems_ftpfs_reply reply = - rtems_ftpfs_get_reply(e, NULL, NULL, verbose); + if ( rv <= 0 ) { + if ( rv == 0 ) { + rtems_ftpfs_reply + reply = rtems_ftpfs_get_reply( e, NULL, NULL, verbose ); - if (reply == RTEMS_FTPFS_REPLY_2) { + if ( reply == RTEMS_FTPFS_REPLY_2 ) { e->eof = true; break; } } - rtems_set_errno_and_return_minus_one(EIO); + rtems_set_errno_and_return_minus_one( EIO ); } in += rv; todo -= (size_t) rv; } - return (ssize_t) (count - todo); + return (ssize_t) ( count - todo ); } static ssize_t rtems_ftpfs_write( rtems_libio_t *iop, - const void *buffer, - size_t count + const void *buffer, + size_t count ) { rtems_ftpfs_entry *e = iop->pathinfo.node_access; - const char *out = buffer; - size_t todo = count; + const char *out = buffer; + size_t todo = count; - while (todo > 0) { - ssize_t rv = send(e->data_socket, out, todo, 0); + while ( todo > 0 ) { + ssize_t rv = send( e->data_socket, out, todo, 0 ); - if (rv <= 0) { - if (rv == 0) { + if ( rv <= 0 ) { + if ( rv == 0 ) { break; } else { - rtems_set_errno_and_return_minus_one(EIO); + rtems_set_errno_and_return_minus_one( EIO ); } } @@ -1158,24 +1136,24 @@ static ssize_t rtems_ftpfs_write( e->file_size += rv; } - return (ssize_t) (count - todo); + return (ssize_t) ( count - todo ); } -static int rtems_ftpfs_close(rtems_libio_t *iop) +static int rtems_ftpfs_close( rtems_libio_t *iop ) { - rtems_ftpfs_entry *e = iop->pathinfo.node_access; + rtems_ftpfs_entry *e = iop->pathinfo.node_access; const rtems_ftpfs_mount_entry *me = iop->pathinfo.mt_entry->fs_info; - int eno = rtems_ftpfs_close_data_connection(e, me->verbose, false); + int eno = rtems_ftpfs_close_data_connection( e, me->verbose, false ); - if (eno == 0) { + if ( eno == 0 ) { return 0; } else { - rtems_set_errno_and_return_minus_one(eno); + rtems_set_errno_and_return_minus_one( eno ); } } /* Dummy version to let fopen(*,"w") work properly */ -static int rtems_ftpfs_ftruncate(rtems_libio_t *iop, off_t count) +static int rtems_ftpfs_ftruncate( rtems_libio_t *iop, off_t count ) { (void) iop; (void) count; @@ -1183,30 +1161,28 @@ static int rtems_ftpfs_ftruncate(rtems_libio_t *iop, off_t count) return 0; } -static void rtems_ftpfs_eval_path( - rtems_filesystem_eval_path_context_t *self -) +static void rtems_ftpfs_eval_path( rtems_filesystem_eval_path_context_t *self ) { int eno = 0; - rtems_filesystem_eval_path_eat_delimiter(self); + rtems_filesystem_eval_path_eat_delimiter( self ); - if (rtems_filesystem_eval_path_has_path(self)) { - const char *path = rtems_filesystem_eval_path_get_path(self); - size_t pathlen = rtems_filesystem_eval_path_get_pathlen(self); - rtems_ftpfs_entry *e = calloc(1, sizeof(*e) + pathlen + 1); + if ( rtems_filesystem_eval_path_has_path( self ) ) { + const char *path = rtems_filesystem_eval_path_get_path( self ); + size_t pathlen = rtems_filesystem_eval_path_get_pathlen( self ); + rtems_ftpfs_entry *e = calloc( 1, sizeof( *e ) + pathlen + 1 ); - rtems_filesystem_eval_path_clear_path(self); + rtems_filesystem_eval_path_clear_path( self ); - if (e != NULL) { - memcpy(e->buffer, path, pathlen); + if ( e != NULL ) { + memcpy( e->buffer, path, pathlen ); eno = rtems_ftpfs_split_names( - e->buffer, - &e->user, - &e->password, - &e->hostname, - &e->filename + e->buffer, + &e->user, + &e->password, + &e->hostname, + &e->filename ); DEBUG_PRINTF( @@ -1216,9 +1192,9 @@ static void rtems_ftpfs_eval_path( e->filename ); - if (eno == 0) { - rtems_filesystem_location_info_t *currentloc = - rtems_filesystem_eval_path_get_currentloc(self); + if ( eno == 0 ) { + rtems_filesystem_location_info_t + *currentloc = rtems_filesystem_eval_path_get_currentloc( self ); rtems_ftpfs_mount_entry *me = currentloc->mt_entry->fs_info; rtems_libio_lock(); @@ -1229,46 +1205,44 @@ static void rtems_ftpfs_eval_path( e->file_size = -1; e->ctrl_socket = -1; - eno = rtems_ftpfs_open_ctrl_connection( - e, - me->verbose, - &me->timeout - ); - if (eno == 0) { + eno = rtems_ftpfs_open_ctrl_connection( e, me->verbose, &me->timeout ); + if ( eno == 0 ) { currentloc->node_access = e; currentloc->handlers = &rtems_ftpfs_handlers; } } - if (eno != 0) { - free(e); + if ( eno != 0 ) { + free( e ); } } else { eno = ENOMEM; } } - if (eno != 0) { - rtems_filesystem_eval_path_error(self, eno); + if ( eno != 0 ) { + rtems_filesystem_eval_path_error( self, eno ); } } -static void rtems_ftpfs_free_node(const rtems_filesystem_location_info_t *loc) +static void rtems_ftpfs_free_node( + const rtems_filesystem_location_info_t *loc +) { rtems_ftpfs_entry *e = loc->node_access; /* The root node handler has no entry */ - if (e != NULL) { + if ( e != NULL ) { const rtems_ftpfs_mount_entry *me = loc->mt_entry->fs_info; /* Close control connection if necessary */ - if (e->ctrl_socket >= 0) { - rtems_ftpfs_send_command(e, "QUIT", NULL, me->verbose); + if ( e->ctrl_socket >= 0 ) { + rtems_ftpfs_send_command( e, "QUIT", NULL, me->verbose ); - close(e->ctrl_socket); + close( e->ctrl_socket ); } - free(e); + free( e ); } } @@ -1279,12 +1253,12 @@ int rtems_ftpfs_initialize( { (void) d; - rtems_ftpfs_mount_entry *me = calloc(1, sizeof(*me)); + rtems_ftpfs_mount_entry *me = calloc( 1, sizeof( *me ) ); /* Mount entry for FTP file system instance */ e->fs_info = me; - if (e->fs_info == NULL) { - rtems_set_errno_and_return_minus_one(ENOMEM); + if ( e->fs_info == NULL ) { + rtems_set_errno_and_return_minus_one( ENOMEM ); } me->verbose = false; me->timeout.tv_sec = 0; @@ -1300,28 +1274,26 @@ int rtems_ftpfs_initialize( return 0; } -static void rtems_ftpfs_unmount_me( - rtems_filesystem_mount_table_entry_t *e -) +static void rtems_ftpfs_unmount_me( rtems_filesystem_mount_table_entry_t *e ) { - free(e->fs_info); + free( e->fs_info ); } static int rtems_ftpfs_ioctl( - rtems_libio_t *iop, + rtems_libio_t *iop, ioctl_command_t command, - void *arg + void *arg ) { rtems_ftpfs_mount_entry *me = iop->pathinfo.mt_entry->fs_info; - bool *verbose = arg; - struct timeval *timeout = arg; + bool *verbose = arg; + struct timeval *timeout = arg; - if (arg == NULL) { - rtems_set_errno_and_return_minus_one(EINVAL); + if ( arg == NULL ) { + rtems_set_errno_and_return_minus_one( EINVAL ); } - switch (command) { + switch ( command ) { case RTEMS_FTPFS_IOCTL_GET_VERBOSE: *verbose = me->verbose; break; @@ -1335,7 +1307,7 @@ static int rtems_ftpfs_ioctl( me->timeout = *timeout; break; default: - rtems_set_errno_and_return_minus_one(EINVAL); + rtems_set_errno_and_return_minus_one( EINVAL ); } return 0; @@ -1349,31 +1321,31 @@ static int rtems_ftpfs_ioctl( */ static int rtems_ftpfs_fstat( const rtems_filesystem_location_info_t *loc, - struct stat *st + struct stat *st ) { - int eno = 0; + int eno = 0; rtems_ftpfs_entry *e = loc->node_access; /* FIXME */ st->st_ino = e->ino; - st->st_dev = rtems_filesystem_make_dev_t(0xcc494cd6U, 0x1d970b4dU); + st->st_dev = rtems_filesystem_make_dev_t( 0xcc494cd6U, 0x1d970b4dU ); st->st_mode = S_IFREG | S_IRWXU | S_IRWXG | S_IRWXO; - if (e->do_size_command) { + if ( e->do_size_command ) { const rtems_ftpfs_mount_entry *me = loc->mt_entry->fs_info; - rtems_ftpfs_get_file_size(e, me->verbose); + rtems_ftpfs_get_file_size( e, me->verbose ); st->st_size = e->file_size; } else { e->do_size_command = true; } - if (eno == 0) { + if ( eno == 0 ) { return 0; } else { - rtems_set_errno_and_return_minus_one(eno); + rtems_set_errno_and_return_minus_one( eno ); } } diff --git a/cpukit/libfs/src/ftpfs/tftpDriver.c b/cpukit/libfs/src/ftpfs/tftpDriver.c index 1a8d06b7a3..3394f431b8 100644 --- a/cpukit/libfs/src/ftpfs/tftpDriver.c +++ b/cpukit/libfs/src/ftpfs/tftpDriver.c @@ -71,37 +71,37 @@ /* * Range of UDP ports to try */ -#define UDP_PORT_BASE 3180 +#define UDP_PORT_BASE 3180 /* * Default limits */ -#define PACKET_FIRST_TIMEOUT_MILLISECONDS 400L -#define TFTP_WINDOW_SIZE_MIN 1 -#define TFTP_BLOCK_SIZE_MIN 8 -#define TFTP_BLOCK_SIZE_MAX 65464 +#define PACKET_FIRST_TIMEOUT_MILLISECONDS 400L +#define TFTP_WINDOW_SIZE_MIN 1 +#define TFTP_BLOCK_SIZE_MIN 8 +#define TFTP_BLOCK_SIZE_MAX 65464 -#define TFTP_BLOCK_SIZE_OPTION "blksize" -#define TFTP_WINDOW_SIZE_OPTION "windowsize" -#define TFTP_DECIMAL_BASE 10 +#define TFTP_BLOCK_SIZE_OPTION "blksize" +#define TFTP_WINDOW_SIZE_OPTION "windowsize" +#define TFTP_DECIMAL_BASE 10 -#define TFTP_DEFAULT_SERVER_PORT 69 +#define TFTP_DEFAULT_SERVER_PORT 69 /* * These values are suggested by RFC 7440. */ -#define TFTP_RFC7440_DATA_RETRANSMISSIONS 6 -#define TFTP_RFC7440_TIMEOUT_MILLISECONDS 1000 +#define TFTP_RFC7440_DATA_RETRANSMISSIONS 6 +#define TFTP_RFC7440_TIMEOUT_MILLISECONDS 1000 /* * 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 -#define TFTP_OPCODE_OACK 6 +#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 +#define TFTP_OPCODE_OACK 6 /* * TFTP error codes @@ -120,10 +120,10 @@ * Special return values for process_*_packet() functions * (other return values are POSIX errors) */ -#define GOT_EXPECTED_PACKET 0 +#define GOT_EXPECTED_PACKET 0 #define GOT_DUPLICATE_OF_CURRENT_PACKET -1 -#define GOT_OLD_PACKET -2 -#define GOT_FIRST_OUT_OF_ORDER_PACKET -3 +#define GOT_OLD_PACKET -2 +#define GOT_FIRST_OUT_OF_ORDER_PACKET -3 /* * Special argument value for getPacket() @@ -136,87 +136,89 @@ */ #define DO_NOT_SEND_PACKET 0 -#define PKT_SIZE_FROM_BLK_SIZE(_blksize) ((_blksize) + 2 * sizeof (uint16_t)) -#define BLK_SIZE_FROM_PKT_SIZE(_pktsize) ((_pktsize) - 2 * sizeof (uint16_t)) -#define MUST_SEND_OPTIONS(_options) (\ - (_options).block_size != TFTP_RFC1350_BLOCK_SIZE || \ - (_options).window_size != TFTP_RFC1350_WINDOW_SIZE ) +#define PKT_SIZE_FROM_BLK_SIZE( _blksize ) \ + ( ( _blksize ) + 2 * sizeof( uint16_t ) ) +#define BLK_SIZE_FROM_PKT_SIZE( _pktsize ) \ + ( ( _pktsize ) - 2 * sizeof( uint16_t ) ) +#define MUST_SEND_OPTIONS( _options ) \ + ( ( _options ).block_size != TFTP_RFC1350_BLOCK_SIZE || \ + ( _options ).window_size != TFTP_RFC1350_WINDOW_SIZE ) /* * Packets transferred between machines */ union tftpPacket { - /* + /* * RRQ/WRQ packet */ - struct tftpRWRQ { - uint16_t opcode; - char filename_mode[]; - } tftpRWRQ; + struct tftpRWRQ { + uint16_t opcode; + char filename_mode[]; + } tftpRWRQ; - /* + /* * DATA packet */ - struct tftpDATA { - uint16_t opcode; - uint16_t blocknum; - uint8_t data[]; - } tftpDATA; + struct tftpDATA { + uint16_t opcode; + uint16_t blocknum; + uint8_t data[]; + } tftpDATA; - /* + /* * ACK packet */ - struct tftpACK { - uint16_t opcode; - uint16_t blocknum; - } tftpACK; + struct tftpACK { + uint16_t opcode; + uint16_t blocknum; + } tftpACK; - /* + /* * OACK packet */ - struct tftpOACK { - uint16_t opcode; - char options[]; - } tftpOACK; + struct tftpOACK { + uint16_t opcode; + char options[]; + } tftpOACK; - /* + /* * ERROR packet */ - struct tftpERROR { - uint16_t opcode; - uint16_t errorCode; - char errorMessage[]; - } tftpERROR; + struct tftpERROR { + uint16_t opcode; + uint16_t errorCode; + char errorMessage[]; + } tftpERROR; }; /* * State of each TFTP stream */ struct tftpStream { - /* + /* * Buffer for storing packets for sending and receiving. Can point * to the same address when only one buffer is needed for reading. */ - union tftpPacket *receive_buf; - union tftpPacket *send_buf; + union tftpPacket *receive_buf; + union tftpPacket *send_buf; - /* + /* * Current block number - i.e. the block currently send or received */ - uint16_t blocknum; + uint16_t blocknum; - /* + /* * Size of the data area in a DATA single packet. */ - size_t block_size; + size_t block_size; - /* + /* * The maximum size of a packet. It depends linearly on the block_size. * The receive_buf and (the packets in) the send_buf are of this size. */ - size_t packet_size; + size_t packet_size; - /* + /* * The number of packets which can be stored in the send buffer. * During option negotiation and for reading a file from the server * only a buffer for a single packet is needed. In those cases, this @@ -227,66 +229,66 @@ struct tftpStream { * Packet N is stored in * send_buf + packet_size * (N % send_buf_size_in_pkts) */ - uint16_t send_buf_size_in_pkts; + uint16_t send_buf_size_in_pkts; - /* + /* * When writing files with windowsize > 1, the number of the completely * filled packet with the highest block number in the send buffer. * When the user calls write(), the data will be written into * the block after this one. */ - uint16_t blocknum_last_filled; + uint16_t blocknum_last_filled; - /* + /* * When writing files with windowsize > 1, the number of the packet * which is the last one in the whole file (i.e. the user * called close()). This block is never full (but maybe empty). */ - uint16_t blocknum_eof_block; + uint16_t blocknum_eof_block; - /* + /* * Data transfer socket */ - int socket; - struct sockaddr_in myAddress; - struct sockaddr_in farAddress; + int socket; + struct sockaddr_in myAddress; + struct sockaddr_in farAddress; - /* + /* * Indices into buffer * In case of sending a file with windowsize > 1, these values apply * only to the packet with the highest number in the send buffer * (blocknum_last_filled + 1). */ - int nleft; - size_t nused; + int nleft; + size_t nused; - /* + /* * Flags */ - int firstReply; - bool at_eof; - bool is_for_reading; + int firstReply; + bool at_eof; + bool is_for_reading; - /* + /* * Function pointers and members for use by communicate_with_server(). */ - ssize_t (*prepare_packet_for_sending) ( - struct tftpStream *tp, - bool force_retransmission, - union tftpPacket **send_buf, - bool *wait_for_packet_reception, - const void *create_packet_data - ); - int (*process_data_packet) (struct tftpStream *tp, ssize_t len); - int (*process_ack_packet) (struct tftpStream *tp, ssize_t len); - int (*process_oack_packet) (struct tftpStream *tp, ssize_t len); - int (*process_error_packet) (struct tftpStream *tp, ssize_t len); - int retransmission_error_code; - bool ignore_out_of_order_packets; - int32_t blocknum_of_first_packet_of_window; - int error; + ssize_t ( *prepare_packet_for_sending )( + struct tftpStream *tp, + bool force_retransmission, + union tftpPacket **send_buf, + bool *wait_for_packet_reception, + const void *create_packet_data + ); + int ( *process_data_packet )( struct tftpStream *tp, ssize_t len ); + int ( *process_ack_packet )( struct tftpStream *tp, ssize_t len ); + int ( *process_oack_packet )( struct tftpStream *tp, ssize_t len ); + int ( *process_error_packet )( struct tftpStream *tp, ssize_t len ); + int retransmission_error_code; + bool ignore_out_of_order_packets; + int32_t blocknum_of_first_packet_of_window; + int error; - /* + /* * Configuration and TFTP options * * * config.options are options desired by the user (i.e. the values @@ -294,353 +296,371 @@ struct tftpStream { * * server_options are the options agreed by the server * (the option values actually used for the transfer of data). */ - tftp_net_config config; - tftp_options server_options; + tftp_net_config config; + tftp_options server_options; }; /* * Forward declaration cannot be avoided. */ -static ssize_t prepare_data_packet_for_sending ( - struct tftpStream *tp, - bool force_retransmission, - union tftpPacket **send_buf, - bool *wait_for_packet_reception, - const void *path_name +static ssize_t prepare_data_packet_for_sending( + struct tftpStream *tp, + bool force_retransmission, + union tftpPacket **send_buf, + bool *wait_for_packet_reception, + const void *path_name ); -static ssize_t prepare_ack_packet_for_sending ( - struct tftpStream *tp, - bool force_retransmission, - union tftpPacket **send_buf, - bool *wait_for_packet_reception, - const void *path_name +static ssize_t prepare_ack_packet_for_sending( + struct tftpStream *tp, + bool force_retransmission, + union tftpPacket **send_buf, + bool *wait_for_packet_reception, + const void *path_name ); /* * Calculate the address of packet N in the send buffer */ -static union tftpPacket *get_send_buffer_packet ( - struct tftpStream *tp, - uint16_t packet_num +static union tftpPacket *get_send_buffer_packet( + struct tftpStream *tp, + uint16_t packet_num ) { - return (union tftpPacket *) ( ( (char *) tp->send_buf) + tp->packet_size * - (packet_num % tp->send_buf_size_in_pkts) ); + return (union tftpPacket *) ( ( (char *) tp->send_buf ) + + tp->packet_size * + ( packet_num % tp->send_buf_size_in_pkts ) ); } /* * Create read or write request */ -static size_t create_request ( - union tftpPacket *send_buf, - size_t data_size, - bool is_for_reading, - const char *path, - const tftp_options *options +static size_t create_request( + union tftpPacket *send_buf, + size_t data_size, + bool is_for_reading, + const char *path, + const tftp_options *options ) { size_t res_size; - char *cur = send_buf->tftpRWRQ.filename_mode; + char *cur = send_buf->tftpRWRQ.filename_mode; - send_buf->tftpRWRQ.opcode = htons ( - is_for_reading ? TFTP_OPCODE_RRQ : TFTP_OPCODE_WRQ + send_buf->tftpRWRQ.opcode = htons( + is_for_reading ? TFTP_OPCODE_RRQ : TFTP_OPCODE_WRQ ); - res_size = snprintf (cur, data_size, "%s%c%s", path, 0, "octet"); - if (res_size >= data_size) { - return -1; + res_size = snprintf( cur, data_size, "%s%c%s", path, 0, "octet" ); + if ( res_size >= data_size ) { + return -1; } res_size++; data_size -= res_size; cur += res_size; - if (options->block_size != TFTP_RFC1350_BLOCK_SIZE) { - res_size = snprintf ( - cur, - data_size, - "%s%c%"PRIu16, - TFTP_BLOCK_SIZE_OPTION, - 0, - options->block_size - ); - if (res_size >= data_size) { - return -1; - } - res_size++; - data_size -= res_size; - cur += res_size; + if ( options->block_size != TFTP_RFC1350_BLOCK_SIZE ) { + res_size = snprintf( + cur, + data_size, + "%s%c%" PRIu16, + TFTP_BLOCK_SIZE_OPTION, + 0, + options->block_size + ); + if ( res_size >= data_size ) { + return -1; + } + res_size++; + data_size -= res_size; + cur += res_size; } - if (options->window_size != TFTP_RFC1350_WINDOW_SIZE) { - res_size = snprintf ( - cur, - data_size, - "%s%c%"PRIu16, - TFTP_WINDOW_SIZE_OPTION, - 0, - options->window_size - ); - if (res_size >= data_size) { - return -1; - } - res_size++; - data_size -= res_size; - cur += res_size; + if ( options->window_size != TFTP_RFC1350_WINDOW_SIZE ) { + res_size = snprintf( + cur, + data_size, + "%s%c%" PRIu16, + TFTP_WINDOW_SIZE_OPTION, + 0, + options->window_size + ); + if ( res_size >= data_size ) { + return -1; + } + res_size++; + data_size -= res_size; + cur += res_size; } - return cur - (char *)send_buf; + return cur - (char *) send_buf; } -static bool parse_decimal_number ( - char **pos, - size_t *remain, - long min, - long max, - uint16_t *variable +static bool parse_decimal_number( + char **pos, + size_t *remain, + long min, + long max, + uint16_t *variable ) { - long value; - const char *start = *pos; - if (*remain < 2) { - return false; - } - value = strtoul(start, pos, TFTP_DECIMAL_BASE); - if (value < min || value > max || **pos != 0) { - return false; - } - *variable = (uint16_t) value; - (*pos)++; - *remain -= *pos - start; + long value; + const char *start = *pos; + if ( *remain < 2 ) { + return false; + } + value = strtoul( start, pos, TFTP_DECIMAL_BASE ); + if ( value < min || value > max || **pos != 0 ) { + return false; + } + *variable = (uint16_t) value; + ( *pos )++; + *remain -= *pos - start; - return true; + return true; } /* * Map error message */ -static int tftpErrno (uint16_t error_code) +static int tftpErrno( uint16_t error_code ) { - unsigned int tftpError; - static const int errorMap[] = { - EINVAL, - ENOENT, - EPERM, - ENOSPC, - EINVAL, - ENXIO, - EEXIST, - ESRCH, - ENOTSUP, /* Error: Option negotiation failed (RFC 2347) */ - }; + unsigned int tftpError; + static const int errorMap[] = { + EINVAL, + ENOENT, + EPERM, + ENOSPC, + EINVAL, + ENXIO, + EEXIST, + ESRCH, + ENOTSUP, /* Error: Option negotiation failed (RFC 2347) */ + }; - tftpError = ntohs (error_code); - if (tftpError < (sizeof errorMap / sizeof errorMap[0])) - return errorMap[tftpError]; - else - return 1000 + tftpError; + tftpError = ntohs( error_code ); + if ( tftpError < ( sizeof errorMap / sizeof errorMap[ 0 ] ) ) { + return errorMap[ tftpError ]; + } else { + return 1000 + tftpError; + } } /* * Parse options from an OACK packet */ -static bool parse_options ( - union tftpPacket *receive_buf, - size_t packet_size, - tftp_options *options_in, - tftp_options *options_out +static bool parse_options( + union tftpPacket *receive_buf, + size_t packet_size, + tftp_options *options_in, + tftp_options *options_out ) { - char *pos = receive_buf->tftpOACK.options; - size_t remain = packet_size - sizeof (receive_buf->tftpOACK.opcode); + char *pos = receive_buf->tftpOACK.options; + size_t remain = packet_size - sizeof( receive_buf->tftpOACK.opcode ); - /* + /* * Make sure there is a 0 byte in the end before comparing strings */ - if (remain > 0 && pos[remain - 1] != 0) { + if ( remain > 0 && pos[ remain - 1 ] != 0 ) { + return false; + } + + while ( remain > 0 ) { + if ( + strcasecmp( pos, TFTP_BLOCK_SIZE_OPTION ) == 0 && + options_in->block_size != TFTP_RFC1350_BLOCK_SIZE + ) { + remain -= sizeof( TFTP_BLOCK_SIZE_OPTION ); + pos += sizeof( TFTP_BLOCK_SIZE_OPTION ); + if ( !parse_decimal_number( + &pos, + &remain, + TFTP_BLOCK_SIZE_MIN, + options_in->block_size, + &options_out->block_size + ) ) { return false; + }; + + } else if ( + strcasecmp( pos, TFTP_WINDOW_SIZE_OPTION ) == 0 && + options_in->window_size != TFTP_RFC1350_WINDOW_SIZE + ) { + remain -= sizeof( TFTP_WINDOW_SIZE_OPTION ); + pos += sizeof( TFTP_WINDOW_SIZE_OPTION ); + if ( !parse_decimal_number( + &pos, + &remain, + TFTP_WINDOW_SIZE_MIN, + options_in->window_size, + &options_out->window_size + ) ) { + return false; + }; + + } else { + return false; /* Unknown option */ } + } - while (remain > 0) { - if (strcasecmp(pos, TFTP_BLOCK_SIZE_OPTION) == 0 && - options_in->block_size != TFTP_RFC1350_BLOCK_SIZE) { - remain -= sizeof (TFTP_BLOCK_SIZE_OPTION); - pos += sizeof (TFTP_BLOCK_SIZE_OPTION); - if (!parse_decimal_number ( - &pos, - &remain, - TFTP_BLOCK_SIZE_MIN, - options_in->block_size, - &options_out->block_size)) { - return false; - }; - - } else if (strcasecmp(pos, TFTP_WINDOW_SIZE_OPTION) == 0 && - options_in->window_size != TFTP_RFC1350_WINDOW_SIZE) { - remain -= sizeof (TFTP_WINDOW_SIZE_OPTION); - pos += sizeof (TFTP_WINDOW_SIZE_OPTION); - if (!parse_decimal_number ( - &pos, - &remain, - TFTP_WINDOW_SIZE_MIN, - options_in->window_size, - &options_out->window_size)) { - return false; - }; - - } else { - return false; /* Unknown option */ - } - } - - return true; + return true; } /* * Send an error message */ -static void send_error ( - struct tftpStream *tp, - struct sockaddr_in *to, - uint8_t error_code, - const char *error_message +static void send_error( + struct tftpStream *tp, + struct sockaddr_in *to, + uint8_t error_code, + const char *error_message ) { - int len; - struct { - uint16_t opcode; - uint16_t errorCode; - char errorMessage[80]; - } msg; + int len; + struct { + uint16_t opcode; + uint16_t errorCode; + char errorMessage[ 80 ]; + } msg; - /* + /* * Create the error packet (Unknown transfer ID). */ - msg.opcode = htons (TFTP_OPCODE_ERROR); - msg.errorCode = htons (error_code); - len = snprintf (msg.errorMessage, sizeof (msg.errorMessage), error_message); - if ((size_t) len >= sizeof (msg.errorMessage)) { - len = sizeof (msg.errorMessage) - 1; - } - len += sizeof (msg.opcode) + sizeof (msg.errorCode) + 1; + msg.opcode = htons( TFTP_OPCODE_ERROR ); + msg.errorCode = htons( error_code ); + len = snprintf( + msg.errorMessage, + sizeof( msg.errorMessage ), + error_message + ); + if ( (size_t) len >= sizeof( msg.errorMessage ) ) { + len = sizeof( msg.errorMessage ) - 1; + } + len += sizeof( msg.opcode ) + sizeof( msg.errorCode ) + 1; - /* + /* * Send it * * Ignoring result because error packets are sent once and maybe lost. */ - (void) sendto (tp->socket, (char *)&msg, len, 0, (struct sockaddr *)to, sizeof *to); + (void) sendto( + tp->socket, + (char *) &msg, + len, + 0, + (struct sockaddr *) to, + sizeof *to + ); } /* * Send a message to make the other end shut up */ -static void sendStifle (struct tftpStream *tp, struct sockaddr_in *to) +static void sendStifle( struct tftpStream *tp, struct sockaddr_in *to ) { - send_error (tp, to, TFTP_ERROR_CODE_UNKNOWN_ID, "GO AWAY"); + send_error( tp, to, TFTP_ERROR_CODE_UNKNOWN_ID, "GO AWAY" ); } /* * Wait for a packet */ -static ssize_t -getPacket (struct tftpStream *tp, int retryCount) +static ssize_t getPacket( struct tftpStream *tp, int retryCount ) { - ssize_t len; - struct timeval tv; - int flags = 0; + ssize_t len; + struct timeval tv; + int flags = 0; - if (retryCount == GET_PACKET_DONT_WAIT) { - flags = MSG_DONTWAIT; - } else if (retryCount == 0) { - tv.tv_sec = tp->config.first_timeout / 1000L; - tv.tv_usec = (tp->config.first_timeout % 1000L) * 1000L; - /* + if ( retryCount == GET_PACKET_DONT_WAIT ) { + flags = MSG_DONTWAIT; + } else if ( retryCount == 0 ) { + tv.tv_sec = tp->config.first_timeout / 1000L; + tv.tv_usec = ( tp->config.first_timeout % 1000L ) * 1000L; + /* * Ignoring result because all possible errors indicate wrong * arguments and these arguments are OK as tested by test suite. */ - (void) setsockopt (tp->socket, SOL_SOCKET, SO_RCVTIMEO, &tv, - sizeof tv); - } else { - tv.tv_sec = tp->config.timeout / 1000L; - tv.tv_usec = (tp->config.timeout % 1000L) * 1000L; - /* + (void) setsockopt( tp->socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv ); + } else { + tv.tv_sec = tp->config.timeout / 1000L; + tv.tv_usec = ( tp->config.timeout % 1000L ) * 1000L; + /* * Ignoring result because all possible errors indicate wrong * arguments and these arguments are OK as tested by test suite. */ - (void) setsockopt (tp->socket, SOL_SOCKET, SO_RCVTIMEO, &tv, - sizeof tv); + (void) setsockopt( tp->socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv ); + } + for ( ;; ) { + union { + struct sockaddr s; + struct sockaddr_in i; + } from; + socklen_t fromlen = sizeof from; + len = recvfrom( + tp->socket, + tp->receive_buf, + tp->packet_size, + flags, + &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; + } } - for (;;) { - union { - struct sockaddr s; - struct sockaddr_in i; - } from; - socklen_t fromlen = sizeof from; - len = recvfrom (tp->socket, - tp->receive_buf, - tp->packet_size, - flags, - &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); - } - if (retryCount != GET_PACKET_DONT_WAIT) { - tv.tv_sec = 0; - tv.tv_usec = 0; - /* + sendStifle( tp, &from.i ); + } + if ( retryCount != GET_PACKET_DONT_WAIT ) { + tv.tv_sec = 0; + tv.tv_usec = 0; + /* * Ignoring result because all possible errors indicate wrong * arguments and these arguments are OK as tested by test suite. */ - (void) setsockopt (tp->socket, SOL_SOCKET, SO_RCVTIMEO, &tv, - sizeof tv); - } - return len; + (void) setsockopt( tp->socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv ); + } + return len; } -static int process_unexpected_packet (struct tftpStream *tp, ssize_t len) +static int process_unexpected_packet( struct tftpStream *tp, ssize_t len ) { - (void) len; - send_error ( - tp, - &tp->farAddress, - TFTP_ERROR_CODE_ILLEGAL, - "Got packet with unexpected opcode from server" - ); - return EPROTO; + (void) len; + send_error( + tp, + &tp->farAddress, + TFTP_ERROR_CODE_ILLEGAL, + "Got packet with unexpected opcode from server" + ); + return EPROTO; } -static int process_malformed_packet (struct tftpStream *tp, ssize_t len) +static int process_malformed_packet( struct tftpStream *tp, ssize_t len ) { - (void) len; - send_error ( - tp, - &tp->farAddress, - TFTP_ERROR_CODE_ILLEGAL, - "Got malformed packet from server" - ); - return EPROTO; + (void) len; + send_error( + tp, + &tp->farAddress, + TFTP_ERROR_CODE_ILLEGAL, + "Got malformed packet from server" + ); + return EPROTO; } -static int process_error_packet (struct tftpStream *tp, ssize_t len) +static int process_error_packet( struct tftpStream *tp, ssize_t len ) { - (void) len; - return tftpErrno (tp->receive_buf->tftpERROR.errorCode); + (void) len; + return tftpErrno( tp->receive_buf->tftpERROR.errorCode ); } /* @@ -659,61 +679,66 @@ static int process_error_packet (struct tftpStream *tp, ssize_t len) * * Check the option values in the OACK whether they are in the * desired range. */ -static int process_error_packet_option_negotiation ( - struct tftpStream *tp, ssize_t len +static int process_error_packet_option_negotiation( + struct tftpStream *tp, + ssize_t len ) { - (void) len; - /* + (void) len; + /* * Setting tp->config.options causes an RRQ or a WRQ to be created without * options. * Setting tp->server_option is defensive programming as these fields * should already have these values. */ - tp->config.options.block_size = TFTP_RFC1350_BLOCK_SIZE; - tp->config.options.window_size = TFTP_RFC1350_WINDOW_SIZE; - tp->server_options.block_size = TFTP_RFC1350_BLOCK_SIZE; - tp->server_options.window_size = TFTP_RFC1350_WINDOW_SIZE; + tp->config.options.block_size = TFTP_RFC1350_BLOCK_SIZE; + tp->config.options.window_size = TFTP_RFC1350_WINDOW_SIZE; + tp->server_options.block_size = TFTP_RFC1350_BLOCK_SIZE; + tp->server_options.window_size = TFTP_RFC1350_WINDOW_SIZE; - tp->process_error_packet = process_error_packet; - /* + tp->process_error_packet = process_error_packet; + /* * GOT_FIRST_OUT_OF_ORDER_PACKET will trigger a re-send of the RRQ or WRQ. */ - return GOT_FIRST_OUT_OF_ORDER_PACKET; + return GOT_FIRST_OUT_OF_ORDER_PACKET; } -static int process_data_packet (struct tftpStream *tp, ssize_t len) +static int process_data_packet( struct tftpStream *tp, ssize_t len ) { - ssize_t plen; - int32_t pkt_blocknum; - union tftpPacket *send_buf; + ssize_t plen; + int32_t pkt_blocknum; + union tftpPacket *send_buf; - if ((size_t) len < sizeof (tp->receive_buf->tftpACK)) { - return process_malformed_packet (tp, len); - } - pkt_blocknum = (int32_t) ntohs (tp->receive_buf->tftpACK.blocknum); - if (pkt_blocknum == 0) { - return process_malformed_packet (tp, len); - } + if ( (size_t) len < sizeof( tp->receive_buf->tftpACK ) ) { + return process_malformed_packet( tp, len ); + } + pkt_blocknum = (int32_t) ntohs( tp->receive_buf->tftpACK.blocknum ); + if ( pkt_blocknum == 0 ) { + return process_malformed_packet( tp, len ); + } - /* + /* * In case of reading a file from the server: * If the latest ACK packet(s) did not reach the server, the server * starts the window from the last ACK it received. This if-clause * ensures, the client sends an ACK after having seen `windowsize` * packets. */ - if (pkt_blocknum < tp->blocknum_of_first_packet_of_window && - pkt_blocknum >= (int32_t) tp->blocknum + 1 - - (int32_t) tp->server_options.window_size) { - tp->blocknum_of_first_packet_of_window = pkt_blocknum; - } - if (!tp->ignore_out_of_order_packets && - pkt_blocknum > (int32_t) tp->blocknum + 1) { - tp->ignore_out_of_order_packets = true; - return GOT_FIRST_OUT_OF_ORDER_PACKET; - } else if (pkt_blocknum == (int32_t) tp->blocknum) { - /* + if ( + pkt_blocknum < tp->blocknum_of_first_packet_of_window && + pkt_blocknum >= + (int32_t) tp->blocknum + 1 - (int32_t) tp->server_options.window_size + ) { + tp->blocknum_of_first_packet_of_window = pkt_blocknum; + } + if ( + !tp->ignore_out_of_order_packets && + pkt_blocknum > (int32_t) tp->blocknum + 1 + ) { + tp->ignore_out_of_order_packets = true; + return GOT_FIRST_OUT_OF_ORDER_PACKET; + } else if ( pkt_blocknum == (int32_t) tp->blocknum ) { + /* * In case of reading a file from the server: * If the last ACK packet send by the client did not reach the * server, the server re-sends all packets of the window. In this @@ -722,209 +747,220 @@ static int process_data_packet (struct tftpStream *tp, ssize_t len) * already received that packet before). * GOT_OLD_PACKET would wrongly suppress this. */ - return GOT_DUPLICATE_OF_CURRENT_PACKET; - } else if (pkt_blocknum != (int32_t) tp->blocknum + 1) { - return GOT_OLD_PACKET; - } - tp->ignore_out_of_order_packets = false; + return GOT_DUPLICATE_OF_CURRENT_PACKET; + } else if ( pkt_blocknum != (int32_t) tp->blocknum + 1 ) { + return GOT_OLD_PACKET; + } + tp->ignore_out_of_order_packets = false; - tp->blocknum++; - tp->nused = 0; /* Only for 2nd, 3rd, 4th DATA packet received */ - tp->nleft = BLK_SIZE_FROM_PKT_SIZE (len); - tp->at_eof = (tp->nleft < tp->server_options.block_size); - /* + tp->blocknum++; + tp->nused = 0; /* Only for 2nd, 3rd, 4th DATA packet received */ + tp->nleft = BLK_SIZE_FROM_PKT_SIZE( len ); + tp->at_eof = ( tp->nleft < tp->server_options.block_size ); + /* * After the last DATA packet, the client must send a final ACK */ - if (tp->at_eof) { - plen = prepare_ack_packet_for_sending (tp, true, &send_buf, NULL, NULL); - - /* - * Send it. Errors during send will not matter for this last ACK. - */ - (void) sendto ( - tp->socket, - send_buf, - plen, - 0, - (struct sockaddr *) &tp->farAddress, - sizeof (tp->farAddress) - ); - } - tp->prepare_packet_for_sending = prepare_ack_packet_for_sending; - return GOT_EXPECTED_PACKET; -} - -static int process_ack_packet (struct tftpStream *tp, ssize_t len) -{ - uint16_t blocknum_ack; - if ((size_t) len < sizeof (tp->receive_buf->tftpACK)) { - return process_malformed_packet (tp, len); - } - blocknum_ack = ntohs (tp->receive_buf->tftpACK.blocknum); - if ((int32_t) blocknum_ack == tp->blocknum_of_first_packet_of_window - 1 && - blocknum_ack != 0 - ) { - tp->blocknum = tp->blocknum_of_first_packet_of_window; - return GOT_DUPLICATE_OF_CURRENT_PACKET; - } - if ((int32_t) blocknum_ack < tp->blocknum_of_first_packet_of_window || - blocknum_ack > tp->blocknum_last_filled) { - return GOT_OLD_PACKET; - } - tp->blocknum = blocknum_ack + 1; - tp->blocknum_of_first_packet_of_window = (int32_t) tp->blocknum; - tp->prepare_packet_for_sending = prepare_data_packet_for_sending; - return GOT_EXPECTED_PACKET; -} - -static ssize_t prepare_data_packet_for_sending ( - struct tftpStream *tp, - bool force_retransmission, - union tftpPacket **send_buf, - bool *wait_for_packet_reception, - const void *not_used -) -{ - (void) force_retransmission; - (void) not_used; - - ssize_t len; - *send_buf = get_send_buffer_packet (tp, tp->blocknum); - - len = PKT_SIZE_FROM_BLK_SIZE ( - (tp->blocknum == tp->blocknum_eof_block) ? tp->nused : tp->block_size - ); - (*send_buf)->tftpDATA.opcode = htons (TFTP_OPCODE_DATA); - (*send_buf)->tftpDATA.blocknum = htons (tp->blocknum); + if ( tp->at_eof ) { + plen = prepare_ack_packet_for_sending( tp, true, &send_buf, NULL, NULL ); /* + * Send it. Errors during send will not matter for this last ACK. + */ + (void) sendto( + tp->socket, + send_buf, + plen, + 0, + (struct sockaddr *) &tp->farAddress, + sizeof( tp->farAddress ) + ); + } + tp->prepare_packet_for_sending = prepare_ack_packet_for_sending; + return GOT_EXPECTED_PACKET; +} + +static int process_ack_packet( struct tftpStream *tp, ssize_t len ) +{ + uint16_t blocknum_ack; + if ( (size_t) len < sizeof( tp->receive_buf->tftpACK ) ) { + return process_malformed_packet( tp, len ); + } + blocknum_ack = ntohs( tp->receive_buf->tftpACK.blocknum ); + if ( + (int32_t) blocknum_ack == tp->blocknum_of_first_packet_of_window - 1 && + blocknum_ack != 0 + ) { + tp->blocknum = tp->blocknum_of_first_packet_of_window; + return GOT_DUPLICATE_OF_CURRENT_PACKET; + } + if ( + (int32_t) blocknum_ack < tp->blocknum_of_first_packet_of_window || + blocknum_ack > tp->blocknum_last_filled + ) { + return GOT_OLD_PACKET; + } + tp->blocknum = blocknum_ack + 1; + tp->blocknum_of_first_packet_of_window = (int32_t) tp->blocknum; + tp->prepare_packet_for_sending = prepare_data_packet_for_sending; + return GOT_EXPECTED_PACKET; +} + +static ssize_t prepare_data_packet_for_sending( + struct tftpStream *tp, + bool force_retransmission, + union tftpPacket **send_buf, + bool *wait_for_packet_reception, + const void *not_used +) +{ + (void) force_retransmission; + (void) not_used; + + ssize_t len; + *send_buf = get_send_buffer_packet( tp, tp->blocknum ); + + len = PKT_SIZE_FROM_BLK_SIZE( + ( tp->blocknum == tp->blocknum_eof_block ) ? tp->nused : tp->block_size + ); + ( *send_buf )->tftpDATA.opcode = htons( TFTP_OPCODE_DATA ); + ( *send_buf )->tftpDATA.blocknum = htons( tp->blocknum ); + + /* * If the client sends the last packet of a window, * it must wait for an ACK and - in case no ACK is received - begin * a retransmission with the first packet of the window. * Note that the last DATA block for the whole transfer is also * a "last packet of a window". */ - if ((int32_t) tp->blocknum + 1 >= - tp->blocknum_of_first_packet_of_window + tp->send_buf_size_in_pkts || - tp->blocknum == tp->blocknum_eof_block) { - tp->blocknum = (uint16_t) tp->blocknum_of_first_packet_of_window; - } else { - tp->blocknum++; - *wait_for_packet_reception = false; - } + if ( + (int32_t) tp->blocknum + 1 >= + tp->blocknum_of_first_packet_of_window + tp->send_buf_size_in_pkts || + tp->blocknum == tp->blocknum_eof_block + ) { + tp->blocknum = (uint16_t) tp->blocknum_of_first_packet_of_window; + } else { + tp->blocknum++; + *wait_for_packet_reception = false; + } - tp->process_data_packet = process_unexpected_packet; - tp->process_ack_packet = process_ack_packet; - tp->process_oack_packet = process_unexpected_packet; - tp->process_error_packet = process_error_packet; + tp->process_data_packet = process_unexpected_packet; + tp->process_ack_packet = process_ack_packet; + tp->process_oack_packet = process_unexpected_packet; + tp->process_error_packet = process_error_packet; - /* + /* * Our last packet won't necessarily be acknowledged! */ - if (tp->blocknum == tp->blocknum_eof_block) { - tp->retransmission_error_code = 0; - } + if ( tp->blocknum == tp->blocknum_eof_block ) { + tp->retransmission_error_code = 0; + } - return len; + return len; } -static ssize_t prepare_ack_packet_for_sending ( - struct tftpStream *tp, - bool force_retransmission, - union tftpPacket **send_buf, - bool *wait_for_packet_reception, - const void *path_name +static ssize_t prepare_ack_packet_for_sending( + struct tftpStream *tp, + bool force_retransmission, + union tftpPacket **send_buf, + bool *wait_for_packet_reception, + const void *path_name ) { - (void) path_name; + (void) path_name; - (void) wait_for_packet_reception; - if (!force_retransmission && - tp->blocknum_of_first_packet_of_window - 1 + - (int32_t) tp->server_options.window_size > (int32_t) tp->blocknum) { - return DO_NOT_SEND_PACKET; - } - tp->blocknum_of_first_packet_of_window = (int32_t) tp->blocknum + 1; + (void) wait_for_packet_reception; + if ( + !force_retransmission && tp->blocknum_of_first_packet_of_window - 1 + + (int32_t) tp->server_options.window_size > + (int32_t) tp->blocknum + ) { + return DO_NOT_SEND_PACKET; + } + tp->blocknum_of_first_packet_of_window = (int32_t) tp->blocknum + 1; - /* + /* * Create the acknowledgement */ - *send_buf = tp->send_buf; - (*send_buf)->tftpACK.opcode = htons (TFTP_OPCODE_ACK); - (*send_buf)->tftpACK.blocknum = htons (tp->blocknum); + *send_buf = tp->send_buf; + ( *send_buf )->tftpACK.opcode = htons( TFTP_OPCODE_ACK ); + ( *send_buf )->tftpACK.blocknum = htons( tp->blocknum ); - tp->process_data_packet = process_data_packet; - tp->process_ack_packet = process_unexpected_packet; - tp->process_oack_packet = process_unexpected_packet; - tp->process_error_packet = process_error_packet; + tp->process_data_packet = process_data_packet; + tp->process_ack_packet = process_unexpected_packet; + tp->process_oack_packet = process_unexpected_packet; + tp->process_error_packet = process_error_packet; - return sizeof (tp->send_buf->tftpACK); + return sizeof( tp->send_buf->tftpACK ); } -static int process_oack_packet (struct tftpStream *tp, ssize_t len) +static int process_oack_packet( struct tftpStream *tp, ssize_t len ) { - if (!parse_options(tp->receive_buf, - len, - &tp->config.options, - &tp->server_options)) { - send_error ( - tp, - &tp->farAddress, - TFTP_ERROR_CODE_OPTION_NEGO, - "Bad options, option values or malformed OACK packet" - ); - return EPROTO; - } - if (tp->is_for_reading) { - /* + if ( !parse_options( + tp->receive_buf, + len, + &tp->config.options, + &tp->server_options + ) ) { + send_error( + tp, + &tp->farAddress, + TFTP_ERROR_CODE_OPTION_NEGO, + "Bad options, option values or malformed OACK packet" + ); + return EPROTO; + } + if ( tp->is_for_reading ) { + /* * Since no DATA packet has been received yet, tell * tftp_read() there is no data left. */ - tp->nleft = 0; - tp->prepare_packet_for_sending = prepare_ack_packet_for_sending; - } else { - tp->blocknum_of_first_packet_of_window = 1; - tp->blocknum = (uint16_t) tp->blocknum_of_first_packet_of_window; - tp->prepare_packet_for_sending = prepare_data_packet_for_sending; - } - return GOT_EXPECTED_PACKET; + tp->nleft = 0; + tp->prepare_packet_for_sending = prepare_ack_packet_for_sending; + } else { + tp->blocknum_of_first_packet_of_window = 1; + tp->blocknum = (uint16_t) tp->blocknum_of_first_packet_of_window; + tp->prepare_packet_for_sending = prepare_data_packet_for_sending; + } + return GOT_EXPECTED_PACKET; } -static ssize_t prepare_request_packet_for_sending ( - struct tftpStream *tp, - bool force_retransmission, - union tftpPacket **send_buf, - bool *wait_for_packet_reception, - const void *path_name +static ssize_t prepare_request_packet_for_sending( + struct tftpStream *tp, + bool force_retransmission, + union tftpPacket **send_buf, + bool *wait_for_packet_reception, + const void *path_name ) { - (void) force_retransmission; + (void) force_retransmission; - (void) wait_for_packet_reception; - ssize_t len; - *send_buf = tp->send_buf; - len = create_request ( - *send_buf, - tp->block_size, - tp->is_for_reading, - path_name, - &tp->config.options - ); + (void) wait_for_packet_reception; + ssize_t len; + *send_buf = tp->send_buf; + len = create_request( + *send_buf, + tp->block_size, + tp->is_for_reading, + path_name, + &tp->config.options + ); - if (len < 0) { - tp->error = ENAMETOOLONG; - } else { - tp->process_data_packet = tp->is_for_reading ? - process_data_packet : process_unexpected_packet; - tp->process_ack_packet = tp->is_for_reading ? - process_unexpected_packet : process_ack_packet; - tp->process_oack_packet = MUST_SEND_OPTIONS(tp->config.options) ? - process_oack_packet : process_unexpected_packet; - tp->process_error_packet = MUST_SEND_OPTIONS(tp->config.options) ? - process_error_packet_option_negotiation : process_error_packet; - } + if ( len < 0 ) { + tp->error = ENAMETOOLONG; + } else { + tp->process_data_packet = tp->is_for_reading ? process_data_packet + : process_unexpected_packet; + tp->process_ack_packet = tp->is_for_reading ? process_unexpected_packet + : process_ack_packet; + tp->process_oack_packet = MUST_SEND_OPTIONS( tp->config.options ) + ? process_oack_packet + : process_unexpected_packet; + tp->process_error_packet = MUST_SEND_OPTIONS( tp->config.options ) + ? process_error_packet_option_negotiation + : process_error_packet; + } - /* + /* * getPacket() will change these values when the first packet is * received. Yet, this first packet may be an unexpected one * (e.g. an ERROR or having a wrong block number). @@ -932,10 +968,10 @@ static ssize_t prepare_request_packet_for_sending ( * be directed to the server port again and not to the port the * first unexpected packet came from. */ - tp->farAddress.sin_port = htons (tp->config.server_port); - tp->firstReply = 1; + tp->farAddress.sin_port = htons( tp->config.server_port ); + tp->firstReply = 1; - return len; + return len; } /* @@ -995,107 +1031,113 @@ static ssize_t prepare_request_packet_for_sending ( * appears in test case "read_file_windowsize_trouble" where the client/server * roles are exchanged.) */ -static int communicate_with_server ( - struct tftpStream *tp, - const void *create_packet_data +static int communicate_with_server( + struct tftpStream *tp, + const void *create_packet_data ) { - ssize_t len; - uint16_t opcode; - union tftpPacket *send_buf; - bool received_duplicated_or_old_package = false; - bool force_retransmission = false; - bool wait_for_packet_reception; - int retryCount = 0; - while (tp->error == 0) { + ssize_t len; + uint16_t opcode; + union tftpPacket *send_buf; + bool received_duplicated_or_old_package = false; + bool force_retransmission = false; + bool wait_for_packet_reception; + int retryCount = 0; + while ( tp->error == 0 ) { + if ( !received_duplicated_or_old_package ) { + wait_for_packet_reception = true; + len = tp->prepare_packet_for_sending( + tp, + force_retransmission, + &send_buf, + &wait_for_packet_reception, + create_packet_data + ); + if ( len < 0 ) { + if ( tp->error == 0 ) { + tp->error = EIO; + } + break; + } - if (!received_duplicated_or_old_package) { - wait_for_packet_reception = true; - len = tp->prepare_packet_for_sending ( - tp, - force_retransmission, - &send_buf, - &wait_for_packet_reception, - create_packet_data - ); - if (len < 0) { - if (tp->error == 0) { - tp->error = EIO; - } - break; - } - - if (len != DO_NOT_SEND_PACKET) { - /* + if ( len != DO_NOT_SEND_PACKET ) { + /* * Send the packet */ - if (sendto (tp->socket, send_buf, len, 0, - (struct sockaddr *)&tp->farAddress, - sizeof tp->farAddress) < 0) { - tp->error = EIO; - break; - } - } + if ( + sendto( + tp->socket, + send_buf, + len, + 0, + (struct sockaddr *) &tp->farAddress, + sizeof tp->farAddress + ) < 0 + ) { + tp->error = EIO; + break; } - received_duplicated_or_old_package = false; - force_retransmission = false; + } + } + received_duplicated_or_old_package = false; + force_retransmission = false; - /* + /* * Get reply */ - len = getPacket ( - tp, - wait_for_packet_reception ? retryCount : GET_PACKET_DONT_WAIT - ); - if (len >= (int) sizeof (tp->receive_buf->tftpDATA.opcode)) { - opcode = ntohs (tp->receive_buf->tftpDATA.opcode); - switch (opcode) { - case TFTP_OPCODE_DATA: - tp->error = tp->process_data_packet (tp, len); - break; - case TFTP_OPCODE_ACK: - tp->error = tp->process_ack_packet (tp, len); - break; - case TFTP_OPCODE_OACK: - tp->error = tp->process_oack_packet (tp, len); - break; - case TFTP_OPCODE_ERROR: - tp->error = tp->process_error_packet (tp, len); - break; - default: - tp->error = process_unexpected_packet (tp, len); - break; - } - if (tp->error == GOT_EXPECTED_PACKET) { - break; - } else if (tp->error == GOT_DUPLICATE_OF_CURRENT_PACKET) { - tp->error = 0; - } else if (tp->error == GOT_OLD_PACKET) { - received_duplicated_or_old_package = true; - tp->error = 0; - } else if (tp->error <= GOT_FIRST_OUT_OF_ORDER_PACKET) { - force_retransmission = true; - tp->error = 0; - } /* else ... tp->error > 0 means "exit this function with error" */ - } else if (len >= 0) { - tp->error = process_malformed_packet (tp, len); - } else if (len < 0 && !wait_for_packet_reception) { - tp->error = 0; - break; - } else { - /* + len = getPacket( + tp, + wait_for_packet_reception ? retryCount : GET_PACKET_DONT_WAIT + ); + if ( len >= (int) sizeof( tp->receive_buf->tftpDATA.opcode ) ) { + opcode = ntohs( tp->receive_buf->tftpDATA.opcode ); + switch ( opcode ) { + case TFTP_OPCODE_DATA: + tp->error = tp->process_data_packet( tp, len ); + break; + case TFTP_OPCODE_ACK: + tp->error = tp->process_ack_packet( tp, len ); + break; + case TFTP_OPCODE_OACK: + tp->error = tp->process_oack_packet( tp, len ); + break; + case TFTP_OPCODE_ERROR: + tp->error = tp->process_error_packet( tp, len ); + break; + default: + tp->error = process_unexpected_packet( tp, len ); + break; + } + if ( tp->error == GOT_EXPECTED_PACKET ) { + break; + } else if ( tp->error == GOT_DUPLICATE_OF_CURRENT_PACKET ) { + tp->error = 0; + } else if ( tp->error == GOT_OLD_PACKET ) { + received_duplicated_or_old_package = true; + tp->error = 0; + } else if ( tp->error <= GOT_FIRST_OUT_OF_ORDER_PACKET ) { + force_retransmission = true; + tp->error = 0; + } /* else ... tp->error > 0 means "exit this function with error" */ + } else if ( len >= 0 ) { + tp->error = process_malformed_packet( tp, len ); + } else if ( len < 0 && !wait_for_packet_reception ) { + tp->error = 0; + break; + } else { + /* * Timeout or other problems to receive packets * Attempt a retransmission */ - if (++retryCount >= (int) tp->config.retransmissions) { - tp->error = tp->retransmission_error_code; - break; - } - force_retransmission = true; - } + if ( ++retryCount >= (int) tp->config.retransmissions ) { + tp->error = tp->retransmission_error_code; + break; + } + force_retransmission = true; } + } - return tp->error; + return tp->error; } /* @@ -1104,268 +1146,266 @@ static int communicate_with_server ( * This function does not check whether the config values are in valid ranges. */ static struct tftpStream *create_stream( - const tftp_net_config *config, - const struct in_addr *farAddress, - bool is_for_reading + const tftp_net_config *config, + const struct in_addr *farAddress, + bool is_for_reading ) { - struct tftpStream *tp = NULL; - tp = malloc (sizeof (struct tftpStream)); - if (tp == NULL) { - return NULL; - } + struct tftpStream *tp = NULL; + tp = malloc( sizeof( struct tftpStream ) ); + if ( tp == NULL ) { + return NULL; + } - /* + /* * Initialize fields accessed by _Tftp_Destroy(). */ - tp->receive_buf = NULL; - tp->send_buf = NULL; - tp->socket = 0; + tp->receive_buf = NULL; + tp->send_buf = NULL; + tp->socket = 0; - /* + /* * Allocate send and receive buffer for exchange of RRQ/WRQ and ACK/OACK. */ - tp->block_size = TFTP_RFC1350_BLOCK_SIZE; - tp->packet_size = PKT_SIZE_FROM_BLK_SIZE (tp->block_size); - tp->receive_buf = malloc (tp->packet_size); - if (tp->receive_buf == NULL) { - _Tftp_Destroy (tp); - return NULL; - } - tp->send_buf = tp->receive_buf; - tp->send_buf_size_in_pkts = 1; + tp->block_size = TFTP_RFC1350_BLOCK_SIZE; + tp->packet_size = PKT_SIZE_FROM_BLK_SIZE( tp->block_size ); + tp->receive_buf = malloc( tp->packet_size ); + if ( tp->receive_buf == NULL ) { + _Tftp_Destroy( tp ); + return NULL; + } + tp->send_buf = tp->receive_buf; + tp->send_buf_size_in_pkts = 1; - /* + /* * Create the socket */ - if ((tp->socket = socket (AF_INET, SOCK_DGRAM, 0)) < 0) { - _Tftp_Destroy (tp); - return NULL; - } + if ( ( tp->socket = socket( AF_INET, SOCK_DGRAM, 0 ) ) < 0 ) { + _Tftp_Destroy( tp ); + return NULL; + } - /* + /* * Setup configuration and options */ - if ( config == NULL ) { - tftp_initialize_net_config (&tp->config); - } else { - tp->config = *config; - } + if ( config == NULL ) { + tftp_initialize_net_config( &tp->config ); + } else { + tp->config = *config; + } - /* + /* * If the server does not confirm our option values later on, * use numbers from the original RFC 1350 for the actual transfer. */ - tp->server_options.block_size = TFTP_RFC1350_BLOCK_SIZE; - tp->server_options.window_size = TFTP_RFC1350_WINDOW_SIZE; + tp->server_options.block_size = TFTP_RFC1350_BLOCK_SIZE; + tp->server_options.window_size = TFTP_RFC1350_WINDOW_SIZE; - /* + /* * 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 (tp->config.server_port); + tp->farAddress.sin_family = AF_INET; + tp->farAddress.sin_addr = *farAddress; + tp->farAddress.sin_port = htons( tp->config.server_port ); - tp->nleft = 0; - tp->nused = 0; - tp->blocknum = 0; - tp->blocknum_last_filled = 0; - tp->blocknum_eof_block = UINT16_MAX; - tp->firstReply = 1; - tp->at_eof = false; - tp->is_for_reading = is_for_reading; + tp->nleft = 0; + tp->nused = 0; + tp->blocknum = 0; + tp->blocknum_last_filled = 0; + tp->blocknum_eof_block = UINT16_MAX; + tp->firstReply = 1; + tp->at_eof = false; + tp->is_for_reading = is_for_reading; - tp->prepare_packet_for_sending = prepare_request_packet_for_sending; - tp->process_data_packet = process_unexpected_packet; - tp->process_ack_packet = process_unexpected_packet; - tp->process_oack_packet = process_unexpected_packet; - tp->process_error_packet = process_error_packet; - tp->retransmission_error_code = EIO; - tp->ignore_out_of_order_packets = false; - tp->blocknum_of_first_packet_of_window = INT32_MIN; - tp->error = 0; + tp->prepare_packet_for_sending = prepare_request_packet_for_sending; + tp->process_data_packet = process_unexpected_packet; + tp->process_ack_packet = process_unexpected_packet; + tp->process_oack_packet = process_unexpected_packet; + tp->process_error_packet = process_error_packet; + tp->retransmission_error_code = EIO; + tp->ignore_out_of_order_packets = false; + tp->blocknum_of_first_packet_of_window = INT32_MIN; + tp->error = 0; - return tp; + return tp; } /* * Change the size of the receive and send buffer to match the options * values acknowledged by the server. */ -static struct tftpStream *reallocate_stream_buffer(struct tftpStream *tp) +static struct tftpStream *reallocate_stream_buffer( struct tftpStream *tp ) { - tp->block_size = tp->server_options.block_size; - tp->packet_size = PKT_SIZE_FROM_BLK_SIZE (tp->block_size); - /* + tp->block_size = tp->server_options.block_size; + tp->packet_size = PKT_SIZE_FROM_BLK_SIZE( tp->block_size ); + /* * Defensive programming */ - if (tp->receive_buf == tp->send_buf) { - tp->send_buf = NULL; - } else { - free (tp->send_buf); - } + if ( tp->receive_buf == tp->send_buf ) { + tp->send_buf = NULL; + } else { + free( tp->send_buf ); + } - tp->receive_buf = realloc (tp->receive_buf, tp->packet_size); - if (tp->is_for_reading) { - tp->send_buf = tp->receive_buf; - } else { - tp->send_buf_size_in_pkts = tp->server_options.window_size; - tp->send_buf = malloc ( - tp->send_buf_size_in_pkts * tp->packet_size - ); - } + tp->receive_buf = realloc( tp->receive_buf, tp->packet_size ); + if ( tp->is_for_reading ) { + tp->send_buf = tp->receive_buf; + } else { + tp->send_buf_size_in_pkts = tp->server_options.window_size; + tp->send_buf = malloc( tp->send_buf_size_in_pkts * tp->packet_size ); + } - if (tp->receive_buf == NULL || tp->send_buf == NULL) { - sendStifle (tp, &tp->farAddress); - _Tftp_Destroy (tp); - return NULL; - } - return tp; + if ( tp->receive_buf == NULL || tp->send_buf == NULL ) { + sendStifle( tp, &tp->farAddress ); + _Tftp_Destroy( tp ); + return NULL; + } + return tp; } /* * Convert hostname to an Internet address */ static struct in_addr *get_ip_address( - const char *hostname, - struct in_addr *farAddress + const char *hostname, + struct in_addr *farAddress ) { - struct hostent *he = gethostbyname(hostname); - if (he == NULL) { - return NULL; - } - memcpy (farAddress, he->h_addr, sizeof (*farAddress)); + struct hostent *he = gethostbyname( hostname ); + if ( he == NULL ) { + return NULL; + } + memcpy( farAddress, he->h_addr, sizeof( *farAddress ) ); return farAddress; } -void tftp_initialize_net_config (tftp_net_config *config) +void tftp_initialize_net_config( tftp_net_config *config ) { static const tftp_net_config default_config = { .retransmissions = TFTP_RFC7440_DATA_RETRANSMISSIONS, - .server_port = TFTP_DEFAULT_SERVER_PORT, - .timeout = TFTP_RFC7440_TIMEOUT_MILLISECONDS, - .first_timeout = PACKET_FIRST_TIMEOUT_MILLISECONDS, + .server_port = TFTP_DEFAULT_SERVER_PORT, + .timeout = TFTP_RFC7440_TIMEOUT_MILLISECONDS, + .first_timeout = PACKET_FIRST_TIMEOUT_MILLISECONDS, .options = { - .block_size = TFTP_DEFAULT_BLOCK_SIZE, - .window_size = TFTP_DEFAULT_WINDOW_SIZE + .block_size = TFTP_DEFAULT_BLOCK_SIZE, + .window_size = TFTP_DEFAULT_WINDOW_SIZE } }; - if (config != NULL) { - memcpy (config, &default_config, sizeof (default_config)); + if ( config != NULL ) { + memcpy( config, &default_config, sizeof( default_config ) ); } } int tftp_open( - const char *hostname, - const char *path, - bool is_for_reading, - const tftp_net_config *config, - void **tftp_handle + const char *hostname, + const char *path, + bool is_for_reading, + const tftp_net_config *config, + void **tftp_handle ) { - struct tftpStream *tp; - struct in_addr farAddress; - int err; + struct tftpStream *tp; + struct in_addr farAddress; + int err; - /* + /* * Check parameters */ - if (tftp_handle == NULL) { - return EINVAL; - } - *tftp_handle = NULL; - if (hostname == NULL || path == NULL) { - return EINVAL; - } - if (config != NULL && ( - config->options.window_size < TFTP_WINDOW_SIZE_MIN || - config->options.block_size < TFTP_BLOCK_SIZE_MIN || - config->options.block_size > TFTP_BLOCK_SIZE_MAX ) ) { - return EINVAL; - } + if ( tftp_handle == NULL ) { + return EINVAL; + } + *tftp_handle = NULL; + if ( hostname == NULL || path == NULL ) { + return EINVAL; + } + if ( + config != NULL && ( config->options.window_size < TFTP_WINDOW_SIZE_MIN || + config->options.block_size < TFTP_BLOCK_SIZE_MIN || + config->options.block_size > TFTP_BLOCK_SIZE_MAX ) + ) { + return EINVAL; + } - /* + /* * Create tftpStream structure */ - if (get_ip_address( hostname, &farAddress ) == NULL) { - return ENOENT; - } - tp = create_stream( config, &farAddress, is_for_reading ); - if (tp == NULL) { - return ENOMEM; - } + if ( get_ip_address( hostname, &farAddress ) == NULL ) { + return ENOENT; + } + tp = create_stream( config, &farAddress, is_for_reading ); + if ( tp == NULL ) { + return ENOMEM; + } - /* + /* * Send RRQ or WRQ and wait for reply */ - tp->prepare_packet_for_sending = prepare_request_packet_for_sending; - err = communicate_with_server (tp, path); - if ( err != 0 ) { - _Tftp_Destroy (tp); - return err; - } + tp->prepare_packet_for_sending = prepare_request_packet_for_sending; + err = communicate_with_server( tp, path ); + if ( err != 0 ) { + _Tftp_Destroy( tp ); + return err; + } - *tftp_handle = reallocate_stream_buffer ( tp ); - if( *tftp_handle == NULL ) { - return ENOMEM; - } + *tftp_handle = reallocate_stream_buffer( tp ); + if ( *tftp_handle == NULL ) { + return ENOMEM; + } - return 0; + return 0; } /* * Read from a TFTP stream */ -ssize_t tftp_read( - void *tftp_handle, - void *buffer, - size_t count -) +ssize_t tftp_read( void *tftp_handle, void *buffer, size_t count ) { - char *bp; - struct tftpStream *tp = tftp_handle; - int nwant; - int err; + char *bp; + struct tftpStream *tp = tftp_handle; + int nwant; + int err; - if (tp == NULL || !tp->is_for_reading || buffer == NULL) - return -EIO; + if ( tp == NULL || !tp->is_for_reading || buffer == NULL ) { + return -EIO; + } - /* + /* * 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->receive_buf->tftpDATA.data[tp->nused], ncopy); - tp->nused += ncopy; - tp->nleft -= ncopy; - bp += ncopy; - nwant -= ncopy; - if (nwant == 0) - break; - } - if (tp->at_eof) { - break; - } + bp = buffer; + nwant = count; + while ( nwant ) { + if ( tp->nleft ) { + int ncopy; + if ( nwant < tp->nleft ) { + ncopy = nwant; + } else { + ncopy = tp->nleft; + } + memcpy( bp, &tp->receive_buf->tftpDATA.data[ tp->nused ], ncopy ); + tp->nused += ncopy; + tp->nleft -= ncopy; + bp += ncopy; + nwant -= ncopy; + if ( nwant == 0 ) { + break; + } + } + if ( tp->at_eof ) { + break; + } - /* + /* * Wait for the next packet */ - tp->retransmission_error_code = -EIO; - err = communicate_with_server(tp, NULL); - if (err == tp->retransmission_error_code) { - return -EIO; - } - /* + tp->retransmission_error_code = -EIO; + err = communicate_with_server( tp, NULL ); + if ( err == tp->retransmission_error_code ) { + return -EIO; + } + /* * If communicate_with_server() returns an error, either * * an error message from the server was received or * * an error message was already sent to the server @@ -1373,12 +1413,12 @@ ssize_t tftp_read( * communicate_with_server() and suppresses the sending of * an error message to the server by tftp_close(). */ - if (err != 0) { - tp->at_eof = true; - return -err; - } + if ( err != 0 ) { + tp->at_eof = true; + return -err; } - return count - nwant; + } + return count - nwant; } /* @@ -1393,17 +1433,17 @@ ssize_t tftp_read( * in the write buffer have been send and acknowledged (or if an error * occurred). */ -static int rtems_tftp_flush (struct tftpStream *tp) +static int rtems_tftp_flush( struct tftpStream *tp ) { - int err; + int err; - if (tp->at_eof) { - return 0; - } + if ( tp->at_eof ) { + return 0; + } - do { - err = communicate_with_server(tp, NULL); - /* + do { + err = communicate_with_server( tp, NULL ); + /* * If communicate_with_server() returns an error, either * * an error message from the server was received or * * an error message was already sent to the server @@ -1411,132 +1451,125 @@ static int rtems_tftp_flush (struct tftpStream *tp) * communicate_with_server() and suppresses the sending of * an error message to the server by tftp_close(). */ - if (err != 0) { - tp->at_eof = true; - return err; - } - } while( - (int32_t) tp->blocknum_last_filled + 1 >= - tp->blocknum_of_first_packet_of_window + tp->send_buf_size_in_pkts || - /* + if ( err != 0 ) { + tp->at_eof = true; + return err; + } + } while ( + (int32_t) tp->blocknum_last_filled + 1 >= + tp->blocknum_of_first_packet_of_window + tp->send_buf_size_in_pkts || + /* * tp->blocknum_eof_block == tp->blocknum_last_filled * holds only true when the user invoked tftp_close(). */ - (tp->blocknum_eof_block == tp->blocknum_last_filled && - tp->blocknum_of_first_packet_of_window <= - (int32_t) tp->blocknum_eof_block) - ); + ( tp->blocknum_eof_block == tp->blocknum_last_filled && + tp->blocknum_of_first_packet_of_window <= + (int32_t) tp->blocknum_eof_block ) + ); - return 0; + return 0; } /* * Close a TFTP stream */ -int tftp_close( - void *tftp_handle -) +int tftp_close( void *tftp_handle ) { - struct tftpStream *tp = tftp_handle; - int e = 0; + struct tftpStream *tp = tftp_handle; + int e = 0; - if (tp == NULL) { - return 0; - } + if ( tp == NULL ) { + return 0; + } - if (!tp->is_for_reading) { - tp->blocknum_last_filled++; - tp->blocknum_eof_block = tp->blocknum_last_filled; - e = rtems_tftp_flush (tp); - tp->at_eof = true; - } - if (!tp->at_eof && !tp->firstReply) { - /* + if ( !tp->is_for_reading ) { + tp->blocknum_last_filled++; + tp->blocknum_eof_block = tp->blocknum_last_filled; + e = rtems_tftp_flush( tp ); + tp->at_eof = true; + } + if ( !tp->at_eof && !tp->firstReply ) { + /* * Tell the other end to stop */ - rtems_interval ticksPerSecond; - send_error ( - tp, - &tp->farAddress, - TFTP_ERROR_CODE_NO_USER, - "User (client) stopped reading or " - "server stopped sending packets (timeout)" - ); - ticksPerSecond = rtems_clock_get_ticks_per_second(); - rtems_task_wake_after (1 + ticksPerSecond / 10); - } - _Tftp_Destroy (tp); - return e; + rtems_interval ticksPerSecond; + send_error( + tp, + &tp->farAddress, + TFTP_ERROR_CODE_NO_USER, + "User (client) stopped reading or " + "server stopped sending packets (timeout)" + ); + ticksPerSecond = rtems_clock_get_ticks_per_second(); + rtems_task_wake_after( 1 + ticksPerSecond / 10 ); + } + _Tftp_Destroy( tp ); + return e; } -ssize_t tftp_write( - void *tftp_handle, - const void *buffer, - size_t count -) +ssize_t tftp_write( void *tftp_handle, const void *buffer, size_t count ) { - const char *bp; - struct tftpStream *tp = tftp_handle; - int nleft, nfree, ncopy; - int err; - union tftpPacket *send_buf; + const char *bp; + struct tftpStream *tp = tftp_handle; + int nleft, nfree, ncopy; + int err; + union tftpPacket *send_buf; - /* + /* * Bail out if an error has occurred */ - if (tp == NULL || tp->is_for_reading || tp->at_eof || buffer == NULL) { - return -EIO; - } + if ( tp == NULL || tp->is_for_reading || tp->at_eof || buffer == NULL ) { + 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 = tp->block_size - tp->nused; - if (nleft < nfree) - ncopy = nleft; - else - ncopy = nfree; - send_buf = get_send_buffer_packet (tp, tp->blocknum_last_filled + 1); - memcpy (&send_buf->tftpDATA.data[tp->nused], bp, ncopy); - tp->nused += ncopy; - nleft -= ncopy; - bp += ncopy; - if (tp->nused == tp->block_size) { - tp->blocknum_last_filled++; - err = rtems_tftp_flush (tp); - if (err) { - return -err; - } - tp->nused = 0; - } + bp = buffer; + nleft = count; + while ( nleft ) { + nfree = tp->block_size - tp->nused; + if ( nleft < nfree ) { + ncopy = nleft; + } else { + ncopy = nfree; } - return count; + send_buf = get_send_buffer_packet( tp, tp->blocknum_last_filled + 1 ); + memcpy( &send_buf->tftpDATA.data[ tp->nused ], bp, ncopy ); + tp->nused += ncopy; + nleft -= ncopy; + bp += ncopy; + if ( tp->nused == tp->block_size ) { + tp->blocknum_last_filled++; + err = rtems_tftp_flush( tp ); + if ( err ) { + return -err; + } + tp->nused = 0; + } + } + return count; } -void _Tftp_Destroy( - void *tftp_handle -) +void _Tftp_Destroy( void *tftp_handle ) { - struct tftpStream *tp = tftp_handle; - if (tp == NULL) { - return; - } + struct tftpStream *tp = tftp_handle; + if ( tp == NULL ) { + return; + } - if (tp->socket >= 0) { - close (tp->socket); - } + if ( tp->socket >= 0 ) { + close( tp->socket ); + } - if (tp->receive_buf == tp->send_buf) { - tp->send_buf = NULL; - } - free (tp->receive_buf); - free (tp->send_buf); - free (tp); + if ( tp->receive_buf == tp->send_buf ) { + tp->send_buf = NULL; + } + free( tp->receive_buf ); + free( tp->send_buf ); + free( tp ); } diff --git a/cpukit/libfs/src/ftpfs/tftp_driver.h b/cpukit/libfs/src/ftpfs/tftp_driver.h index 690ff415f6..51ea7ff457 100644 --- a/cpukit/libfs/src/ftpfs/tftp_driver.h +++ b/cpukit/libfs/src/ftpfs/tftp_driver.h @@ -75,15 +75,13 @@ extern "C" { * @param tftp_handle is the reference returned by a call to tftp_open(). * If this parameter is @c NULL, the directive call is a no-op. */ -void _Tftp_Destroy( - void *tftp_handle -); +void _Tftp_Destroy( void *tftp_handle ); /* Only non-private to ease unit testing */ ssize_t _Tftpfs_Parse_options( - const char *option_str, + const char *option_str, tftp_net_config *tftp_config, - uint32_t *flags + uint32_t *flags ); /** @} */ diff --git a/cpukit/libfs/src/ftpfs/tftpfs.c b/cpukit/libfs/src/ftpfs/tftpfs.c index bad6b42634..963619177b 100644 --- a/cpukit/libfs/src/ftpfs/tftpfs.c +++ b/cpukit/libfs/src/ftpfs/tftpfs.c @@ -64,33 +64,33 @@ /* * Flags for filesystem info. */ -#define TFTPFS_VERBOSE (1 << 0) +#define TFTPFS_VERBOSE ( 1 << 0 ) /* * TFTP File system info. */ typedef struct tftpfs_info_s { - uint32_t flags; + uint32_t flags; rtems_mutex tftp_mutex; - size_t nStreams; - void ** volatile tftpStreams; + size_t nStreams; + void **volatile tftpStreams; tftp_net_config tftp_config; } tftpfs_info_t; -#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))) +#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 ) ) ) /* Forward declarations */ -static const rtems_filesystem_operations_table rtems_tftp_ops; -static const rtems_filesystem_file_handlers_r rtems_tftp_handlers; +static const rtems_filesystem_operations_table rtems_tftp_ops; +static const rtems_filesystem_file_handlers_r rtems_tftp_handlers; -static bool rtems_tftp_is_directory( - const char *path, - size_t pathlen -) +static bool rtems_tftp_is_directory( const char *path, size_t pathlen ) { - return path [pathlen - 1] == '/'; + return path[ pathlen - 1 ] == '/'; } /* @@ -99,47 +99,51 @@ static bool rtems_tftp_is_directory( * N+1 if parsing failed at position N */ ssize_t _Tftpfs_Parse_options( - const char *option_str, + const char *option_str, tftp_net_config *tftp_config, - uint32_t *flags + uint32_t *flags ) { const char *cur_pos = option_str; - size_t verbose_len = strlen ("verbose"); - size_t rfc1350_len = strlen ("rfc1350"); - int len; + size_t verbose_len = strlen( "verbose" ); + size_t rfc1350_len = strlen( "rfc1350" ); + int len; - while(cur_pos != NULL && *cur_pos != '\0') { - if (strncmp (cur_pos, "verbose", verbose_len) == 0) { + while ( cur_pos != NULL && *cur_pos != '\0' ) { + if ( strncmp( cur_pos, "verbose", verbose_len ) == 0 ) { *flags |= TFTPFS_VERBOSE; len = (int) verbose_len; - } else if (strncmp (cur_pos, "rfc1350", rfc1350_len) == 0) { + } else if ( strncmp( cur_pos, "rfc1350", rfc1350_len ) == 0 ) { tftp_config->options.block_size = TFTP_RFC1350_BLOCK_SIZE; tftp_config->options.window_size = TFTP_RFC1350_WINDOW_SIZE; len = (int) rfc1350_len; - } else if (sscanf( + } else if ( + sscanf( cur_pos, - "blocksize=%"SCNu16"%n", + "blocksize=%" SCNu16 "%n", &tftp_config->options.block_size, &len - ) == 1) { - } else if (sscanf( + ) == 1 + ) { + } else if ( + sscanf( cur_pos, - "windowsize=%"SCNu16"%n", + "windowsize=%" SCNu16 "%n", &tftp_config->options.window_size, &len - ) == 1) { - } else if (*cur_pos == ',') { /* skip surplus "," */ + ) == 1 + ) { + } else if ( *cur_pos == ',' ) { /* skip surplus "," */ len = 0; } else { return cur_pos - option_str + 1; } cur_pos += len; - if (*cur_pos != ',' && *cur_pos != '\0') { + if ( *cur_pos != ',' && *cur_pos != '\0' ) { return cur_pos - option_str + 1; } - if (*cur_pos == ',') { + if ( *cur_pos == ',' ) { cur_pos++; } } @@ -152,44 +156,46 @@ int rtems_tftpfs_initialize( const void *data ) { - const char *device = mt_entry->dev; - size_t devicelen = strlen (device); + const char *device = mt_entry->dev; + size_t devicelen = strlen( device ); tftpfs_info_t *fs = NULL; - char *root_path; - size_t err_pos; - int errno_store = ENOMEM; + char *root_path; + size_t err_pos; + int errno_store = ENOMEM; - if (devicelen == 0) { - root_path = malloc (1); - if (root_path == NULL) + if ( devicelen == 0 ) { + root_path = malloc( 1 ); + if ( root_path == NULL ) { goto error; - root_path [0] = '\0'; - } - else { - root_path = malloc (devicelen + 2); - if (root_path == NULL) + } + root_path[ 0 ] = '\0'; + } else { + root_path = malloc( devicelen + 2 ); + if ( root_path == NULL ) { goto error; + } - root_path = memcpy (root_path, device, devicelen); - root_path [devicelen] = '/'; - root_path [devicelen + 1] = '\0'; + root_path = memcpy( root_path, device, devicelen ); + root_path[ devicelen ] = '/'; + root_path[ devicelen + 1 ] = '\0'; } - fs = malloc (sizeof (*fs)); - if (fs == NULL) + fs = malloc( sizeof( *fs ) ); + if ( fs == NULL ) { goto error; + } fs->flags = 0; fs->nStreams = 0; fs->tftpStreams = 0; - tftp_initialize_net_config (&fs->tftp_config); - err_pos = _Tftpfs_Parse_options (data, &fs->tftp_config, &fs->flags); - if (err_pos != 0) { + tftp_initialize_net_config( &fs->tftp_config ); + err_pos = _Tftpfs_Parse_options( data, &fs->tftp_config, &fs->flags ); + if ( err_pos != 0 ) { printf( "TFTP FS: ERROR in mount options '%s'.\n" - "TFTP FS: Cannot parse from this point: '%s'\n", - ((char *) data), - ((char *) data) + (err_pos - 1) + "TFTP FS: Cannot parse from this point: '%s'\n", + ( (char *) data ), + ( (char *) data ) + ( err_pos - 1 ) ); errno_store = EINVAL; goto error; @@ -206,366 +212,375 @@ int rtems_tftpfs_initialize( * NOTE: This could be in an fsinfo for this filesystem type. */ - rtems_mutex_init (&fs->tftp_mutex, "TFTPFS"); + rtems_mutex_init( &fs->tftp_mutex, "TFTPFS" ); return 0; error: - free (fs); - free (root_path); + free( fs ); + free( root_path ); - rtems_set_errno_and_return_minus_one (errno_store); + rtems_set_errno_and_return_minus_one( errno_store ); } /* * Clear the pointer to a stream */ -static void -releaseStream (tftpfs_info_t *fs, size_t s) +static void releaseStream( tftpfs_info_t *fs, size_t s ) { - rtems_mutex_lock (&fs->tftp_mutex); - fs->tftpStreams[s] = NULL; - rtems_mutex_unlock (&fs->tftp_mutex); + rtems_mutex_lock( &fs->tftp_mutex ); + fs->tftpStreams[ s ] = NULL; + rtems_mutex_unlock( &fs->tftp_mutex ); } -static void -rtems_tftpfs_shutdown (rtems_filesystem_mount_table_entry_t* mt_entry) +static void rtems_tftpfs_shutdown( + rtems_filesystem_mount_table_entry_t *mt_entry +) { - tftpfs_info_t *fs = tftpfs_info_mount_table (mt_entry); + tftpfs_info_t *fs = tftpfs_info_mount_table( mt_entry ); size_t s; void *tp; - for (s = 0; s < fs->nStreams; s++) { - tp = fs->tftpStreams[s]; - releaseStream (fs, s); - _Tftp_Destroy(tp); + for ( s = 0; s < fs->nStreams; s++ ) { + tp = fs->tftpStreams[ s ]; + releaseStream( fs, s ); + _Tftp_Destroy( tp ); } - rtems_mutex_destroy (&fs->tftp_mutex); - free (fs); - free (mt_entry->mt_fs_root->location.node_access); + rtems_mutex_destroy( &fs->tftp_mutex ); + free( fs ); + free( mt_entry->mt_fs_root->location.node_access ); } /* * Convert a path to canonical form */ -static void -fixPath (char *path) +static void fixPath( char *path ) { - char *inp, *outp, *base; + char *inp, *outp, *base; - outp = inp = path; - base = NULL; - for (;;) { - if (inp[0] == '.') { - if (inp[1] == '\0') - break; - if (inp[1] == '/') { - inp += 2; - continue; + 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--; } - 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; - } + } + 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; + if ( base == NULL ) { + base = inp; + } + while ( inp[ 0 ] != '/' ) { + if ( ( *outp++ = *inp++ ) == '\0' ) { + return; + } + } + *outp++ = '/'; + while ( inp[ 0 ] == '/' ) { + inp++; + } + } + *outp = '\0'; + return; } -static void rtems_tftp_eval_path(rtems_filesystem_eval_path_context_t *self) +static void rtems_tftp_eval_path( rtems_filesystem_eval_path_context_t *self ) { - int eval_flags = rtems_filesystem_eval_path_get_flags (self); + int eval_flags = rtems_filesystem_eval_path_get_flags( self ); - if ((eval_flags & RTEMS_FS_MAKE) == 0) { - int rw = RTEMS_FS_PERMS_READ | RTEMS_FS_PERMS_WRITE; + if ( ( eval_flags & RTEMS_FS_MAKE ) == 0 ) { + int rw = RTEMS_FS_PERMS_READ | RTEMS_FS_PERMS_WRITE; - if ((eval_flags & rw) != rw) { - rtems_filesystem_location_info_t *currentloc = - rtems_filesystem_eval_path_get_currentloc (self); - char *current = currentloc->node_access; - size_t currentlen = strlen (current); - const char *path = rtems_filesystem_eval_path_get_path (self); - size_t pathlen = rtems_filesystem_eval_path_get_pathlen (self); - size_t len = currentlen + pathlen; + if ( ( eval_flags & rw ) != rw ) { + rtems_filesystem_location_info_t + *currentloc = rtems_filesystem_eval_path_get_currentloc( self ); + char *current = currentloc->node_access; + size_t currentlen = strlen( current ); + const char *path = rtems_filesystem_eval_path_get_path( self ); + size_t pathlen = rtems_filesystem_eval_path_get_pathlen( self ); + size_t len = currentlen + pathlen; - rtems_filesystem_eval_path_clear_path (self); + rtems_filesystem_eval_path_clear_path( self ); - current = realloc (current, len + 1); - if (current != NULL) { - memcpy (current + currentlen, path, pathlen); - current [len] = '\0'; - if (!rtems_tftp_is_directory (current, len)) { - fixPath (current); - } - currentloc->node_access = current; - } else { - rtems_filesystem_eval_path_error (self, ENOMEM); - } - } else { - rtems_filesystem_eval_path_error (self, EINVAL); + current = realloc( current, len + 1 ); + if ( current != NULL ) { + memcpy( current + currentlen, path, pathlen ); + current[ len ] = '\0'; + if ( !rtems_tftp_is_directory( current, len ) ) { + fixPath( current ); } + currentloc->node_access = current; + } else { + rtems_filesystem_eval_path_error( self, ENOMEM ); + } } else { - rtems_filesystem_eval_path_error (self, EIO); + rtems_filesystem_eval_path_error( self, EINVAL ); } + } else { + rtems_filesystem_eval_path_error( self, EIO ); + } } /* * 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, - int oflag + rtems_libio_t *iop, + char *full_path_name, + int oflag ) { - tftpfs_info_t *fs; - void *tp; - size_t s; - char *cp1; - char *remoteFilename; - char *hostname; - int err; + tftpfs_info_t *fs; + void *tp; + size_t s; + char *cp1; + char *remoteFilename; + char *hostname; + int err; - /* + /* * Get the file system info. */ - fs = tftpfs_info_iop (iop); + fs = tftpfs_info_iop( iop ); - /* + /* * Extract the host name component */ - if (*full_path_name == '/') - full_path_name++; + if ( *full_path_name == '/' ) { + full_path_name++; + } - hostname = full_path_name; - cp1 = strchr (full_path_name, ':'); - if (!cp1) { - return EINVAL; /* No ':' in path: no hostname or no filename */ - } else { - *cp1 = '\0'; - ++cp1; - } + hostname = full_path_name; + cp1 = strchr( full_path_name, ':' ); + if ( !cp1 ) { + return EINVAL; /* No ':' in path: no hostname or no filename */ + } else { + *cp1 = '\0'; + ++cp1; + } - /* + /* * Extract file pathname component */ - if (*cp1 == '\0') - return ENOENT; - remoteFilename = cp1; + if ( *cp1 == '\0' ) { + return ENOENT; + } + remoteFilename = cp1; - /* + /* * Establish the connection */ - err = tftp_open ( - hostname, - remoteFilename, - (oflag & O_ACCMODE) == O_RDONLY, - &fs->tftp_config, - &tp - ); - if (err != 0) { - return err; - } + err = tftp_open( + hostname, + remoteFilename, + ( oflag & O_ACCMODE ) == O_RDONLY, + &fs->tftp_config, + &tp + ); + if ( err != 0 ) { + return err; + } - /* + /* * Find a free stream */ - rtems_mutex_lock (&fs->tftp_mutex); - for (s = 0 ; s < fs->nStreams ; s++) { - if (fs->tftpStreams[s] == NULL) - break; + rtems_mutex_lock( &fs->tftp_mutex ); + for ( s = 0; s < fs->nStreams; s++ ) { + if ( fs->tftpStreams[ s ] == NULL ) { + break; } - if (s == fs->nStreams) { - /* + } + if ( s == fs->nStreams ) { + /* * Reallocate stream pointers * Guard against the case where realloc() returns NULL. */ - void **np; + void **np; - np = realloc (fs->tftpStreams, ++fs->nStreams * sizeof *fs->tftpStreams); - if (np == NULL) { - rtems_mutex_unlock (&fs->tftp_mutex); - tftp_close( tp ); - return ENOMEM; - } - fs->tftpStreams = np; + np = realloc( fs->tftpStreams, ++fs->nStreams * sizeof *fs->tftpStreams ); + if ( np == NULL ) { + rtems_mutex_unlock( &fs->tftp_mutex ); + tftp_close( tp ); + return ENOMEM; } - fs->tftpStreams[s] = tp; - rtems_mutex_unlock (&fs->tftp_mutex); - iop->data0 = s; - iop->data1 = tp; + fs->tftpStreams = np; + } + fs->tftpStreams[ s ] = tp; + rtems_mutex_unlock( &fs->tftp_mutex ); + iop->data0 = s; + iop->data1 = tp; - return 0; + return 0; } static int rtems_tftp_open( - rtems_libio_t *iop, - const char *new_name, - int oflag, - mode_t mode + rtems_libio_t *iop, + const char *new_name, + int oflag, + mode_t mode ) { - (void) new_name; - (void) mode; + (void) new_name; + (void) mode; - tftpfs_info_t *fs; - char *full_path_name; - int err; + tftpfs_info_t *fs; + char *full_path_name; + int err; - full_path_name = iop->pathinfo.node_access; + full_path_name = iop->pathinfo.node_access; - if (rtems_tftp_is_directory (full_path_name, strlen (full_path_name))) { - rtems_set_errno_and_return_minus_one (ENOTSUP); - } + if ( rtems_tftp_is_directory( full_path_name, strlen( full_path_name ) ) ) { + rtems_set_errno_and_return_minus_one( ENOTSUP ); + } - /* + /* * Get the file system info. */ - fs = tftpfs_info_iop (iop); + fs = tftpfs_info_iop( iop ); - if (fs->flags & TFTPFS_VERBOSE) - printf ("TFTPFS: %s\n", full_path_name); + if ( fs->flags & TFTPFS_VERBOSE ) { + printf( "TFTPFS: %s\n", full_path_name ); + } - err = rtems_tftp_open_worker (iop, full_path_name, oflag); - if (err != 0) { - rtems_set_errno_and_return_minus_one (err); - } + err = rtems_tftp_open_worker( iop, full_path_name, oflag ); + if ( err != 0 ) { + rtems_set_errno_and_return_minus_one( err ); + } - return 0; + return 0; } /* * Read from a TFTP stream */ static ssize_t rtems_tftp_read( - rtems_libio_t *iop, - void *buffer, - size_t count + rtems_libio_t *iop, + void *buffer, + size_t count ) { - void *tp = iop->data1; - ssize_t result = tftp_read (tp, buffer, count); + void *tp = iop->data1; + ssize_t result = tftp_read( tp, buffer, count ); - if (result < 0) { - rtems_set_errno_and_return_minus_one (-result); - } - return result; + if ( result < 0 ) { + rtems_set_errno_and_return_minus_one( -result ); + } + return result; } /* * Close a TFTP stream */ -static int rtems_tftp_close( - rtems_libio_t *iop -) +static int rtems_tftp_close( rtems_libio_t *iop ) { - tftpfs_info_t *fs; - void *tp = iop->data1; - int e = 0; + tftpfs_info_t *fs; + void *tp = iop->data1; + int e = 0; - /* + /* * Get the file system info. */ - fs = tftpfs_info_iop (iop); + fs = tftpfs_info_iop( iop ); - if (!tp) - rtems_set_errno_and_return_minus_one (EIO); + if ( !tp ) { + rtems_set_errno_and_return_minus_one( EIO ); + } - releaseStream (fs, iop->data0); - e = tftp_close (tp); - if (e) - rtems_set_errno_and_return_minus_one (e); - return 0; + releaseStream( fs, iop->data0 ); + e = tftp_close( tp ); + if ( e ) { + rtems_set_errno_and_return_minus_one( e ); + } + return 0; } static ssize_t rtems_tftp_write( - rtems_libio_t *iop, - const void *buffer, - size_t count + rtems_libio_t *iop, + const void *buffer, + size_t count ) { - void *tp = iop->data1; - ssize_t result = tftp_write (tp, buffer, count); + void *tp = iop->data1; + ssize_t result = tftp_write( tp, buffer, count ); - if (result < 0) { - rtems_set_errno_and_return_minus_one (-result); - } - return result; + if ( result < 0 ) { + rtems_set_errno_and_return_minus_one( -result ); + } + return result; } /* * Dummy version to let fopen(xxxx,"w") work properly. */ static int rtems_tftp_ftruncate( - rtems_libio_t *iop RTEMS_UNUSED, - off_t count RTEMS_UNUSED + rtems_libio_t *iop RTEMS_UNUSED, + off_t count RTEMS_UNUSED ) { - return 0; + return 0; } static int rtems_tftp_fstat( - const rtems_filesystem_location_info_t *loc, - struct stat *buf + const rtems_filesystem_location_info_t *loc, + struct stat *buf ) { - const char *path = loc->node_access; - size_t pathlen = strlen (path); + const char *path = loc->node_access; + size_t pathlen = strlen( path ); - buf->st_mode = S_IRWXU | S_IRWXG | S_IRWXO - | (rtems_tftp_is_directory (path, pathlen) ? S_IFDIR : S_IFREG); + buf->st_mode = S_IRWXU | S_IRWXG | S_IRWXO | + ( rtems_tftp_is_directory( path, pathlen ) ? S_IFDIR + : S_IFREG ); - return 0; + return 0; } -static int rtems_tftp_clone( - rtems_filesystem_location_info_t *loc -) +static int rtems_tftp_clone( rtems_filesystem_location_info_t *loc ) { - int rv = 0; + int rv = 0; - loc->node_access = strdup (loc->node_access); + loc->node_access = strdup( loc->node_access ); - if (loc->node_access == NULL) { - errno = ENOMEM; - rv = -1; - } + if ( loc->node_access == NULL ) { + errno = ENOMEM; + rv = -1; + } - return rv; + return rv; } static void rtems_tftp_free_node_info( - const rtems_filesystem_location_info_t *loc + const rtems_filesystem_location_info_t *loc ) { - free (loc->node_access); + free( loc->node_access ); } static bool rtems_tftp_are_nodes_equal( @@ -573,46 +588,46 @@ static bool rtems_tftp_are_nodes_equal( const rtems_filesystem_location_info_t *b ) { - return strcmp (a->node_access, b->node_access) == 0; + return strcmp( a->node_access, b->node_access ) == 0; } -static const rtems_filesystem_operations_table rtems_tftp_ops = { - .lock_h = rtems_filesystem_default_lock, - .unlock_h = rtems_filesystem_default_unlock, - .eval_path_h = rtems_tftp_eval_path, - .link_h = rtems_filesystem_default_link, - .are_nodes_equal_h = rtems_tftp_are_nodes_equal, - .mknod_h = rtems_filesystem_default_mknod, - .rmnod_h = rtems_filesystem_default_rmnod, - .fchmod_h = rtems_filesystem_default_fchmod, - .chown_h = rtems_filesystem_default_chown, - .clonenod_h = rtems_tftp_clone, - .freenod_h = rtems_tftp_free_node_info, - .mount_h = rtems_filesystem_default_mount, - .unmount_h = rtems_filesystem_default_unmount, - .fsunmount_me_h = rtems_tftpfs_shutdown, - .utimens_h = rtems_filesystem_default_utimens, - .symlink_h = rtems_filesystem_default_symlink, - .readlink_h = rtems_filesystem_default_readlink, - .rename_h = rtems_filesystem_default_rename, - .statvfs_h = rtems_filesystem_default_statvfs +static const rtems_filesystem_operations_table rtems_tftp_ops = { + .lock_h = rtems_filesystem_default_lock, + .unlock_h = rtems_filesystem_default_unlock, + .eval_path_h = rtems_tftp_eval_path, + .link_h = rtems_filesystem_default_link, + .are_nodes_equal_h = rtems_tftp_are_nodes_equal, + .mknod_h = rtems_filesystem_default_mknod, + .rmnod_h = rtems_filesystem_default_rmnod, + .fchmod_h = rtems_filesystem_default_fchmod, + .chown_h = rtems_filesystem_default_chown, + .clonenod_h = rtems_tftp_clone, + .freenod_h = rtems_tftp_free_node_info, + .mount_h = rtems_filesystem_default_mount, + .unmount_h = rtems_filesystem_default_unmount, + .fsunmount_me_h = rtems_tftpfs_shutdown, + .utimens_h = rtems_filesystem_default_utimens, + .symlink_h = rtems_filesystem_default_symlink, + .readlink_h = rtems_filesystem_default_readlink, + .rename_h = rtems_filesystem_default_rename, + .statvfs_h = rtems_filesystem_default_statvfs }; static const rtems_filesystem_file_handlers_r rtems_tftp_handlers = { - .open_h = rtems_tftp_open, - .close_h = rtems_tftp_close, - .read_h = rtems_tftp_read, - .write_h = rtems_tftp_write, - .ioctl_h = rtems_filesystem_default_ioctl, - .lseek_h = rtems_filesystem_default_lseek, - .fstat_h = rtems_tftp_fstat, - .ftruncate_h = rtems_tftp_ftruncate, - .fsync_h = rtems_filesystem_default_fsync_or_fdatasync, - .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, - .fcntl_h = rtems_filesystem_default_fcntl, - .kqfilter_h = rtems_filesystem_default_kqfilter, - .mmap_h = rtems_filesystem_default_mmap, - .poll_h = rtems_filesystem_default_poll, - .readv_h = rtems_filesystem_default_readv, - .writev_h = rtems_filesystem_default_writev + .open_h = rtems_tftp_open, + .close_h = rtems_tftp_close, + .read_h = rtems_tftp_read, + .write_h = rtems_tftp_write, + .ioctl_h = rtems_filesystem_default_ioctl, + .lseek_h = rtems_filesystem_default_lseek, + .fstat_h = rtems_tftp_fstat, + .ftruncate_h = rtems_tftp_ftruncate, + .fsync_h = rtems_filesystem_default_fsync_or_fdatasync, + .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, + .fcntl_h = rtems_filesystem_default_fcntl, + .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, + .poll_h = rtems_filesystem_default_poll, + .readv_h = rtems_filesystem_default_readv, + .writev_h = rtems_filesystem_default_writev };