ftp_free(inode);
}
-void ftp_open(struct url_info *url, struct inode *inode)
+void ftp_open(struct url_info *url, struct inode *inode, const char **redir)
{
struct pxe_pvt_inode *socket = PVT(inode);
struct pxe_pvt_inode *ctlsock;
int resp;
err_t err;
+ (void)redir; /* FTP does not redirect */
inode->size = 0;
if (!url->port)
return success;
}
-void http_open(struct url_info *url, struct inode *inode)
+void http_open(struct url_info *url, struct inode *inode, const char **redir)
{
struct pxe_pvt_inode *socket = PVT(inode);
char header_buf[4096];
st_eoh,
} state;
struct ip_addr addr;
- char location[1024], new_url[1024];
+ static char location[FILENAME_MAX];
uint32_t content_length; /* same as inode->size */
size_t response_size;
int status;
int pos;
- int redirect_count;
socket->fill_buffer = tcp_fill_buffer;
socket->close = tcp_close_file;
- redirect_count = 0;
-restart:
/* Reset all of the variables */
inode->size = content_length = -1;
/* Skip leading whitespace */
while (isspace(*next))
next++;
- strcpy(location, next);
+ strlcpy(location, next, sizeof location);
}
/* Start the field name and field value afress */
field_name_len = 1;
/* A redirect */
if (!location[0])
goto fail;
- redirect_count++;
- if (redirect_count > 5)
- goto fail;
- strlcpy(new_url, location, sizeof new_url);
- parse_url(url, new_url);
- url_set_ip(url);
- tcp_close_file(inode);
- /* XXX: This needs to go all the way back to scheme selection */
- goto restart;
- break;
+ *redir = location;
+ goto fail;
default:
goto fail;
break;
static struct url_scheme {
const char *name;
- void (*open)(struct url_info *url, struct inode *inode);
+ void (*open)(struct url_info *url, struct inode *inode, const char **redir);
} url_schemes[] = {
{ "tftp", tftp_open },
{ "http", http_open },
char fullpath[2*FILENAME_MAX];
struct url_info url;
const struct url_scheme *us;
+ int redirect_count = 0;
inode = file->inode = NULL;
- strlcpy(fullpath, filename, sizeof fullpath);
- parse_url(&url, fullpath);
- if (url.type == URL_SUFFIX) {
- snprintf(fullpath, sizeof fullpath, "%s%s", fs->cwd_name, filename);
- parse_url(&url, fullpath);
- }
-
- inode = allocate_socket(fs);
- if (!inode)
- return; /* Allocation failure */
+ while (filename) {
+ if (redirect_count++ > 5)
+ break;
- url_set_ip(&url);
+ strlcpy(fullpath, filename, sizeof fullpath);
+ parse_url(&url, fullpath);
+ if (url.type == URL_SUFFIX) {
+ snprintf(fullpath, sizeof fullpath, "%s%s", fs->cwd_name, filename);
+ parse_url(&url, fullpath);
+ }
- for (us = url_schemes; us->name; us++) {
- if (!strcmp(us->name, url.scheme)) {
- us->open(&url, inode);
- break;
+ inode = allocate_socket(fs);
+ if (!inode)
+ return; /* Allocation failure */
+
+ url_set_ip(&url);
+
+ filename = NULL;
+ for (us = url_schemes; us->name; us++) {
+ if (!strcmp(us->name, url.scheme)) {
+ us->open(&url, inode, &filename);
+ break;
+ }
}
+
+ /* filename here is set on a redirect */
}
if (inode->size)
void free_port(uint16_t port);
/* tftp.c */
-void tftp_open(struct url_info *url, struct inode *inode);
+void tftp_open(struct url_info *url, struct inode *inode, const char **redir);
/* gpxeurl.c */
void gpxe_open(struct inode *inode, const char *url);
#define GPXE 1
/* http.c */
-void http_open(struct url_info *url, struct inode *inode);
+void http_open(struct url_info *url, struct inode *inode, const char **redir);
/* ftp.c */
-void ftp_open(struct url_info *url, struct inode *inode);
+void ftp_open(struct url_info *url, struct inode *inode, const char **redir);
/* tcp.c */
void tcp_close_file(struct inode *inode);
* @out: the lenght of this file, stores in file->file_len
*
*/
-void tftp_open(struct url_info *url, struct inode *inode)
+void tftp_open(struct url_info *url, struct inode *inode, const char **redir)
{
struct pxe_pvt_inode *socket = PVT(inode);
char *buf;
uint32_t opdata, *opdata_ptr;
struct ip_addr addr;
+ (void)redir; /* TFTP does not redirect */
+
if (url->type != URL_OLD_TFTP) {
/*
* The TFTP URL specification allows the TFTP to end with a