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., 51 Franklin Street, Fifth Floor, Boston, MA
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
29 #include <ipxe/xfer.h>
31 #include <ipxe/socket.h>
32 #include <ipxe/open.h>
36 * Data transfer interface opening
41 * Find opener for URI scheme
43 * @v scheme URI scheme
44 * @ret opener Opener, or NULL
46 struct uri_opener * xfer_uri_opener ( const char *scheme ) {
47 struct uri_opener *opener;
49 for_each_table_entry ( opener, URI_OPENERS ) {
50 if ( strcmp ( scheme, opener->scheme ) == 0 )
59 * @v intf Data transfer interface
61 * @ret rc Return status code
63 * The URI will be regarded as being relative to the current working
66 int xfer_open_uri ( struct interface *intf, struct uri *uri ) {
67 struct uri_opener *opener;
68 struct uri *resolved_uri;
72 resolved_uri = resolve_uri ( cwuri, uri );
73 if ( ! resolved_uri ) {
78 /* Find opener which supports this URI scheme */
79 opener = xfer_uri_opener ( resolved_uri->scheme );
81 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open "
82 "unsupported URI scheme \"%s\"\n",
83 INTF_DBG ( intf ), resolved_uri->scheme );
89 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening %s URI\n",
90 INTF_DBG ( intf ), resolved_uri->scheme );
91 if ( ( rc = opener->open ( intf, resolved_uri ) ) != 0 ) {
92 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " could not open: "
93 "%s\n", INTF_DBG ( intf ), strerror ( rc ) );
99 uri_put ( resolved_uri );
107 * @v intf Data transfer interface
108 * @v uri_string URI string (e.g. "http://ipxe.org/kernel")
109 * @ret rc Return status code
111 * The URI will be regarded as being relative to the current working
114 int xfer_open_uri_string ( struct interface *intf,
115 const char *uri_string ) {
119 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening URI %s\n",
120 INTF_DBG ( intf ), uri_string );
122 uri = parse_uri ( uri_string );
126 rc = xfer_open_uri ( intf, uri );
135 * @v intf Data transfer interface
136 * @v semantics Communication semantics (e.g. SOCK_STREAM)
137 * @v peer Peer socket address
138 * @v local Local socket address, or NULL
139 * @ret rc Return status code
141 int xfer_open_socket ( struct interface *intf, int semantics,
142 struct sockaddr *peer, struct sockaddr *local ) {
143 struct socket_opener *opener;
145 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening (%s,%s) socket\n",
146 INTF_DBG ( intf ), socket_semantics_name ( semantics ),
147 socket_family_name ( peer->sa_family ) );
149 for_each_table_entry ( opener, SOCKET_OPENERS ) {
150 if ( ( opener->semantics == semantics ) &&
151 ( opener->family == peer->sa_family ) ) {
152 return opener->open ( intf, peer, local );
156 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open "
157 "unsupported socket type (%s,%s)\n",
158 INTF_DBG ( intf ), socket_semantics_name ( semantics ),
159 socket_family_name ( peer->sa_family ) );
166 * @v intf Data transfer interface
167 * @v type Location type
168 * @v args Remaining arguments depend upon location type
169 * @ret rc Return status code
171 int xfer_vopen ( struct interface *intf, int type, va_list args ) {
173 case LOCATION_URI_STRING: {
174 const char *uri_string = va_arg ( args, const char * );
176 return xfer_open_uri_string ( intf, uri_string ); }
178 struct uri *uri = va_arg ( args, struct uri * );
180 return xfer_open_uri ( intf, uri ); }
181 case LOCATION_SOCKET: {
182 int semantics = va_arg ( args, int );
183 struct sockaddr *peer = va_arg ( args, struct sockaddr * );
184 struct sockaddr *local = va_arg ( args, struct sockaddr * );
186 return xfer_open_socket ( intf, semantics, peer, local ); }
188 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to "
189 "open unsupported location type %d\n",
190 INTF_DBG ( intf ), type );
198 * @v intf Data transfer interface
199 * @v type Location type
200 * @v ... Remaining arguments depend upon location type
201 * @ret rc Return status code
203 int xfer_open ( struct interface *intf, int type, ... ) {
207 va_start ( args, type );
208 rc = xfer_vopen ( intf, type, args );
216 * @v intf Data transfer interface
217 * @v type Location type
218 * @v args Remaining arguments depend upon location type
219 * @ret rc Return status code
221 * This will close the existing connection and open a new connection
222 * using xfer_vopen(). It is intended to be used as a .vredirect
225 int xfer_vreopen ( struct interface *intf, int type, va_list args ) {
227 /* Close existing connection */
228 intf_restart ( intf, 0 );
230 /* Open new location */
231 return xfer_vopen ( intf, type, args );