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
20 FILE_LICENCE ( GPL2_OR_LATER );
25 #include <ipxe/xfer.h>
27 #include <ipxe/socket.h>
28 #include <ipxe/open.h>
32 * Data transfer interface opening
37 * Find opener for URI scheme
39 * @v scheme URI scheme
40 * @ret opener Opener, or NULL
42 struct uri_opener * xfer_uri_opener ( const char *scheme ) {
43 struct uri_opener *opener;
45 for_each_table_entry ( opener, URI_OPENERS ) {
46 if ( strcmp ( scheme, opener->scheme ) == 0 )
55 * @v intf Data transfer interface
57 * @ret rc Return status code
59 * The URI will be regarded as being relative to the current working
62 int xfer_open_uri ( struct interface *intf, struct uri *uri ) {
63 struct uri_opener *opener;
64 struct uri *resolved_uri;
68 resolved_uri = resolve_uri ( cwuri, uri );
69 if ( ! resolved_uri ) {
74 /* Find opener which supports this URI scheme */
75 opener = xfer_uri_opener ( resolved_uri->scheme );
77 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open "
78 "unsupported URI scheme \"%s\"\n",
79 INTF_DBG ( intf ), resolved_uri->scheme );
85 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening %s URI\n",
86 INTF_DBG ( intf ), resolved_uri->scheme );
87 if ( ( rc = opener->open ( intf, resolved_uri ) ) != 0 ) {
88 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " could not open: "
89 "%s\n", INTF_DBG ( intf ), strerror ( rc ) );
95 uri_put ( resolved_uri );
103 * @v intf Data transfer interface
104 * @v uri_string URI string (e.g. "http://ipxe.org/kernel")
105 * @ret rc Return status code
107 * The URI will be regarded as being relative to the current working
110 int xfer_open_uri_string ( struct interface *intf,
111 const char *uri_string ) {
115 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening URI %s\n",
116 INTF_DBG ( intf ), uri_string );
118 uri = parse_uri ( uri_string );
122 rc = xfer_open_uri ( intf, uri );
131 * @v intf Data transfer interface
132 * @v semantics Communication semantics (e.g. SOCK_STREAM)
133 * @v peer Peer socket address
134 * @v local Local socket address, or NULL
135 * @ret rc Return status code
137 int xfer_open_socket ( struct interface *intf, int semantics,
138 struct sockaddr *peer, struct sockaddr *local ) {
139 struct socket_opener *opener;
141 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening (%s,%s) socket\n",
142 INTF_DBG ( intf ), socket_semantics_name ( semantics ),
143 socket_family_name ( peer->sa_family ) );
145 for_each_table_entry ( opener, SOCKET_OPENERS ) {
146 if ( ( opener->semantics == semantics ) &&
147 ( opener->family == peer->sa_family ) ) {
148 return opener->open ( intf, peer, local );
152 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open "
153 "unsupported socket type (%s,%s)\n",
154 INTF_DBG ( intf ), socket_semantics_name ( semantics ),
155 socket_family_name ( peer->sa_family ) );
162 * @v intf Data transfer interface
163 * @v type Location type
164 * @v args Remaining arguments depend upon location type
165 * @ret rc Return status code
167 int xfer_vopen ( struct interface *intf, int type, va_list args ) {
169 case LOCATION_URI_STRING: {
170 const char *uri_string = va_arg ( args, const char * );
172 return xfer_open_uri_string ( intf, uri_string ); }
174 struct uri *uri = va_arg ( args, struct uri * );
176 return xfer_open_uri ( intf, uri ); }
177 case LOCATION_SOCKET: {
178 int semantics = va_arg ( args, int );
179 struct sockaddr *peer = va_arg ( args, struct sockaddr * );
180 struct sockaddr *local = va_arg ( args, struct sockaddr * );
182 return xfer_open_socket ( intf, semantics, peer, local ); }
184 DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to "
185 "open unsupported location type %d\n",
186 INTF_DBG ( intf ), type );
194 * @v intf Data transfer interface
195 * @v type Location type
196 * @v ... Remaining arguments depend upon location type
197 * @ret rc Return status code
199 int xfer_open ( struct interface *intf, int type, ... ) {
203 va_start ( args, type );
204 rc = xfer_vopen ( intf, type, args );
212 * @v intf Data transfer interface
213 * @v type Location type
214 * @v args Remaining arguments depend upon location type
215 * @ret rc Return status code
217 * This will close the existing connection and open a new connection
218 * using xfer_vopen(). It is intended to be used as a .vredirect
221 int xfer_vreopen ( struct interface *intf, int type, va_list args ) {
223 /* Close existing connection */
224 intf_restart ( intf, 0 );
226 /* Open new location */
227 return xfer_vopen ( intf, type, args );