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 <strings.h>
29 #include <errno.h>
30 #include <ipxe/xfer.h>
31 #include <ipxe/uri.h>
32 #include <ipxe/socket.h>
33 #include <ipxe/open.h>
34 
35 /** @file
36  *
37  * Data transfer interface opening
38  *
39  */
40 
41 /**
42  * Find opener for URI scheme
43  *
44  * @v scheme URI scheme
45  * @ret opener Opener, or NULL
46  */
47 struct uri_opener * xfer_uri_opener ( const char *scheme ) {
48  struct uri_opener *opener;
49 
50  for_each_table_entry ( opener, URI_OPENERS ) {
51  if ( strcasecmp ( scheme, opener->scheme ) == 0 )
52  return opener;
53  }
54  return NULL;
55 }
56 
57 /**
58  * Open URI
59  *
60  * @v intf Data transfer interface
61  * @v uri URI
62  * @ret rc Return status code
63  *
64  * The URI will be regarded as being relative to the current working
65  * URI (see churi()).
66  */
67 int xfer_open_uri ( struct interface *intf, struct uri *uri ) {
68  struct uri_opener *opener;
69  struct uri *resolved_uri;
70  int rc;
71 
72  /* Resolve URI */
73  resolved_uri = resolve_uri ( cwuri, uri );
74  if ( ! resolved_uri ) {
75  rc = -ENOMEM;
76  goto err_resolve_uri;
77  }
78 
79  /* Find opener which supports this URI scheme */
80  opener = xfer_uri_opener ( resolved_uri->scheme );
81  if ( ! opener ) {
82  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open "
83  "unsupported URI scheme \"%s\"\n",
84  INTF_DBG ( intf ), resolved_uri->scheme );
85  rc = -ENOTSUP;
86  goto err_opener;
87  }
88 
89  /* Call opener */
90  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening %s URI\n",
91  INTF_DBG ( intf ), resolved_uri->scheme );
92  if ( ( rc = opener->open ( intf, resolved_uri ) ) != 0 ) {
93  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " could not open: "
94  "%s\n", INTF_DBG ( intf ), strerror ( rc ) );
95  goto err_open;
96  }
97 
98  err_open:
99  err_opener:
100  uri_put ( resolved_uri );
101  err_resolve_uri:
102  return rc;
103 }
104 
105 /**
106  * Open URI string
107  *
108  * @v intf Data transfer interface
109  * @v uri_string URI string (e.g. "http://ipxe.org/kernel")
110  * @ret rc Return status code
111  *
112  * The URI will be regarded as being relative to the current working
113  * URI (see churi()).
114  */
115 int xfer_open_uri_string ( struct interface *intf,
116  const char *uri_string ) {
117  struct uri *uri;
118  int rc;
119 
120  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening URI %s\n",
121  INTF_DBG ( intf ), uri_string );
122 
123  uri = parse_uri ( uri_string );
124  if ( ! uri )
125  return -ENOMEM;
126 
127  rc = xfer_open_uri ( intf, uri );
128 
129  uri_put ( uri );
130  return rc;
131 }
132 
133 /**
134  * Open socket
135  *
136  * @v intf Data transfer interface
137  * @v semantics Communication semantics (e.g. SOCK_STREAM)
138  * @v peer Peer socket address
139  * @v local Local socket address, or NULL
140  * @ret rc Return status code
141  */
142 int xfer_open_socket ( struct interface *intf, int semantics,
143  struct sockaddr *peer, struct sockaddr *local ) {
144  struct socket_opener *opener;
145 
146  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " opening (%s,%s) socket\n",
148  socket_family_name ( peer->sa_family ) );
149 
151  if ( opener->semantics == semantics )
152  return opener->open ( intf, peer, local );
153  }
154 
155  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open "
156  "unsupported socket type (%s,%s)\n",
158  socket_family_name ( peer->sa_family ) );
159  return -ENOTSUP;
160 }
161 
162 /**
163  * Open location
164  *
165  * @v intf Data transfer interface
166  * @v type Location type
167  * @v args Remaining arguments depend upon location type
168  * @ret rc Return status code
169  */
170 int xfer_vopen ( struct interface *intf, int type, va_list args ) {
171  switch ( type ) {
172  case LOCATION_URI_STRING: {
173  const char *uri_string = va_arg ( args, const char * );
174 
175  return xfer_open_uri_string ( intf, uri_string ); }
176  case LOCATION_URI: {
177  struct uri *uri = va_arg ( args, struct uri * );
178 
179  return xfer_open_uri ( intf, uri ); }
180  case LOCATION_SOCKET: {
181  int semantics = va_arg ( args, int );
182  struct sockaddr *peer = va_arg ( args, struct sockaddr * );
183  struct sockaddr *local = va_arg ( args, struct sockaddr * );
184 
185  return xfer_open_socket ( intf, semantics, peer, local ); }
186  default:
187  DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to "
188  "open unsupported location type %d\n",
189  INTF_DBG ( intf ), type );
190  return -ENOTSUP;
191  }
192 }
193 
194 /**
195  * Open location
196  *
197  * @v intf Data transfer interface
198  * @v type Location type
199  * @v ... Remaining arguments depend upon location type
200  * @ret rc Return status code
201  */
202 int xfer_open ( struct interface *intf, int type, ... ) {
203  va_list args;
204  int rc;
205 
206  va_start ( args, type );
207  rc = xfer_vopen ( intf, type, args );
208  va_end ( args );
209  return rc;
210 }
211 
212 /**
213  * Reopen location
214  *
215  * @v intf Data transfer interface
216  * @v type Location type
217  * @v args Remaining arguments depend upon location type
218  * @ret rc Return status code
219  *
220  * This will close the existing connection and open a new connection
221  * using xfer_vopen(). It is intended to be used as a .vredirect
222  * method handler.
223  */
224 int xfer_vreopen ( struct interface *intf, int type, va_list args ) {
225 
226  /* Close existing connection */
227  intf_restart ( intf, 0 );
228 
229  /* Open new location */
230  return xfer_vopen ( intf, type, args );
231 }
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:342
#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:254
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition: uri.h:205
#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:142
Location is a URI.
Definition: open.h:27
uint8_t type
Type.
Definition: ena.h:16
int xfer_open_uri(struct interface *intf, struct uri *uri)
Open URI.
Definition: open.c:67
#define INTF_COL(intf)
Find debugging colourisation for an object interface.
Definition: interface.h:243
sa_family_t sa_family
Socket address family.
Definition: socket.h:101
#define DBGC(...)
Definition: compiler.h:505
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition: string.c:208
Uniform Resource Identifiers.
int semantics
Communication semantics (e.g.
Definition: open.h:72
Location is a URI string.
Definition: open.h:34
Location is a socket.
Definition: open.h:43
#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:68
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:85
An object interface.
Definition: interface.h:124
const char * scheme
URI protocol name.
Definition: open.h:53
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:202
int xfer_vreopen(struct interface *intf, int type, va_list args)
Reopen location.
Definition: open.c:224
int(* open)(struct interface *intf, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Definition: open.h:80
__builtin_va_list va_list
Definition: stdarg.h:6
int xfer_vopen(struct interface *intf, int type, va_list args)
Open location.
Definition: open.c:170
A Uniform Resource Identifier.
Definition: uri.h:64
struct uri_opener * xfer_uri_opener(const char *scheme)
Find opener for URI scheme.
Definition: open.c:47
struct uri * resolve_uri(const struct uri *base_uri, struct uri *relative_uri)
Resolve base+relative URI.
Definition: uri.c:689
#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:115
Socket addresses.
A URI opener.
Definition: open.h:47
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
String functions.
String functions.
struct uri * parse_uri(const char *uri_string)
Parse URI.
Definition: uri.c:296
#define INTF_FMT
printf() format string for INTF_DBG()
Definition: interface.h:246
A socket opener.
Definition: open.h:70