📄 ftp.c
字号:
if(taskthread->connsocket)
{
os_socket_tcp_close(taskthread->connsocket);
taskthread->connsocket = 0;
}
if(taskthread->datasocket)
{
os_socket_tcp_close(taskthread->datasocket);
taskthread->datasocket = 0;
}
taskthread->block = os_free(taskthread->block);
}
VOID ftp_cmd_user(FtpTaskThread *taskthread)
{
CHAR buf[SOCKET_BUF_MAX + 1];
BOOL writeable, error;
INT replycode;
if(taskthread->cmdstatus == FTP_STATUS_WELCOME_OK)
{
os_socket_tcp_status(taskthread->connsocket, NULL, &writeable, &error);
if(writeable)
{
dld_taskthread_add_log((DldTaskThread *)taskthread, _("Sending username(%s)."), taskthread->parenttask->username->str);
strcpy(buf, "USER anonymous\r\n");
if(taskthread->parenttask->username)
if(strlen(taskthread->parenttask->username->str) > 0)
snprintf(buf, sizeof(buf) - 1, "USER %s\r\n", taskthread->parenttask->username->str);
os_socket_tcp_send(taskthread->connsocket, buf, strlen(buf));
taskthread->cmdstatus = FTP_STATUS_USER;
taskthread->buffer = buffer_clear(taskthread->buffer);
}
}
if(taskthread->cmdstatus == FTP_STATUS_USER)
{
if((replycode = ftp_recv_reply(taskthread) ) != -1)
{
if(replycode == 331) //need password
{
dld_taskthread_add_log((DldTaskThread *)taskthread, _("Username OK"));
taskthread->cmdstatus = FTP_STATUS_USER_OK;
taskthread->buffer = buffer_clear(taskthread->buffer);
}
else
{
// connect ftp error!
ftp_taskthread_meet_error(taskthread, TRUE);
}
}
}
}
VOID ftp_cmd_pass(FtpTaskThread *taskthread)
{
CHAR buf[SOCKET_BUF_MAX + 1];
BOOL writeable, error;
INT replycode;
if(taskthread->cmdstatus == FTP_STATUS_USER_OK)
{
os_socket_tcp_status(taskthread->connsocket, NULL, &writeable, &error);
if(writeable)
{
dld_taskthread_add_log((DldTaskThread *)taskthread, _("Sending password ..."));
strcpy(buf, "PASS dld@dld.com\r\n");
if(taskthread->parenttask->username)
if(strlen(taskthread->parenttask->username->str) > 0 && strcmpi(taskthread->parenttask->username->str, "anonymous") != 0)
snprintf(buf, sizeof(buf) - 1, "PASS %s\r\n", taskthread->parenttask->password->str);
os_socket_tcp_send(taskthread->connsocket, buf, strlen(buf));
taskthread->cmdstatus = FTP_STATUS_PASS;
taskthread->buffer = buffer_clear(taskthread->buffer);
}
}
if(taskthread->cmdstatus == FTP_STATUS_PASS)
{
if((replycode = ftp_recv_reply(taskthread)) != -1)
{
if(replycode == 230) //pass OK
{
dld_taskthread_add_log((DldTaskThread *)taskthread, _("Password OK."));
taskthread->cmdstatus = FTP_STATUS_PASS_OK;
taskthread->buffer = buffer_clear(taskthread->buffer);
}
else
{
// connect ftp error!
ftp_taskthread_meet_error(taskthread, TRUE);
}
}
}
}
VOID ftp_cmd_binary(FtpTaskThread *taskthread)
{
CHAR buf[SOCKET_BUF_MAX + 1];
BOOL writeable, error;
INT replycode;
if(taskthread->cmdstatus == FTP_STATUS_PASS_OK)
{
os_socket_tcp_status(taskthread->connsocket, NULL, &writeable, &error);
if(writeable)
{
dld_taskthread_add_log((DldTaskThread *)taskthread, _("Enterning BINARY mode ..."));
strcpy(buf, "TYPE I\r\n");
os_socket_tcp_send(taskthread->connsocket, buf, strlen(buf));
taskthread->cmdstatus = FTP_STATUS_BINARY;
taskthread->buffer = buffer_clear(taskthread->buffer);
}
}
if(taskthread->cmdstatus == FTP_STATUS_BINARY)
{
if((replycode = ftp_recv_reply(taskthread)) != -1)
{
//FIXME
//!!!!!!!!!!
//type i
//200 Type set to I
if(replycode == 200) //binary OK
{
dld_taskthread_add_log((DldTaskThread *)taskthread, _("Entered BINARY mode."));
taskthread->cmdstatus = FTP_STATUS_BINARY_OK;
taskthread->buffer = buffer_clear(taskthread->buffer);
}
else
{
// connect ftp error!
ftp_taskthread_meet_error(taskthread, TRUE);
}
}
}
}
VOID ftp_cmd_size(FtpTaskThread *taskthread)
{
CHAR buf[SOCKET_BUF_MAX + 1];
BOOL writeable, error;
INT replycode;
if(taskthread->cmdstatus == FTP_STATUS_BINARY_OK)
{
os_socket_tcp_status(taskthread->connsocket, NULL, &writeable, &error);
if(writeable)
{
dld_taskthread_add_log((DldTaskThread *)taskthread, _("Getting file size ..."));
snprintf(buf, sizeof(buf) - 1, "SIZE %s\r\n", taskthread->parenttask->remotefile->str);
os_socket_tcp_send(taskthread->connsocket, buf, strlen(buf));
taskthread->cmdstatus = FTP_STATUS_SIZE;
taskthread->buffer = buffer_clear(taskthread->buffer);
}
}
if(taskthread->cmdstatus == FTP_STATUS_SIZE)
{
if((replycode = ftp_recv_reply(taskthread)) != -1)
{
if(replycode == 213) //213 filesize
{
taskthread->cmdstatus = FTP_STATUS_SIZE_OK;
dld_task_set_filesize(taskthread->parenttask, atoi(taskthread->buffer->data + 4)); //213 filesize
taskthread->buffer = buffer_clear(taskthread->buffer);
dld_taskthread_add_log((DldTaskThread *)taskthread, _("File size is %d."), taskthread->parenttask->filesize);
}
else
{
// connect ftp error!
ftp_taskthread_meet_error(taskthread, TRUE);
}
dprintf("[ftp_cmd_size] %d CMD FINISHED\r\n", taskthread);
}
}
}
VOID ftp_cmd_reset(FtpTaskThread *taskthread)
{
CHAR buf[SOCKET_BUF_MAX + 1];
BOOL writeable, error;
INT replycode;
if(taskthread->cmdstatus == FTP_STATUS_BINARY_OK || taskthread->cmdstatus == FTP_STATUS_SIZE_OK)
{
os_socket_tcp_status(taskthread->connsocket, NULL, &writeable, &error);
if(writeable)
{
if(!taskthread->block)
{
dld_task_alloc_block((DldTaskThread *)taskthread);
dld_taskthread_add_log((DldTaskThread *)taskthread, _("Trying to alloc a new block ..."));
if(!taskthread->block)
{
dld_taskthread_add_log((DldTaskThread *)taskthread, _("No more blocks. Thread finished successfully."));
os_socket_tcp_send(taskthread->connsocket, "ABOR\r\n", 6);
os_socket_tcp_send(taskthread->connsocket, "QUIT\r\n", 6);
os_sleep(100);
ftp_taskthread_stop((DldTaskThread *)taskthread);
return;
}
}
dld_taskthread_add_log((DldTaskThread *)taskthread, _("Reset remote file read-position to %d ..."), taskthread->block->start);
snprintf(buf, sizeof(buf) - 1, "REST %d\r\n", taskthread->block->start);
os_socket_tcp_send(taskthread->connsocket, buf, strlen(buf));
taskthread->cmdstatus = FTP_STATUS_RESET;
taskthread->buffer = buffer_clear(taskthread->buffer);
}
}
if(taskthread->cmdstatus == FTP_STATUS_RESET)
{
if((replycode = ftp_recv_reply(taskthread)) != -1)
{
if(replycode == 350) //350 ok
{
taskthread->cmdstatus = FTP_STATUS_RESET_OK;
taskthread->buffer = buffer_clear(taskthread->buffer);
dld_taskthread_add_log((DldTaskThread *)taskthread, _("Reset remote file read-position OK."));
}
else
{
// connect ftp error!
ftp_taskthread_meet_error(taskthread, TRUE);
}
dprintf("[ftp_cmd_reset] %d CMD FINISHED\r\n", taskthread);
}
}
}
VOID ftp_cmd_pasv(FtpTaskThread *taskthread)
{
BOOL writeable, error;
INT replycode;
INT pasv_addr[6];
CHAR ip[20];
USHORT port;
CHAR *p;
if(taskthread->cmdstatus == FTP_STATUS_RESET_OK)
{
os_socket_tcp_status(taskthread->connsocket, NULL, &writeable, &error);
if(writeable)
{
dld_taskthread_add_log((DldTaskThread *)taskthread, _("Try to enter PASV mode ..."));
os_socket_tcp_send(taskthread->connsocket, "PASV\r\n", 6);
taskthread->cmdstatus = FTP_STATUS_PASV;
taskthread->buffer = buffer_clear(taskthread->buffer);
}
}
if(taskthread->cmdstatus == FTP_STATUS_PASV)
{
if((replycode = ftp_recv_reply(taskthread)) != -1)
{
if(replycode == 227)
{
taskthread->cmdstatus = FTP_STATUS_PASV_OK;
p = strchr(taskthread->buffer->data, '(');
sscanf(p, "(%d,%d,%d,%d,%d,%d)", &pasv_addr[0], &pasv_addr[1], &pasv_addr[2], &pasv_addr[3], &pasv_addr[4], &pasv_addr[5]);
sprintf(ip, "%d.%d.%d.%d", pasv_addr[0], pasv_addr[1], pasv_addr[2], pasv_addr[3]);
port =(USHORT)((pasv_addr[4] << 8) + pasv_addr[5]);
dld_taskthread_add_log((DldTaskThread *)taskthread, _("PASV OK! %s:%d"), ip, port);
taskthread->datasocket = os_socket_tcp_connect(ip, port, TRUE);
taskthread->buffer = buffer_clear(taskthread->buffer);
}
else
{
// connect ftp error!
ftp_taskthread_meet_error(taskthread, TRUE);
}
dprintf("[ftp_cmd_pasv] %d CMD FINISHED\r\n", taskthread);
}
}
}
VOID ftp_cmd_retr(FtpTaskThread *taskthread)
{
CHAR buf[SOCKET_BUF_MAX + 1];
BOOL writeable, error;
INT replycode;
if(taskthread->cmdstatus == FTP_STATUS_PASV_OK)
{
os_socket_tcp_status(taskthread->connsocket, NULL, &writeable, &error);
if(writeable)
{
dld_taskthread_add_log((DldTaskThread *)taskthread, _("Try to return file %s."), taskthread->parenttask->remotefile->str);
snprintf(buf, sizeof(buf) - 1, "RETR %s\r\n", taskthread->parenttask->remotefile->str);
os_socket_tcp_send(taskthread->connsocket, buf, strlen(buf));
taskthread->cmdstatus = FTP_STATUS_RETR;
taskthread->buffer = buffer_clear(taskthread->buffer);
}
}
if(taskthread->cmdstatus == FTP_STATUS_RETR)
{
if((replycode = ftp_recv_reply(taskthread)) != -1)
{
if(replycode == 150) //150 open data stream ...
{
dld_taskthread_add_log((DldTaskThread *)taskthread, _("File is returning ..."));
taskthread->cmdstatus = FTP_STATUS_RETR_OK;
taskthread->buffer = buffer_clear(taskthread->buffer);
}
else
{
// connect ftp error!
ftp_taskthread_meet_error(taskthread, TRUE);
}
dprintf("[ftp_cmd_retr] %d CMD FINISHED\r\n", taskthread);
}
}
}
VOID ftp_recv_data(FtpTaskThread *taskthread)
{
CHAR buf[SOCKET_BUF_MAX + 1];
BOOL readable, error;
INT recvlen;
BOOL blockfinished;
INT ret;
INT replycode;
if(taskthread->cmdstatus == FTP_STATUS_RETR_OK)
{
os_socket_tcp_status(taskthread->datasocket, &readable, NULL, &error);
if(readable)
{
recvlen = os_socket_tcp_recv(taskthread->datasocket, buf, SOCKET_BUF_MAX);
if(recvlen > 0)
{
//clear TIMEOUT tick
os_tick_clear(taskthread->timeouttick);
ret = dld_task_save_thread_data((DldTaskThread *)taskthread, buf, recvlen);
blockfinished = (ret == DLD_ERR_BLOCK_FINISH);
if(blockfinished)
{
taskthread->cmdstatus = FTP_STATUS_RETR_OVER;
dprintf("[ftp_recv_data] %d BLOCK FINISHED!\r\n", taskthread);
os_socket_tcp_close(taskthread->datasocket);
taskthread->datasocket = 0;
taskthread->buffer = buffer_clear(taskthread->buffer);
os_socket_tcp_send(taskthread->connsocket, "ABOR\r\n", 6);
dld_taskthread_add_log((DldTaskThread *)taskthread, _("Current block is finished. Trying to alloc a new block ..."));
}
}
}
if(error)
{
ftp_taskthread_meet_error(taskthread, FALSE);
}
}
//TODO
// make it better ............
if(taskthread->cmdstatus == FTP_STATUS_RETR_OVER)
{
//dprintf("[ftp_recv_data] BUFFER = %s\r\n", taskthread->buffer->data);
if((replycode = ftp_recv_reply(taskthread)) != -1)
{
//if(replycode == 150) //150 open data stream ...
{
//FIXME!!!!!!
//Change the flow ....
taskthread->cmdstatus = FTP_STATUS_BINARY_OK;
taskthread->block = os_free(taskthread->block);
}
dprintf("[ftp_cmd_retr] ++++++++++++++++++++++++++++++++++++++\r\n", taskthread);
dprintf("[ftp_cmd_retr] %d DATA TRANFER OVER\r\n", taskthread);
dprintf("[ftp_cmd_retr] %d Wait to download a new part\r\n", taskthread);
}
}
}
VOID ftp_taskthread_process(DldTaskThread *dldtaskthread)
{
FtpTaskThread *taskthread = (FtpTaskThread *)dldtaskthread;
DldTask *task;
task = taskthread->parenttask;
if(!taskthread) return;
if(taskthread->status != DLD_TASKTHREAD_RUNNING) return;
// TODO
// end myself, then start a new thread.
if(taskthread->protocoltype != DLD_PROTOCOL_FTP) return;
os_tick_set_delay(taskthread->timeouttick, g_config.timeout);
os_tick_set_delay(taskthread->retrytick, g_config.retrydelay);
if(task->filesize == 0)
{
//task is first run, we need to get info from remote host...
if(taskthread == task->taskthreads->data)
{
// I am the first taskthread (only the first thread can get the info)
//WARNING: the order is IMPORTANT!!!!!!!!!!
ftp_connect(taskthread);
ftp_cmd_user(taskthread);
ftp_cmd_pass(taskthread);
ftp_cmd_binary(taskthread);
ftp_cmd_size(taskthread);
}
else
{
//clear other taskthreads' timeout tick .
os_tick_clear(taskthread->timeouttick);
}
}
else
{
if(!task->ip)
task->ip = os_socket_getip(task->host->str);
//WARNING: the order is IMPORTANT!!!!!!!!!!
ftp_connect(taskthread);
ftp_cmd_user(taskthread);
ftp_cmd_pass(taskthread);
ftp_cmd_binary(taskthread);
ftp_cmd_reset(taskthread);
ftp_cmd_pasv(taskthread);
ftp_cmd_retr(taskthread);
ftp_recv_data(taskthread);
//TODO
//ftp_close(taskthread); don't close it here , or no file will return ...
}
if(os_tick_check(taskthread->timeouttick) && os_tick_timeout(taskthread->retrytick))
{
ftp_taskthread_meet_error(taskthread, FALSE);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -