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.
22 #include <gpxe/xfer.h>
24 #include <gpxe/socket.h>
25 #include <gpxe/open.h>
29 * Data transfer interface opening
33 /** Registered URI openers */
34 static struct uri_opener uri_openers
[0]
35 __table_start ( struct uri_opener
, uri_openers
);
36 static struct uri_opener uri_openers_end
[0]
37 __table_end ( struct uri_opener
, uri_openers
);
39 /** Registered socket openers */
40 static struct socket_opener socket_openers
[0]
41 __table_start ( struct socket_opener
, socket_openers
);
42 static struct socket_opener socket_openers_end
[0]
43 __table_end ( struct socket_opener
, socket_openers
);
48 * @v xfer Data transfer interface
50 * @ret rc Return status code
52 * The URI will be regarded as being relative to the current working
55 int xfer_open_uri ( struct xfer_interface
*xfer
, struct uri
*uri
) {
56 struct uri_opener
*opener
;
57 struct uri
*resolved_uri
;
61 resolved_uri
= resolve_uri ( cwuri
, uri
);
65 /* Find opener which supports this URI scheme */
66 for ( opener
= uri_openers
; opener
< uri_openers_end
; opener
++ ) {
67 if ( strcmp ( resolved_uri
->scheme
, opener
->scheme
) == 0 ) {
68 rc
= opener
->open ( xfer
, resolved_uri
);
72 DBGC ( xfer
, "XFER %p attempted to open unsupported URI scheme "
73 "\"%s\"\n", xfer
, resolved_uri
->scheme
);
76 uri_put ( resolved_uri
);
83 * @v xfer Data transfer interface
84 * @v uri_string URI string (e.g. "http://etherboot.org/kernel")
85 * @ret rc Return status code
87 * The URI will be regarded as being relative to the current working
90 int xfer_open_uri_string ( struct xfer_interface
*xfer
,
91 const char *uri_string
) {
95 DBGC ( xfer
, "XFER %p opening URI %s\n", xfer
, uri_string
);
97 uri
= parse_uri ( uri_string
);
101 rc
= xfer_open_uri ( xfer
, uri
);
110 * @v xfer Data transfer interface
111 * @v semantics Communication semantics (e.g. SOCK_STREAM)
112 * @v peer Peer socket address
113 * @v local Local socket address, or NULL
114 * @ret rc Return status code
116 int xfer_open_socket ( struct xfer_interface
*xfer
, int semantics
,
117 struct sockaddr
*peer
, struct sockaddr
*local
) {
118 struct socket_opener
*opener
;
120 DBGC ( xfer
, "XFER %p opening (%s,%s) socket\n", xfer
,
121 socket_semantics_name ( semantics
),
122 socket_family_name ( peer
->sa_family
) );
124 for ( opener
= socket_openers
; opener
< socket_openers_end
; opener
++ ){
125 if ( ( opener
->semantics
== semantics
) &&
126 ( opener
->family
== peer
->sa_family
) ) {
127 return opener
->open ( xfer
, peer
, local
);
131 DBGC ( xfer
, "XFER %p attempted to open unsupported socket type "
132 "(%s,%s)\n", xfer
, socket_semantics_name ( semantics
),
133 socket_family_name ( peer
->sa_family
) );
140 * @v xfer Data transfer interface
141 * @v type Location type
142 * @v args Remaining arguments depend upon location type
143 * @ret rc Return status code
145 int xfer_vopen ( struct xfer_interface
*xfer
, int type
, va_list args
) {
147 case LOCATION_URI_STRING
: {
148 const char *uri_string
= va_arg ( args
, const char * );
150 return xfer_open_uri_string ( xfer
, uri_string
); }
152 struct uri
*uri
= va_arg ( args
, struct uri
* );
154 return xfer_open_uri ( xfer
, uri
); }
155 case LOCATION_SOCKET
: {
156 int semantics
= va_arg ( args
, int );
157 struct sockaddr
*peer
= va_arg ( args
, struct sockaddr
* );
158 struct sockaddr
*local
= va_arg ( args
, struct sockaddr
* );
160 return xfer_open_socket ( xfer
, semantics
, peer
, local
); }
162 DBGC ( xfer
, "XFER %p attempted to open unsupported location "
163 "type %d\n", xfer
, type
);
171 * @v xfer Data transfer interface
172 * @v type Location type
173 * @v ... Remaining arguments depend upon location type
174 * @ret rc Return status code
176 int xfer_open ( struct xfer_interface
*xfer
, int type
, ... ) {
180 va_start ( args
, type
);
181 rc
= xfer_vopen ( xfer
, type
, args
);