Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /tags/REL-2.2/ftp_get_buffer.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 38 - (hide annotations) (download) (as text)
Sun Mar 1 15:51:51 2009 UTC (15 years, 1 month ago) by hirohitohigashi
Original Path: trunk/ftp_get_buffer.c
File MIME type: text/x-csrc
File size: 4064 byte(s)
modified some functions for robustness.

1 hirohitohigashi 17 /*
2     liboftp: this is an FTP library to simplify the work to a Developer
3     who want to work with FTP servers (RFC 959).
4    
5     Copyright (c) 2009 hirohito higashi. All rights reserved.
6     This file is distributed under BSD license.
7     */
8    
9    
10     /***** Feature test switches ************************************************/
11     /***** System headers *******************************************************/
12     #include <unistd.h>
13     #include <sys/types.h>
14     #include <sys/socket.h>
15 hirohitohigashi 28 #include <string.h>
16     #include <errno.h>
17 hirohitohigashi 17
18    
19     /***** Local headers ********************************************************/
20     #include "liboftp.h"
21     #include "sub.h"
22    
23    
24     /***** Constat values *******************************************************/
25     #define TRANSFER_SEGMENT_SIZE 4096 /* 一度のrecv()で転送するバイト数 */
26    
27    
28     /***** Macros ***************************************************************/
29     /***** Typedefs *************************************************************/
30     /***** Function prototypes **************************************************/
31     /***** Local variables ******************************************************/
32     /***** Global variables *****************************************************/
33     /***** Signal catching functions ********************************************/
34     /***** Local functions ******************************************************/
35     /***** Global functions *****************************************************/
36    
37     /****************************************************************************/
38     /*! バッファへファイル取得
39     *
40     *@param ftp LIBOFTPへのポインタ。
41     *@param fname サーバ上のファイル名
42     *@param buf バッファへのポインタ
43     *@param bufsiz バッファサイズ
44 hirohitohigashi 34 *@retval int 取得したバイト数 マイナス値ならエラーコード
45 hirohitohigashi 17 *@note
46     */
47     int ftp_get_buffer( LIBOFTP *ftp, const char *fname, char *buf, int bufsiz )
48     {
49     int data_socket;
50     char *p = buf;
51 hirohitohigashi 34 int res;
52 hirohitohigashi 17
53     /*
54     * 受信準備
55     */
56     if( ftp->flag_passive ) {
57 hirohitohigashi 26 data_socket = ftp_getready_pasv( ftp, "RETR", fname );
58 hirohitohigashi 17 } else {
59 hirohitohigashi 26 data_socket = ftp_getready_active( ftp, "RETR", fname );
60 hirohitohigashi 17 }
61 hirohitohigashi 20 if( data_socket < 0 ) {
62     return data_socket;
63     }
64 hirohitohigashi 17
65     /*
66     * タイムアウトが意図通りに働くように、分割してrecvする。
67     */
68     while( 1 ) {
69 hirohitohigashi 34 int n;
70 hirohitohigashi 17 int len = bufsiz;
71     if( len > TRANSFER_SEGMENT_SIZE ) {
72     len = TRANSFER_SEGMENT_SIZE;
73     }
74     n = recv( data_socket, p, len, 0 );
75     DEBUGPRINT1( "RECV: n=%d\n", n );
76     if( n < 0 ) {
77 hirohitohigashi 36 int ret;
78 hirohitohigashi 29 DEBUGPRINT1( "recv error. %s\n", strerror(errno) );
79 hirohitohigashi 36 if( errno == EAGAIN ) {
80     ret = LIBOFTP_ERROR_TIMEOUT;
81     } else {
82     ret = LIBOFTP_ERROR_OS;
83     copy_strerror();
84     }
85 hirohitohigashi 17 close( data_socket );
86 hirohitohigashi 36 return ret;
87 hirohitohigashi 17 }
88     if( n == 0 ) {
89     break;
90     }
91     p += n;
92     bufsiz -= n;
93     if( bufsiz <= 0 ) {
94 hirohitohigashi 38 break; /* buffer too small */
95 hirohitohigashi 17 }
96     }
97    
98 hirohitohigashi 38 if( bufsiz > 0 ) { /* バッファ不足だったか? */
99     /*
100     * 不足していない
101     */
102     close( data_socket );
103 hirohitohigashi 17
104 hirohitohigashi 38 /* 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 hirohitohigashi 29 DEBUGPRINT1( "buffer too small. %s\n", "" );
118     strncpy( ftp->error_message, "buffer too small", sizeof( ftp->error_message ) - 1 );
119 hirohitohigashi 38
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 hirohitohigashi 29 return LIBOFTP_ERROR_BUFFER;
137 hirohitohigashi 17 }
138     }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26