• R/O
  • SSH
  • HTTPS

liboftp: コミット


コミットメタ情報

リビジョン49 (tree)
日時2009-12-03 00:12:52
作者hirohitohigashi

ログメッセージ

Improvement of robustness

変更サマリ

差分

--- trunk/sub.c (revision 48)
+++ trunk/sub.c (revision 49)
@@ -167,7 +167,7 @@
167167 copy_strerror();
168168 return LIBOFTP_ERROR_OS;
169169 }
170- DEBUGPRINT1( "RESP1: %s", str1 );
170+ DEBUGPRINT1( "RESP1: %s\n", str1 );
171171 if( n < 3 ) {
172172 return LIBOFTP_ERROR_PROTOCOL;
173173 }
@@ -185,7 +185,7 @@
185185 copy_strerror();
186186 return LIBOFTP_ERROR_OS;
187187 }
188- DEBUGPRINT1( "RESP2: %s", str1 );
188+ DEBUGPRINT1( "RESP2: %s\n", str1 );
189189 if( n < 3 ) {
190190 return LIBOFTP_ERROR_PROTOCOL;
191191 }
@@ -223,7 +223,7 @@
223223 */
224224 int ftp_getready_active( LIBOFTP *ftp, const char *cmd, const char *fname )
225225 {
226- int sock = 0;
226+ int sock_listen, sock_accept = -1;
227227 struct sockaddr_in saddr;
228228 int saddr_len;
229229 unsigned char *ip, *pt;
@@ -231,6 +231,7 @@
231231 int res;
232232 struct timeval timeout;
233233 fd_set rfds, wfds;
234+ int flag_status_ok = 0;
234235
235236 /*
236237 * open data port.
@@ -237,8 +238,8 @@
237238 * (note)
238239 * same command port ip and automatic random port.
239240 */
240- sock = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
241- if( sock < 0 ) {
241+ sock_listen = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
242+ if( sock_listen < 0 ) {
242243 DEBUGPRINT1( "getready_active: can't open socket. %s\n", strerror(errno) );
243244 goto ERROR_OS;
244245 }
@@ -251,23 +252,22 @@
251252 }
252253 saddr.sin_port = htons( 0 );
253254
254- if( bind( sock, (struct sockaddr *)&saddr, sizeof( saddr ) ) < 0 ) {
255+ if( bind( sock_listen, (struct sockaddr *)&saddr, sizeof( saddr ) ) < 0 ) {
255256 DEBUGPRINT1( "getready_active: can't bind socket. %s\n", strerror(errno) );
256257 goto ERROR_OS;
257258 }
258259
259- if( listen( sock, 1 ) < 0 ) {
260+ if( listen( sock_listen, 1 ) < 0 ) {
260261 DEBUGPRINT1( "getready_active: can't listen socket. %s\n", strerror(errno) );
261262 goto ERROR_OS;
262263 }
263264
264-
265265 /*
266266 * make PORT command.
267267 */
268268 memset( &saddr, 0, sizeof( saddr ) );
269269 saddr_len = sizeof( saddr );
270- if( getsockname( sock, (struct sockaddr *)&saddr, &saddr_len ) < 0 ) {
270+ if( getsockname( sock_listen, (struct sockaddr *)&saddr, &saddr_len ) < 0 ) {
271271 DEBUGPRINT1( "getready_active: can't get data socket name. %s\n", strerror(errno) );
272272 goto ERROR_OS;
273273 }
@@ -280,13 +280,13 @@
280280 */
281281 if( ftp_send_command( ftp, str1 ) < 0 ) {
282282 DEBUGPRINT1( "getready_active: %s command sending error.\n", "PORT" );
283- close( sock );
283+ close( sock_listen );
284284 return LIBOFTP_ERROR_OS;
285285 }
286286 res = ftp_receive_response( ftp, ftp->error_message, sizeof(ftp->error_message) - 1 );
287287 if( res != 200 ) { /* 200: Command okay. */
288288 DEBUGPRINT1( "getready_active: get PORT response code %d\n", res );
289- close( sock );
289+ close( sock_listen );
290290 return LIBOFTP_ERROR_PROTOCOL;
291291 }
292292
@@ -300,29 +300,35 @@
300300 }
301301 if( ftp_send_command( ftp, str1 ) < 0 ) {
302302 DEBUGPRINT1( "getready_active: command sending error. %s", str1 );
303- close( sock );
303+ close( sock_listen );
304304 return LIBOFTP_ERROR_OS;
305305 }
306306
307307 /*
308- * accept data connection with timeout.
308+ * accept data connection with timeout, or get status by control connection.
309309 */
310310 timeout.tv_sec = ftp->timeout_sec;
311311 timeout.tv_usec = 0;
312-
313312 do {
313+ int nfds = (sock_listen > ftp->socket)? sock_listen: ftp->socket;
314314 FD_ZERO( &rfds );
315315 FD_ZERO( &wfds );
316- FD_SET( sock, &rfds );
317- FD_SET( sock, &wfds );
316+ if( sock_listen >= 0) {
317+ FD_SET( sock_listen, &rfds );
318+ FD_SET( sock_listen, &wfds );
319+ }
320+ FD_SET( ftp->socket, &rfds );
318321
319- res = select( sock+1, &rfds, &wfds, 0, &timeout );
320- if( res == 0 ) { /* timeout */
322+ res = select( nfds+1, &rfds, &wfds, 0, &timeout );
323+ /* ckeck timeout */
324+ if( res == 0 ) {
321325 DEBUGPRINT1( "getready_active: waiting connection timeout.%s\n", "" );
322- close( sock );
326+ close( sock_listen );
323327 strncpy( ftp->error_message, "connection timeout.", sizeof( ftp->error_message )-1 );
324328 return LIBOFTP_ERROR_TIMEOUT;
325329 }
330+
331+ /* check some OS errors. */
326332 if( res < 0 ) {
327333 if( errno == EINTR ) continue;
328334 DEBUGPRINT1( "getready_active: select error. %s\n", strerror(errno) );
@@ -329,34 +335,39 @@
329335 goto ERROR_OS;
330336 }
331337
332- if( FD_ISSET( sock, &rfds ) || FD_ISSET( sock, &wfds ) ) break;
333- } while( 1 );
338+ /* accept data connection. */
339+ if( FD_ISSET( sock_listen, &rfds ) || FD_ISSET( sock_listen, &wfds ) ) {
340+ sock_accept = accept( sock_listen, (struct sockaddr *)&saddr, &saddr_len );
341+ close( sock_listen );
342+ sock_listen = -1;
343+ if( sock_accept < 0 ) {
344+ DEBUGPRINT1( "getready_active: socket accept error. %s\n", strerror(errno) );
345+ goto ERROR_OS;
346+ }
347+ DEBUGPRINT1( "getready_active: socket accept. fd=%d\n", sock_accept );
348+ }
334349
335- res = accept( sock, (struct sockaddr *)&saddr, &saddr_len );
336- close( sock );
337- if( res < 0 ) {
338- DEBUGPRINT1( "getready_active: socket accept error. %s\n", strerror(errno) );
339- goto ERROR_OS;
340- }
341- sock = res;
350+ /* get status. */
351+ if( FD_ISSET( ftp->socket, &rfds ) ) {
352+ res = ftp_receive_response( ftp, ftp->error_message, sizeof(ftp->error_message) - 1 );
353+ DEBUGPRINT1( "getready_active: get STOR/RETR response code %d\n", res );
354+ if( res != 150 ) { /* 150: File status okay; about to open data connection. */
355+ if( sock_listen >= 0 ) close( sock_listen );
356+ if( sock_accept >= 0 ) close( sock_accept );
357+ return LIBOFTP_ERROR_PROTOCOL;
358+ }
359+ flag_status_ok = 1;
360+ }
361+
362+ } while( !( sock_accept >= 0 && flag_status_ok ) );
342363
343- /*
344- * get status.
345- */
346- res = ftp_receive_response( ftp, ftp->error_message, sizeof(ftp->error_message) - 1 );
347- if( res != 150 ) { /* 150: File status okay; about to open data connection. */
348- DEBUGPRINT1( "getready_active: get STOR/RETR response code %d\n", res );
349- close( sock );
350- return LIBOFTP_ERROR_PROTOCOL;
351- }
364+ return sock_accept;
352365
353- return sock;
354-
355366
356367 ERROR_OS:
357368 copy_strerror();
358- if( sock > 0 ) {
359- close( sock );
369+ if( sock_listen >= 0 ) {
370+ close( sock_listen );
360371 }
361372 return LIBOFTP_ERROR_OS;
362373 }
旧リポジトリブラウザで表示