iPXE
open.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3  *
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.
8  *
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.
13  *
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
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <stdarg.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <ipxe/xfer.h>
30 #include <ipxe/uri.h>
31 #include <ipxe/socket.h>
32 #include <ipxe/open.h>
33 
34 /** @file
35  *
36  * Data transfer interface opening
37  *
38  */
39 
40 /**
41  * Find opener for URI scheme
42  *
43  * @v scheme URI scheme
44  * @ret opener Opener, or NULL
45  */
46 struct uri_opener * xfer_uri_opener ( const char *scheme ) {
47  struct uri_opener *opener;
48 
49  for_each_table_entry ( opener, URI_OPENERS ) {
50  if ( strcmp ( scheme, opener->scheme ) == 0 )
51  return opener;
52  }
53  return NULL;
54 }
55 
56 /**
57  * Open URI
58  *
59  * @v intf Data transfer interface
60  * @v uri URI
61  * @ret rc Return status code
62  *
63  * The URI will be regarded as being relative to the current working
64  * URI (see churi()).
65  */
66 int xfer_open_uri ( struct interface *intf, struct uri *uri ) {
67  struct uri_opener *opener;
68  struct uri *resolved_uri;
69  int rc;
70 
71  /* Resolve URI */
72  resolved_uri = resolve_uri ( cwuri, uri );
73  if ( ! resolved_uri ) {
74  rc = -ENOMEM;
75  goto err_resolve_uri;
76  }
77 
78  /* Find opener which supports this URI scheme */
79  opener = xfer_uri_opener ( resolved_uri->scheme );
80  if ( ! opener ) {
81  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open "
82  "unsupported URI scheme \"%s\"\n",
83  INTF_DBG ( intf ), resolved_uri->scheme );
84  rc = -ENOTSUP;
85  goto err_opener;
86  }
87 
88  /* Call opener */
89  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening %s URI\n",
90  INTF_DBG ( intf ), resolved_uri->scheme );
91  if ( ( rc = opener->open ( intf, resolved_uri ) ) != 0 ) {
92  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " could not open: "
93  "%s\n", INTF_DBG ( intf ), strerror ( rc ) );
94  goto err_open;
95  }
96 
97  err_open:
98  err_opener:
99  uri_put ( resolved_uri );
100  err_resolve_uri:
101  return rc;
102 }
103 
104 /**
105  * Open URI string
106  *
107  * @v intf Data transfer interface
108  * @v uri_string URI string (e.g. "http://ipxe.org/kernel")
109  * @ret rc Return status code
110  *
111  * The URI will be regarded as being relative to the current working
112  * URI (see churi()).
113  */
114 int xfer_open_uri_string ( struct interface *intf,
115  const char *uri_string ) {
116  struct uri *uri;
117  int rc;
118 
119  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening URI %s\n",
120  INTF_DBG ( intf ), uri_string );
121 
122  uri = parse_uri ( uri_string );
123  if ( ! uri )
124  return -ENOMEM;
125 
126  rc = xfer_open_uri ( intf, uri );
127 
128  uri_put ( uri );
129  return rc;
130 }
131 
132 /**
133  * Open socket
134  *
135  * @v intf Data transfer interface
136  * @v semantics Communication semantics (e.g. SOCK_STREAM)
137  * @v peer Peer socket address
138  * @v local Local socket address, or NULL
139  * @ret rc Return status code
140  */
141 int xfer_open_socket ( struct interface *intf, int semantics,
142  struct sockaddr *peer, struct sockaddr *local ) {
143  struct socket_opener *opener;
144 
145  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening (%s,%s) socket\n",
147  socket_family_name ( peer->sa_family ) );
148 
150  if ( ( opener->semantics == semantics ) &&
151  ( opener->family == peer->sa_family ) ) {
152  return opener->open ( intf, peer, local );
153  }
154  }
155 
156  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open "
157  "unsupported socket type (%s,%s)\n",
159  socket_family_name ( peer->sa_family ) );
160  return -ENOTSUP;
161 }
162 
163 /**
164  * Open location
165  *
166  * @v intf Data transfer interface
167  * @v type Location type
168  * @v args Remaining arguments depend upon location type
169  * @ret rc Return status code
170  */
171 int xfer_vopen ( struct interface *intf, int type, va_list args ) {
172  switch ( type ) {
173  case LOCATION_URI_STRING: {
174  const char *uri_string = va_arg ( args, const char * );
175 
176  return xfer_open_uri_string ( intf, uri_string ); }
177  case LOCATION_URI: {
178  struct uri *uri = va_arg ( args, struct uri * );
179 
180  return xfer_open_uri ( intf, uri ); }
181  case LOCATION_SOCKET: {
182  int semantics = va_arg ( args, int );
183  struct sockaddr *peer = va_arg ( args, struct sockaddr * );
184  struct sockaddr *local = va_arg ( args, struct sockaddr * );
185 
186  return xfer_open_socket ( intf, semantics, peer, local ); }
187  default:
188  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to "
189  "open unsupported location type %d\n",
190  INTF_DBG ( intf ), type );
191  return -ENOTSUP;
192  }
193 }
194 
195 /**
196  * Open location
197  *
198  * @v intf Data transfer interface
199  * @v type Location type
200  * @v ... Remaining arguments depend upon location type
201  * @ret rc Return status code
202  */
203 int xfer_open ( struct interface *intf, int type, ... ) {
204  va_list args;
205  int rc;
206 
207  va_start ( args, type );
208  rc = xfer_vopen ( intf, type, args );
209  va_end ( args );
210  return rc;
211 }
212 
213 /**
214  * Reopen location
215  *
216  * @v intf Data transfer interface
217  * @v type Location type
218  * @v args Remaining arguments depend upon location type
219  * @ret rc Return status code
220  *
221  * This will close the existing connection and open a new connection
222  * using xfer_vopen(). It is intended to be used as a .vredirect
223  * method handler.
224  */
225 int xfer_vreopen ( struct interface *intf, int type, va_list args ) {
226 
227  /* Close existing connection */
228  intf_restart ( intf, 0 );
229 
230  /* Open new location */
231  return xfer_vopen ( intf, type, args );
232 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:337
#define va_end(ap)
Definition: stdarg.h:9
static const char * socket_semantics_name(int semantics)
Name communication semantics.
Definition: socket.h:45
#define INTF_DBG(intf)
printf() arguments for representing an object interface
Definition: interface.h:237
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition: uri.h:188
#define URI_OPENERS
URI opener table.
Definition: open.h:64
Error codes.
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition: open.c:141
uint8_t type
Type.
Definition: ena.h:16
int xfer_open_uri(struct interface *intf, struct uri *uri)
Open URI.
Definition: open.c:66
#define INTF_COL(intf)
Find debugging colourisation for an object interface.
Definition: interface.h:226
sa_family_t sa_family
Socket address family.
Definition: socket.h:101
#define DBGC(...)
Definition: compiler.h:505
Uniform Resource Identifiers.
int semantics
Communication semantics (e.g.
Definition: open.h:72
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
Data transfer interfaces.
#define ENOMEM
Not enough space.
Definition: errno.h:534
const char * scheme
Scheme.
Definition: uri.h:54
int(* open)(struct interface *intf, struct uri *uri)
Open URI.
Definition: open.h:60
#define va_arg(ap, type)
Definition: stdarg.h:8
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define SOCKET_OPENERS
Socket opener table.
Definition: open.h:87
An object interface.
Definition: interface.h:109
const char * scheme
URI protocol name.
Definition: open.h:53
int family
Address family (e.g.
Definition: open.h:74
Generalized socket address structure.
Definition: socket.h:96
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:358
static const char * socket_family_name(int family)
Name address family.
Definition: socket.h:75
Data transfer interface opening.
int xfer_open(struct interface *intf, int type,...)
Open location.
Definition: open.c:203
int xfer_vreopen(struct interface *intf, int type, va_list args)
Reopen location.
Definition: open.c:225
int(* open)(struct interface *intf, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition: open.h:82
__builtin_va_list va_list
Definition: stdarg.h:6
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:157
Location is a socket.
Definition: open.h:43
Location is a URI string.
Definition: open.h:34
int xfer_vopen(struct interface *intf, int type, va_list args)
Open location.
Definition: open.c:171
A Uniform Resource Identifier.
Definition: uri.h:50
struct uri_opener * xfer_uri_opener(const char *scheme)
Find opener for URI scheme.
Definition: open.c:46
struct uri * resolve_uri(const struct uri *base_uri, struct uri *relative_uri)
Resolve base+relative URI.
Definition: uri.c:676
#define va_start(ap, last)
Definition: stdarg.h:7
struct uri * cwuri
Current working URI.
Definition: cwuri.c:38
int xfer_open_uri_string(struct interface *intf, const char *uri_string)
Open URI string.
Definition: open.c:114
Socket addresses.
A URI opener.
Definition: open.h:47
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
String functions.
Location is a URI.
Definition: open.h:27
struct uri * parse_uri(const char *uri_string)
Parse URI.
Definition: uri.c:295
#define INTF_FMT
printf() format string for INTF_DBG()
Definition: interface.h:229
A socket opener.
Definition: open.h:70