diff options
Diffstat (limited to 'src/usr')
| -rw-r--r-- | src/usr/dhcpmgmt.c | 12 | ||||
| -rw-r--r-- | src/usr/fetch.c | 63 |
2 files changed, 46 insertions, 29 deletions
diff --git a/src/usr/dhcpmgmt.c b/src/usr/dhcpmgmt.c index 6042f8b2c..0e36d5557 100644 --- a/src/usr/dhcpmgmt.c +++ b/src/usr/dhcpmgmt.c @@ -23,6 +23,7 @@ #include <gpxe/dhcp.h> #include <gpxe/async.h> #include <gpxe/netdevice.h> +#include <usr/ifmgmt.h> #include <usr/dhcpmgmt.h> /** @file @@ -43,6 +44,7 @@ int dhcp ( struct net_device *netdev ) { struct in_addr address = { htonl ( 0 ) }; struct in_addr netmask = { htonl ( 0 ) }; struct in_addr gateway = { INADDR_NONE }; + struct async async; int rc; /* Check we can open the interface first */ @@ -60,8 +62,14 @@ int dhcp ( struct net_device *netdev ) { printf ( "DHCP (%s %s)...", netdev->name, netdev_hwaddr ( netdev ) ); memset ( &dhcp, 0, sizeof ( dhcp ) ); dhcp.netdev = netdev; - if ( ( rc = async_wait ( start_dhcp ( &dhcp ) ) ) != 0 ) { - printf ( "failed\n" ); + async_init_orphan ( &async ); + if ( ( rc = start_dhcp ( &dhcp, &async ) ) != 0 ) { + printf ( "could not start (%s)\n", strerror ( rc ) ); + return rc; + } + async_wait ( &async, &rc, 1 ); + if ( rc != 0 ) { + printf ( "failed (%s)\n", strerror ( rc ) ); return rc; } printf ( "done\n" ); diff --git a/src/usr/fetch.c b/src/usr/fetch.c index ce0fea954..9e3c2de6f 100644 --- a/src/usr/fetch.c +++ b/src/usr/fetch.c @@ -23,10 +23,12 @@ * */ +#include <errno.h> #include <vsprintf.h> #include <gpxe/emalloc.h> #include <gpxe/ebuffer.h> #include <gpxe/image.h> +#include <gpxe/uri.h> #include <usr/fetch.h> #include <byteswap.h> @@ -46,32 +48,30 @@ * caller is responsible for eventually freeing the buffer with * efree(). */ -int fetch ( const char *filename, userptr_t *data, size_t *len ) { +int fetch ( const char *uri_string, userptr_t *data, size_t *len ) { + struct uri *uri; struct buffer buffer; int rc; + /* Parse the URI */ + uri = parse_uri ( uri_string ); + if ( ! uri ) { + rc = -ENOMEM; + goto err_parse_uri; + } + /* Allocate an expandable buffer to hold the file */ - if ( ( rc = ebuffer_alloc ( &buffer, 0 ) ) != 0 ) - return rc; + if ( ( rc = ebuffer_alloc ( &buffer, 0 ) ) != 0 ) { + goto err_ebuffer_alloc; + } #warning "Temporary pseudo-URL parsing code" /* Retrieve the file */ - union { - struct sockaddr_tcpip st; - struct sockaddr_in sin; - } server; - struct tftp_session tftp; - struct http_request http; - struct async_operation *aop; - - memset ( &tftp, 0, sizeof ( tftp ) ); - memset ( &http, 0, sizeof ( http ) ); - memset ( &server, 0, sizeof ( server ) ); - server.sin.sin_family = AF_INET; - find_global_dhcp_ipv4_option ( DHCP_EB_SIADDR, - &server.sin.sin_addr ); + struct async async; + int ( * download ) ( struct uri *uri, struct buffer *buffer, + struct async *parent ); #if 0 server.sin.sin_port = htons ( TFTP_PORT ); @@ -80,22 +80,31 @@ int fetch ( const char *filename, userptr_t *data, size_t *len ) { tftp.buffer = &buffer; aop = tftp_get ( &tftp ); #else - server.sin.sin_port = htons ( HTTP_PORT ); - memcpy ( &http.server, &server, sizeof ( http.server ) ); - http.hostname = inet_ntoa ( server.sin.sin_addr ); - http.filename = filename; - http.buffer = &buffer; - aop = http_get ( &http ); + download = http_get; #endif - if ( ( rc = async_wait ( aop ) ) != 0 ) { - efree ( buffer.addr ); - return rc; - } + async_init_orphan ( &async ); + if ( ( rc = download ( uri, &buffer, &async ) ) != 0 ) + goto err; + uri = NULL; + async_wait ( &async, &rc, 1 ); + if ( rc != 0 ) + goto err; /* Fill in buffer address and length */ *data = buffer.addr; *len = buffer.fill; + /* Release temporary resources. The ebuffer storage is now + * owned by our caller, so we don't free it. + */ + return 0; + + err: + efree ( buffer.addr ); + err_ebuffer_alloc: + free_uri ( uri ); + err_parse_uri: + return rc; } |
