| 16 |
#include <string.h> |
#include <string.h> |
| 17 |
#include <arpa/inet.h> |
#include <arpa/inet.h> |
| 18 |
#include <sys/time.h> |
#include <sys/time.h> |
| 19 |
|
#include <sys/select.h> |
| 20 |
|
|
| 21 |
|
|
| 22 |
/***** Local headers ********************************************************/ |
/***** Local headers ********************************************************/ |
| 109 |
|
|
| 110 |
|
|
| 111 |
/****************************************************************************/ |
/****************************************************************************/ |
| 112 |
|
/*! send ftp command |
| 113 |
|
* |
| 114 |
|
*@param ftp pointer of LIBOFTP. |
| 115 |
|
*@param cmd ftp command. |
| 116 |
|
*@retval int 0 is no error, or -1 if an error. |
| 117 |
|
*@note |
| 118 |
|
* |
| 119 |
|
*/ |
| 120 |
|
int ftp_send_command( LIBOFTP *ftp, const char *cmd ) |
| 121 |
|
{ |
| 122 |
|
int ret; |
| 123 |
|
DEBUGPRINT1( "SENDC: %s", cmd ); |
| 124 |
|
ret = sendn( ftp->socket, cmd, strlen( cmd ), 0 ); |
| 125 |
|
if( ret < 0 ) { |
| 126 |
|
return ret; |
| 127 |
|
} |
| 128 |
|
|
| 129 |
|
return 0; |
| 130 |
|
} |
| 131 |
|
|
| 132 |
|
|
| 133 |
|
|
| 134 |
|
/****************************************************************************/ |
| 135 |
/*! receive response |
/*! receive response |
| 136 |
* |
* |
| 137 |
*@param ftp pointer of LIBOFTP. |
*@param ftp pointer of LIBOFTP. |
| 243 |
*/ |
*/ |
| 244 |
str1[255] = 0; |
str1[255] = 0; |
| 245 |
snprintf( str1, sizeof(str1)-1, "PASV\r\n" ); |
snprintf( str1, sizeof(str1)-1, "PASV\r\n" ); |
| 246 |
if( sendn( ftp->socket, str1, strlen( str1 ), 0 ) < 0 ) { |
if( ftp_send_command( ftp, str1 ) < 0 ) { |
| 247 |
return -1; |
return -1; |
| 248 |
} |
} |
| 249 |
res = ftp_receive_response( ftp, str1, sizeof(str1) ); |
res = ftp_receive_response( ftp, str1, sizeof(str1) ); |
| 270 |
* send ftp command. |
* send ftp command. |
| 271 |
*/ |
*/ |
| 272 |
snprintf( str1, sizeof(str1), "%s %s\r\n", cmd, fname ); |
snprintf( str1, sizeof(str1), "%s %s\r\n", cmd, fname ); |
| 273 |
if( sendn( ftp->socket, str1, strlen( str1 ), 0 ) < 0 ) { |
if( ftp_send_command( ftp, str1 ) < 0 ) { |
| 274 |
return -2; |
return -2; |
| 275 |
} |
} |
| 276 |
|
|
| 308 |
} |
} |
| 309 |
|
|
| 310 |
|
|
| 311 |
|
|
| 312 |
|
int ftp_getready_active( LIBOFTP *ftp, const char *fname, const char *cmd ) |
| 313 |
|
{ |
| 314 |
|
int sock; |
| 315 |
|
struct sockaddr_in saddr; |
| 316 |
|
int saddr_len; |
| 317 |
|
unsigned char *ip, *pt; |
| 318 |
|
char str1[256]; |
| 319 |
|
int res; |
| 320 |
|
struct timeval timeout; |
| 321 |
|
fd_set rfds, wfds; |
| 322 |
|
|
| 323 |
|
/* |
| 324 |
|
* open data port. |
| 325 |
|
* (note) |
| 326 |
|
* same command port ip and automatic random port. |
| 327 |
|
*/ |
| 328 |
|
sock = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP ); |
| 329 |
|
if( sock < 0 ) { |
| 330 |
|
DEBUGPRINT1( "getready_active: can't open socket. %s\n", strerror(errno) ); |
| 331 |
|
return -1; |
| 332 |
|
} |
| 333 |
|
|
| 334 |
|
memset( &saddr, 0, sizeof( saddr ) ); |
| 335 |
|
saddr_len = sizeof( saddr ); |
| 336 |
|
if( getsockname( ftp->socket, (struct sockaddr *)&saddr, &saddr_len ) < 0 ) { |
| 337 |
|
DEBUGPRINT1( "getready_active: can't get control socket name. %s\n", strerror(errno) ); |
| 338 |
|
close( sock ); |
| 339 |
|
return -2; |
| 340 |
|
} |
| 341 |
|
saddr.sin_port = htons( 0 ); |
| 342 |
|
|
| 343 |
|
if( bind( sock, (struct sockaddr *)&saddr, sizeof( saddr ) ) < 0 ) { |
| 344 |
|
DEBUGPRINT1( "getready_active: can't bind socket. %s\n", strerror(errno) ); |
| 345 |
|
close( sock ); |
| 346 |
|
return -2; |
| 347 |
|
} |
| 348 |
|
|
| 349 |
|
if( listen( sock, 1 ) < 0 ) { |
| 350 |
|
DEBUGPRINT1( "getready_active: can't listen socket. %s\n", strerror(errno) ); |
| 351 |
|
close( sock ); |
| 352 |
|
return -2; |
| 353 |
|
} |
| 354 |
|
|
| 355 |
|
|
| 356 |
|
/* |
| 357 |
|
* make PORT command. |
| 358 |
|
*/ |
| 359 |
|
memset( &saddr, 0, sizeof( saddr ) ); |
| 360 |
|
saddr_len = sizeof( saddr ); |
| 361 |
|
if( getsockname( sock, (struct sockaddr *)&saddr, &saddr_len ) < 0 ) { |
| 362 |
|
DEBUGPRINT1( "getready_active: can't get data socket name. %s\n", strerror(errno) ); |
| 363 |
|
close( sock ); |
| 364 |
|
return -2; |
| 365 |
|
} |
| 366 |
|
ip = (unsigned char*)&saddr.sin_addr.s_addr; |
| 367 |
|
pt = (unsigned char*)&saddr.sin_port; |
| 368 |
|
snprintf( str1, sizeof(str1), "PORT %d,%d,%d,%d,%d,%d\r\n", ip[0], ip[1], ip[2], ip[3], pt[0], pt[1] ); |
| 369 |
|
|
| 370 |
|
/* |
| 371 |
|
* send PORT command and get status. |
| 372 |
|
*/ |
| 373 |
|
if( ftp_send_command( ftp, str1 ) < 0 ) { |
| 374 |
|
close( sock ); |
| 375 |
|
return -1; |
| 376 |
|
} |
| 377 |
|
res = ftp_receive_response( ftp, str1, sizeof(str1) ); |
| 378 |
|
if( res != 200 ) { /* 200: Command okay. */ |
| 379 |
|
DEBUGPRINT1( "getready_active: get PORT response code %d\n", res ); |
| 380 |
|
close( sock ); |
| 381 |
|
return -2; |
| 382 |
|
} |
| 383 |
|
|
| 384 |
|
/* |
| 385 |
|
* send ftp command. |
| 386 |
|
*/ |
| 387 |
|
snprintf( str1, sizeof(str1), "%s %s\r\n", cmd, fname ); |
| 388 |
|
if( ftp_send_command( ftp, str1 ) < 0 ) { |
| 389 |
|
close( sock ); |
| 390 |
|
return -2; |
| 391 |
|
} |
| 392 |
|
|
| 393 |
|
/* |
| 394 |
|
* accept data connection with timeout. |
| 395 |
|
*/ |
| 396 |
|
timeout.tv_sec = ftp->timeout_sec; |
| 397 |
|
timeout.tv_usec = 0; |
| 398 |
|
FD_ZERO( &rfds ); |
| 399 |
|
FD_ZERO( &wfds ); |
| 400 |
|
FD_SET( sock, &rfds ); |
| 401 |
|
FD_SET( sock, &wfds ); |
| 402 |
|
|
| 403 |
|
res = select( sock+1, &rfds, &wfds, 0, &timeout ); |
| 404 |
|
if( res == 0 ) { /* timeout */ |
| 405 |
|
DEBUGPRINT1( "getready_active: waiting connection timeout.%s\n", "" ); |
| 406 |
|
close( sock ); |
| 407 |
|
return -3; |
| 408 |
|
} |
| 409 |
|
|
| 410 |
|
res = accept( sock, (struct sockaddr *)&saddr, &saddr_len ); |
| 411 |
|
close( sock ); |
| 412 |
|
if( res < 0 ) { |
| 413 |
|
DEBUGPRINT1( "getready_active: socket accept error. %s\n", strerror(errno) ); |
| 414 |
|
close( sock ); |
| 415 |
|
return -1; |
| 416 |
|
} |
| 417 |
|
sock = res; |
| 418 |
|
|
| 419 |
|
/* |
| 420 |
|
* get status. |
| 421 |
|
*/ |
| 422 |
|
res = ftp_receive_response( ftp, str1, sizeof(str1) ); |
| 423 |
|
if( res != 150 ) { /* 150: File status okay; about to open data connection. */ |
| 424 |
|
DEBUGPRINT1( "getready_active: get STOR/RETR response code %d\n", res ); |
| 425 |
|
close( sock ); |
| 426 |
|
return -2; |
| 427 |
|
} |
| 428 |
|
|
| 429 |
|
|
| 430 |
|
return sock; |
| 431 |
|
} |