浏览代码

Change FTP to use a data buffer rather than a callback function.

tags/v0.9.3
Michael Brown 17 年前
父节点
当前提交
6918cf9e9e
共有 3 个文件被更改,包括 47 次插入25 次删除
  1. 6
    9
      src/include/gpxe/ftp.h
  2. 27
    14
      src/net/tcp/ftp.c
  3. 14
    2
      src/tests/ftptest.c

+ 6
- 9
src/include/gpxe/ftp.h 查看文件

@@ -11,6 +11,8 @@
11 11
 #include <gpxe/async.h>
12 12
 #include <gpxe/tcp.h>
13 13
 
14
+struct buffer;
15
+
14 16
 /** FTP default port */
15 17
 #define FTP_PORT 21
16 18
 
@@ -40,15 +42,8 @@ struct ftp_request {
40 42
 	struct sockaddr_tcpip server;
41 43
 	/** File to download */
42 44
 	const char *filename;
43
-	/** Callback function
44
-	 *
45
-	 * @v data	Received data
46
-	 * @v len	Length of received data
47
-	 *
48
-	 * This function is called for all data received from the
49
-	 * remote server.
50
-	 */
51
-	void ( *callback ) ( char *data, size_t len );
45
+	/** Data buffer to fill */
46
+	struct buffer *buffer;
52 47
 
53 48
 	/** Current state */
54 49
 	enum ftp_state state;
@@ -62,6 +57,8 @@ struct ftp_request {
62 57
 	char status_text[4];
63 58
 	/** Passive-mode parameters, as text */
64 59
 	char passive_text[24]; /* "aaa,bbb,ccc,ddd,eee,fff" */
60
+	/** Amount of data received */
61
+	size_t data_rcvd;
65 62
 
66 63
 	/** TCP application for the control channel */
67 64
 	struct tcp_application tcp;

+ 27
- 14
src/net/tcp/ftp.c 查看文件

@@ -5,6 +5,7 @@
5 5
 #include <assert.h>
6 6
 #include <errno.h>
7 7
 #include <gpxe/async.h>
8
+#include <gpxe/buffer.h>
8 9
 #include <gpxe/ftp.h>
9 10
 
10 11
 /** @file
@@ -268,14 +269,14 @@ static void ftp_senddata ( struct tcp_application *app,
268 269
  * When the control channel is closed, the data channel must also be
269 270
  * closed, if it is currently open.
270 271
  */
271
-static void ftp_closed ( struct tcp_application *app, int status ) {
272
+static void ftp_closed ( struct tcp_application *app, int rc ) {
272 273
 	struct ftp_request *ftp = tcp_to_ftp ( app );
273 274
 
274
-	DBGC ( ftp, "FTP %p control connection closed (status %d)\n",
275
-	       ftp, status );
275
+	DBGC ( ftp, "FTP %p control connection closed: %s\n",
276
+	       ftp, strerror ( rc ) );
276 277
 
277 278
 	/* Complete FTP operation */
278
-	ftp_done ( ftp, status );
279
+	ftp_done ( ftp, rc );
279 280
 }
280 281
 
281 282
 /** FTP control channel operations */
@@ -314,15 +315,15 @@ tcp_to_ftp_data ( struct tcp_application *app ) {
314 315
  *
315 316
  * If the data channel is closed due to an error, we abort the request.
316 317
  */
317
-static void ftp_data_closed ( struct tcp_application *app, int status ) {
318
+static void ftp_data_closed ( struct tcp_application *app, int rc ) {
318 319
 	struct ftp_request *ftp = tcp_to_ftp_data ( app );
319 320
 
320
-	DBGC ( ftp, "FTP %p data connection closed (status %d)\n",
321
-	       ftp, status );
321
+	DBGC ( ftp, "FTP %p data connection closed: %s\n",
322
+	       ftp, strerror ( rc ) );
322 323
 	
323 324
 	/* If there was an error, close control channel and record status */
324
-	if ( status )
325
-		ftp_done ( ftp, status );
325
+	if ( rc )
326
+		ftp_done ( ftp, rc );
326 327
 }
327 328
 
328 329
 /**
@@ -331,14 +332,23 @@ static void ftp_data_closed ( struct tcp_application *app, int status ) {
331 332
  * @v app	TCP application
332 333
  * @v data	New data
333 334
  * @v len	Length of new data
334
- *
335
- * Data is handed off to the callback registered in the FTP request.
336 335
  */
337 336
 static void ftp_data_newdata ( struct tcp_application *app,
338 337
 			       void *data, size_t len ) {
339 338
 	struct ftp_request *ftp = tcp_to_ftp_data ( app );
339
+	int rc;
340
+
341
+	/* Fill data buffer */
342
+	if ( ( rc = fill_buffer ( ftp->buffer, data,
343
+				  ftp->data_rcvd, len ) ) != 0 ){
344
+		DBGC ( ftp, "FTP %p failed to fill data buffer: %s\n",
345
+		       ftp, strerror ( rc ) );
346
+		ftp_done ( ftp, rc );
347
+		return;
348
+	}
340 349
 
341
-	ftp->callback ( data, len );
350
+	/* Update received data total */
351
+	ftp->data_rcvd += len;
342 352
 }
343 353
 
344 354
 /** FTP data channel operations */
@@ -363,10 +373,13 @@ struct async_operation * ftp_get ( struct ftp_request *ftp ) {
363 373
 
364 374
 	DBGC ( ftp, "FTP %p fetching %s\n", ftp, ftp->filename );
365 375
 
366
-	ftp->tcp.tcp_op = &ftp_tcp_operations;
367
-	ftp->tcp_data.tcp_op = &ftp_data_tcp_operations;
376
+	ftp->state = FTP_CONNECT;
377
+	ftp->already_sent = 0;
368 378
 	ftp->recvbuf = ftp->status_text;
369 379
 	ftp->recvsize = sizeof ( ftp->status_text ) - 1;
380
+	ftp->data_rcvd = 0;
381
+	ftp->tcp.tcp_op = &ftp_tcp_operations;
382
+	ftp->tcp_data.tcp_op = &ftp_data_tcp_operations;
370 383
 	if ( ( rc = tcp_connect ( &ftp->tcp, &ftp->server, 0 ) ) != 0 )
371 384
 		ftp_done ( ftp, rc );
372 385
 

+ 14
- 2
src/tests/ftptest.c 查看文件

@@ -4,9 +4,10 @@
4 4
 #include <console.h>
5 5
 #include <vsprintf.h>
6 6
 #include <gpxe/async.h>
7
+#include <gpxe/buffer.h>
7 8
 #include <gpxe/ftp.h>
8 9
 
9
-static void test_ftp_callback ( char *data, size_t len ) {
10
+static void print_ftp_response ( char *data, size_t len ) {
10 11
 	unsigned int i;
11 12
 	char c;
12 13
 
@@ -23,18 +24,29 @@ static void test_ftp_callback ( char *data, size_t len ) {
23 24
 }
24 25
 
25 26
 void test_ftp ( struct sockaddr_tcpip *server, const char *filename ) {
27
+	char data[256];
28
+	struct buffer buffer;
26 29
 	struct ftp_request ftp;
27 30
 	int rc;
28 31
 
29 32
 	printf ( "FTP fetching %s\n", filename );
30 33
 	
34
+	memset ( &buffer, 0, sizeof ( buffer ) );
35
+	buffer.addr = virt_to_phys ( data );
36
+	buffer.len = sizeof ( data );
37
+
31 38
 	memset ( &ftp, 0, sizeof ( ftp ) );
32 39
 	memcpy ( &ftp.server, server, sizeof ( ftp.server ) );
33 40
 	ftp.filename = filename;
34
-	ftp.callback = test_ftp_callback;
41
+	ftp.buffer = &buffer;
35 42
 
36 43
 	rc = async_wait ( ftp_get ( &ftp ) );
37 44
 	if ( rc ) {
38 45
 		printf ( "FTP fetch failed\n" );
46
+		return;
39 47
 	}
48
+
49
+	printf ( "FTP received %d bytes\n", buffer.fill );
50
+
51
+	print_ftp_response ( data, buffer.fill );
40 52
 }

正在加载...
取消
保存