Adding debian version 3.70~pre8+dfsg-1.
[syslinux-debian/hramrach.git] / gpxe / src / core / open.c
blobdb8d92e669da17175c775a53faadb7426951de93
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 #include <stdarg.h>
20 #include <string.h>
21 #include <errno.h>
22 #include <gpxe/xfer.h>
23 #include <gpxe/uri.h>
24 #include <gpxe/socket.h>
25 #include <gpxe/open.h>
27 /** @file
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 );
45 /**
46 * Open URI
48 * @v xfer Data transfer interface
49 * @v uri URI
50 * @ret rc Return status code
52 * The URI will be regarded as being relative to the current working
53 * URI (see churi()).
55 int xfer_open_uri ( struct xfer_interface *xfer, struct uri *uri ) {
56 struct uri_opener *opener;
57 struct uri *resolved_uri;
58 int rc = -ENOTSUP;
60 /* Resolve URI */
61 resolved_uri = resolve_uri ( cwuri, uri );
62 if ( ! resolved_uri )
63 return -ENOMEM;
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 );
69 goto done;
72 DBGC ( xfer, "XFER %p attempted to open unsupported URI scheme "
73 "\"%s\"\n", xfer, resolved_uri->scheme );
75 done:
76 uri_put ( resolved_uri );
77 return rc;
80 /**
81 * Open URI string
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
88 * URI (see churi()).
90 int xfer_open_uri_string ( struct xfer_interface *xfer,
91 const char *uri_string ) {
92 struct uri *uri;
93 int rc;
95 DBGC ( xfer, "XFER %p opening URI %s\n", xfer, uri_string );
97 uri = parse_uri ( uri_string );
98 if ( ! uri )
99 return -ENOMEM;
101 rc = xfer_open_uri ( xfer, uri );
103 uri_put ( uri );
104 return rc;
108 * Open socket
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 ) );
134 return -ENOTSUP;
138 * Open location
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 ) {
146 switch ( type ) {
147 case LOCATION_URI_STRING: {
148 const char *uri_string = va_arg ( args, const char * );
150 return xfer_open_uri_string ( xfer, uri_string ); }
151 case LOCATION_URI: {
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 ); }
161 default:
162 DBGC ( xfer, "XFER %p attempted to open unsupported location "
163 "type %d\n", xfer, type );
164 return -ENOTSUP;
169 * Open location
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, ... ) {
177 va_list args;
178 int rc;
180 va_start ( args, type );
181 rc = xfer_vopen ( xfer, type, args );
182 va_end ( args );
183 return rc;