diff options
author | Michael Brown | 2007-01-15 10:58:26 +0100 |
---|---|---|
committer | Michael Brown | 2007-01-15 10:58:26 +0100 |
commit | df0397f33469f9e3ed1d54cedd5fe6282881e3fc (patch) | |
tree | 91bef77876d4799fcd0cdaa260fb11805a72baa6 /src/net/udp/tftp.c | |
parent | Protocol's get() method no longer takes ownership of the URI. HTTP is the (diff) | |
download | ipxe-df0397f33469f9e3ed1d54cedd5fe6282881e3fc.tar.gz ipxe-df0397f33469f9e3ed1d54cedd5fe6282881e3fc.tar.xz ipxe-df0397f33469f9e3ed1d54cedd5fe6282881e3fc.zip |
Update TFTP and FTP to take the same temporary URI scheme as HTTP
Diffstat (limited to 'src/net/udp/tftp.c')
-rw-r--r-- | src/net/udp/tftp.c | 82 |
1 files changed, 65 insertions, 17 deletions
diff --git a/src/net/udp/tftp.c b/src/net/udp/tftp.c index 69650ab0..992b82ba 100644 --- a/src/net/udp/tftp.c +++ b/src/net/udp/tftp.c @@ -26,6 +26,7 @@ #include <vsprintf.h> #include <gpxe/async.h> #include <gpxe/tftp.h> +#include <gpxe/uri.h> /** @file * @@ -203,7 +204,7 @@ static int tftp_send_rrq ( struct tftp_session *tftp, void *buf, size_t len ) { void *data; void *end; - DBGC ( tftp, "TFTP %p requesting \"%s\"\n", tftp, tftp->filename ); + DBGC ( tftp, "TFTP %p requesting \"%s\"\n", tftp, tftp->uri->path ); data = rrq->data; end = ( buf + len ); @@ -211,7 +212,7 @@ static int tftp_send_rrq ( struct tftp_session *tftp, void *buf, size_t len ) { goto overflow; data += ( snprintf ( data, ( end - data ), "%s%coctet%cblksize%c%d%ctsize%c0", - tftp->filename, 0, 0, 0, + tftp->uri->path, 0, 0, 0, tftp->request_blksize, 0, 0 ) + 1 ); if ( data > end ) goto overflow; @@ -453,37 +454,84 @@ static struct udp_operations tftp_udp_operations = { }; /** + * Reap asynchronous operation + * + * @v async Asynchronous operation + */ +static void tftp_reap ( struct async *async ) { + struct tftp_session *tftp = + container_of ( async, struct tftp_session, async ); + + free ( tftp ); +} + +/** TFTP asynchronous operations */ +static struct async_operations tftp_async_operations = { + .reap = tftp_reap, +}; + +/** * Initiate TFTP download * - * @v tftp TFTP session - * @ret aop Asynchronous operation + * @v uri Uniform Resource Identifier + * @v buffer Buffer into which to download file + * @v parent Parent asynchronous operation + * @ret rc Return status code */ -struct async_operation * tftp_get ( struct tftp_session *tftp ) { +int tftp_get ( struct uri *uri, struct buffer *buffer, struct async *parent ) { + struct tftp_session *tftp = NULL; int rc; - assert ( tftp->filename != NULL ); - assert ( tftp->buffer != NULL ); - assert ( tftp->udp.peer.st_family != 0 ); + /* Sanity checks */ + if ( ! uri->path ) { + rc = -EINVAL; + goto err; + } - /* Initialise TFTP session */ + /* Allocate and populate TFTP structure */ + tftp = malloc ( sizeof ( *tftp ) ); + if ( ! tftp ) { + rc = -ENOMEM; + goto err; + } + memset ( tftp, 0, sizeof ( *tftp ) ); + tftp->uri = uri; + tftp->buffer = buffer; if ( ! tftp->request_blksize ) tftp->request_blksize = TFTP_MAX_BLKSIZE; tftp->blksize = TFTP_DEFAULT_BLKSIZE; - tftp->tsize = 0; - tftp->tid = 0; tftp->state = -1; tftp->udp.udp_op = &tftp_udp_operations; tftp->timer.expired = tftp_timer_expired; - /* Open UDP connection */ - if ( ( rc = udp_open ( &tftp->udp, 0 ) ) != 0 ) { - async_done ( &tftp->async, rc ); - goto out; + +#warning "Quick name resolution hack" + union { + struct sockaddr_tcpip st; + struct sockaddr_in sin; + } server; + server.sin.sin_port = htons ( TFTP_PORT ); + server.sin.sin_family = AF_INET; + if ( inet_aton ( uri->host, &server.sin.sin_addr ) == 0 ) { + rc = -EINVAL; + goto err; } + udp_connect ( &tftp->udp, &server.st ); + + + /* Open UDP connection */ + if ( ( rc = udp_open ( &tftp->udp, 0 ) ) != 0 ) + goto err; /* Transmit initial RRQ */ tftp_send_packet ( tftp ); - out: - return &tftp->async; + async_init ( &tftp->async, &tftp_async_operations, parent ); + return 0; + + err: + DBGC ( tftp, "TFTP %p could not create session: %s\n", + tftp, strerror ( rc ) ); + free ( tftp ); + return rc; } |