Develop and Download Open Source Software

Browse Subversion Repository

Contents of /tags/REL-2.1/ftp_get_buffer.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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