|
@@ -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
|
|