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
);