| /************************************************************* |
| Description: |
| $file_description$ |
| Author: |
| LiuBin |
| Date: |
| 2020/10/28 11:49:08 |
| *************************************************************/ |
| #include <ctype.h> |
| |
| #include "mbtk_ftp.h" |
| #include "mbtk_list.h" |
| #include "mbtk_sock.h" |
| #include "mbtk_str.h" |
| #include "mbtk_sock2.h" |
| #include <linux/msg.h> |
| |
| /************************************************************* |
| Constants and Macros |
| *************************************************************/ |
| #define FTP_HANDLE_MAX 5 |
| #define FTP_ANONYMOUS_USER "Anonymous" |
| #define FTP_ANONYMOUS_PASS "@" |
| |
| //#define FTP_RESUME_DEBUG |
| |
| #ifdef MBTK_PLATFORM_QCOMM |
| #define FTP_TIMEOUT 60000 // 60s |
| #else |
| #define FTP_TIMEOUT 3000 // 3s |
| #endif |
| |
| /************************************************************* |
| typedef struct:local at |
| *************************************************************/ |
| typedef struct |
| { |
| char host[64]; |
| uint16 port; |
| mbtk_ftp_auth_type_enum auth_type; |
| bool ftp_type; |
| bool use_cert; |
| char name[FTP_SERVER_USER_NAME_MAX+1]; |
| char pass[FTP_SERVER_USER_PASS_MAX+1]; |
| mbtk_ftp_handle at_ftp_handle; |
| char remote_path[MBTK_FTP_FILE_NAME_MAX+1]; |
| char local_path[MBTK_FTP_FILE_NAME_MAX+1]; |
| int rest_size; |
| int read_size; |
| int put_len; |
| } mbtk_at_init_parameter; |
| |
| mbtk_at_init_parameter mbtk_at_ftp_par={0}; |
| |
| /************************************************************* |
| Variables:local |
| *************************************************************/ |
| static list_node_t *ftp_client_list = NULL; |
| |
| /************************************************************* |
| Variables:public |
| *************************************************************/ |
| |
| /************************************************************* |
| Local Function Declaration |
| *************************************************************/ |
| |
| /************************************************************* |
| Local Function Definitions |
| *************************************************************/ |
| static bool ftp_ch_is_space(char ch) |
| { |
| if (ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t') |
| return true; |
| |
| return false; |
| } |
| |
| static const char* ftp_str_next(const char* str, char *result, uint32 len) |
| { |
| memset(result, 0x0, len); |
| const char* ptr = str; |
| const char* ptr_result; |
| while (*ptr && ftp_ch_is_space(*ptr)) |
| { |
| ptr++; |
| } |
| if (*ptr == '\0') |
| { |
| return NULL; |
| } |
| // Point to first no space char. |
| ptr_result = ptr; |
| while (*ptr && !ftp_ch_is_space(*ptr)) |
| { |
| ptr++; |
| } |
| |
| // Point to first space char or '\0'. |
| memcpy(result, ptr_result, ptr - ptr_result); |
| |
| if (*ptr == '\0') |
| { |
| return NULL; |
| } |
| |
| return ptr; |
| } |
| |
| static int ftp_cmd_handle(mbtk_ftp_info_s *info, void *cmd, void *rsp, |
| uint32 *rsp_len) |
| { |
| int err; |
| int rsp_code; |
| unsigned int len = strlen((char*) cmd); |
| // Write cmd |
| if(info->auth_type != 0) |
| { |
| mbtk_sock_write(info->ftp_ssl_handle,info->session,cmd,len,60000,&err); |
| if(err!=0) |
| { |
| printf("\nmbtk_sock_write error:%d\n",err); |
| return err; |
| } |
| } |
| else |
| { |
| if (sock_write(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], cmd, len, 60000, &err) |
| != len) |
| { |
| LOGE("Socket write fail[err = %d].", err); |
| return -1; |
| } |
| } |
| |
| // Read cmd response |
| if (rsp != NULL && *rsp_len > 0) |
| { |
| read_angin_1: |
| memset(rsp, 0x0, *rsp_len); |
| if(info->auth_type != 0) |
| { |
| unsigned char mbtk_ftp_ssl_read_buf[16384 + 1]; |
| len = mbtk_sock_read(info->ftp_ssl_handle,info->session,mbtk_ftp_ssl_read_buf,sizeof(mbtk_ftp_ssl_read_buf),FTP_TIMEOUT,&err); |
| if(err != 0) |
| { |
| printf("\n mbtk_sock_read error:%d \n",err); |
| } |
| rsp_code = atoi((char*)mbtk_ftp_ssl_read_buf); |
| printf("%s -> Code:%d; RSP:%s\n", (char*)cmd, rsp_code, (char* )mbtk_ftp_ssl_read_buf); |
| if (rsp_code == 0) |
| { |
| goto read_angin_1; |
| } |
| memcpy((char* )rsp, mbtk_ftp_ssl_read_buf, strlen((char*)mbtk_ftp_ssl_read_buf)); |
| //printf("\nrsp = %s\n",(char* )rsp); |
| return rsp_code; |
| } |
| else |
| { |
| len = sock_readline(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], rsp, *rsp_len, FTP_TIMEOUT,&err); |
| } |
| if (len <= 0) |
| { |
| LOGE("Socket read fail[len = %d].", len); |
| return -1; |
| } |
| rsp_code = atoi(rsp); |
| LOGI("%s -> Code:%d; RSP:%s", (char*)cmd, rsp_code, (char* )rsp); |
| //log_hex("FTP_RSP",(char* )rsp,len); |
| |
| if (rsp_code == 0) |
| { |
| goto read_angin_1; |
| } |
| |
| *rsp_len = len; |
| } |
| else |
| { |
| char buff[1024]; |
| |
| read_angin_2: |
| memset(buff, 0x0, 1024); |
| if(info->auth_type != 0) |
| { |
| char mbtk_ftp_ssl_read_buf[16384 + 1]; |
| len = mbtk_sock_read(info->ftp_ssl_handle,info->session,mbtk_ftp_ssl_read_buf,sizeof(mbtk_ftp_ssl_read_buf),FTP_TIMEOUT,&err); |
| if(err != 0) |
| { |
| printf("\nmbtk_sock_read error:%d\n",err); |
| } |
| rsp_code = atoi(mbtk_ftp_ssl_read_buf); |
| printf("%s -> Code:%d; RSP:%s\n", (char*)cmd, rsp_code, (char* )mbtk_ftp_ssl_read_buf); |
| char *mbtk_ftp_ssl_read_buf_p = strstr(mbtk_ftp_ssl_read_buf,"\n"); |
| if(mbtk_ftp_ssl_read_buf_p!=NULL) |
| { |
| if(strlen(mbtk_ftp_ssl_read_buf_p)>1) |
| { |
| mbtk_ftp_ssl_read_buf_p++; |
| rsp_code = atoi(mbtk_ftp_ssl_read_buf_p); |
| } |
| } |
| if (rsp_code == 0) |
| { |
| goto read_angin_2; |
| } |
| return rsp_code; |
| } |
| else |
| { |
| len = sock_readline(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], buff, 1024, FTP_TIMEOUT, |
| &err); |
| } |
| if (len <= 0) |
| { |
| LOGE("Socket read fail[len = %d].", len); |
| return -1; |
| } |
| |
| rsp_code = atoi(buff); |
| LOGI("%s -> Code:%d; RSP:%s", (char*)cmd, rsp_code, buff); |
| //log_hex("FTP_RSP",buff,len); |
| |
| if (rsp_code == 0) |
| { |
| goto read_angin_2; |
| } |
| } |
| |
| return rsp_code; |
| } |
| |
| // Create data socket service and waitting client connect. |
| static mbtk_ftp_error_enum ftp_data_sock_service_create(mbtk_ftp_sock_s *sock) |
| { |
| return FTP_ERR_SUCCESS; |
| } |
| |
| static bool ftp_internal_ipv4_check(void *ipv4) |
| { |
| char *ip = (char*) ipv4; |
| int ip1 = atoi(ip); |
| ip = strstr(ip, "."); |
| if (!ip) |
| return FALSE; |
| int ip2 = atoi(ip + 1); |
| |
| if (ip1 == 10) // 10.x.x.x |
| { |
| return TRUE; |
| } |
| else if (ip1 == 172 && (ip2 >= 16 && ip2 <= 31)) // 172.16.0.0 ~ 172.31.255.255 |
| { |
| return TRUE; |
| } |
| else if (ip1 == 192 && ip2 == 168) // 192.168.x.x |
| { |
| return TRUE; |
| } |
| else |
| { |
| return FALSE; |
| } |
| } |
| |
| static mbtk_ftp_error_enum ftp_sock_set_by_port(mbtk_ftp_info_s *info, |
| mbtk_ftp_sock_s *sock) |
| { |
| // port = port1 * 256 + port2 |
| // "PORT ip1,ip2,ip3,ip4,port1,port2\r\n" |
| int code; |
| char cmd_buff[100]; |
| memset(cmd_buff, 0x0, 100); |
| if (info->sock_info[FTP_SOCK_CTRL].addr_family == MBTK_ADDR_IPV6 || sock->port <= 1024 |
| || strlen((char*) sock->host) == 0) |
| { |
| LOGE("FTP params set error."); |
| return FTP_ERR_PARAM_SET; |
| } |
| |
| if (ftp_data_sock_service_create(sock) != FTP_ERR_SUCCESS) |
| { |
| LOGE("FTP data services create fail."); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| uint8 *ptr = sock->host; |
| while (*ptr) |
| { |
| if (*ptr == '.') |
| *ptr = ','; |
| ptr++; |
| } |
| // Waitting client connect. |
| snprintf(cmd_buff, 100, "PORT %s,%d,%d\r\n", sock->host, sock->port / 256, |
| sock->port % 256); |
| code = ftp_cmd_handle(info, cmd_buff, NULL, NULL); |
| if (code / 100 != 2) // Not 2xx |
| { |
| LOGE("PORT rsp error[code = %d].", code); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| return FTP_ERR_SUCCESS; |
| } |
| |
| static mbtk_ftp_error_enum ftp_sock_set_by_eprt(mbtk_ftp_info_s *info, |
| mbtk_ftp_sock_s *sock) |
| { |
| int code; |
| char cmd_buff[100]; |
| memset(cmd_buff, 0x0, 100); |
| if (sock->port <= 1024 || strlen((char*) sock->host) == 0) |
| { |
| LOGE("FTP params set error."); |
| return FTP_ERR_PARAM_SET; |
| } |
| if (ftp_data_sock_service_create(sock) != FTP_ERR_SUCCESS) |
| { |
| LOGE("FTP data services create fail."); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| // "EPRT |2|1080::8:800:200C:417A|5282|" |
| if (info->sock_info[FTP_SOCK_CTRL].addr_family == MBTK_ADDR_IPV6) |
| { |
| uint8 *ptr = NULL; |
| if (sock->host[strlen((char*) sock->host) - 1] == ']') |
| sock->host[strlen((char*) sock->host) - 1] = '\0'; |
| |
| if (sock->host[0] == '[') |
| ptr = sock->host + 1; |
| else |
| ptr = sock->host; |
| snprintf(cmd_buff, 100, "EPRT |2|%s|%d|\r\n", ptr, sock->port); |
| } |
| else // IPV4 "EPRT |1|132.235.1.2|6275|" |
| { |
| snprintf(cmd_buff, 100, "EPRT |1|%s|%d|\r\n", sock->host, sock->port); |
| } |
| |
| code = ftp_cmd_handle(info, cmd_buff, NULL, NULL); |
| if (code / 100 != 2) // Not 2xx |
| { |
| LOGE("PORT rsp error[code = %d].", code); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| return FTP_ERR_SUCCESS; |
| } |
| |
| static mbtk_ftp_error_enum ftp_sock_get_by_pasv(mbtk_ftp_info_s *info, |
| mbtk_ftp_sock_s *sock) |
| { |
| int code; |
| uint8 rsp[1024]; |
| uint32 rsp_len = 1024; |
| memset(sock, 0x0, sizeof(mbtk_ftp_sock_s)); |
| code = ftp_cmd_handle(info, "PASV\r\n", rsp, &rsp_len); |
| /* Found reply-strings include: |
| * "227 Entering Passive Mode (127,0,0,1,4,51)" |
| * "227 Data transfer will passively listen to 127,0,0,1,4,51" |
| * "227 Entering passive mode. 127,0,0,1,4,51" |
| */ |
| if (code != 227) |
| { |
| LOGE("PASV rsp error[code = %d].", code); |
| if(code == 421) |
| { |
| printf("\n code:%d\n",code); |
| return FTP_ERR_UNKNOWN+1; |
| } |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| // Get IPv4 and port |
| char *ptr = (char*)rsp + 4; |
| while (*ptr) |
| { |
| if (isdigit(*ptr)) |
| break; |
| ptr++; |
| } |
| // ptr point to first digit. |
| memcpy(sock->host, ptr, strlen((char*) ptr)); |
| ptr = (char*)(sock->host); |
| int count = 0; |
| while (*ptr) |
| { |
| if (*ptr == ',') |
| { |
| *ptr = '.'; |
| count++; |
| } |
| if (count == 4) |
| { |
| *ptr = '\0'; |
| break; |
| } |
| ptr++; |
| } |
| ptr++; |
| |
| // ptr point to first port digit. |
| int port1 = atoi((char*) ptr); |
| while (*ptr) |
| { |
| if (*ptr == ',') |
| break; |
| ptr++; |
| } |
| ptr++; |
| |
| // ptr point to second port digit. |
| int port2 = atoi((char*) ptr); |
| sock->port = port1 * 256 + port2; |
| |
| LOGI("PASV: %s:%d", sock->host, sock->port); |
| |
| if(ftp_internal_ipv4_check(sock->host)) |
| { |
| memset(sock->host,0x0,MBTK_FTP_IP_MAX + 1); |
| memcpy(sock->host,info->sock_info[FTP_SOCK_CTRL].host,strlen(info->sock_info[FTP_SOCK_CTRL].host)); |
| LOGI("This is internal ipv4,so use IP - %s:%d",sock->host, sock->port); |
| } |
| |
| return FTP_ERR_SUCCESS; |
| } |
| |
| static mbtk_ftp_error_enum ftp_sock_get_by_epsv(mbtk_ftp_info_s *info, |
| mbtk_ftp_sock_s *sock) |
| { |
| int code; |
| char rsp[1024]; |
| uint32 rsp_len = 1024; |
| memset(sock, 0x0, sizeof(mbtk_ftp_sock_s)); |
| // |||6446| |
| code = ftp_cmd_handle(info, "EPSV\r\n", rsp, &rsp_len); |
| if (code != 229) |
| { |
| LOGE("EPSV rsp error[code = %d].", code); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| /* positive EPSV response */ |
| char *ptr = strchr(rsp, '('); |
| if (ptr) |
| { |
| unsigned int num; |
| char separator[4]; |
| ptr++; |
| if (5 |
| == sscanf(ptr, "%c%c%c%u%c", &separator[0], &separator[1], |
| &separator[2], &num, &separator[3])) |
| { |
| const char sep1 = separator[0]; |
| int i; |
| |
| /* The four separators should be identical, or else this is an oddly |
| formatted reply and we bail out immediately. */ |
| for (i = 1; i < 4; i++) |
| { |
| if (separator[i] != sep1) |
| { |
| ptr = NULL; /* set to NULL to signal error */ |
| break; |
| } |
| } |
| if (num > 0xffff) |
| { |
| LOGE("Illegal port number in EPSV reply"); |
| return FTP_ERR_UNKNOWN; |
| } |
| if (ptr) |
| { |
| sock->port = (uint32) (num & 0xffff); |
| memcpy(sock->host, info->sock_info[FTP_SOCK_CTRL].host, |
| strlen(info->sock_info[FTP_SOCK_CTRL].host)); |
| } |
| } |
| else |
| { |
| ptr = NULL; |
| } |
| } |
| if (!ptr) |
| { |
| LOGE("Weirdly formatted EPSV reply"); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| LOGI("PASV: %s:%d", sock->host, sock->port); |
| |
| return FTP_ERR_SUCCESS; |
| } |
| |
| /* |
| * 04-26-20 02:13PM 379193 audio_0426.zip |
| * 09-10-20 02:31PM 4660645 Log.zip |
| * 10-28-20 01:53PM <DIR> PicLibs |
| */ |
| |
| /* |
| *-rw-r--r-- 1 ftp ftp 2097152000 Feb 18 17:28 ASR1803_Linux.tar.gz_aa |
| *-rw-r--r-- 1 ftp ftp 2097152000 Feb 18 17:21 ASR1803_Linux.tar.gz_ab |
| *-rw-r--r-- 1 ftp ftp 1198057917 Feb 18 17:29 ASR1803_Linux.tar.gz_ac |
| *-rw-r--r-- 1 ftp ftp 445043 Apr 06 2021 data |
| *drwxr-xr-x 1 ftp ftp 0 Apr 10 2021 L306 |
| */ |
| static mbtk_ftp_error_enum ftp_cmd_list_parse(mbtk_ftp_info_s *info, |
| mbtk_ftp_file_info_s *file_list) |
| { |
| char line[1024]; |
| char line_buf[1024]; |
| int len, err; |
| mbtk_ftp_file_info_s file_ptr; |
| memset(file_list, 0x0, sizeof(mbtk_ftp_file_info_s)-sizeof(void *)); |
| |
| // Save file number. |
| file_list->size = 0; |
| len = 1; |
| int read_line_count=0; |
| while (len > 0) |
| { |
| if(info->auth_type!=0) |
| { |
| len = mbtk_sock_readline(info->ftp_ssl_handle,info->session_data,line_buf,1024,FTP_TIMEOUT,&err,&read_line_count,line); |
| } |
| else |
| { |
| len = sock_readline(&info->net_info, &info->sock_info[FTP_SOCK_DATA], line, 1024,FTP_TIMEOUT, &err); |
| } |
| LOGD("Line:%s", line); |
| if(len <= 0) |
| { |
| if (err == MBTK_SOCK_SUCCESS) |
| return FTP_ERR_SUCCESS; |
| break; |
| } |
| else |
| len = strlen(line) - 1; |
| if (line[0] >= '0' && line[0] <= '9') |
| { |
| /* |
| * 04-26-20 02:13PM 379193 audio_0426.zip |
| * 09-10-20 02:31PM 4660645 Log.zip |
| * 10-28-20 01:53PM <DIR> PicLibs |
| */ |
| line[len] = '\0'; |
| /* |
| file_ptr = (mbtk_ftp_file_info_s*) malloc( |
| sizeof(mbtk_ftp_file_info_s)); |
| if (!file_ptr) |
| { |
| LOGE("malloc() fail."); |
| return FTP_ERR_UNKNOWN; |
| } |
| */ |
| memset(&file_ptr, 0x0, sizeof(mbtk_ftp_file_info_s)); |
| |
| char str[MBTK_FTP_FILE_NAME_MAX]; |
| const char *temp = line; |
| // Data |
| temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX); |
| if (strlen(str) > 0) |
| { |
| LOGV("Data:%s", str); |
| } |
| |
| // Time |
| temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX); |
| if (strlen(str) > 0) |
| { |
| LOGV("Time:%s", str); |
| } |
| |
| // <DIR> or file size |
| temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX); |
| if (strlen(str) > 0) |
| { |
| LOGV("<DIR>/size:%s", str); |
| if (!strcmp("<DIR>", str)) |
| { |
| file_ptr.is_file = false; |
| file_ptr.size = 0; |
| } |
| else |
| { |
| file_ptr.is_file = true; |
| file_ptr.size = atoi(str); |
| } |
| } |
| |
| const char *name = temp; |
| while (*name && ftp_ch_is_space(*name)) |
| { |
| name++; |
| } |
| |
| // Name |
| if (strlen(name) > 0) |
| { |
| LOGV("Name:%s",name); |
| memset(file_ptr.name,0,strlen((char*)(file_ptr.name))+1); |
| memcpy(file_ptr.name, name, strlen(name)); |
| char *temp = (char*) file_ptr.name |
| + strlen((char*) file_ptr.name) - 1; |
| while (ftp_ch_is_space(*temp)) |
| { |
| *temp = '\0'; |
| temp--; |
| } |
| } |
| else |
| { |
| LOGE("Can not get name[%s].", line); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| (file_list->ftp_ls_cb_typedef)(&file_ptr); |
| //file_ptr->next = file_list->next; |
| //file_list->next = file_ptr; |
| //file_list->size++; |
| //free(file_ptr); |
| } else if(!ftp_ch_is_space(line[0])) { |
| /* |
| *-rw-r--r-- 1 ftp ftp 2097152000 Feb 18 17:28 ASR1803_Linux.tar.gz_aa |
| *-rw-r--r-- 1 ftp ftp 2097152000 Feb 18 17:21 ASR1803_Linux.tar.gz_ab |
| *-rw-r--r-- 1 ftp ftp 1198057917 Feb 18 17:29 ASR1803_Linux.tar.gz_ac |
| *-rw-r--r-- 1 ftp ftp 445043 Apr 06 2021 data |
| *drwxr-xr-x 1 ftp ftp 0 Apr 10 2021 L306 |
| */ |
| line[len] = '\0'; |
| /* |
| file_ptr = (mbtk_ftp_file_info_s*) malloc( |
| sizeof(mbtk_ftp_file_info_s)); |
| if (!file_ptr) |
| { |
| LOGE("malloc() fail."); |
| return FTP_ERR_UNKNOWN; |
| } |
| */ |
| memset(&file_ptr, 0x0, sizeof(mbtk_ftp_file_info_s)); |
| |
| char str[MBTK_FTP_FILE_NAME_MAX]; |
| const char *temp = line; |
| // rwx |
| temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX); |
| if (strlen(str) > 0) |
| { |
| LOGV("rwx:%s", str); |
| file_ptr.is_file = (str[0] == '-' ? true : false); |
| } |
| |
| // 1 ftp ftp |
| temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX); |
| temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX); |
| temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX); |
| |
| // size |
| temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX); |
| if (strlen(str) > 0) |
| { |
| LOGV("Size:%s", str); |
| file_ptr.size = atoi(str); |
| } |
| |
| // Feb 18 17:28 |
| // or |
| // Apr 10 2021 |
| temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX); |
| temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX); |
| temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX); |
| |
| const char *name = temp; |
| while (*name && ftp_ch_is_space(*name)) |
| { |
| name++; |
| } |
| |
| // Name |
| if (strlen(name) > 0) |
| { |
| LOGV("Name:%s",name); |
| memset(file_ptr.name,0,strlen((char*)file_ptr.name)+1); |
| memcpy(file_ptr.name, name, strlen(name)); |
| char *temp = (char*) file_ptr.name |
| + strlen((char*) file_ptr.name) - 1; |
| while (ftp_ch_is_space(*temp)) |
| { |
| *temp = '\0'; |
| temp--; |
| } |
| } |
| else |
| { |
| LOGE("Can not get name[%s].", line); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| (file_list->ftp_ls_cb_typedef)(&file_ptr); |
| //file_ptr->next = file_list->next; |
| //file_list->next = file_ptr; |
| //file_list->size++; |
| //free(file_ptr); |
| }else { |
| LOGE("Data error."); |
| return FTP_ERR_UNKNOWN; |
| } |
| } |
| return FTP_ERR_SUCCESS; |
| } |
| |
| static mbtk_ftp_error_enum ftp_download_process(mbtk_ftp_info_s *info) |
| { |
| #define READ_BUF_SIZE 2048 |
| char buff[READ_BUF_SIZE]; |
| int len, err, len_read; |
| int read_count = info->file_trans.size_send; |
| |
| #ifdef FTP_RESUME_DEBUG |
| int count = 0; |
| #endif |
| |
| if (info->file_trans.size_count - read_count > READ_BUF_SIZE) |
| len_read = READ_BUF_SIZE; |
| else |
| len_read = info->file_trans.size_count - read_count; |
| |
| if(info->auth_type != 0) |
| len = mbtk_sock_read(info->ftp_ssl_handle,info->session_data,buff,len_read,FTP_TIMEOUT,&err); |
| else |
| len = sock_read(&info->net_info, &info->sock_info[FTP_SOCK_DATA], buff, len_read,FTP_TIMEOUT, &err); |
| /* |
| while (len_read > 0 && (len = sock_read(&info->net_info, &info->sock_info[FTP_SOCK_DATA], buff, len_read, |
| FTP_TIMEOUT, &err)) > 0) |
| */ |
| while (len_read > 0 && len > 0) |
| { |
| read_count += len; |
| |
| #ifdef FTP_RESUME_DEBUG |
| count++; |
| if (count <= 1000) |
| { |
| #endif |
| if (info->file_trans.data_cb) |
| { |
| info->file_trans.data_cb(buff, len); |
| } |
| else // Write to efs. |
| { |
| if (len != file_write(info->file_trans.fd, buff, len)) |
| { |
| LOGE("EFS write fail."); |
| return FTP_ERR_EFS_FILE; |
| } |
| } |
| memset(buff,0,sizeof(buff)); |
| info->file_trans.size_send = read_count; |
| #ifdef FTP_RESUME_DEBUG |
| } |
| #endif |
| |
| if (info->file_trans.size_count - read_count > READ_BUF_SIZE) |
| len_read = READ_BUF_SIZE; |
| else |
| len_read = info->file_trans.size_count - read_count; |
| |
| if(info->auth_type != 0) |
| len = mbtk_sock_read(info->ftp_ssl_handle,info->session_data,buff,len_read,FTP_TIMEOUT,&err); |
| else |
| len = sock_read(&info->net_info, &info->sock_info[FTP_SOCK_DATA], buff, len_read,FTP_TIMEOUT, &err); |
| } |
| |
| return FTP_ERR_SUCCESS; |
| } |
| |
| static mbtk_ftp_error_enum ftp_update_process(mbtk_ftp_info_s *info) |
| { |
| #define READ_BUF_SIZE 2048 |
| char buff[READ_BUF_SIZE]; |
| int len, err, len_write; |
| int file_total_size = 0; |
| int write_count = 0; |
| |
| if(info->file_trans.fd > 0) |
| { |
| file_total_size = file_length(info->file_trans.fd); |
| info->file_trans.size_count = file_total_size; |
| while((len_write = file_read(info->file_trans.fd, buff, READ_BUF_SIZE)) > 0 ) |
| { |
| LOGE("file_read.len:%d, buf;%s", len_write, buff); |
| if(info->auth_type != 0) |
| len = mbtk_sock_write(info->ftp_ssl_handle,info->session_data,buff,len_write,FTP_TIMEOUT,&err); |
| else |
| len = sock_write(&info->net_info, &info->sock_info[FTP_SOCK_DATA], buff, len_write, |
| FTP_TIMEOUT, &err); |
| if(len < 0) |
| { |
| LOGE("EFS write fail.len:%d, err;%d", len, err); |
| return FTP_ERR_EFS_FILE; |
| } |
| |
| write_count += len; |
| } |
| |
| info->file_trans.size_send = write_count; |
| if( write_count != file_total_size) |
| { |
| LOGE("socket write fail.,file_total_size:%d, write_count:%d", file_total_size,write_count); |
| return FTP_ERR_NET_WRITE; |
| } |
| else{ |
| LOGE("socket write success.,file_total_size:%d, write_count:%d", file_total_size, write_count); |
| } |
| |
| } |
| else |
| { |
| LOGE("EFS write fail."); |
| return FTP_ERR_EFS_FILE; |
| } |
| |
| return FTP_ERR_SUCCESS; |
| } |
| |
| |
| /* |
| * audio_0426.zip |
| * Log.zip |
| * PicLibs |
| */ |
| static mbtk_ftp_error_enum ftp_cmd_nlst_parse(mbtk_ftp_info_s *info, |
| mbtk_ftp_file_info_s *file_list) |
| { |
| char line[1024]; |
| int len, err; |
| mbtk_ftp_file_info_s *file_ptr = NULL; |
| while ((len = sock_readline(&info->net_info, &info->sock_info[FTP_SOCK_DATA], line, 1024, |
| FTP_TIMEOUT, &err)) > 0) |
| { |
| if (!ftp_ch_is_space(line[0])) |
| { |
| file_ptr = (mbtk_ftp_file_info_s*) malloc( |
| sizeof(mbtk_ftp_file_info_s)); |
| if (!file_ptr) |
| { |
| LOGE("malloc() fail."); |
| return FTP_ERR_UNKNOWN; |
| } |
| memset(file_ptr, 0x0, sizeof(mbtk_ftp_file_info_s)); |
| memcpy(file_ptr->name, line, strlen(line)); |
| char *temp = (char*) file_ptr->name + strlen((char*) file_ptr->name) |
| - 1; |
| while (ftp_ch_is_space(*temp)) |
| { |
| *temp = '\0'; |
| temp--; |
| } |
| |
| file_ptr->next = file_list->next; |
| file_list->next = file_ptr; |
| } |
| } |
| return FTP_ERR_SUCCESS; |
| } |
| |
| static mbtk_ftp_error_enum ftp_data_sock_read(mbtk_ftp_info_s *info, |
| mbtk_ftp_cmd_enum cmd, void *req, void *rsp) |
| { |
| int err, len, code; |
| mbtk_ftp_error_enum result = FTP_ERR_SUCCESS; |
| char buff[1024]; |
| if (info->is_data_sock_busy) |
| { |
| LOGW("Data socket is busy!"); |
| return FTP_ERR_DATA_SOCK_BUSY; |
| } |
| |
| info->is_data_sock_busy = true; |
| // Connect to service by data socket. |
| if (info->data_mode == FTP_MODE_PASSIVE) |
| { |
| mbtk_ftp_sock_s sock; |
| if(info->auth_type != FTP_AUTH_TYPE_NON) { |
| // PROT P |
| char cmd_ssl[50]; |
| memset(cmd_ssl,0,50); |
| snprintf(cmd_ssl, 50, "PROT P\r\n"); |
| code = ftp_cmd_handle(info, cmd_ssl, NULL,NULL); |
| if (code/100 != 2) |
| { |
| LOGE("PROT P error[code = %d].", code); |
| goto end; |
| } |
| } |
| |
| if (info->sock_info[FTP_SOCK_CTRL].addr_family == MBTK_ADDR_IPV6) |
| { |
| if ((result = ftp_sock_get_by_epsv(info, &sock)) |
| != FTP_ERR_SUCCESS) |
| { |
| goto end; |
| } |
| } |
| else |
| { |
| if ((result = ftp_sock_get_by_pasv(info, &sock)) |
| != FTP_ERR_SUCCESS) |
| { |
| printf("\nftp_sock_get_by_pasv end.result=%d\n",result); |
| } |
| else |
| { |
| printf("\nftp_sock_get_by_pasv ok!\n"); |
| } |
| } |
| |
| if(info->auth_type != FTP_AUTH_TYPE_NON) |
| { |
| info->ftp_ssl_handle_data = mbtk_sock_init(&info->ftp_ssl_info_data); |
| if(info->ftp_ssl_handle_data == -1) |
| { |
| printf("mbtk_sock_init error\n"); |
| } |
| info->ftp_sock_ssl_info_data = (mbtk_sock_info*) malloc(sizeof(mbtk_sock_info)); |
| memset(info->ftp_sock_ssl_info_data, 0x0, sizeof(mbtk_sock_info)); |
| info->ftp_sock_ssl_info_data->is_support_ssl = info->auth_type; |
| info->ftp_sock_ssl_info_data->ftp_ssl_support=1; |
| info->ftp_sock_ssl_info_data->port = sock.port; |
| info->ftp_sock_ssl_info_data->type = MBTK_SOCK_TCP; |
| info->ftp_sock_ssl_info_data->ingnore_cert = !(info->sock_info[FTP_SOCK_CTRL].use_cert); |
| memcpy(info->ftp_sock_ssl_info_data->address, sock.host, strlen((char*)sock.host)); |
| if(info->ftp_sock_ssl_info_data->is_support_ssl != 0) |
| { |
| info->ftp_sock_ssl_info_data->is_support_ssl = 0; |
| } |
| info->session_data = mbtk_sock_open(info->ftp_ssl_handle,info->ftp_sock_ssl_info_data,60000,&err); |
| if(err!=0) |
| { |
| printf("mbtk_sock_open error : %d\n",err); |
| } |
| else |
| { |
| info->ftp_sock_ssl_info_data->is_support_ssl = info->auth_type; |
| //printf("\ninfo->session_data = %d \n",info->session_data); |
| } |
| } |
| else |
| { |
| memcpy(info->sock_info[FTP_SOCK_DATA].host, sock.host, strlen((char*)sock.host)); |
| info->sock_info[FTP_SOCK_DATA].port = sock.port; |
| info->sock_info[FTP_SOCK_DATA].is_ssl = (info->auth_type != FTP_AUTH_TYPE_NON); |
| info->sock_info[FTP_SOCK_DATA].addr_family = info->sock_info[FTP_SOCK_CTRL].addr_family; |
| info->sock_info[FTP_SOCK_DATA].use_cert = info->sock_info[FTP_SOCK_CTRL].use_cert; |
| info->net_info.keep_alive = FALSE; |
| info->net_info.recv_buff_size = 32 * 1024; // 32K |
| info->sock_info[FTP_SOCK_DATA].fd = sock_open(&info->net_info, &info->sock_info[FTP_SOCK_DATA], |
| FTP_TIMEOUT, &err); |
| } |
| |
| } |
| else // Active mode |
| { |
| if (req == NULL) |
| { |
| result = FTP_ERR_PARAM_SET; |
| goto end; |
| } |
| mbtk_ftp_sock_s *sock = (mbtk_ftp_sock_s*) req; |
| |
| if (info->sock_info[FTP_SOCK_CTRL].addr_family == MBTK_ADDR_IPV6) |
| { |
| if ((result = ftp_sock_set_by_eprt(info, sock)) |
| != FTP_ERR_SUCCESS) |
| { |
| goto end; |
| } |
| } |
| else |
| { |
| if ((result = ftp_sock_set_by_port(info, sock)) |
| != FTP_ERR_SUCCESS) |
| { |
| goto end; |
| } |
| } |
| |
| // Wait for client[service] connect. |
| |
| } |
| if(info->auth_type != FTP_AUTH_TYPE_NON) |
| { |
| if(info->session_data < 0) |
| { |
| //printf("Socket open/connect ssl fail[err = %d].", err); |
| result = FTP_ERR_NET_CONN; |
| goto read_end; |
| } |
| } |
| else |
| { |
| if (info->sock_info[FTP_SOCK_DATA].fd < 0) |
| { |
| LOGE("Socket open/connect fail[err = %d].", err); |
| result = FTP_ERR_NET_CONN; |
| goto read_end; |
| } |
| |
| if(info->auth_type == FTP_AUTH_TYPE_IMPLICIT) { |
| info->sock_info[FTP_SOCK_DATA].is_ssl = true; |
| } |
| } |
| |
| if (cmd == FTP_CMD_GET) // Is download |
| { |
| char cmd[200]; |
| if (info->file_trans.size_send > 0) // Resume transmission |
| { |
| // REST size |
| memset(cmd, 0x0, sizeof(cmd)); |
| snprintf(cmd, sizeof(cmd), "REST %d\r\n", info->file_trans.size_send); |
| code = ftp_cmd_handle(info, cmd, NULL, NULL); |
| if (code != 350) |
| { |
| LOGE("REST rsp error[code = %d].", code); |
| result = FTP_ERR_UNKNOWN; |
| goto end; |
| } |
| } |
| |
| memset(cmd, 0x0, sizeof(cmd)); |
| snprintf(cmd, sizeof(cmd), "RETR %s\r\n", info->file_trans.remote_name); |
| code = ftp_cmd_handle(info, cmd, NULL, NULL); |
| if (code != 125 && code != 150) |
| { |
| LOGE("RETR %s rsp error[code = %d].", info->file_trans.remote_name, |
| code); |
| result = FTP_ERR_UNKNOWN; |
| goto end; |
| } |
| |
| int mbtk_errno; |
| if(info->auth_type != 0) |
| { |
| mbtk_errno = mbtk_ssl_init_func(info->ftp_ssl_handle,info->ftp_sock_ssl_info_data->ingnore_cert,info->session_data); |
| if(mbtk_errno != 0) |
| { |
| printf("\nmbtk_ssl_init_func error = %d",mbtk_errno); |
| goto end; |
| } |
| |
| } |
| result = ftp_download_process(info); |
| if(info->auth_type != 0) |
| { |
| char mbtk_ftp_ssl_read_buf[256]; |
| memset(mbtk_ftp_ssl_read_buf,0,sizeof(mbtk_ftp_ssl_read_buf)); |
| mbtk_sock_read(info->ftp_ssl_handle,info->session, |
| mbtk_ftp_ssl_read_buf, |
| sizeof(mbtk_ftp_ssl_read_buf), |
| 6000, |
| &mbtk_errno); |
| printf("\nmbtk_sock_read:\n%s\n",mbtk_ftp_ssl_read_buf); |
| } |
| if(info->auth_type != 0) |
| goto read_end; |
| } |
| else if (cmd == FTP_CMD_PUT) // Is download |
| { |
| if(info->auth_type != 0) |
| { |
| int mbtk_errno; |
| char cmd[200]; |
| memset(cmd, 0x0, sizeof(cmd)); |
| snprintf(cmd, sizeof(cmd), "STOR %s\r\n", info->file_trans.remote_name); |
| LOGE("STOR %s .name:%s ", cmd, info->file_trans.remote_name); |
| code = ftp_cmd_handle(info, cmd, NULL, NULL); |
| if (code != 125 && code != 150) |
| { |
| LOGE("RETR %s rsp error[code = %d].", info->file_trans.remote_name, |
| code); |
| //printf("RETR %s rsp error[code = %d].\n", info->file_trans.remote_name,code); |
| result = FTP_ERR_UNKNOWN; |
| goto end; |
| } |
| |
| mbtk_errno = mbtk_ssl_init_func(info->ftp_ssl_handle,info->ftp_sock_ssl_info_data->ingnore_cert,info->session_data); |
| if(mbtk_errno != 0) |
| { |
| printf("\nmbtk_ssl_init_func error = %d",mbtk_errno); |
| goto end; |
| } |
| if(info->file_trans.size_count == 0) |
| { |
| result = ftp_update_process(info); |
| goto read_end; |
| } |
| else |
| { |
| //printf("FTP_SOCK_DATA,fd:%d\n",info->file_trans.size_count); |
| return FTP_ERR_SUCCESS; |
| } |
| goto end; |
| } |
| else |
| { |
| char cmd[200]; |
| memset(cmd, 0x0, sizeof(cmd)); |
| snprintf(cmd, sizeof(cmd), "STOR %s\r\n", info->file_trans.remote_name); |
| LOGE("STOR %s .name:%s ", cmd, info->file_trans.remote_name); |
| code = ftp_cmd_handle(info, cmd, NULL, NULL); |
| if (code != 125 && code != 150) |
| { |
| LOGE("RETR %s rsp error[code = %d].", info->file_trans.remote_name, |
| code); |
| result = FTP_ERR_UNKNOWN; |
| goto end; |
| } |
| |
| if(info->file_trans.size_count == 0) |
| { |
| result = ftp_update_process(info); |
| goto read_end; |
| } |
| else |
| { |
| LOGE("FTP_SOCK_DATA,fd:%d", info->sock_info[FTP_SOCK_DATA].fd); |
| return FTP_ERR_SUCCESS; |
| } |
| } |
| } |
| else if (cmd == FTP_CMD_LIST) |
| { |
| if(info->auth_type != 0) |
| { |
| int mbtk_errno; |
| code = ftp_cmd_handle(info, "LIST\r\n", NULL, NULL); |
| if (code != 125 && code != 150) |
| { |
| LOGE("LIST rsp error[code = %d].", code); |
| result = FTP_ERR_UNKNOWN; |
| goto read_end; |
| } |
| |
| mbtk_errno = mbtk_ssl_init_func(info->ftp_ssl_handle,info->ftp_sock_ssl_info_data->ingnore_cert,info->session_data); |
| if(mbtk_errno != 0) |
| { |
| printf("\nmbtk_ssl_init_func error = %d",mbtk_errno); |
| goto read_end; |
| } |
| |
| result = ftp_cmd_list_parse(info, (mbtk_ftp_file_info_s*) rsp); |
| char mbtk_ftp_ssl_read_buf[1024]; |
| memset(mbtk_ftp_ssl_read_buf,0,sizeof(mbtk_ftp_ssl_read_buf)); |
| mbtk_sock_read(info->ftp_ssl_handle,info->session, |
| mbtk_ftp_ssl_read_buf, |
| sizeof(mbtk_ftp_ssl_read_buf), |
| 6000, |
| &mbtk_errno); |
| printf("\nmbtk_sock_read:\n%s\n",mbtk_ftp_ssl_read_buf); |
| int rsp_code = atoi(mbtk_ftp_ssl_read_buf); |
| if(rsp_code / 200) |
| result = FTP_ERR_SUCCESS; |
| goto read_end; |
| } |
| else |
| { |
| code = ftp_cmd_handle(info, "LIST\r\n", NULL, NULL); |
| if (code != 125 && code != 150) |
| { |
| LOGE("LIST rsp error[code = %d].", code); |
| result = FTP_ERR_UNKNOWN; |
| goto end; |
| } |
| |
| result = ftp_cmd_list_parse(info, (mbtk_ftp_file_info_s*) rsp); |
| } |
| } |
| else if (cmd == FTP_CMD_NLST) |
| { |
| code = ftp_cmd_handle(info, "NLST\r\n", NULL, NULL); |
| if (code != 125 && code != 150) |
| { |
| LOGE("LIST rsp error[code = %d].", code); |
| result = FTP_ERR_UNKNOWN; |
| goto end; |
| } |
| |
| result = ftp_cmd_nlst_parse(info, (mbtk_ftp_file_info_s*) rsp); |
| } |
| else |
| { |
| LOGE("No support this cmd[%d].", cmd); |
| result = FTP_ERR_UNKNOWN; |
| goto read_end; |
| } |
| |
| // Read [226 Transfer complete.] |
| read_code: |
| memset(buff, 0x0, 1024); |
| len = sock_readline(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], buff, 1024, FTP_TIMEOUT, |
| &err); |
| if (len <= 0) |
| { |
| LOGE("Socket read fail[len = %d].", len); |
| result = FTP_ERR_NET_READ; |
| goto sock_error; |
| } |
| LOGI("RSP[len-%d]:%s",len,buff); |
| //log_hex("FTP_RSP",buff,len); |
| code = atoi(buff); |
| if (code == 0) |
| { |
| goto read_code; |
| } |
| #if 1 |
| // 426 Connection closed; aborted transfer of "/files/test" |
| else if (code == 426) |
| { |
| LOGE("Connection closed,restart download..."); |
| result = FTP_ERR_UNKNOWN; |
| goto sock_error; |
| } |
| #endif |
| else if (code != 226) |
| { |
| LOGE("Code not be 226[%s].", buff); |
| result = FTP_ERR_UNKNOWN; |
| goto read_end; |
| } |
| |
| goto read_end; |
| sock_error: |
| { |
| if (info->sock_info[FTP_SOCK_CTRL].fd > 0) |
| { |
| if (sock_close(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], FTP_TIMEOUT, &err)) |
| { |
| LOGE("Close ctrl socket fail[%d].", err); |
| } |
| } |
| info->state = FTP_STATE_NON; |
| info->sock_info[FTP_SOCK_CTRL].fd = -1; |
| } |
| read_end: |
| // Close data socket. |
| if (info->sock_info[FTP_SOCK_DATA].fd > 0) |
| { |
| if (sock_close(&info->net_info, &info->sock_info[FTP_SOCK_DATA], FTP_TIMEOUT, &err)) |
| { |
| LOGE("Close data socket fail[%d].", err); |
| result = FTP_ERR_NET_CLOSE; |
| } |
| else |
| { |
| info->sock_info[FTP_SOCK_DATA].fd = -1; |
| } |
| } |
| if(info->auth_type != 0) |
| { |
| if(mbtk_sock_close(info->ftp_ssl_handle,info->session_data,6000,&err)) |
| { |
| LOGE("Close ssl data socket fail[%d].", err); |
| result = FTP_ERR_NET_CLOSE; |
| } |
| else |
| { |
| // info->sock_info[FTP_SOCK_DATA].fd = -1; |
| } |
| } |
| if (info->data_mode == FTP_MODE_PASSIVE) |
| { |
| |
| } |
| else |
| { |
| |
| } |
| |
| end: |
| // Default is passive. |
| info->data_mode = FTP_MODE_PASSIVE; |
| info->is_data_sock_busy = false; |
| |
| return result; |
| } |
| |
| static mbtk_ftp_error_enum ftp_cmd_process_pwd(mbtk_ftp_info_s *info, |
| char *path) |
| { |
| int code; |
| char rsp[100]; |
| uint32 rsp_len = 100; |
| code = ftp_cmd_handle(info, "PWD\r\n", rsp, &rsp_len); |
| if (code != 257) |
| { |
| LOGE("PWD rsp error[code = %d].", code); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| // "path" is current .... |
| char *ptr = strchr(rsp, '"'); |
| if (!ptr) |
| { |
| LOGE("PWD rsp error[%d].", code); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| ptr++; |
| char *ptr_temp = ptr; |
| while (*ptr_temp) |
| { |
| if (*ptr_temp == '"') |
| { |
| *ptr_temp = '\0'; |
| break; |
| } |
| ptr_temp++; |
| } |
| memcpy(path, ptr, strlen(ptr)); |
| path[strlen(ptr)] = '\0'; |
| |
| return FTP_ERR_SUCCESS; |
| } |
| |
| static mbtk_ftp_error_enum ftp_cmd_process_cwd(mbtk_ftp_info_s *info, |
| const char *path) |
| { |
| int code; |
| char cmd[100] = { 0 }; |
| snprintf(cmd, 100, "CWD %s\r\n", path); |
| code = ftp_cmd_handle(info, cmd, NULL, NULL); |
| if (code != 250) |
| { |
| LOGE("CWD rsp error[code = %d].", code); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| return FTP_ERR_SUCCESS; |
| } |
| |
| static mbtk_ftp_error_enum ftp_cmd_process_mkd(mbtk_ftp_info_s *info, |
| const char *path) |
| { |
| int code; |
| char cmd[100] = { 0 }; |
| snprintf(cmd, 100, "MKD %s\r\n", path); |
| code = ftp_cmd_handle(info, cmd, NULL, NULL); |
| if (code == 257) |
| { |
| return FTP_ERR_SUCCESS; |
| } |
| else if (code == 550) |
| { |
| LOGE("Dir has exist[%s].", path); |
| return FTP_ERR_FILE_EXIST; |
| } |
| else |
| { |
| LOGE("MKD rsp error[code = %d].", code); |
| return FTP_ERR_UNKNOWN; |
| } |
| } |
| |
| static mbtk_ftp_error_enum ftp_cmd_process_rmd(mbtk_ftp_info_s *info, |
| const char *path) |
| { |
| int code; |
| char cmd[100] = { 0 }; |
| snprintf(cmd, 100, "RMD %s\r\n", path); |
| code = ftp_cmd_handle(info, cmd, NULL, NULL); |
| if (code == 250) |
| { |
| return FTP_ERR_SUCCESS; |
| } |
| else if (code == 550) |
| { |
| LOGE("Dir not exist or not empty[%s].", path); |
| return FTP_ERR_FILE_NO_FOUND; |
| } |
| else |
| { |
| LOGE("RMD rsp error[code = %d].", code); |
| return FTP_ERR_UNKNOWN; |
| } |
| } |
| |
| static mbtk_ftp_error_enum ftp_cmd_process_stat(mbtk_ftp_info_s *info, |
| void *status) |
| { |
| int code; |
| char rsp[1024]; |
| uint32 rsp_len = 1024; |
| code = ftp_cmd_handle(info, "STAT\r\n", rsp, &rsp_len); |
| if (code != 211) |
| { |
| LOGE("STAT rsp error[code = %d].", code); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| memcpy(status, rsp, rsp_len); |
| |
| return FTP_ERR_SUCCESS; |
| } |
| |
| static mbtk_ftp_error_enum ftp_cmd_process_type(mbtk_ftp_info_s *info, |
| mbtk_ftp_data_type_enum type) |
| { |
| int code; |
| if (type == FTP_DATA_TYPE_I) |
| code = ftp_cmd_handle(info, "TYPE I\r\n", NULL, NULL); |
| else if (type == FTP_DATA_TYPE_E) |
| code = ftp_cmd_handle(info, "TYPE E\r\n", NULL, NULL); |
| else |
| code = ftp_cmd_handle(info, "TYPE A\r\n", NULL, NULL); |
| |
| if (code != 200) |
| { |
| LOGE("TYPE rsp error[code = %d].", code); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| return FTP_ERR_SUCCESS; |
| } |
| |
| static mbtk_ftp_error_enum ftp_cmd_process_size(mbtk_ftp_info_s *info, |
| const char *path, uint32 *size) |
| { |
| int code; |
| char cmd[100] = { 0 }; |
| char rsp[100]; |
| uint32 rsp_len = 100; |
| snprintf(cmd, 100, "SIZE %s\r\n", path); |
| code = ftp_cmd_handle(info, cmd, rsp, &rsp_len); |
| |
| if (code == 213) |
| { |
| // "213 4660645" |
| *size = atoi(rsp + 4); |
| } |
| else if (code == 550) |
| { |
| LOGW("No found file[%s].", path); |
| return FTP_ERR_FILE_NO_FOUND; |
| } |
| else |
| { |
| LOGE("SIZE rsp error[code = %d].", code); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| return FTP_ERR_SUCCESS; |
| } |
| |
| static mbtk_ftp_error_enum ftp_cmd_process_mdtm(mbtk_ftp_info_s *info, |
| const char *path, char *time) |
| { |
| int code; |
| char cmd[100] = { 0 }; |
| char rsp[100]; |
| uint32 rsp_len = 100; |
| snprintf(cmd, 100, "MDTM %s\r\n", path); |
| code = ftp_cmd_handle(info, cmd, rsp, &rsp_len); |
| |
| if (code == 213) |
| { |
| // "213 20181017014716" |
| memcpy(time, rsp + 4, 14); |
| } |
| else if (code == 550) |
| { |
| LOGW("No found file[%s].", path); |
| return FTP_ERR_FILE_NO_FOUND; |
| } |
| else |
| { |
| LOGE("MDTM rsp error[code = %d].", code); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| return FTP_ERR_SUCCESS; |
| } |
| |
| static mbtk_ftp_error_enum ftp_cmd_process_dele(mbtk_ftp_info_s *info, |
| const char *path) |
| { |
| int code; |
| char cmd[100] = { 0 }; |
| snprintf(cmd, 100, "DELE %s\r\n", path); |
| code = ftp_cmd_handle(info, cmd, NULL, NULL); |
| if (code == 250) |
| { |
| return FTP_ERR_SUCCESS; |
| } |
| else if (code == 550) |
| { |
| LOGW("No found file[%s].", path); |
| return FTP_ERR_FILE_NO_FOUND; |
| } |
| else |
| { |
| LOGE("DELE rsp error[code = %d].", code); |
| return FTP_ERR_UNKNOWN; |
| } |
| } |
| |
| static mbtk_ftp_error_enum ftp_cmd_process_quit(mbtk_ftp_info_s *info) |
| { |
| int code; |
| code = ftp_cmd_handle(info, "QUIT\r\n", NULL, NULL); |
| if (code != 221) |
| { |
| LOGE("CWD rsp error[code = %d].", code); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| return FTP_ERR_SUCCESS; |
| } |
| |
| static mbtk_ftp_error_enum ftp_cmd_process(mbtk_ftp_info_s *info, |
| mbtk_ftp_cmd_enum cmd, void *req, void *rsp) |
| { |
| mbtk_ftp_error_enum result = FTP_ERR_SUCCESS; |
| if (info->state == FTP_STATE_READY) // FTP login |
| { |
| info->state = FTP_STATE_CMD_PROCESS; |
| switch (cmd) |
| { |
| case FTP_CMD_LIST: |
| { |
| result = ftp_data_sock_read(info, FTP_CMD_LIST, req, rsp); |
| break; |
| } |
| case FTP_CMD_NLST: |
| { |
| result = ftp_data_sock_read(info, FTP_CMD_NLST, req, rsp); |
| break; |
| } |
| case FTP_CMD_PWD: |
| { |
| result = ftp_cmd_process_pwd(info, rsp); |
| break; |
| } |
| case FTP_CMD_CWD: |
| { |
| result = ftp_cmd_process_cwd(info, (char*) req); |
| break; |
| } |
| case FTP_CMD_MKD: |
| { |
| result = ftp_cmd_process_mkd(info, (char*) req); |
| break; |
| } |
| case FTP_CMD_RMD: |
| { |
| result = ftp_cmd_process_rmd(info, (char*) req); |
| break; |
| } |
| case FTP_CMD_STAT: |
| { |
| result = ftp_cmd_process_stat(info, rsp); |
| break; |
| } |
| case FTP_CMD_TYPE: |
| { |
| mbtk_ftp_data_type_enum *type = (mbtk_ftp_data_type_enum*) req; |
| result = ftp_cmd_process_type(info, *type); |
| break; |
| } |
| case FTP_CMD_SIZE: |
| { |
| result = ftp_cmd_process_size(info, (char*) req, (uint32*) rsp); |
| break; |
| } |
| case FTP_CMD_MDTM: |
| { |
| result = ftp_cmd_process_mdtm(info, (char*) req, (char*) rsp); |
| break; |
| } |
| case FTP_CMD_DELE: |
| { |
| result = ftp_cmd_process_dele(info, (char*) req); |
| break; |
| } |
| case FTP_CMD_QUIT: |
| { |
| result = ftp_cmd_process_quit(info); |
| break; |
| } |
| default: |
| { |
| LOGE("Unknown cmd:%d", cmd); |
| result = FTP_ERR_UNKNOWN; |
| break; |
| } |
| } |
| info->state = FTP_STATE_READY; |
| } |
| else |
| { |
| LOGW("FTP state error[%d].", info->state); |
| result = FTP_ERR_UNKNOWN; |
| } |
| |
| return result; |
| } |
| |
| static mbtk_ftp_error_enum ftp_login(mbtk_ftp_info_s *info,mbtk_ftp_user_info_s *user) |
| { |
| // Open net in the first. |
| if(info->net_info.net_id <= 0) { |
| if(sock_net_open(&info->net_info,info->sock_info[FTP_SOCK_CTRL].addr_family)) |
| { |
| LOGE("sock_net_open() fail."); |
| return FTP_ERR_NET_CONN; |
| } |
| } |
| |
| int err; |
| mbtk_ftp_error_enum ftp_err = FTP_ERR_SUCCESS; |
| info->state = FTP_STATE_CONNECTING; |
| info->net_info.keep_alive = TRUE; |
| info->net_info.recv_buff_size = 0; // Default |
| info->sock_info[FTP_SOCK_CTRL].fd = sock_open(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], FTP_TIMEOUT, &err); |
| if (info->sock_info[FTP_SOCK_CTRL].fd < 0) // Fail |
| { |
| LOGE("Socket open/connect fail[err = %d].", err); |
| ftp_err = FTP_ERR_NET_CONN; |
| goto login_fail; |
| } |
| |
| if(info->auth_type == FTP_AUTH_TYPE_IMPLICIT) |
| info->sock_info[FTP_SOCK_CTRL].is_ssl = true; |
| |
| // Ctrl socket connect success. |
| info->state = FTP_STATE_CONNECTED; |
| LOGI("FTP ctrl socket connected."); |
| |
| char buff[1024]; |
| int len; |
| char *ptr = NULL; |
| |
| // 220-FileZilla Server version 0.9.43 beta |
| // 220-written by Tim Kosse (tim.kosse@filezilla-project.org) |
| // 220 Please visit http://sourceforge.net/projects/filezilla/ |
| while(TRUE) { |
| memset(buff, 0x0, 1024); |
| len = sock_readline(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], buff, 1024, FTP_TIMEOUT, |
| &err); |
| if (len <= 0) |
| { |
| LOGE("Socket read fail[err = %d].", err); |
| ftp_err = FTP_ERR_NET_READ; |
| goto login_fail; |
| } else {// xxx yyyyyy |
| if((ptr = strstr(buff,"220 ")) || (ptr = strstr(buff,"230 "))) { |
| LOGI("RSP:%s",ptr); |
| break; |
| } |
| } |
| } |
| |
| int code = atoi(ptr); |
| if (code == 230) // Has logged in. |
| { |
| info->state = FTP_STATE_READY; |
| LOGI("FTP Has logged in."); |
| return FTP_ERR_SUCCESS; |
| } |
| else if (code == 220) // Should logn in. |
| { |
| int len; |
| char cmd_buff[50]; |
| |
| #if 0 |
| // Read other data. |
| char buff[1024]; |
| memset(buff,0x0,1024); |
| while((len = sock_read(&info->net_info,info->ctrl_sock.fd, buff, 1024, info->ssl_enable, 1000, |
| &err)) > 0) |
| { |
| LOGI("RSP[%d]:%s",len,buff); |
| memset(buff,0x0,1024); |
| } |
| #endif |
| |
| if(info->auth_type == FTP_AUTH_TYPE_EXPLICIT_SSL |
| || info->auth_type == FTP_AUTH_TYPE_EXPLICIT_TLS) { |
| if(info->auth_type == FTP_AUTH_TYPE_EXPLICIT_SSL) { |
| len = snprintf(cmd_buff, 50, "AUTH SSL\r\n"); |
| } else { |
| len = snprintf(cmd_buff, 50, "AUTH TLS\r\n"); |
| } |
| cmd_buff[len] = '\0'; |
| code = ftp_cmd_handle(info, cmd_buff, NULL, NULL); |
| if (code != 234 && code != 334) |
| { |
| LOGE("AUTH SSL/TLS fail[code = %d].", code); |
| ftp_err = FTP_ERR_LOGIN_DENIED; |
| goto login_fail; |
| } |
| |
| #if 0 |
| if(sock_ssl_enable(&info->net_info,info->ctrl_sock.fd |
| ,info->ctrl_sock.host,info->ctrl_sock.port,info->use_cert,FTP_TIMEOUT)){ |
| LOGE("sock_ssl_enable() fail."); |
| ftp_err = FTP_ERR_LOGIN_DENIED; |
| goto login_fail; |
| } |
| #endif |
| info->sock_info[FTP_SOCK_CTRL].is_ssl = true; |
| } |
| |
| if(info->auth_type != FTP_AUTH_TYPE_NON) { |
| len = snprintf(cmd_buff, 50, "PBSZ 0\r\n"); |
| cmd_buff[len] = '\0'; |
| code = ftp_cmd_handle(info, cmd_buff, NULL, NULL); |
| if (code != 200 && code != 220) |
| { |
| LOGE("PBSZ 0 fail[code = %d].", code); |
| ftp_err = FTP_ERR_LOGIN_DENIED; |
| goto login_fail; |
| } |
| } |
| |
| len = snprintf(cmd_buff, 50, "USER %s\r\n", user->name); |
| cmd_buff[len] = '\0'; |
| code = ftp_cmd_handle(info, cmd_buff, NULL, NULL); |
| if (code == 331) // USER is 331 |
| { |
| len = snprintf(cmd_buff, 50, "PASS %s\r\n", user->pass); |
| cmd_buff[len] = '\0'; |
| code = ftp_cmd_handle(info, cmd_buff, NULL, NULL); |
| } |
| |
| if (code / 100 == 2) // USER/PASS is 2xx |
| { |
| info->state = FTP_STATE_READY; |
| LOGI("FTP logn in success."); |
| return FTP_ERR_SUCCESS; |
| } |
| else if (code == 332) // // USER/PASS is 332 |
| { |
| LOGW("Should set ACCT."); |
| ftp_err = FTP_ERR_UNKNOWN; |
| goto login_fail; |
| } |
| else |
| { |
| LOGE("FTP login denied[code = %d].", code); |
| ftp_err = FTP_ERR_LOGIN_DENIED; |
| goto login_fail; |
| } |
| } |
| else |
| { |
| LOGE("FTP code error[%d].", code); |
| ftp_err = FTP_ERR_UNKNOWN; |
| goto login_fail; |
| } |
| |
| login_fail: |
| info->state = FTP_STATE_NON; |
| return ftp_err; |
| } |
| |
| static mbtk_ftp_info_s* ftp_info_find(mbtk_ftp_handle handle) |
| { |
| if (!ftp_client_list) |
| { |
| LOGE("FTP Client List not init."); |
| return NULL; |
| } |
| |
| mbtk_ftp_info_s *result = NULL; |
| list_first(ftp_client_list); |
| while ((result = (mbtk_ftp_info_s*) list_next(ftp_client_list))) |
| { |
| if (result->handle == handle) |
| break; |
| } |
| |
| return result; |
| } |
| |
| mbtk_ftp_handle mbtk_ftp_upload_end(mbtk_ftp_handle handle) |
| { |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| printf("No such FTP handle:%d\n", handle); |
| } |
| |
| char buff[1024]={0}; |
| int err=0; |
| int len=0; |
| int result; |
| |
| if (info->sock_info[FTP_SOCK_DATA].fd > 0) |
| { |
| if (sock_close(&info->net_info, &info->sock_info[FTP_SOCK_DATA], FTP_TIMEOUT, &err)) |
| { |
| LOGE("Close data socket fail[%d].", err); |
| result = FTP_ERR_NET_CLOSE; |
| } |
| else |
| { |
| // info->sock_info[FTP_SOCK_DATA].fd = -1; |
| } |
| } |
| if(info->auth_type != 0) |
| { |
| if(mbtk_sock_close(info->ftp_ssl_handle,info->session_data,6000,&err)) |
| { |
| LOGE("Close ssl data socket fail[%d].", err); |
| result = FTP_ERR_NET_CLOSE; |
| } |
| else |
| { |
| // info->sock_info[FTP_SOCK_DATA].fd = -1; |
| } |
| } |
| info->data_mode = FTP_MODE_PASSIVE; |
| info->is_data_sock_busy = false; |
| info->file_trans.size_count = 0; |
| info->file_trans.size_send = 0; |
| |
| // char line_buf[1024]; |
| if(info->auth_type != 0) |
| len = mbtk_sock_read(info->ftp_ssl_handle,info->session,buff,sizeof(buff),FTP_TIMEOUT,&err); |
| else |
| len = sock_readline(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], buff, 1024, FTP_TIMEOUT, &err); |
| if(len > 0) |
| { |
| printf("\n%s\n",buff); |
| if(err != 0) |
| printf("socket read error: %d\n",err); |
| } |
| else |
| { |
| printf("socket_read error:%d\n",err); |
| result = -1; |
| } |
| |
| return result; |
| } |
| |
| static mbtk_ftp_handle ftp_next_handle() |
| { |
| if (!ftp_client_list) |
| { |
| LOGE("FTP Client List not init."); |
| return -1; |
| } |
| |
| mbtk_ftp_info_s *info = NULL; |
| mbtk_ftp_handle handle = 1; |
| bool used; |
| while (handle <= FTP_HANDLE_MAX) |
| { |
| used = false; |
| // This handle used? |
| list_first(ftp_client_list); |
| while ((info = (mbtk_ftp_info_s*) list_next(ftp_client_list))) |
| { |
| if (handle == info->handle) |
| { |
| used = true; |
| break; |
| } |
| } |
| |
| if (!used) |
| { |
| break; |
| } |
| |
| handle++; |
| } |
| |
| LOGI("Get free handle:%d", handle); |
| |
| return handle; |
| } |
| |
| static void ftp_free_func(void *data) |
| { |
| if (data) |
| { |
| mbtk_ftp_info_s *info = (mbtk_ftp_info_s*) data; |
| LOGI("Free FTP client[handle = %d].", info->handle); |
| free(info); |
| } |
| } |
| |
| /************************************************************* |
| Public Function Definitions |
| *************************************************************/ |
| mbtk_ftp_handle mbtk_ftp_init(const void* host, uint16 port, mbtk_ftp_auth_type_enum auth_type, |
| bool is_ipv6, bool use_cert) |
| { |
| if (!ftp_client_list) |
| ftp_client_list = list_create(ftp_free_func); |
| |
| if (!ftp_client_list) |
| { |
| LOGE("FTP Client List not init."); |
| return -1; |
| } |
| |
| if (list_size(ftp_client_list) > FTP_HANDLE_MAX) |
| { |
| LOGE("FTP client is full."); |
| return -1; |
| } |
| |
| if (host == NULL || strlen(host) == 0) |
| { |
| LOGE("Host error."); |
| return -1; |
| } |
| |
| if (port == 0) |
| { |
| port = FTP_SERVICE_PORT_DEF; |
| } |
| |
| mbtk_ftp_info_s *info = (mbtk_ftp_info_s*) malloc(sizeof(mbtk_ftp_info_s)); |
| if (!info) |
| { |
| LOGE("malloc() fail."); |
| return -1; |
| } |
| memset(info, 0x0, sizeof(mbtk_ftp_info_s)); |
| list_add(ftp_client_list, info); |
| memcpy(info->sock_info[FTP_SOCK_CTRL].host, host, strlen(host)); |
| info->sock_info[FTP_SOCK_CTRL].port = port; |
| // info->auth_type == FTP_AUTH_TYPE_IMPLICIT, info->is_ipv6 ? MBTK_ADDR_IPV6 : MBTK_ADDR_IPV4,info->use_cert, |
| info->sock_info[FTP_SOCK_CTRL].is_ssl = (auth_type == FTP_AUTH_TYPE_IMPLICIT); |
| info->sock_info[FTP_SOCK_CTRL].addr_family = is_ipv6 ? MBTK_ADDR_IPV6: MBTK_ADDR_IPV4; |
| info->sock_info[FTP_SOCK_CTRL].use_cert = use_cert; |
| |
| info->handle = ftp_next_handle(); |
| info->state = FTP_STATE_NON; |
| info->data_mode = FTP_MODE_PASSIVE; |
| info->sock_info[FTP_SOCK_CTRL].fd = -1; |
| info->sock_info[FTP_SOCK_DATA].fd = -1; |
| //info->is_ipv6 = is_ipv6; |
| info->auth_type = auth_type; |
| //info->use_cert = use_cert; |
| |
| LOGI("FTP info#host:%s,port:%d,ipv6:%d,ssl:%d,cert:%d",info->sock_info[FTP_SOCK_CTRL].host, |
| info->sock_info[FTP_SOCK_CTRL].port, |
| is_ipv6,info->auth_type,use_cert); |
| |
| if(auth_type != FTP_AUTH_TYPE_NON) |
| { |
| info->ftp_ssl_handle = mbtk_sock_init(&info->ftp_ssl_info); |
| if(info->ftp_ssl_handle == -1) |
| { |
| printf("mbtk_sock_init error\n"); |
| } |
| |
| info->ftp_sock_ssl_info = (mbtk_sock_info*) malloc(sizeof(mbtk_sock_info)); |
| memset(info->ftp_sock_ssl_info, 0x0, sizeof(mbtk_sock_info)); |
| info->ftp_sock_ssl_info->is_support_ssl = (auth_type != FTP_AUTH_TYPE_NON); |
| info->ftp_sock_ssl_info->ftp_ssl_support = 1; |
| info->ftp_sock_ssl_info->port = port; |
| info->ftp_sock_ssl_info->type = MBTK_SOCK_TCP; |
| info->ftp_sock_ssl_info->ingnore_cert = !use_cert; |
| memcpy(info->ftp_sock_ssl_info->address, host, strlen(host)); |
| } |
| return info->handle; |
| } |
| |
| mbtk_ftp_error_enum mbtk_ftp_reconfig(mbtk_ftp_handle handle,const void* host, uint16 port, mbtk_ftp_auth_type_enum auth_type, |
| bool is_ipv6, bool use_cert) |
| { |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return FTP_ERR_UNKNOWN; |
| } |
| if(auth_type != FTP_AUTH_TYPE_NON) |
| { |
| info->ftp_sock_ssl_info = (mbtk_sock_info*) malloc(sizeof(mbtk_sock_info)); |
| memset(info->ftp_sock_ssl_info, 0x0, sizeof(mbtk_sock_info)); |
| if(host && strlen(host) > 0) |
| { |
| memcpy(info->ftp_sock_ssl_info->address, host, strlen(host)); |
| info->ftp_sock_ssl_info->address[strlen(host)] = '\0'; |
| } |
| info->ftp_sock_ssl_info->is_support_ssl = (auth_type != FTP_AUTH_TYPE_NON); |
| info->ftp_sock_ssl_info->ftp_ssl_support = 1; |
| info->ftp_sock_ssl_info->port = port; |
| info->ftp_sock_ssl_info->ingnore_cert = !use_cert; |
| info->ftp_sock_ssl_info->type = MBTK_SOCK_TCP; |
| } |
| if(info->state == FTP_STATE_NON) |
| { |
| if(host && strlen(host) > 0) |
| { |
| memcpy(info->sock_info[FTP_SOCK_CTRL].host, host, strlen(host)); |
| info->sock_info[FTP_SOCK_CTRL].host[strlen(host)] = '\0'; |
| } |
| info->sock_info[FTP_SOCK_CTRL].port = port; |
| info->sock_info[FTP_SOCK_CTRL].addr_family = is_ipv6 ? MBTK_ADDR_IPV6 : MBTK_ADDR_IPV4; |
| info->auth_type = auth_type; |
| info->sock_info[FTP_SOCK_CTRL].use_cert = use_cert; |
| |
| return FTP_ERR_SUCCESS; |
| } |
| else |
| { |
| LOGE("Not reset FTP config.The state is %d", info->state); |
| return FTP_ERR_UNKNOWN; |
| } |
| } |
| |
| mbtk_ftp_error_enum mbtk_ftp_user_set(mbtk_ftp_handle handle,void* user,void* pass) |
| { |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| if(info->state == FTP_STATE_NON && !str_empty(user) && !str_empty(pass)) |
| { |
| memset(&info->user,0x0,sizeof(mbtk_ftp_user_info_s)); |
| memcpy(info->user.name, user, strlen(user)); |
| memcpy(info->user.pass, pass, strlen(pass)); |
| return FTP_ERR_SUCCESS; |
| } |
| else |
| { |
| LOGE("Not reset FTP config.The state is %d", info->state); |
| return FTP_ERR_UNKNOWN; |
| } |
| } |
| |
| mbtk_ftp_error_enum mbtk_ftp_deinit(mbtk_ftp_handle handle) |
| { |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| if (list_remove(ftp_client_list, info)) |
| { |
| int err; |
| if(info->auth_type == FTP_AUTH_TYPE_NON) { |
| sock_close(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], FTP_TIMEOUT, &err); |
| sock_close(&info->net_info, &info->sock_info[FTP_SOCK_DATA], FTP_TIMEOUT, &err); |
| } else { |
| mbtk_sock_deinit(info->ftp_ssl_handle); |
| } |
| ftp_free_func(info); |
| } |
| |
| return FTP_ERR_SUCCESS; |
| } |
| |
| /* |
| * Quit FTP service. |
| */ |
| mbtk_ftp_error_enum mbtk_ftp_quit(mbtk_ftp_handle handle) |
| { |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| int err = 0; |
| if(info->sock_info[FTP_SOCK_CTRL].fd > 0) { |
| mbtk_ftp_error_enum ftp_err = ftp_cmd_process(info, FTP_CMD_QUIT, NULL, |
| NULL); |
| if (ftp_err != FTP_ERR_SUCCESS) |
| { |
| LOGE("FTP QUIT fail[%d].", ftp_err); |
| //return ftp_err; |
| } |
| |
| // FTP quit success. |
| info->state = FTP_STATE_CONNECTED; |
| } |
| |
| if(info->auth_type == FTP_AUTH_TYPE_NON) { |
| if (sock_close(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], FTP_TIMEOUT, &err)) |
| { |
| LOGE("Close ctrl socket fail[%d].", err); |
| return FTP_ERR_NET_CLOSE; |
| } |
| |
| if (sock_close(&info->net_info, &info->sock_info[FTP_SOCK_DATA], FTP_TIMEOUT, &err)) |
| { |
| LOGE("Close data socket fail[%d].", err); |
| return FTP_ERR_NET_CLOSE; |
| } |
| } else { |
| if(mbtk_sock_close(info->ftp_ssl_handle,info->session,6000,&err)) |
| { |
| LOGE("Close ssl ctrl socket fail[%d].", err); |
| //return FTP_ERR_NET_CLOSE; |
| } |
| |
| if(mbtk_sock_close(info->ftp_ssl_handle,info->session_data,6000,&err)) |
| { |
| LOGE("Close ssl data socket fail[%d].", err); |
| //return FTP_ERR_NET_CLOSE; |
| } |
| } |
| |
| |
| info->state = FTP_STATE_NON; |
| info->data_mode = FTP_MODE_PASSIVE; |
| memset(&info->file_trans, 0x0, sizeof(mbtk_ftp_file_trans_info_s)); |
| info->sock_info[FTP_SOCK_CTRL].fd = -1; |
| info->sock_info[FTP_SOCK_DATA].fd = -1; |
| |
| return FTP_ERR_SUCCESS; |
| } |
| |
| mbtk_ftp_error_enum mbtk_ftp_net_close(mbtk_ftp_handle handle) |
| { |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| if(info->net_info.net_id > 0) { |
| int err; |
| if(sock_net_close(&info->net_info, FTP_TIMEOUT,&err)) |
| { |
| LOGE("sock_net_close() fail[%ld].",err); |
| return FTP_ERR_NET_CLOSE; |
| } |
| |
| info->net_info.net_id = -1; |
| } |
| |
| return FTP_ERR_SUCCESS; |
| } |
| |
| |
| mbtk_ftp_info_s* mbtk_ftp_info_get(mbtk_ftp_handle handle) |
| { |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return NULL; |
| } |
| |
| return info; |
| } |
| |
| /* |
| * Login specified FTP service. |
| */ |
| mbtk_ftp_error_enum mbtk_ftp_login(mbtk_ftp_handle handle, void *name, |
| void *pass) |
| { |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| if (info->state == FTP_STATE_NON) |
| { |
| mbtk_ftp_user_info_s user; |
| memset(&user,0x0,sizeof(mbtk_ftp_user_info_s)); |
| if (!str_empty(name) && !str_empty(pass)) |
| { |
| memcpy(user.name, name, strlen(name)); |
| memcpy(user.pass, pass, strlen(pass)); |
| memcpy(info->user.name, name, strlen(name)); |
| memcpy(info->user.pass, pass, strlen(pass)); |
| } |
| else |
| { |
| memcpy(user.name, FTP_ANONYMOUS_USER, strlen(FTP_ANONYMOUS_USER)); |
| memcpy(user.pass, FTP_ANONYMOUS_PASS, strlen(FTP_ANONYMOUS_PASS)); |
| memcpy(info->user.name, FTP_ANONYMOUS_USER, strlen(FTP_ANONYMOUS_USER)); |
| memcpy(info->user.pass, FTP_ANONYMOUS_PASS, strlen(FTP_ANONYMOUS_PASS)); |
| } |
| |
| LOGI("FTP login#user:%s,pass:%s",user.name,user.pass); |
| |
| if(info->auth_type != 0) |
| { |
| int mbtk_errno=-1; |
| info->session = mbtk_sock_open(info->ftp_ssl_handle,info->ftp_sock_ssl_info,60000,&mbtk_errno); |
| if(mbtk_errno!=0) |
| { |
| printf("mbtk_sock_open error : %d\n",mbtk_errno); |
| } |
| else |
| { |
| unsigned char mbtk_ftp_ssl_read_buf[16384 + 1]; |
| char cmd[50]; |
| memset(cmd,0,50); |
| // int len_ssl; |
| |
| |
| memset(cmd,0,50); |
| snprintf(cmd, 50, "PBSZ 0\r\n"); |
| mbtk_sock_write(info->ftp_ssl_handle,info->session, |
| cmd, |
| sizeof(cmd), |
| 60000, |
| &mbtk_errno); |
| memset(mbtk_ftp_ssl_read_buf,0,sizeof(mbtk_ftp_ssl_read_buf)); |
| mbtk_sock_read(info->ftp_ssl_handle,info->session, |
| mbtk_ftp_ssl_read_buf, |
| sizeof(mbtk_ftp_ssl_read_buf), |
| 60000, |
| &mbtk_errno); |
| printf("\nmbtk_sock_read PBSZ 0:\n%s\n",mbtk_ftp_ssl_read_buf); |
| memset(cmd,0,50); |
| snprintf(cmd, 50, "PROT P\r\n"); |
| mbtk_sock_write(info->ftp_ssl_handle,info->session, |
| cmd, |
| sizeof(cmd), |
| 60000, |
| &mbtk_errno); |
| memset(mbtk_ftp_ssl_read_buf,0,sizeof(mbtk_ftp_ssl_read_buf)); |
| mbtk_sock_read(info->ftp_ssl_handle,info->session, |
| mbtk_ftp_ssl_read_buf, |
| sizeof(mbtk_ftp_ssl_read_buf), |
| 60000, |
| &mbtk_errno); |
| printf("\nmbtk_sock_read PROT P:\n%s\n",mbtk_ftp_ssl_read_buf); |
| memset(cmd,0,50); |
| snprintf(cmd, 50, "USER %s\r\n",info->user.name); |
| mbtk_sock_write(info->ftp_ssl_handle,info->session, |
| cmd, |
| sizeof(cmd), |
| 60000, |
| &mbtk_errno); |
| memset(mbtk_ftp_ssl_read_buf,0,sizeof(mbtk_ftp_ssl_read_buf)); |
| mbtk_sock_read(info->ftp_ssl_handle,info->session, |
| mbtk_ftp_ssl_read_buf, |
| sizeof(mbtk_ftp_ssl_read_buf), |
| 60000, |
| &mbtk_errno); |
| printf("\nmbtk_sock_read USER:\n%s\n",mbtk_ftp_ssl_read_buf); |
| memset(cmd,0,50); |
| snprintf(cmd, 50, "PASS %s\r\n",info->user.pass); |
| mbtk_sock_write(info->ftp_ssl_handle,info->session, |
| cmd, |
| sizeof(cmd), |
| 60000, |
| &mbtk_errno); |
| memset(mbtk_ftp_ssl_read_buf,0,sizeof(mbtk_ftp_ssl_read_buf)); |
| mbtk_sock_read(info->ftp_ssl_handle,info->session, |
| mbtk_ftp_ssl_read_buf, |
| sizeof(mbtk_ftp_ssl_read_buf), |
| 60000, |
| &mbtk_errno); |
| printf("\nmbtk_sock_read PASS:\n%s\n",mbtk_ftp_ssl_read_buf); |
| char *ptr = NULL; |
| if((ptr = strstr((char*)mbtk_ftp_ssl_read_buf,"220 ")) || (ptr = strstr((char*)mbtk_ftp_ssl_read_buf,"230 "))) { |
| LOGI("RSP:%s",ptr); |
| printf("RSP:%s\n",ptr); |
| } |
| else |
| { |
| printf("\nptr error.\n"); |
| return FTP_ERR_UNKNOWN; |
| } |
| int code = atoi(ptr); |
| if (code / 100 == 2) // USER/PASS is 2xx |
| { |
| info->state = FTP_STATE_READY; |
| LOGI("FTP logn in success."); |
| printf("FTP logn in success.\n"); |
| } |
| else if (code == 332) // // USER/PASS is 332 |
| { |
| LOGW("Should set ACCT."); |
| printf("Should set ACCT.\n"); |
| return FTP_ERR_UNKNOWN; |
| } |
| else |
| { |
| LOGE("FTP login denied[code = %d].", code); |
| printf("FTP login denied[code = %d].\n", code); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| memset(cmd,0,50); |
| snprintf(cmd, 50, "PWD\r\n"); |
| mbtk_sock_write(info->ftp_ssl_handle,info->session, |
| cmd, |
| sizeof(cmd), |
| 60000, |
| &mbtk_errno); |
| memset(mbtk_ftp_ssl_read_buf,0,sizeof(mbtk_ftp_ssl_read_buf)); |
| mbtk_sock_read(info->ftp_ssl_handle,info->session, |
| mbtk_ftp_ssl_read_buf, |
| sizeof(mbtk_ftp_ssl_read_buf), |
| 60000, |
| &mbtk_errno); |
| printf("\nmbtk_sock_read PWD:\n%s\n",mbtk_ftp_ssl_read_buf); |
| } |
| return mbtk_errno; |
| } |
| |
| return ftp_login(info,&user); |
| } |
| else |
| { |
| LOGD("Has login."); |
| return FTP_ERR_SUCCESS; |
| } |
| } |
| |
| /* |
| * Get current directory's path. |
| */ |
| mbtk_ftp_error_enum mbtk_ftp_pwd(mbtk_ftp_handle handle, void *path) |
| { |
| if (!path) |
| { |
| LOGE("No set path"); |
| return FTP_ERR_PARAM_SET; |
| } |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| return ftp_cmd_process(info, FTP_CMD_PWD, NULL, path); |
| } |
| |
| /* |
| * Go to specified directory. |
| */ |
| mbtk_ftp_error_enum mbtk_ftp_cd(mbtk_ftp_handle handle, void *path) |
| { |
| if (!path) |
| { |
| LOGE("No set path"); |
| return FTP_ERR_PARAM_SET; |
| } |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| return ftp_cmd_process(info, FTP_CMD_CWD, path, NULL); |
| } |
| |
| /* |
| * Get the native ip and free port. |
| */ |
| mbtk_ftp_error_enum mbtk_ftp_get_ip_and_port(char *ipBuf_out, |
| int *port,int iptype) |
| { |
| char psz_port_cmd[128]; |
| // int i=0; |
| |
| *port = rand() % (60000 - 50000 + 1) + 50000; |
| sprintf(psz_port_cmd, "netstat -an | grep :%d > /dev/null", *port); |
| |
| char ipBuf[1024] = {0}; |
| FILE *fstream=NULL; |
| |
| char buff[1024] = {0}; |
| // char iptype_str[8]; |
| memset(buff,0,sizeof(buff)); |
| /*eth0可以换成eth1、docker0、em1、lo等*/ |
| if(iptype == MBTK_ADDR_IPV6) |
| { |
| |
| if(NULL==(fstream=popen("ifconfig ccinet0 | grep \"inet6 addr: 2\" | awk '{print $3}'","r"))) |
| { |
| snprintf(ipBuf, 39, "%s","0:0:0:0:0:0:0:0"); |
| } |
| if(NULL!=fgets(buff, sizeof(buff), fstream)) |
| { |
| snprintf(ipBuf, sizeof(buff), "%s",buff); |
| } |
| else |
| { |
| snprintf(ipBuf, 39, "%s","0:0:0:0:0:0:0:0"); |
| pclose(fstream); |
| } |
| } |
| else |
| { |
| if(NULL==(fstream=popen("ifconfig ccinet0 | grep \"inet addr:\" | awk \'{print $2}\' | cut -c 6-","r"))) |
| { |
| snprintf(ipBuf, 18, "%s","0.0.0.0"); |
| } |
| if(NULL!=fgets(buff, sizeof(buff), fstream)) |
| { |
| snprintf(ipBuf, sizeof(ipBuf), "%s",buff); |
| } |
| else |
| { |
| snprintf(ipBuf, 18, "%s","0.0.0.0"); |
| pclose(fstream); |
| } |
| } |
| pclose(fstream); |
| |
| printf("ip:%s\n", ipBuf); |
| memcpy(ipBuf_out, ipBuf, 32); |
| return 0; |
| } |
| /* |
| * Get current directory's subdirectory. |
| */ |
| mbtk_ftp_error_enum mbtk_ftp_dir_ls(mbtk_ftp_handle handle, |
| mbtk_ftp_file_info_s *list_head) |
| { |
| if (!list_head) |
| { |
| LOGE("No set file list."); |
| return FTP_ERR_PARAM_SET; |
| } |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| return ftp_cmd_process(info, FTP_CMD_LIST, NULL, list_head); |
| } |
| |
| /* |
| * Get specified file's size. |
| */ |
| uint32 mbtk_ftp_file_size(mbtk_ftp_handle handle, void *path) |
| { |
| if (!path) |
| { |
| LOGE("No set path"); |
| return 0; |
| } |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return 0; |
| } |
| uint32 size = 0; |
| if (ftp_cmd_process(info, FTP_CMD_SIZE, path, &size) != FTP_ERR_SUCCESS) |
| return 0; |
| |
| return size; |
| } |
| |
| /* |
| * Get specified file's modify time. |
| */ |
| mbtk_ftp_error_enum mbtk_ftp_file_time(mbtk_ftp_handle handle, void *path, |
| void *time) |
| { |
| if (!path) |
| { |
| LOGE("No set path"); |
| return FTP_ERR_PARAM_SET; |
| } |
| |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| return ftp_cmd_process(info, FTP_CMD_MDTM, path, time); |
| } |
| |
| /* |
| * Delete specified file. |
| */ |
| mbtk_ftp_error_enum mbtk_ftp_file_del(mbtk_ftp_handle handle, void *path) |
| { |
| if (!path) |
| { |
| LOGE("No set path"); |
| return FTP_ERR_PARAM_SET; |
| } |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| return ftp_cmd_process(info, FTP_CMD_DELE, path, NULL); |
| } |
| |
| /* |
| * Create specified directory. |
| */ |
| mbtk_ftp_error_enum mbtk_ftp_dir_mkdir(mbtk_ftp_handle handle, void *path) |
| { |
| if (!path) |
| { |
| LOGE("No set path"); |
| return FTP_ERR_PARAM_SET; |
| } |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| return ftp_cmd_process(info, FTP_CMD_MKD, path, NULL); |
| } |
| |
| /* |
| * Delete specified directory. |
| */ |
| mbtk_ftp_error_enum mbtk_ftp_dir_rmdir(mbtk_ftp_handle handle, void *path) |
| { |
| if (!path) |
| { |
| LOGE("No set path"); |
| return FTP_ERR_PARAM_SET; |
| } |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| return ftp_cmd_process(info, FTP_CMD_RMD, path, NULL); |
| } |
| |
| /* |
| * Set data type. |
| */ |
| mbtk_ftp_error_enum mbtk_ftp_data_type_set(mbtk_ftp_handle handle, |
| mbtk_ftp_data_type_enum data_type) |
| { |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| return ftp_cmd_process(info, FTP_CMD_TYPE, &data_type, NULL); |
| } |
| |
| /* |
| * Set FTP mode. |
| */ |
| mbtk_ftp_error_enum mbtk_ftp_mode_set(mbtk_ftp_handle handle, |
| mbtk_ftp_mode_enum mode) |
| { |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| info->data_mode = mode; |
| |
| return FTP_ERR_SUCCESS; |
| } |
| |
| uint32 mbtk_ftp_download_start(mbtk_ftp_handle handle, void *remote_path, |
| void *local_path, mbtk_data_cb_func data_cb) |
| { |
| if (!remote_path || (local_path && data_cb) || (!local_path && !data_cb)) |
| { |
| LOGE("Param set error."); |
| return 0; |
| } |
| |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return 0; |
| } |
| |
| if (info->state >= FTP_STATE_READY && !info->is_trans) |
| { |
| int retry_time = 0; |
| memset(&info->file_trans, 0x0, sizeof(mbtk_ftp_file_trans_info_s)); |
| |
| // Set data type to "I" |
| if (FTP_ERR_SUCCESS |
| != mbtk_ftp_data_type_set(handle, FTP_DATA_TYPE_I)) |
| { |
| LOGE("Set data type to I fail."); |
| return 0; |
| } |
| |
| // Get file size. |
| info->file_trans.size_count = mbtk_ftp_file_size(handle, remote_path); |
| if (info->file_trans.size_count > 0) |
| { |
| LOGI("File size:%d", info->file_trans.size_count); |
| } |
| else |
| { |
| LOGE("File not exist."); |
| return 0; |
| } |
| |
| //Get file modify time. |
| if (FTP_ERR_SUCCESS |
| != mbtk_ftp_file_time(handle, remote_path, |
| (char*) info->file_trans.modify_time)) |
| { |
| LOGE("Get file modify time fail."); |
| return 0; |
| } |
| |
| memcpy(info->file_trans.remote_name, remote_path, |
| strlen((char*) remote_path)); |
| if (local_path) |
| { |
| memcpy(info->file_trans.local_name, local_path, |
| strlen((char*) local_path)); |
| info->file_trans.data_cb = NULL; |
| } |
| else |
| { |
| info->file_trans.data_cb = data_cb; |
| } |
| info->file_trans.size_send = 0; |
| info->file_trans.is_download = true; |
| info->file_trans.fd = -1; |
| info->is_trans = true; |
| |
| if (!info->file_trans.data_cb) // Save to efs |
| { |
| info->file_trans.fd = file_open((const char*)info->file_trans.local_name, |
| O_WRONLY | O_CREAT | O_TRUNC); |
| if (info->file_trans.fd <= 0) |
| { |
| LOGE("Can not open EFS file[%s].", info->file_trans.local_name); |
| return 0; |
| } |
| } |
| |
| do { |
| // Start download file. |
| if (FTP_ERR_SUCCESS |
| != ftp_data_sock_read(info, FTP_CMD_GET, NULL, NULL)) |
| { |
| LOGW("ftp_data_sock_read() fail."); |
| } |
| |
| if(info->sock_info[FTP_SOCK_CTRL].fd <= 0) { |
| // Download fail. |
| LOGW("Ctrl socket error,should login angin."); |
| break; |
| } else if (info->file_trans.size_send == info->file_trans.size_count) { |
| // Download success |
| break; |
| } |
| |
| // Should redownload without quit. |
| char time[20] = { 0 }; |
| if (FTP_ERR_SUCCESS |
| != mbtk_ftp_file_time(handle, info->file_trans.remote_name, |
| time)) |
| { |
| LOGE("Get file modify time fail."); |
| break; |
| } |
| |
| if (strcmp(time, (char*) info->file_trans.modify_time)) |
| { |
| LOGW("Service file changed."); |
| break; |
| } |
| |
| retry_time++; |
| } while(retry_time < 5); |
| |
| |
| if (!info->file_trans.data_cb && info->file_trans.fd > 0) // Save to efs |
| { |
| if (file_close(info->file_trans.fd)) |
| { |
| LOGE("EFS close fail."); |
| return 0; |
| } |
| } |
| |
| // Download success. |
| if (info->file_trans.size_send == info->file_trans.size_count) |
| { |
| LOGI("Download %s success[%d].", (char* )remote_path, |
| info->file_trans.size_count); |
| |
| // Reset download configs. |
| info->is_trans = false; |
| // memset(&info->file_trans, 0x0, sizeof(mbtk_ftp_file_trans_info_s)); |
| } |
| else |
| { |
| LOGW("Download %s fail[%d / %d].", (char* )remote_path, |
| info->file_trans.size_send, info->file_trans.size_count); |
| } |
| |
| return info->file_trans.size_send; |
| } |
| else |
| { |
| LOGE("FTP state error[%d].", info->state); |
| return 0; |
| } |
| } |
| |
| uint32 mbtk_ftp_download_continue(mbtk_ftp_handle handle) |
| { |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return 0; |
| } |
| |
| if(info->state == FTP_STATE_NON) { |
| if(FTP_ERR_SUCCESS != ftp_login(info,&info->user)) { |
| LOGE("FTP login fail."); |
| return 0; |
| } |
| } |
| |
| if (info->state >= FTP_STATE_READY && info->is_trans |
| && info->file_trans.is_download |
| && info->file_trans.size_send < info->file_trans.size_count) |
| { |
| // Set data type to "I" |
| if (FTP_ERR_SUCCESS |
| != mbtk_ftp_data_type_set(handle, FTP_DATA_TYPE_I)) |
| { |
| LOGE("Set data type to I fail."); |
| return 0; |
| } |
| |
| // Get file size. |
| uint32 size = mbtk_ftp_file_size(handle, info->file_trans.remote_name); |
| if (size > 0) |
| { |
| LOGI("File size:%d", size); |
| } |
| else |
| { |
| LOGE("File not exist."); |
| return 0; |
| } |
| if (size != info->file_trans.size_count) |
| { |
| LOGW("Service file changed."); |
| return 0; |
| } |
| |
| //Get file modify time. |
| char time[20] = { 0 }; |
| if (FTP_ERR_SUCCESS |
| != mbtk_ftp_file_time(handle, info->file_trans.remote_name, |
| time)) |
| { |
| LOGE("Get file modify time fail."); |
| return 0; |
| } |
| if (strcmp(time, (char*) info->file_trans.modify_time)) |
| { |
| LOGW("Service file changed."); |
| return 0; |
| } |
| |
| if (!info->file_trans.data_cb) // Save to efs |
| { |
| info->file_trans.fd = file_open((const char*)info->file_trans.local_name, |
| O_WRONLY | O_CREAT | O_APPEND); |
| if (info->file_trans.fd <= 0) |
| { |
| LOGE("Can not open EFS file[%s].", info->file_trans.local_name); |
| return FTP_ERR_EFS_FILE; |
| } |
| } |
| |
| uint32 size_last = info->file_trans.size_send; |
| // Start download file. |
| if (FTP_ERR_SUCCESS |
| != ftp_data_sock_read(info, FTP_CMD_GET, NULL, NULL)) |
| { |
| LOGW("Data download fail."); |
| } |
| |
| if (!info->file_trans.data_cb && info->file_trans.fd > 0) |
| { |
| if (file_close(info->file_trans.fd)) |
| { |
| LOGE("EFS close fail."); |
| return 0; |
| } |
| } |
| |
| // Download success. |
| if (info->file_trans.size_send == info->file_trans.size_count) |
| { |
| LOGI("Download %s success[%d].", info->file_trans.remote_name, |
| info->file_trans.size_count); |
| |
| // Reset download configs. |
| info->is_trans = false; |
| //memset(&info->file_trans, 0x0, sizeof(mbtk_ftp_file_trans_info_s)); |
| } |
| else |
| { |
| LOGW("Download %s fail[%d / %d].", info->file_trans.remote_name, |
| info->file_trans.size_send, info->file_trans.size_count); |
| } |
| |
| return info->file_trans.size_send - size_last; |
| } |
| else |
| { |
| LOGE("FTP state error[%d].", info->state); |
| return 0; |
| } |
| } |
| |
| /* |
| * Upload EFS: local_path is efs path;size_byte is 0. |
| * Upload data: local_path is NULL;size_byte is data size. |
| */ |
| int mbtk_ftp_upload_start(mbtk_ftp_handle handle, const void *remote_path, |
| const void *local_path, uint32 size_byte) |
| { |
| if (!remote_path || (size_byte == 0 && !local_path) |
| || (size_byte > 0 && local_path)) |
| { |
| LOGE("Param set error."); |
| return -1; |
| } |
| |
| int result = 0; |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return -1; |
| } |
| |
| LOGE("info->state:%d, info->is_trans:%d", info->state,info->is_trans); |
| |
| if (info->state >= FTP_STATE_READY && !info->is_trans) |
| { |
| // Set data type to "I" |
| if (FTP_ERR_SUCCESS |
| != mbtk_ftp_data_type_set(handle, FTP_DATA_TYPE_I)) |
| { |
| LOGE("Set data type to I fail."); |
| return -1; |
| } |
| |
| memset(&info->file_trans, 0x0, sizeof(mbtk_ftp_file_trans_info_s)); |
| info->file_trans.is_download = false; |
| |
| memcpy(info->file_trans.remote_name, remote_path, |
| strlen((char*) remote_path)); |
| |
| if (local_path) |
| { |
| memcpy(info->file_trans.local_name, local_path, |
| strlen((char*) local_path)); |
| info->file_trans.fd = file_open((const char*)info->file_trans.local_name, |
| O_RDONLY); |
| if (info->file_trans.fd <= 0) |
| { |
| LOGE("Can not open EFS file[%s].", info->file_trans.local_name); |
| return -1; |
| } |
| |
| } |
| info->file_trans.size_count = size_byte; |
| info->file_trans.size_send = 0; |
| // Start upload data. |
| |
| |
| // Start update file. |
| if (FTP_ERR_SUCCESS != ftp_data_sock_read(info, FTP_CMD_PUT, NULL, NULL)) |
| { |
| LOGW("ftp_data_sock_read() fail."); |
| if(info->file_trans.size_count == info->file_trans.size_send && info->file_trans.size_send != 0) |
| { |
| result = FTP_ERR_SUCCESS; |
| } |
| else |
| { |
| mbtk_at_ftp_par.rest_size = info->file_trans.size_send; |
| result = FTP_ERR_UNKNOWN; |
| } |
| } |
| |
| if (info->file_trans.fd > 0 ) // Save to efs |
| { |
| info->file_trans.size_count = 0; |
| info->file_trans.size_send = 0; |
| if (file_close(info->file_trans.fd)) |
| { |
| LOGE("EFS close fail."); |
| return -1; |
| } |
| } |
| |
| } |
| else |
| { |
| LOGE("FTP state error[%d].", info->state); |
| return -1; |
| } |
| |
| return result; |
| } |
| |
| /* |
| * This only for upload data(No for upload efs). |
| */ |
| int mbtk_ftp_upload_send(mbtk_ftp_handle handle, const void *data,uint16 data_len) |
| { |
| if (!data || data_len == 0) |
| { |
| LOGE("Param set error."); |
| return -1; |
| } |
| |
| int err; |
| int result = 0; |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return -1; |
| } |
| |
| if(info->file_trans.fd > 0) // Is upload from efs. |
| { |
| LOGE("Not upload from EFS."); |
| return -1; |
| } |
| |
| //LOGE("1socket:%d, data:%s, data_len:%d", info->sock_info[FTP_SOCK_DATA].fd, data, data_len ); |
| if((info->file_trans.size_send + data_len) > info->file_trans.size_count) |
| { |
| printf("send over set length\n"); |
| result = FTP_ERR_UNKNOWN; |
| goto overlong; |
| } |
| int len; |
| if(info->auth_type != 0) |
| len = mbtk_sock_write(info->ftp_ssl_handle,info->session_data,data,data_len,FTP_TIMEOUT,&err); |
| else |
| len = sock_write(&info->net_info, &info->sock_info[FTP_SOCK_DATA], data, data_len, |
| FTP_TIMEOUT, &err); |
| if(len < 0) |
| { |
| LOGE("EFS write fail.len:%d, err;%d", len, err); |
| return FTP_ERR_EFS_FILE; |
| } |
| |
| info->file_trans.size_send += len; |
| mbtk_at_ftp_par.rest_size = info->file_trans.size_send; |
| |
| LOGE("size_count:%d, size_send:%d.", info->file_trans.size_count,info->file_trans.size_send); |
| |
| if((info->file_trans.size_count <= info->file_trans.size_send) ) |
| { |
| printf("\nClose data socket begin!\n "); |
| // Close data socket. |
| overlong: if (info->sock_info[FTP_SOCK_DATA].fd > 0) |
| { |
| if (sock_close(&info->net_info, &info->sock_info[FTP_SOCK_DATA], FTP_TIMEOUT, &err)) |
| { |
| LOGE("Close data socket fail[%d].", err); |
| printf("\nClose data socket fail[%d].\n", err); |
| result = FTP_ERR_NET_CLOSE; |
| } |
| else |
| { |
| printf("\nClose data socket ok[%d].\n", err); |
| // info->sock_info[FTP_SOCK_DATA].fd = -1; |
| } |
| } |
| if(info->auth_type != 0) |
| { |
| if(mbtk_sock_close(info->ftp_ssl_handle,info->session_data,6000,&err)) |
| { |
| LOGE("Close ssl data socket fail[%d].", err); |
| printf("\nClose ssl data socket fail[%d].\n", err); |
| result = FTP_ERR_NET_CLOSE; |
| } |
| else |
| { |
| printf("\nClose ssl data socket ok[%d].\n", err); |
| // info->sock_info[FTP_SOCK_DATA].fd = -1; |
| } |
| } |
| info->data_mode = FTP_MODE_PASSIVE; |
| info->is_data_sock_busy = false; |
| info->file_trans.size_count = 0; |
| info->file_trans.size_send = 0; |
| } |
| else |
| { |
| LOGE("size_count:%d, size_send:%d.", info->file_trans.size_count,info->file_trans.size_send); |
| } |
| |
| |
| // Start update data. |
| |
| return result; |
| } |
| |
| mbtk_ftp_error_enum mbtk_ftp_trans_reset(mbtk_ftp_handle handle) |
| { |
| mbtk_ftp_info_s *info = ftp_info_find(handle); |
| if (!info) |
| { |
| LOGE("No such FTP handle:%d", handle); |
| return FTP_ERR_UNKNOWN; |
| } |
| |
| info->is_trans = false; |
| memset(&info->file_trans, 0x0, sizeof(mbtk_ftp_file_trans_info_s)); |
| |
| return FTP_ERR_SUCCESS; |
| } |
| |
| void mbtk_ftp_lib_info_print() |
| { |
| MBTK_SOURCE_INFO_PRINT("mbtk_ftp_lib"); |
| } |
| |