Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/ftp_get_buffer.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 50 - (show annotations) (download) (as text)
Wed Dec 2 15:13:30 2009 UTC (14 years, 3 months ago) by hirohitohigashi
File MIME type: text/x-csrc
File size: 5927 byte(s)
add error check
1 /*
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 <string.h>
14 #include <sys/types.h>
15 #include <sys/socket.h>
16
17
18 /***** Local headers ********************************************************/
19 #include "liboftp.h"
20 #include "sub.h"
21
22
23 /***** Constat values *******************************************************/
24 #define TRANSFER_SEGMENT_SIZE 4096 /* 一度のrecv()で転送するバイト数 */
25
26
27 /***** Macros ***************************************************************/
28 /***** Typedefs *************************************************************/
29 /***** Function prototypes **************************************************/
30 /***** Local variables ******************************************************/
31 /***** Global variables *****************************************************/
32 /***** Signal catching functions ********************************************/
33 /***** Local functions ******************************************************/
34
35 /****************************************************************************/
36 /*! バッファへリスト取得 作業ルーチン
37 *
38 *@param ftp LIBOFTPへのポインタ。
39 *@param cmd コマンド (RETR|LIST|NLST)
40 *@param fname ファイル名または、グロブ。
41 *@param buf バッファへのポインタ
42 *@param bufsiz バッファサイズ
43 *@retval int 取得したバイト数 マイナス値ならエラーコード
44 *@note
45 */
46 static int ftp_get_buffer_main( LIBOFTP *ftp, const char *cmd, const char *fname, char *buf, int bufsiz )
47 {
48 int data_socket;
49 char *p = buf;
50 int res;
51
52 if( ftp->socket < 0 ) return LIBOFTP_ERROR;
53
54 /*
55 * 受信準備
56 */
57 if( ftp->flag_passive ) {
58 data_socket = ftp_getready_pasv( ftp, cmd, fname );
59 } else {
60 data_socket = ftp_getready_active( ftp, cmd, fname );
61 }
62 if( data_socket < 0 ) {
63 return data_socket;
64 }
65
66 /*
67 * タイムアウトが意図通りに働くように、分割してrecvする。
68 */
69 while( 1 ) {
70 int n;
71 int len = bufsiz;
72 if( len > TRANSFER_SEGMENT_SIZE ) {
73 len = TRANSFER_SEGMENT_SIZE;
74 }
75 n = recv( data_socket, p, len, 0 );
76 DEBUGPRINT1( "RECV: n=%d\n", n );
77 if( n < 0 ) {
78 int ret;
79 DEBUGPRINT1( "recv error. %s\n", strerror(errno) );
80 if( errno == EAGAIN ) {
81 ret = LIBOFTP_ERROR_TIMEOUT;
82 } else {
83 ret = LIBOFTP_ERROR_OS;
84 copy_strerror();
85 }
86 close( data_socket );
87 return ret;
88 }
89 if( n == 0 ) {
90 break;
91 }
92 p += n;
93 bufsiz -= n;
94 if( bufsiz <= 0 ) {
95 break; /* buffer too small */
96 }
97 }
98
99 if( bufsiz > 0 ) { /* バッファ不足だったか? */
100 /*
101 * 不足していない
102 */
103 close( data_socket );
104
105 /* receive response. */
106 res = ftp_receive_response( ftp, ftp->error_message, sizeof(ftp->error_message)-1 );
107 if( res != 226 ) { /* 226: Closing data connection. */
108 DEBUGPRINT1( "got illegal response %d\n", res );
109 return res < 0? res: LIBOFTP_ERROR_PROTOCOL;
110 }
111
112 return p - buf; /* return with transfered bytes */
113
114 } else {
115 /*
116 * バッファ不足時
117 */
118 DEBUGPRINT1( "buffer too small. %s\n", "" );
119 strncpy( ftp->error_message, "buffer too small", sizeof( ftp->error_message ) - 1 );
120
121 if( ftp_send_command( ftp, "ABOR\r\n" ) < 0 ) {
122 DEBUGPRINT1( "command sending error. %s\n", "ABOR" );
123 close( data_socket );
124 return LIBOFTP_ERROR_BUFFER;
125 }
126
127 res = ftp_receive_response( ftp, 0, 0 );
128 if( res == 426 ) { /* 426: Connection closed; transfer aborted. */
129 res = ftp_receive_response( ftp, 0, 0 );
130 }
131 close( data_socket );
132 if( res != 226 ) { /* 226: Closing data connection. */
133 DEBUGPRINT1( "got illegal response %d\n", res );
134 return res < 0? res: LIBOFTP_ERROR_PROTOCOL;
135 }
136
137 return LIBOFTP_ERROR_BUFFER;
138 }
139 }
140
141
142
143 /***** Global functions *****************************************************/
144
145 /****************************************************************************/
146 /*! バッファへファイル取得
147 *
148 *@param ftp LIBOFTPへのポインタ。
149 *@param fname サーバ上のファイル名
150 *@param buf バッファへのポインタ
151 *@param bufsiz バッファサイズ
152 *@retval int 取得したバイト数 マイナス値ならエラーコード
153 *@note
154 */
155 int ftp_get_buffer( LIBOFTP *ftp, const char *fname, char *buf, int bufsiz )
156 {
157 return ftp_get_buffer_main( ftp, "RETR", fname, buf, bufsiz );
158 }
159
160
161
162 /****************************************************************************/
163 /*! ディレクトリリスト(LIST) 取得
164 *
165 *@param ftp LIBOFTPへのポインタ。
166 *@param fglob ファイルリストグロブ (ex: *.txt) or NULL
167 *@param buf バッファへのポインタ
168 *@param bufsiz バッファサイズ
169 *@retval int エラーコード
170 *@note
171 */
172 int ftp_list( LIBOFTP *ftp, const char *fglob, char *buf, int bufsiz )
173 {
174 int ret;
175
176 ret = ftp_get_buffer_main( ftp, "LIST", fglob, buf, bufsiz );
177 if( ret > 0 ) {
178 buf[ret] = 0;
179 return LIBOFTP_NOERROR;
180 }
181
182 return ret;
183 }
184
185
186
187 /****************************************************************************/
188 /*! ディレクトリリスト(NLST) 取得
189 *
190 *@param ftp LIBOFTPへのポインタ。
191 *@param fglob ファイルリストグロブ (ex: *.txt) or NULL
192 *@param buf バッファへのポインタ
193 *@param bufsiz バッファサイズ
194 *@retval int エラーコード
195 *@note
196 */
197 int ftp_nlist( LIBOFTP *ftp, const char *fglob, char *buf, int bufsiz )
198 {
199 int ret;
200
201 ret = ftp_get_buffer_main( ftp, "NLST", fglob, buf, bufsiz );
202 if( ret > 0 ) {
203 buf[ret] = 0;
204 return LIBOFTP_NOERROR;
205 }
206
207 return ret;
208 }

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