diff options
author | Gene Cumm <gene.cumm@gmail.com> | 2015-09-27 06:47:23 -0400 |
---|---|---|
committer | Gene Cumm <gene.cumm@gmail.com> | 2015-09-27 06:47:23 -0400 |
commit | 804efa7bb278a032d384c97e8530195b294e71bc (patch) | |
tree | 0902227a2181fa6e95bc36949989f3cdca2cf5f6 /core/legacynet/core.c | |
parent | 7d9c9eca562857fed25b4c8ef902e3de968d7631 (diff) | |
download | syslinux-804efa7bb278a032d384c97e8530195b294e71bc.tar.gz syslinux-804efa7bb278a032d384c97e8530195b294e71bc.tar.xz syslinux-804efa7bb278a032d384c97e8530195b294e71bc.zip |
core: readd gPXE/iPXE support for HTTP on pxelinux.0
When adding lwIP functionality, the gPXE/iPXE callback was broken. This
prevented pxelinux.0 from calling gPXE/iPXE for HTTP and FTP URLs. Re-add
for pxelinux.0 and add code to find file size.
Move to core/legacynet/core.c to access packet_buf and leave a dummy
function for lpxelinux.0.
Signed-off-by: Gene Cumm <gene.cumm@gmail.com>
Diffstat (limited to 'core/legacynet/core.c')
-rw-r--r-- | core/legacynet/core.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/core/legacynet/core.c b/core/legacynet/core.c index eacb4927..24a670e0 100644 --- a/core/legacynet/core.c +++ b/core/legacynet/core.c @@ -220,3 +220,104 @@ int reset_pxe(void) return err; } + +#if GPXE + +static void gpxe_close_file(struct inode *inode) +{ + struct pxe_pvt_inode *socket = PVT(inode); + static __lowmem struct s_PXENV_FILE_CLOSE file_close; + + file_close.FileHandle = socket->tftp_remoteport; + pxe_call(PXENV_FILE_CLOSE, &file_close); +} + +/** + * Get a fresh packet from a gPXE socket + * @param: inode -> Inode pointer + * + */ +static void gpxe_get_packet(struct inode *inode) +{ + struct pxe_pvt_inode *socket = PVT(inode); + static __lowmem struct s_PXENV_FILE_READ file_read; + int err; + + while (1) { + file_read.FileHandle = socket->tftp_remoteport; + file_read.Buffer = FAR_PTR(packet_buf); + file_read.BufferSize = PKTBUF_SIZE; + err = pxe_call(PXENV_FILE_READ, &file_read); + if (!err) /* successed */ + break; + + if (file_read.Status != PXENV_STATUS_TFTP_OPEN) + kaboom(); + } + + memcpy(socket->tftp_pktbuf, packet_buf, file_read.BufferSize); + + socket->tftp_dataptr = socket->tftp_pktbuf; + socket->tftp_bytesleft = file_read.BufferSize; + socket->tftp_filepos += file_read.BufferSize; + + if (socket->tftp_bytesleft == 0) + inode->size = socket->tftp_filepos; + + /* if we're done here, close the file */ + if (inode->size > socket->tftp_filepos) + return; + + /* Got EOF, close it */ + socket->tftp_goteof = 1; + gpxe_close_file(inode); +} + +const struct pxe_conn_ops gpxe_conn_ops = { + .fill_buffer = gpxe_get_packet, + .close = gpxe_close_file, +}; + +/** + * Open a url using gpxe + * + * @param:inode, the inode to store our state in + * @param:url, the url we want to open + * + * @out: open_file_t structure, stores in file->open_file + * @out: the lenght of this file, stores in file->file_len + * + */ +void gpxe_open(struct inode *inode, const char *url) +{ + static __lowmem struct s_PXENV_FILE_OPEN file_open; + static __lowmem struct s_PXENV_GET_FILE_SIZE file_size; + static __lowmem char lowurl[2*FILENAME_MAX]; + struct pxe_pvt_inode *socket = PVT(inode); + int err; + + socket->tftp_pktbuf = malloc(PKTBUF_SIZE); + if (!socket->tftp_pktbuf) + return; + + snprintf(lowurl, sizeof lowurl, "%s", url); + file_open.Status = PXENV_STATUS_BAD_FUNC; + file_open.FileName = FAR_PTR(lowurl); + err = pxe_call(PXENV_FILE_OPEN, &file_open); + if (err) + return; + + + socket->ops = &gpxe_conn_ops; + socket->tftp_remoteport = file_open.FileHandle; + file_size.Status = PXENV_STATUS_BAD_FUNC; + file_size.FileHandle = file_open.FileHandle; + err = pxe_call(PXENV_GET_FILE_SIZE, &file_size); + if (err) { + inode->size = -1; /* fallback size; this shouldn't be an error */ + } else { + inode->size = file_size.FileSize; + } +} + +#endif /* GPXE */ |