| 41 |
*@param fname サーバ上のファイル名 |
*@param fname サーバ上のファイル名 |
| 42 |
*@param buf バッファへのポインタ |
*@param buf バッファへのポインタ |
| 43 |
*@param bufsiz バッファサイズ |
*@param bufsiz バッファサイズ |
| 44 |
*@retval int 0: no error. -1: OS level error. -2: ftp protocol error. -3: buffer too small. |
*@retval int 取得したバイト数 マイナス値ならエラーコード |
| 45 |
*@note |
*@note |
| 46 |
*/ |
*/ |
| 47 |
int ftp_get_buffer( LIBOFTP *ftp, const char *fname, char *buf, int bufsiz ) |
int ftp_get_buffer( LIBOFTP *ftp, const char *fname, char *buf, int bufsiz ) |
| 48 |
{ |
{ |
| 49 |
int data_socket; |
int data_socket; |
| 50 |
char *p = buf; |
char *p = buf; |
| 51 |
int n, res; |
int res; |
| 52 |
|
|
| 53 |
/* |
/* |
| 54 |
* 受信準備 |
* 受信準備 |
| 66 |
* タイムアウトが意図通りに働くように、分割してrecvする。 |
* タイムアウトが意図通りに働くように、分割してrecvする。 |
| 67 |
*/ |
*/ |
| 68 |
while( 1 ) { |
while( 1 ) { |
| 69 |
|
int n; |
| 70 |
int len = bufsiz; |
int len = bufsiz; |
| 71 |
if( len > TRANSFER_SEGMENT_SIZE ) { |
if( len > TRANSFER_SEGMENT_SIZE ) { |
| 72 |
len = TRANSFER_SEGMENT_SIZE; |
len = TRANSFER_SEGMENT_SIZE; |
| 74 |
n = recv( data_socket, p, len, 0 ); |
n = recv( data_socket, p, len, 0 ); |
| 75 |
DEBUGPRINT1( "RECV: n=%d\n", n ); |
DEBUGPRINT1( "RECV: n=%d\n", n ); |
| 76 |
if( n < 0 ) { |
if( n < 0 ) { |
| 77 |
DEBUGPRINT1( "get_buffer: recv error. %s\n", strerror(errno) ); |
int ret; |
| 78 |
|
DEBUGPRINT1( "recv error. %s\n", strerror(errno) ); |
| 79 |
|
if( errno == EAGAIN ) { |
| 80 |
|
ret = LIBOFTP_ERROR_TIMEOUT; |
| 81 |
|
} else { |
| 82 |
|
ret = LIBOFTP_ERROR_OS; |
| 83 |
|
copy_strerror(); |
| 84 |
|
} |
| 85 |
close( data_socket ); |
close( data_socket ); |
| 86 |
return -1; |
return ret; |
| 87 |
} |
} |
| 88 |
if( n == 0 ) { |
if( n == 0 ) { |
| 89 |
break; |
break; |
| 91 |
p += n; |
p += n; |
| 92 |
bufsiz -= n; |
bufsiz -= n; |
| 93 |
if( bufsiz <= 0 ) { |
if( bufsiz <= 0 ) { |
| 94 |
break; |
break; /* buffer too small */ |
| 95 |
} |
} |
| 96 |
} |
} |
|
close( data_socket ); |
|
| 97 |
|
|
| 98 |
/* |
if( bufsiz > 0 ) { /* バッファ不足だったか? */ |
| 99 |
* receive response. |
/* |
| 100 |
*/ |
* 不足していない |
| 101 |
if( (res = ftp_receive_response( ftp, 0, 0 )) != 226 ) { /* 226: Closing data connection. */ |
*/ |
| 102 |
DEBUGPRINT1( "get_buffer: got illegal response %d\n", res ); |
close( data_socket ); |
| 103 |
return -2; |
|
| 104 |
} |
/* receive response. */ |
| 105 |
|
res = ftp_receive_response( ftp, ftp->error_message, sizeof(ftp->error_message)-1 ); |
| 106 |
|
if( res != 226 ) { /* 226: Closing data connection. */ |
| 107 |
|
DEBUGPRINT1( "got illegal response %d\n", res ); |
| 108 |
|
return res < 0? res: LIBOFTP_ERROR_PROTOCOL; |
| 109 |
|
} |
| 110 |
|
|
| 111 |
|
return p - buf; /* return with transfered bytes */ |
| 112 |
|
|
| 113 |
|
} else { |
| 114 |
|
/* |
| 115 |
|
* バッファ不足時 |
| 116 |
|
*/ |
| 117 |
|
DEBUGPRINT1( "buffer too small. %s\n", "" ); |
| 118 |
|
strncpy( ftp->error_message, "buffer too small", sizeof( ftp->error_message ) - 1 ); |
| 119 |
|
|
| 120 |
|
if( ftp_send_command( ftp, "ABOR\r\n" ) < 0 ) { |
| 121 |
|
DEBUGPRINT1( "command sending error. %s\n", "ABOR" ); |
| 122 |
|
close( data_socket ); |
| 123 |
|
return LIBOFTP_ERROR_BUFFER; |
| 124 |
|
} |
| 125 |
|
|
| 126 |
|
res = ftp_receive_response( ftp, 0, 0 ); |
| 127 |
|
if( res == 426 ) { /* 426: Connection closed; transfer aborted. */ |
| 128 |
|
res = ftp_receive_response( ftp, 0, 0 ); |
| 129 |
|
} |
| 130 |
|
close( data_socket ); |
| 131 |
|
if( res != 226 ) { /* 226: Closing data connection. */ |
| 132 |
|
DEBUGPRINT1( "got illegal response %d\n", res ); |
| 133 |
|
return res < 0? res: LIBOFTP_ERROR_PROTOCOL; |
| 134 |
|
} |
| 135 |
|
|
| 136 |
if( bufsiz <= 0 ) { |
return LIBOFTP_ERROR_BUFFER; |
|
DEBUGPRINT1( "get_buffer: buffer too small. %s\n", "" ); |
|
|
return -3; |
|
| 137 |
} |
} |
|
return 0; |
|
| 138 |
} |
} |