2
* Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License as
6
* published by the Free Software Foundation; either version 2 of the
7
* License, or any later version.
9
* This program is distributed in the hope that it will be useful, but
10
* WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
FILE_LICENCE ( GPL2_OR_LATER );
24
#include <gpxe/xfer.h>
26
#include <gpxe/socket.h>
27
#include <gpxe/open.h>
31
* Data transfer interface opening
38
* @v xfer Data transfer interface
40
* @ret rc Return status code
42
* The URI will be regarded as being relative to the current working
45
int xfer_open_uri ( struct xfer_interface *xfer, struct uri *uri ) {
46
struct uri_opener *opener;
47
struct uri *resolved_uri;
51
resolved_uri = resolve_uri ( cwuri, uri );
55
/* Find opener which supports this URI scheme */
56
for_each_table_entry ( opener, URI_OPENERS ) {
57
if ( strcmp ( resolved_uri->scheme, opener->scheme ) == 0 ) {
58
DBGC ( xfer, "XFER %p opening %s URI\n",
59
xfer, opener->scheme );
60
rc = opener->open ( xfer, resolved_uri );
64
DBGC ( xfer, "XFER %p attempted to open unsupported URI scheme "
65
"\"%s\"\n", xfer, resolved_uri->scheme );
68
uri_put ( resolved_uri );
75
* @v xfer Data transfer interface
76
* @v uri_string URI string (e.g. "http://etherboot.org/kernel")
77
* @ret rc Return status code
79
* The URI will be regarded as being relative to the current working
82
int xfer_open_uri_string ( struct xfer_interface *xfer,
83
const char *uri_string ) {
87
DBGC ( xfer, "XFER %p opening URI %s\n", xfer, uri_string );
89
uri = parse_uri ( uri_string );
93
rc = xfer_open_uri ( xfer, uri );
102
* @v xfer Data transfer interface
103
* @v semantics Communication semantics (e.g. SOCK_STREAM)
104
* @v peer Peer socket address
105
* @v local Local socket address, or NULL
106
* @ret rc Return status code
108
int xfer_open_socket ( struct xfer_interface *xfer, int semantics,
109
struct sockaddr *peer, struct sockaddr *local ) {
110
struct socket_opener *opener;
112
DBGC ( xfer, "XFER %p opening (%s,%s) socket\n", xfer,
113
socket_semantics_name ( semantics ),
114
socket_family_name ( peer->sa_family ) );
116
for_each_table_entry ( opener, SOCKET_OPENERS ) {
117
if ( ( opener->semantics == semantics ) &&
118
( opener->family == peer->sa_family ) ) {
119
return opener->open ( xfer, peer, local );
123
DBGC ( xfer, "XFER %p attempted to open unsupported socket type "
124
"(%s,%s)\n", xfer, socket_semantics_name ( semantics ),
125
socket_family_name ( peer->sa_family ) );
132
* @v xfer Data transfer interface
133
* @v type Location type
134
* @v args Remaining arguments depend upon location type
135
* @ret rc Return status code
137
int xfer_vopen ( struct xfer_interface *xfer, int type, va_list args ) {
139
case LOCATION_URI_STRING: {
140
const char *uri_string = va_arg ( args, const char * );
142
return xfer_open_uri_string ( xfer, uri_string ); }
144
struct uri *uri = va_arg ( args, struct uri * );
146
return xfer_open_uri ( xfer, uri ); }
147
case LOCATION_SOCKET: {
148
int semantics = va_arg ( args, int );
149
struct sockaddr *peer = va_arg ( args, struct sockaddr * );
150
struct sockaddr *local = va_arg ( args, struct sockaddr * );
152
return xfer_open_socket ( xfer, semantics, peer, local ); }
154
DBGC ( xfer, "XFER %p attempted to open unsupported location "
155
"type %d\n", xfer, type );
163
* @v xfer Data transfer interface
164
* @v type Location type
165
* @v ... Remaining arguments depend upon location type
166
* @ret rc Return status code
168
int xfer_open ( struct xfer_interface *xfer, int type, ... ) {
172
va_start ( args, type );
173
rc = xfer_vopen ( xfer, type, args );
181
* @v xfer Data transfer interface
182
* @v type Location type
183
* @v args Remaining arguments depend upon location type
184
* @ret rc Return status code
186
* This will close the existing connection and open a new connection
187
* using xfer_vopen(). It is intended to be used as a .vredirect
190
int xfer_vreopen ( struct xfer_interface *xfer, int type, va_list args ) {
192
/* Close existing connection */
193
xfer_close ( xfer, 0 );
195
/* Open new location */
196
return xfer_vopen ( xfer, type, args );