[contrib] Allow Network Protocol header to display in rom-o-matic
[gpxe.git] / src / core / open.c
blob70b427ba2225b93b52ec31e867a26bb0cde4be5c
1 /*
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 );
21 #include <stdarg.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <gpxe/xfer.h>
25 #include <gpxe/uri.h>
26 #include <gpxe/socket.h>
27 #include <gpxe/open.h>
29 /** @file
31 * Data transfer interface opening
35 /**
36 * Open URI
38 * @v xfer Data transfer interface
39 * @v uri URI
40 * @ret rc Return status code
42 * The URI will be regarded as being relative to the current working
43 * URI (see churi()).
45 int xfer_open_uri ( struct xfer_interface *xfer, struct uri *uri ) {
46 struct uri_opener *opener;
47 struct uri *resolved_uri;
48 int rc = -ENOTSUP;
50 /* Resolve URI */
51 resolved_uri = resolve_uri ( cwuri, uri );
52 if ( ! resolved_uri )
53 return -ENOMEM;
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 );
61 goto done;
64 DBGC ( xfer, "XFER %p attempted to open unsupported URI scheme "
65 "\"%s\"\n", xfer, resolved_uri->scheme );
67 done:
68 uri_put ( resolved_uri );
69 return rc;
72 /**
73 * Open URI string
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
80 * URI (see churi()).
82 int xfer_open_uri_string ( struct xfer_interface *xfer,
83 const char *uri_string ) {
84 struct uri *uri;
85 int rc;
87 DBGC ( xfer, "XFER %p opening URI %s\n", xfer, uri_string );
89 uri = parse_uri ( uri_string );
90 if ( ! uri )
91 return -ENOMEM;
93 rc = xfer_open_uri ( xfer, uri );
95 uri_put ( uri );
96 return rc;
99 /**
100 * Open socket
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 ) );
126 return -ENOTSUP;
130 * Open location
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 ) {
138 switch ( type ) {
139 case LOCATION_URI_STRING: {
140 const char *uri_string = va_arg ( args, const char * );
142 return xfer_open_uri_string ( xfer, uri_string ); }
143 case LOCATION_URI: {
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 ); }
153 default:
154 DBGC ( xfer, "XFER %p attempted to open unsupported location "
155 "type %d\n", xfer, type );
156 return -ENOTSUP;
161 * Open location
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, ... ) {
169 va_list args;
170 int rc;
172 va_start ( args, type );
173 rc = xfer_vopen ( xfer, type, args );
174 va_end ( args );
175 return rc;
179 * Reopen location
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
188 * method handler.
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 );