summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2005-05-09 16:27:29 +0200
committerMichael Brown2005-05-09 16:27:29 +0200
commit0fe74493f48c25bb92373e68bf6856eda7ac5667 (patch)
treedc52d59e0531c6d2526013fde650581386f60eb6
parentoff_t should be signed. (diff)
downloadipxe-0fe74493f48c25bb92373e68bf6856eda7ac5667.tar.gz
ipxe-0fe74493f48c25bb92373e68bf6856eda7ac5667.tar.xz
ipxe-0fe74493f48c25bb92373e68bf6856eda7ac5667.zip
Protocols now load data into a buffer; they don't execute it.
-rw-r--r--src/core/main.c12
-rw-r--r--src/core/nic.c19
-rw-r--r--src/include/dev.h13
-rw-r--r--src/include/proto.h10
-rw-r--r--src/include/tftp.h9
-rw-r--r--src/proto/tftp.c24
6 files changed, 37 insertions, 50 deletions
diff --git a/src/core/main.c b/src/core/main.c
index 08f6d6a58..260a44b88 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -162,6 +162,7 @@ void initialise ( void ) {
MAIN - Kick off routine
**************************************************************************/
int main ( void ) {
+ struct buffer buffer;
int skip = 0;
/* Print out configuration */
@@ -213,8 +214,15 @@ int main ( void ) {
continue;
}
- /* Boot from the device */
- load ( &dev, load_block );
+ /* Load boot file from the device */
+ init_buffer ( &buffer, 0x7c00, 0x100 );
+ if ( ! load ( &dev, &buffer ) ) {
+ /* Load (e.g. TFTP failed) */
+ printf ( "...load failed\n" );
+ continue;
+ }
+
+ printf ( "Loaded file of size %d\n", buffer.fill );
}
diff --git a/src/core/nic.c b/src/core/nic.c
index fc8deebe5..3909f5489 100644
--- a/src/core/nic.c
+++ b/src/core/nic.c
@@ -282,14 +282,10 @@ static int nic_configure ( struct type_dev *type_dev ) {
/*
- * Download a file from the specified URL and process it with the
- * specified function
+ * Download a file from the specified URL into the specified buffer
*
*/
-int download_url ( char *url,
- int ( * process ) ( unsigned char *data,
- unsigned int blocknum,
- unsigned int len, int eof ) ) {
+int download_url ( char *url, struct buffer *buffer ) {
struct protocol *proto;
struct sockaddr_in server;
char *filename;
@@ -303,7 +299,7 @@ int download_url ( char *url,
}
/* Call protocol's method to download the file */
- return proto->load ( url, &server, filename, process );
+ return proto->load ( url, &server, filename, buffer );
}
@@ -312,10 +308,7 @@ int download_url ( char *url,
/**************************************************************************
LOAD - Try to get booted
**************************************************************************/
-static int nic_load ( struct type_dev *type_dev,
- int ( * process ) ( unsigned char *data,
- unsigned int blocknum,
- unsigned int size, int eof ) ) {
+static int nic_load ( struct type_dev *type_dev, struct buffer *buffer ) {
char *kernel;
/* Now use TFTP to load file */
@@ -327,12 +320,10 @@ static int nic_load ( struct type_dev *type_dev,
#endif
: KERNEL_BUF;
if ( kernel ) {
- download_url(kernel,process); /* We don't return except on error */
- printf("Unable to load file.\n");
+ return download_url ( kernel, buffer );
} else {
printf("No filename\n");
}
- interruptible_sleep(2); /* lay off the server for a while */
return 0;
}
diff --git a/src/include/dev.h b/src/include/dev.h
index 8bf173554..0d0d4d8ef 100644
--- a/src/include/dev.h
+++ b/src/include/dev.h
@@ -3,6 +3,7 @@
#include "stdint.h"
#include "string.h"
+#include "buffer.h"
#include "dhcp.h" /* for dhcp_dev_id */
#include "tables.h"
@@ -182,10 +183,7 @@ struct type_driver {
struct type_dev *type_dev; /* single instance */
char * ( * describe_device ) ( struct type_dev *type_dev );
int ( * configure ) ( struct type_dev *type_dev );
- int ( * load ) ( struct type_dev *type_dev,
- int ( * process ) ( unsigned char *data,
- unsigned int blocknum,
- unsigned int len, int eof ) );
+ int ( * load ) ( struct type_dev *type_dev, struct buffer *buffer );
};
#define __type_driver __attribute__ (( used, __table_section(type_driver,01) ))
@@ -277,11 +275,8 @@ static inline int configure ( struct dev *dev ) {
return dev->type_driver->configure ( dev->type_dev );
}
/* Boot from a device */
-static inline int load ( struct dev *dev,
- int ( * process ) ( unsigned char *data,
- unsigned int blocknum,
- unsigned int len, int eof ) ) {
- return dev->type_driver->load ( dev->type_dev, process );
+static inline int load ( struct dev *dev, struct buffer *buffer ) {
+ return dev->type_driver->load ( dev->type_dev, buffer );
}
#endif /* DEV_H */
diff --git a/src/include/proto.h b/src/include/proto.h
index 2c157ee4e..fb4e4137c 100644
--- a/src/include/proto.h
+++ b/src/include/proto.h
@@ -2,18 +2,14 @@
#define PROTO_H
#include "tables.h"
+#include "buffer.h"
#include "in.h"
struct protocol {
char *name;
in_port_t default_port;
- int ( * load ) ( char *url,
- struct sockaddr_in *server,
- char *file,
- int ( * process ) ( unsigned char *data,
- unsigned int blocknum,
- unsigned int len,
- int eof ) );
+ int ( * load ) ( char *url, struct sockaddr_in *server, char *file,
+ struct buffer *buffer );
};
/*
diff --git a/src/include/tftp.h b/src/include/tftp.h
index 5f129ead9..70192067c 100644
--- a/src/include/tftp.h
+++ b/src/include/tftp.h
@@ -2,6 +2,7 @@
#define TFTP_H
#include "in.h"
+#include "buffer.h"
#include "nic.h"
#define TFTP_PORT 69
@@ -83,11 +84,7 @@ struct tftpblk_info_t {
*/
extern int tftp_block ( struct tftpreq_info_t *request,
struct tftpblk_info_t *block );
-extern int tftp ( char *url,
- struct sockaddr_in *server,
- char *file,
- int ( * process ) ( unsigned char *data,
- unsigned int blocknum,
- unsigned int len, int eof ) );
+extern int tftp ( char *url, struct sockaddr_in *server, char *file,
+ struct buffer *buffer );
#endif /* TFTP_H */
diff --git a/src/proto/tftp.c b/src/proto/tftp.c
index c59807d7b..6d35e1704 100644
--- a/src/proto/tftp.c
+++ b/src/proto/tftp.c
@@ -144,12 +144,8 @@ int tftp_block ( struct tftpreq_info_t *request,
* Download a file via TFTP
*
*/
-int tftp ( char *url __unused,
- struct sockaddr_in *server,
- char *file,
- int ( * process ) ( unsigned char *data,
- unsigned int blocknum,
- unsigned int len, int eof ) ) {
+int tftp ( char *url __unused, struct sockaddr_in *server, char *file,
+ struct buffer *buffer ) {
struct tftpreq_info_t request_data = {
.server = server,
.name = file,
@@ -157,14 +153,18 @@ int tftp ( char *url __unused,
};
struct tftpreq_info_t *request = &request_data;
struct tftpblk_info_t block;
- int rc;
+ off_t offset = 0;
- while ( tftp_block ( request, &block ) ) {
+ do {
+ if ( ! tftp_block ( request, &block ) )
+ return 0;
+ if ( ! fill_buffer ( buffer, block.data, offset, block.len ) )
+ return 0;
+ offset += block.len;
request = NULL; /* Send request only once */
- rc = process ( block.data, block.block, block.len, block.eof );
- if ( rc <= 0 ) return ( rc );
- }
- return 0;
+ } while ( ! block.eof );
+
+ return 1;
}
struct protocol tftp_protocol __default_protocol = {