diff options
Diffstat (limited to 'agent/download-agent-file.c')
-rwxr-xr-x | agent/download-agent-file.c | 1477 |
1 files changed, 597 insertions, 880 deletions
diff --git a/agent/download-agent-file.c b/agent/download-agent-file.c index 0da5445..ea901e2 100755 --- a/agent/download-agent-file.c +++ b/agent/download-agent-file.c @@ -14,593 +14,69 @@ * limitations under the License. */ -#include <stdio.h> +#include <stdlib.h> #include <dirent.h> #include <unistd.h> +#include <string.h> +#include <sys/vfs.h> #include <math.h> #include <errno.h> -#include "download-agent-client-mgr.h" + #include "download-agent-debug.h" -#include "download-agent-utils.h" -#include "download-agent-dl-mgr.h" #include "download-agent-file.h" #include "download-agent-mime-util.h" -#include "download-agent-http-mgr.h" +/* FIXME Later */ +#include "download-agent-http-msg-handler.h" +#include "download-agent-plugin-drm.h" #include "download-agent-plugin-conf.h" +#include <storage.h> -#define NO_NAME_TEMP_STR "No name" - -static da_result_t __set_file_size(stage_info *stage); -static da_result_t __saved_file_open(stage_info *stage); - -static char *__derive_extension(stage_info *stage); -static da_result_t __divide_file_name_into_pure_name_N_extesion( - const char *in_file_name, - char **out_pure_file_name, - char **out_extension); -static da_result_t __get_candidate_file_name(stage_info *stage, - char **out_pure_file_name, char **out_extension); - -static da_result_t __file_write_buf_make_buf(file_info *file_storage); -static da_result_t __file_write_buf_destroy_buf(file_info *file_storage); -static da_result_t __file_write_buf_flush_buf(stage_info *stage, - file_info *file_storage); -static da_result_t __file_write_buf_copy_to_buf(file_info *file_storage, - char *body, int body_len); -static da_result_t __file_write_buf_directly_write(stage_info *stage, - file_info *file_storage, char *body, int body_len); - -da_result_t clean_files_from_dir(char *dir_path) -{ - da_result_t ret = DA_RESULT_OK; - struct dirent *d = DA_NULL; - DIR *dir; - char file_path[DA_MAX_FULL_PATH_LEN] = { 0, }; - - DA_LOG_FUNC_LOGD(FileManager); - - if (dir_path == DA_NULL) - return DA_ERR_INVALID_ARGUMENT; - - if (is_dir_exist(dir_path)) { - dir = opendir(dir_path); - if (DA_NULL == dir) { - DA_LOG_ERR(FileManager, "opendir() is failed."); - ret = DA_ERR_INVALID_INSTALL_PATH; - } else { - while (DA_NULL != (d = readdir(dir))) { - DA_SECURE_LOGD("%s",d->d_name); - if (0 == strncmp(d->d_name, ".", strlen(".")) - || 0 == strncmp(d->d_name, - "..", - strlen(".."))) { - continue; - } - - memset(file_path, 0x00, DA_MAX_FULL_PATH_LEN); - snprintf(file_path, DA_MAX_FULL_PATH_LEN, - "%s/%s", dir_path, d->d_name); - if (remove(file_path) < 0) { - DA_LOG_ERR(FileManager, "fail to remove file"); - } - } - - closedir(dir); - if (remove(dir_path) < 0) { - DA_LOG_ERR(FileManager, "fail to remove dir"); - } - } - } - return ret; -} - -/* Priority to obtain MIME Type - * 1. HTTP response header's <Content-Type> field - * 2. from OMA descriptor file's <content-type> attribute (mandatory field) - * 3. Otherwise, leave blank for MIME Type - */ -da_result_t get_mime_type(stage_info *stage, char **out_mime_type) -{ - char *mime_type = DA_NULL; - - if (!GET_STAGE_SOURCE_INFO(stage)) - return DA_ERR_INVALID_ARGUMENT; - - /* Priority 1 */ - if (GET_REQUEST_HTTP_HDR_CONT_TYPE(GET_STAGE_TRANSACTION_INFO(stage))) { - mime_type = GET_REQUEST_HTTP_HDR_CONT_TYPE(GET_STAGE_TRANSACTION_INFO(stage)); -// DA_SECURE_LOGI("content type from HTTP response header [%s]", mime_type); - } - - if (!mime_type) { - DA_LOG(FileManager, "no content type derived"); - return DA_RESULT_OK; - } - - /* FIXME really need memory allocation? */ - *out_mime_type = (char *)calloc(1, strlen(mime_type) + 1); - if (*out_mime_type) { - strncpy(*out_mime_type, mime_type, strlen(mime_type)); -// DA_SECURE_LOGD("out_mime_type str[%s] ptr[%p] len[%d]", -// *out_mime_type,*out_mime_type,strlen(*out_mime_type)); - } else { - DA_LOG_ERR(FileManager, "fail to allocate memory"); - return DA_ERR_FAIL_TO_MEMALLOC; - } - -// DA_SECURE_LOGD("mime type = %s", *out_mime_type); - return DA_RESULT_OK; -} - -da_bool_t is_file_exist(const char *file_path) -{ - struct stat dir_state; - int stat_ret; - - if (file_path == DA_NULL) { - DA_LOG_ERR(FileManager, "file path is DA_NULL"); - return DA_FALSE; - } - - stat_ret = stat(file_path, &dir_state); - - if (stat_ret == 0) { - if (dir_state.st_mode & S_IFREG) { - DA_SECURE_LOGD("Exist! %s is a regular file & its size = %lu", file_path, dir_state.st_size); - return DA_TRUE; - } - - return DA_FALSE; - } - return DA_FALSE; - -} - -da_bool_t is_dir_exist(const char *file_path) -{ - struct stat dir_state; - int stat_ret; - - if (file_path == DA_NULL) { - DA_LOG_ERR(FileManager, "file path is DA_NULL"); - return DA_FALSE; - } - - stat_ret = stat(file_path, &dir_state); - - if (stat_ret == 0) { - if (dir_state.st_mode & S_IFDIR) { - DA_LOG_VERBOSE(FileManager, "Existed directory."); - return DA_TRUE; - } - - return DA_FALSE; - } - return DA_FALSE; -} - -void get_file_size(char *file_path, unsigned long long *out_file_size) -{ - struct stat dir_state; - int stat_ret; - - *out_file_size = -1; - - if (file_path == DA_NULL) { - DA_LOG_ERR(FileManager, "file path is DA_NULL"); - return; - } - /* Please do not use ftell() to obtain file size, use stat instead. - * This is a guide from www.securecoding.cert.org - * : FIO19-C. Do not use fseek() and ftell() to compute the size of a file - */ - stat_ret = stat(file_path, &dir_state); - if (stat_ret == 0) { - if (dir_state.st_mode & S_IFREG) { - DA_LOG(FileManager, "size = %lu", dir_state.st_size); - *out_file_size = dir_state.st_size; - } - } - return; -} +#define NO_NAME_TEMP_STR "No name" +#define MAX_SUFFIX_COUNT 1000000000 -da_result_t __saved_file_open(stage_info *stage) +da_ret_t __saved_file_open(file_info_t *file_info) { - da_result_t ret = DA_RESULT_OK; - file_info *file_storage = DA_NULL; + da_ret_t ret = DA_RESULT_OK; char *actual_file_path = DA_NULL; void *fd = DA_NULL; - DA_LOG_FUNC_LOGV(FileManager); - - file_storage = GET_STAGE_CONTENT_STORE_INFO(stage); - if (!file_storage) - return DA_ERR_INVALID_ARGUMENT; + DA_LOGV(""); - actual_file_path = GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_storage); + actual_file_path = file_info->file_path; if (!actual_file_path) return DA_ERR_INVALID_ARGUMENT; fd = fopen(actual_file_path, "a+"); // for resume if (fd == DA_NULL) { - DA_LOG_ERR(FileManager, "File open failed"); + DA_LOGE("File open failed"); if (errno == ENOSPC) ret = DA_ERR_DISK_FULL; else ret = DA_ERR_FAIL_TO_ACCESS_FILE; goto ERR; } - GET_CONTENT_STORE_FILE_HANDLE(file_storage) = fd; -// DA_SECURE_LOGD("file path for saving = %s", -// GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_storage)); + file_info->file_handle = fd; + //DA_SECURE_LOGD("file path for saving[%s]", file_info->file_path); ERR: if (DA_RESULT_OK != ret) { - GET_CONTENT_STORE_FILE_HANDLE(file_storage) = DA_NULL; + file_info->file_handle = DA_NULL; } return ret; } -da_result_t __set_file_size(stage_info *stage) -{ - da_result_t ret = DA_RESULT_OK; - req_dl_info *stage_req_info = DA_NULL; - file_info *file_storage = DA_NULL; - - DA_LOG_FUNC_LOGV(FileManager); - - if (!stage) { - ret = DA_ERR_INVALID_ARGUMENT; - goto ERR; - } - - stage_req_info = GET_STAGE_TRANSACTION_INFO(stage); - - file_storage = GET_STAGE_CONTENT_STORE_INFO(stage); - if (!file_storage) - goto ERR; - - if (GET_REQUEST_HTTP_HDR_CONT_LEN(stage_req_info) != 0) { - GET_CONTENT_STORE_FILE_SIZE(file_storage) - = GET_REQUEST_HTTP_HDR_CONT_LEN(stage_req_info); - } else { - GET_CONTENT_STORE_FILE_SIZE(file_storage) = 0; - } - DA_LOG_VERBOSE(FileManager, "file size = %d", GET_CONTENT_STORE_FILE_SIZE(file_storage)); -ERR: - return ret; - -} - -/* Priority to derive extension - * 1. according to MIME-Type - * 2. if MIME-Type is ambiguous or blank, - * 2-1. derived from <Content-Disposition> field's "filename" attribute - * 2-2. derived from url - * 3. if url does not have extension, leave blank for extension - */ -char *__derive_extension(stage_info *stage) -{ - if (!stage) - return DA_NULL; - - source_info_t *source_info = GET_STAGE_SOURCE_INFO(stage); - req_dl_info *request_info = GET_STAGE_TRANSACTION_INFO(stage); - file_info *file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage); - char *extension = DA_NULL; - char *url = DA_NULL; - - /* Priority 1 */ - char *mime_type = DA_NULL; - mime_type = GET_CONTENT_STORE_CONTENT_TYPE(file_info_data); - if (mime_type && !is_ambiguous_MIME_Type(mime_type)) { - char *extension = DA_NULL; - da_result_t ret = get_extension_from_mime_type(mime_type, &extension); - if (ret == DA_RESULT_OK && extension) - return extension; - } - - /* Priority 2-1 */ - http_msg_response_t *http_msg_response = DA_NULL; - http_msg_response = request_info->http_info.http_msg_response; - if (http_msg_response) { - char *file_name = DA_NULL; - da_bool_t b_ret = http_msg_response_get_content_disposition(http_msg_response, - DA_NULL, &file_name); - if (b_ret && file_name) { - char *extension = DA_NULL; - DA_SECURE_LOGD("Name from Content-Disposition :[%s]", file_name); - __divide_file_name_into_pure_name_N_extesion(file_name, DA_NULL, &extension); - if (file_name) { - free(file_name); - file_name = DA_NULL; - } - if (extension) - return extension; - } - } - /* Priority 2-2 */ - /* If there is location url from response header in case of redirection, - * it try to parse the extention name from the location url */ - if (GET_REQUEST_HTTP_REQ_LOCATION(request_info)) - url = GET_REQUEST_HTTP_REQ_LOCATION(request_info); - else - url = GET_SOURCE_BASIC_URL(source_info); - if (url) { - DA_SECURE_LOGD("url:[%s]", url); - da_bool_t b_ret = da_get_extension_name_from_url(url, &extension); - if (b_ret && extension) - return extension; - } - - return DA_NULL; -} - -/** Priority for deciding file name - * 1. what client wants, which is conveyed by DA_FEATURE_FILE_NAME - * 2. 'filename' option on HTTP response header's Content-Disposition field - * 3. requesting URL - * 4. Otherwise, define it as "No name" - */ -da_result_t __get_candidate_file_name(stage_info *stage, char **out_pure_file_name, char **out_extension) -{ - da_result_t ret = DA_RESULT_OK; - source_info_t *source_info = DA_NULL; - char *pure_file_name = DA_NULL; - char *extension = DA_NULL; - - DA_LOG_FUNC_LOGV(FileManager); - - if (!stage || !out_pure_file_name) - return DA_ERR_INVALID_ARGUMENT; - - source_info = GET_STAGE_SOURCE_INFO(stage); - if (!source_info) - return DA_ERR_INVALID_ARGUMENT; - - /* Priority 1 */ - if (!pure_file_name && GET_DL_USER_FILE_NAME(GET_STAGE_DL_ID(stage))) { - __divide_file_name_into_pure_name_N_extesion( - GET_DL_USER_FILE_NAME(GET_STAGE_DL_ID(stage)), - &pure_file_name, &extension); - } - - /* Priority 2 */ - if (!pure_file_name) { - req_dl_info *request_info = GET_STAGE_TRANSACTION_INFO(stage); - http_msg_response_t *http_msg_response = DA_NULL; - http_msg_response = request_info->http_info.http_msg_response; - if (http_msg_response) { - char *file_name = DA_NULL; - da_bool_t b_ret = http_msg_response_get_content_disposition(http_msg_response, - DA_NULL, &file_name); - if (b_ret && file_name) { - DA_SECURE_LOGD("Name from Content-Disposition :[%s]", file_name); - __divide_file_name_into_pure_name_N_extesion(file_name, &pure_file_name, &extension); - if (file_name) { - free(file_name); - file_name = DA_NULL; - } - } - } - } - - /* Priority 3 */ - if (!pure_file_name) { - char *url = DA_NULL; - req_dl_info *request_info = GET_STAGE_TRANSACTION_INFO(stage); - /* If there is location url from response header in case of redirection, - * it try to parse the file name from the location url */ - if (GET_REQUEST_HTTP_REQ_LOCATION(request_info)) - url = GET_REQUEST_HTTP_REQ_LOCATION(request_info); - else - url = GET_SOURCE_BASIC_URL(source_info); - if (url) { - DA_SECURE_LOGD("url: [%s]", url); - da_get_file_name_from_url(url, &pure_file_name); - } - } - - /* Priority 4 */ - if (!pure_file_name) { - pure_file_name = strdup(NO_NAME_TEMP_STR); - if (!pure_file_name) { - ret = DA_ERR_FAIL_TO_MEMALLOC; - goto ERR; - } - } - - *out_pure_file_name = pure_file_name; - pure_file_name = DA_NULL; - DA_SECURE_LOGD("candidate file name [%s]", *out_pure_file_name); - - if (out_extension) { - if (extension) { - *out_extension = extension; - extension = DA_NULL; - } else { - *out_extension = __derive_extension(stage); - DA_SECURE_LOGD("candidate extension [%s]", *out_extension); - } - } - - if (extension) - free(extension); - - return DA_RESULT_OK; - -ERR: - if (extension) - free(extension); - - return ret; -} - -da_result_t __decide_file_path(stage_info *stage) -{ - da_result_t ret = DA_RESULT_OK; - char *temp_dir = DA_NULL; - char *extension = DA_NULL; - char *file_name_without_extension = DA_NULL; - char *tmp_file_path = DA_NULL; - char *user_install_path = DA_NULL; - file_info *file_info_data = DA_NULL; - int len = 0; - DA_LOG_FUNC_LOGV(FileManager); - - file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage); - if (!file_info_data) - return DA_ERR_INVALID_ARGUMENT; - - - /* If the installed path which user want is set, the temporary directory is same to the installation directory. - * Otherwise, the default temporary directory is used. - */ - user_install_path = GET_DL_USER_INSTALL_PATH(GET_STAGE_DL_ID(stage)); - if (user_install_path) { - len = strlen(user_install_path); - temp_dir = (char *)calloc(len + 1, sizeof(char)); - if (!temp_dir) { - ret = DA_ERR_FAIL_TO_MEMALLOC; - goto ERR; - } - memcpy(temp_dir, user_install_path, len); - temp_dir[len] = '\0'; - - } else { - ret = get_default_install_dir(&temp_dir); - if (DA_RESULT_OK != ret || DA_NULL == temp_dir) { - goto ERR; - } - } - - ret = __get_candidate_file_name(stage, &file_name_without_extension, &extension); - if (ret != DA_RESULT_OK) - goto ERR; - - // for resume - tmp_file_path = get_full_path_avoided_duplication(temp_dir, file_name_without_extension, extension); - if (tmp_file_path) { - GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)) - = tmp_file_path; - tmp_file_path = DA_NULL; - } else { - ret = DA_ERR_FAIL_TO_ACCESS_FILE; - goto ERR; - } - - if (file_name_without_extension && !GET_CONTENT_STORE_PURE_FILE_NAME(file_info_data)) { - GET_CONTENT_STORE_PURE_FILE_NAME(file_info_data) = file_name_without_extension; - file_name_without_extension = DA_NULL; - } - - if (extension && !GET_CONTENT_STORE_EXTENSION(file_info_data)) { - GET_CONTENT_STORE_EXTENSION(file_info_data) = extension; - extension = DA_NULL; - } - -ERR: - DA_SECURE_LOGI("decided file path = %s", GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_info_data)); - if (temp_dir) { - free(temp_dir); - temp_dir = DA_NULL; - } - if (file_name_without_extension) { - free(file_name_without_extension); - file_name_without_extension = DA_NULL; - } - if (extension) { - free(extension); - extension = DA_NULL; - } - return ret; -} - -char *get_full_path_avoided_duplication(char *in_dir, char *in_candidate_file_name, char *in_extension) -{ - char *dir = in_dir; - char *file_name = in_candidate_file_name; - char *extension = in_extension; - char *final_path = DA_NULL; - - int final_path_len = 0; - int extension_len = 0; - - int suffix_count = 0; /* means suffix on file name. up to "_1000000000" */ - const int max_suffix_count = 1000000000; - int suffix_len = (int)log10(max_suffix_count+1) + 1; /* 1 means "_" */ - - if (!in_dir || !in_candidate_file_name) - return DA_NULL; - -// DA_SECURE_LOGD("in_candidate_file_name=[%s], in_extension=[%s]", in_candidate_file_name, in_extension); - - if (extension) - extension_len = strlen(extension); - - /* first 1 for "/", second 1 for ".", last 1 for DA_NULL */ - final_path_len = strlen(dir) + 1 + strlen(file_name) + 1 - + suffix_len + extension_len + 1; - - final_path = (char*)calloc(1, final_path_len); - if (!final_path) { - DA_LOG_ERR(FileManager, "DA_ERR_FAIL_TO_MEMALLOC"); - return DA_NULL; - } - - do { - /* e.g) /tmp/abc.jpg - * if there is no extension name, just make a file name without extension */ - if (0 == extension_len) { - if (suffix_count == 0) { - snprintf(final_path, final_path_len, - "%s/%s", dir, file_name); - } else { - snprintf(final_path, final_path_len, - "%s/%s_%d", dir, file_name, suffix_count); - } - } else { - if (suffix_count == 0) { - snprintf(final_path, final_path_len, - "%s/%s.%s", dir, file_name, extension); - } else { - snprintf(final_path, final_path_len, - "%s/%s_%d.%s", - dir, file_name, suffix_count, extension); - } - } - - if (is_file_exist(final_path)) { - suffix_count++; - if (suffix_count > max_suffix_count) { - free(final_path); - final_path = DA_NULL; - break; - } else { - memset(final_path, 0x00, final_path_len); - continue; - } - } - - break; - } while (1); - -// DA_SECURE_LOGD("decided path = [%s]", final_path); - return final_path; -} - -da_result_t __divide_file_name_into_pure_name_N_extesion(const char *in_file_name, char **out_pure_file_name, char **out_extension) +da_ret_t __divide_file_name_into_pure_name_N_extesion(const char *in_file_name, char **out_pure_file_name, char **out_extension) { char *file_name = DA_NULL; char *tmp_ptr = DA_NULL; char temp_file[DA_MAX_FILE_PATH_LEN] = {0,}; char tmp_ext[DA_MAX_STR_LEN] = {0,}; int len = 0; - da_result_t ret = DA_RESULT_OK; + da_ret_t ret = DA_RESULT_OK; - DA_LOG_FUNC_LOGD(FileManager); + DA_LOGV(""); if (!in_file_name) return DA_ERR_INVALID_ARGUMENT; @@ -639,553 +115,794 @@ da_result_t __divide_file_name_into_pure_name_N_extesion(const char *in_file_nam (const char*) temp_file); } - DA_SECURE_LOGD("pure file name [%s]", *out_pure_file_name); + DA_LOGV( "pure file name [%s]", *out_pure_file_name); return ret; } -da_result_t __file_write_buf_make_buf(file_info *file_storage) +da_ret_t __file_write_buf_make_buf(file_info_t *file_info) { - da_result_t ret = DA_RESULT_OK; + da_ret_t ret = DA_RESULT_OK; char *buffer = DA_NULL; - DA_LOG_FUNC_LOGV(FileManager); + DA_LOGV(""); - buffer = (char*) calloc(DOWNLOAD_NOTIFY_LIMIT, 1); + buffer = (char*) calloc(1, DA_FILE_BUF_SIZE); if (DA_NULL == buffer) { - DA_LOG_ERR(FileManager, "Calloc failure "); + DA_LOGE("Calloc failure "); ret = DA_ERR_FAIL_TO_MEMALLOC; } else { - GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) = 0; - GET_CONTENT_STORE_FILE_BUFFER(file_storage) = buffer; + file_info->buffer_len = 0; + file_info->buffer = buffer; } return ret; } -da_result_t __file_write_buf_destroy_buf(file_info *file_storage) +da_ret_t __file_write_buf_destroy_buf(file_info_t *file_info) { - da_result_t ret = DA_RESULT_OK; - - DA_LOG_FUNC_LOGV(FileManager); + da_ret_t ret = DA_RESULT_OK; - if (GET_CONTENT_STORE_FILE_BUFFER(file_storage)) - free(GET_CONTENT_STORE_FILE_BUFFER(file_storage)); + DA_LOGV(""); + NULL_CHECK_RET(file_info); - GET_CONTENT_STORE_FILE_BUFFER(file_storage) = DA_NULL; - GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) = 0; + free(file_info->buffer); + file_info->buffer = DA_NULL; + file_info->buffer_len = 0; return ret; } -da_result_t __file_write_buf_flush_buf(stage_info *stage, file_info *file_storage) +da_ret_t __file_write_buf_flush_buf(file_info_t *file_info) { - da_result_t ret = DA_RESULT_OK; + da_ret_t ret = DA_RESULT_OK; char *buffer = DA_NULL; int buffer_size = 0; int write_success_len = 0; void *fd = DA_NULL; - DA_LOG_FUNC_LOGV(FileManager); + // DA_LOGV(""); - buffer = GET_CONTENT_STORE_FILE_BUFFER(file_storage); - buffer_size = GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage); + buffer = file_info->buffer; + buffer_size = file_info->buffer_len; if (buffer_size == 0) { - DA_LOG_ERR(FileManager, "no data on buffer.."); + DA_LOGE("no data on buffer.."); return ret; } - fd = GET_CONTENT_STORE_FILE_HANDLE(file_storage); + fd = file_info->file_handle; if (DA_NULL == fd) { - DA_LOG_ERR(FileManager, "There is no file handle."); + DA_LOGE("There is no file handle."); ret = DA_ERR_FAIL_TO_ACCESS_FILE; goto ERR; } + write_success_len = fwrite(buffer, sizeof(char), buffer_size, (FILE *) fd); /* FIXME : This can be necessary later due to progressive download. * The solution for reducing fflush is needed */ //fflush((FILE *) fd); if (write_success_len != buffer_size) { - DA_LOG_ERR(FileManager, "write fails "); + DA_LOGE("write fails "); if (errno == ENOSPC) ret = DA_ERR_DISK_FULL; else ret = DA_ERR_FAIL_TO_ACCESS_FILE; goto ERR; } - GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)) - += write_success_len; - DA_LOG_VERBOSE(FileManager, "write %d bytes", write_success_len); - IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(file_storage) = DA_TRUE; - GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) = 0; - + file_info->bytes_written_to_file += write_success_len; + file_info->is_updated = DA_TRUE; + file_info->buffer_len = 0; ERR: return ret; } -da_result_t __file_write_buf_copy_to_buf(file_info *file_storage, char *body, +da_ret_t __file_write_buf_copy_to_buf(file_info_t *file_info, char *body, int body_len) { - da_result_t ret = DA_RESULT_OK; + da_ret_t ret = DA_RESULT_OK; char *buffer = DA_NULL; int buffer_size = 0; - DA_LOG_FUNC_LOGV(FileManager); + DA_LOGV(""); - buffer = GET_CONTENT_STORE_FILE_BUFFER(file_storage); - buffer_size = GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage); + NULL_CHECK_RET(file_info->buffer); + buffer = file_info->buffer; + buffer_size = file_info->buffer_len; memcpy(buffer + buffer_size, body, body_len); - GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) += body_len; + file_info->buffer_len += body_len; return ret; } -da_result_t __file_write_buf_directly_write(stage_info *stage, - file_info *file_storage, char *body, int body_len) +da_ret_t __file_write_buf_directly_write(file_info_t *file_info, + char *body, int body_len) { - da_result_t ret = DA_RESULT_OK; - int write_success_len = 0; + da_ret_t ret = DA_RESULT_OK; + size_t write_success_len = 0; void *fd = DA_NULL; - DA_LOG_FUNC_LOGV(FileManager); + // DA_LOGV(""); - fd = GET_CONTENT_STORE_FILE_HANDLE(file_storage); + fd = file_info->file_handle; if (DA_NULL == fd) { - DA_LOG_ERR(FileManager, "There is no file handle."); - + DA_LOGE("There is no file handle."); ret = DA_ERR_FAIL_TO_ACCESS_FILE; goto ERR; } - write_success_len = fwrite(body, sizeof(char), body_len, + + write_success_len = fwrite(body, sizeof(char), (size_t)body_len, (FILE *) fd); /* FIXME : This can be necessary later due to progressive download. * The solution for reducing fflush is needed */ //fflush((FILE *) fd); - if (write_success_len != body_len) { - DA_LOG_ERR(FileManager, "write fails "); + if (write_success_len != (size_t)body_len) { + DA_LOGE("write fails "); if (errno == ENOSPC) ret = DA_ERR_DISK_FULL; else ret = DA_ERR_FAIL_TO_ACCESS_FILE; goto ERR; } - GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)) - += write_success_len; - DA_LOG(FileManager, "write %d bytes", write_success_len); - IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(file_storage) = DA_TRUE; + file_info->bytes_written_to_file += write_success_len; + DA_LOGV( "write %llu bytes", write_success_len); + file_info->is_updated = DA_TRUE; ERR: return ret; } -da_result_t file_write_ongoing(stage_info *stage, char *body, int body_len) +/* Priority to derive extension + * 1. extension name which client set + * 2. according to MIME-Type + * 3. if MIME-Type is ambiguous or blank, + * 3-1. derived from <Content-Disposition> field's "filename" attribute + * 3-2. derived from url + * 4. if url does not have extension, leave blank for extension + */ +char *__get_extension_name(char *mime_type, + char *file_name_from_header, char *url) { - da_result_t ret = DA_RESULT_OK; - file_info *file_storage = DA_NULL; - int buffer_size = 0; - char *buffer = DA_NULL; - - DA_LOG_FUNC_LOGV(FileManager); + char *extension = DA_NULL; - file_storage = GET_STAGE_CONTENT_STORE_INFO(stage); - if (!file_storage) { - DA_LOG_ERR(FileManager, "file_info is empty."); - ret = DA_ERR_FAIL_TO_ACCESS_FILE; - goto ERR; + /* Priority 1 */ + if (mime_type && !is_ambiguous_MIME_Type(mime_type)) { + char *extension = DA_NULL; + da_ret_t ret = get_extension_from_mime_type(mime_type, &extension); + if (ret == DA_RESULT_OK && extension) + return extension; } + /* Priority 2-1 */ + if (file_name_from_header) { + char *extension = DA_NULL; + DA_SECURE_LOGI("Content-Disposition :[%s]", file_name_from_header); + __divide_file_name_into_pure_name_N_extesion(file_name_from_header, + DA_NULL, &extension); + if (extension) + return extension; + } + /* Priority 2-2 */ + if (url) { + DA_LOGV("Get extension from url"); + da_bool_t b_ret = da_get_extension_name_from_url(url, &extension); + if (b_ret && extension) + return extension; + } + return DA_NULL; +} - buffer = GET_CONTENT_STORE_FILE_BUFFER(file_storage); - buffer_size = GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage); - IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(file_storage) = DA_FALSE; - - if (DA_NULL == buffer) { - if (body_len < DOWNLOAD_NOTIFY_LIMIT) { - ret = __file_write_buf_make_buf(file_storage); - if (ret != DA_RESULT_OK) - goto ERR; - - __file_write_buf_copy_to_buf(file_storage, body, body_len); - } else { - ret = __file_write_buf_directly_write(stage, - file_storage, body, body_len); - if (ret != DA_RESULT_OK) - goto ERR; - } - } else { - if (DOWNLOAD_NOTIFY_LIMIT <= body_len) { - ret = __file_write_buf_flush_buf(stage, file_storage); - if (ret != DA_RESULT_OK) - goto ERR; - - ret = __file_write_buf_directly_write(stage, - file_storage, body, body_len); - if (ret != DA_RESULT_OK) - goto ERR; +/** Priority for deciding file name + * 1. file name which client set + * 2. 'filename' option on HTTP response header's Content-Disposition field + * 3. requesting URL + * 4. Otherwise, define it as "No name" + */ +da_ret_t __get_candidate_file_name(char *user_file_name, char *url, + char *file_name_from_header, + char **out_pure_file_name, char **out_extension) +{ + da_ret_t ret = DA_RESULT_OK; - } else if ((DOWNLOAD_NOTIFY_LIMIT - buffer_size) <= body_len) { - ret = __file_write_buf_flush_buf(stage, file_storage); - if (ret != DA_RESULT_OK) - goto ERR; + DA_LOGV(""); - __file_write_buf_copy_to_buf(file_storage, body, body_len); - } else { - __file_write_buf_copy_to_buf(file_storage, body, body_len); - } + /* Priority 1 */ + if (user_file_name) { + __divide_file_name_into_pure_name_N_extesion( + user_file_name, out_pure_file_name, out_extension); } - -ERR: - if (ret != DA_RESULT_OK) { - if (file_storage) { - GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) = 0; - if (GET_CONTENT_STORE_FILE_BUFFER(file_storage)) { - free( - GET_CONTENT_STORE_FILE_BUFFER(file_storage)); - GET_CONTENT_STORE_FILE_BUFFER(file_storage) - = DA_NULL; - } - } + if (*out_pure_file_name) + return ret; + /* Priority 2 */ + if (file_name_from_header) { + DA_SECURE_LOGI("Content-Disposition:[%s]", file_name_from_header); + __divide_file_name_into_pure_name_N_extesion(file_name_from_header, + out_pure_file_name, DA_NULL); } + if (*out_pure_file_name) + return ret ; + /* Priority 3 */ + if (url) { + DA_LOGV("Get file name from url"); + da_get_file_name_from_url(url, out_pure_file_name); + } + if (*out_pure_file_name) + return ret ; + /* Priority 4 */ + *out_pure_file_name = strdup(NO_NAME_TEMP_STR); + if (*out_pure_file_name == DA_NULL) + ret = DA_ERR_FAIL_TO_MEMALLOC; return ret; } -da_result_t file_write_complete(stage_info *stage) +da_ret_t __decide_file_path(da_info_t *da_info) { - da_result_t ret = DA_RESULT_OK; - file_info*file_storage = DA_NULL; - char *buffer = DA_NULL; - unsigned int buffer_size = 0; - void *fd = DA_NULL; + da_ret_t ret = DA_RESULT_OK; + char *extension = DA_NULL; + char *file_name = DA_NULL; + char *tmp_file_path = DA_NULL; + char *install_dir = DA_DEFAULT_INSTALL_PATH_FOR_PHONE; + char *user_file_name = DA_NULL; + char *file_name_from_header = DA_NULL; + char *url = DA_NULL; + file_info_t *file_info = DA_NULL; + req_info_t *req_info = DA_NULL; + http_info_t *http_info = DA_NULL; + + DA_LOGV(""); + + NULL_CHECK_RET(da_info); + file_info = da_info->file_info; + NULL_CHECK_RET(file_info); + req_info = da_info->req_info; + NULL_CHECK_RET(req_info); + http_info = da_info->http_info; + NULL_CHECK_RET(http_info); + + if (req_info->install_path) + install_dir = req_info->install_path; + user_file_name = req_info->file_name; + /* If there is location url from response header in case of redirection, + * it try to parse the file name from the location url */ + if (http_info->location_url) { + url = http_info->location_url; + DA_LOGI("[TEST] location_url[%s][%p]",http_info->location_url, http_info->location_url); + } else + url = req_info->url; + + file_name_from_header = http_info->file_name_from_header; + + /* extension is extracted only if User set specific name */ + ret = __get_candidate_file_name(user_file_name, url, file_name_from_header, + &file_name, &extension); + if (ret != DA_RESULT_OK) + goto ERR; - DA_LOG_FUNC_LOGV(FileManager); + if (file_name && strpbrk(file_name, DA_INVALID_PATH_STRING) != NULL) { + DA_LOGI("Invalid string at file name"); + free(file_name); + file_name = strdup(NO_NAME_TEMP_STR); + if (!file_name) { + ret = DA_ERR_FAIL_TO_MEMALLOC; + goto ERR; + } - file_storage = GET_STAGE_CONTENT_STORE_INFO(stage); - if (!file_storage) { - DA_LOG_ERR(FileManager, "file_info is DA_NULL."); - ret = DA_ERR_FAIL_TO_ACCESS_FILE; - goto ERR; } - buffer = GET_CONTENT_STORE_FILE_BUFFER(file_storage); - buffer_size = GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage); + DA_SECURE_LOGI("candidate file name [%s]", file_name); - if (DA_NULL == buffer) { - DA_LOG_ERR(FileManager, "file buffer is DA_NULL"); - } else { - if (buffer_size != 0) { - ret = __file_write_buf_flush_buf(stage, file_storage); - if (ret != DA_RESULT_OK) - goto ERR; - } - __file_write_buf_destroy_buf(file_storage); + if (!extension) { + extension = __get_extension_name(file_info->mime_type, + file_name_from_header, url); + } + if (file_name && !file_info->pure_file_name) { + file_info->pure_file_name = file_name; + file_name = DA_NULL; + } + if (extension && !file_info->extension) { + DA_LOGV("candidate extension [%s]", extension); + file_info->extension = extension; + extension = DA_NULL; } - fd = GET_CONTENT_STORE_FILE_HANDLE(file_storage); - if (fd) { - fclose(fd); - fd = DA_NULL; + // for resume + tmp_file_path = get_full_path_avoided_duplication(install_dir, + file_info->pure_file_name, file_info->extension); + if (tmp_file_path) { + file_info->file_path = tmp_file_path; + tmp_file_path = DA_NULL; + } else { + ret = DA_ERR_FAIL_TO_ACCESS_FILE; + goto ERR; } - GET_CONTENT_STORE_FILE_HANDLE(file_storage) = DA_NULL; + ERR: + DA_SECURE_LOGI("decided file path [%s]", file_info->file_path); + free(file_name); + free(extension); return ret; } -da_result_t start_file_writing(stage_info *stage) +// for resume with new download request +da_ret_t __decide_file_path_for_resume(file_info_t *file_info) { - da_result_t ret = DA_RESULT_OK; - file_info *file_info_data = DA_NULL; + da_ret_t ret = DA_RESULT_OK; + char *extension = DA_NULL; + char *file_name = DA_NULL; + char *file_path = DA_NULL; + char *ptr = DA_NULL; + char *ptr2 = DA_NULL; + + DA_LOGV(""); + + NULL_CHECK_RET(file_info); + + file_path = file_info->file_path; + ptr = strrchr(file_path, '/'); + if (ptr) { + ptr++; + ptr2 = strrchr(ptr, '.'); + if (ptr2) { + int len = 0; + len = ptr2 - ptr; + ptr2++; + extension = strdup(ptr2); + file_name = calloc(1, len + 1); + if (file_name) + snprintf(file_name, len + 1, "%s", ptr); + } else { + file_name = strdup(ptr); + } + } - DA_LOG_FUNC_LOGV(FileManager); + if (file_name && !file_info->pure_file_name) { + file_info->pure_file_name = file_name; + file_name = DA_NULL; + } else { + free(file_name); + } + if (extension && !file_info->extension) { + DA_LOGV( "candidate extension [%s]", extension); + file_info->extension = extension; + extension = DA_NULL; + } else { + free(extension); + } + return ret; +} - file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage); - ret = get_mime_type(stage, - &GET_CONTENT_STORE_CONTENT_TYPE(file_info_data)); - if (ret != DA_RESULT_OK) - goto ERR; +da_ret_t start_file_writing(da_info_t *da_info) +{ + da_ret_t ret = DA_RESULT_OK; + file_info_t *file_info = DA_NULL; + req_info_t *req_info = DA_NULL; + + DA_LOGV(""); + + NULL_CHECK_RET(da_info); + file_info = da_info->file_info; + NULL_CHECK_RET(file_info); + req_info = da_info->req_info; + NULL_CHECK_RET(req_info); + + /* resume case */ + if (req_info->etag || req_info->temp_file_path) { + char *file_path = DA_NULL; + char *origin_path = DA_NULL; + file_path = req_info->temp_file_path; + if (!file_path) + return DA_ERR_INVALID_ARGUMENT; + origin_path = file_info->file_path; + file_info->file_path = strdup(file_path); + free(origin_path); + ret = __decide_file_path_for_resume(file_info); + } else { + ret = __decide_file_path(da_info); + } - ret = __decide_file_path(stage); if (ret != DA_RESULT_OK) goto ERR; - ret = __set_file_size(stage); - if (DA_RESULT_OK != ret) - goto ERR; - - GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)) - = 0; - - ret = __saved_file_open(stage); - + if (req_info->etag || req_info->temp_file_path) { + da_size_t file_size = 0; + get_file_size(req_info->temp_file_path, &file_size); + if (file_size < 1) + goto ERR; +#ifdef _RAF_SUPPORT + file_info->file_size_of_temp_file = file_size; +#endif + file_info->bytes_written_to_file = file_size; + } else { + file_info->bytes_written_to_file = 0; + } + ret = __saved_file_open(file_info); ERR: return ret; } - -da_result_t start_file_writing_append(stage_info *stage) +da_ret_t start_file_append(file_info_t *file_info) { - da_result_t ret = DA_RESULT_OK; + da_ret_t ret = DA_RESULT_OK; - DA_LOG_FUNC_LOGD(FileManager); + DA_LOGV(""); - ret = __saved_file_open(stage); + NULL_CHECK_RET(file_info); + ret = __saved_file_open(file_info); return ret; } -// for resume with new download request -da_result_t start_file_writing_append_with_new_download(stage_info *stage) +da_ret_t file_write_ongoing(file_info_t *file_info, char *body, int body_len) { - da_result_t ret = DA_RESULT_OK; - file_info *file_storage = DA_NULL; - char *original_file_path = DA_NULL; - char *temp_file_path = DA_NULL; - char *extension = DA_NULL; - char *file_name_without_extension = DA_NULL; - req_dl_info *request_info = DA_NULL; - unsigned long long temp_file_size = 0; - - DA_LOG_FUNC_LOGD(FileManager); - - file_storage = GET_STAGE_CONTENT_STORE_INFO(stage); - if (!file_storage) - return DA_ERR_INVALID_ARGUMENT; - request_info = GET_STAGE_TRANSACTION_INFO(stage); - if (!request_info) - return DA_ERR_INVALID_ARGUMENT; - temp_file_path = GET_REQUEST_HTTP_USER_REQUEST_TEMP_FILE_PATH(request_info); - if (!temp_file_path) - return DA_ERR_INVALID_ARGUMENT; - original_file_path = GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_storage); - - GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_storage) = strdup(temp_file_path); - - if (original_file_path) - free(original_file_path); + da_ret_t ret = DA_RESULT_OK; + int buffer_size = 0; + char *buffer = DA_NULL; - ret = get_mime_type(stage, - &GET_CONTENT_STORE_CONTENT_TYPE(file_storage)); - if (ret != DA_RESULT_OK) - goto ERR; + DA_LOGV(""); - ret = __get_candidate_file_name(stage, &file_name_without_extension, &extension); - if (ret != DA_RESULT_OK) - goto ERR; + buffer = file_info->buffer; + buffer_size = file_info->buffer_len; - if (file_name_without_extension) { - if (!GET_CONTENT_STORE_PURE_FILE_NAME(file_storage)) { - GET_CONTENT_STORE_PURE_FILE_NAME(file_storage) = file_name_without_extension; - file_name_without_extension = DA_NULL; + if (DA_NULL == buffer) { + if (body_len < DA_FILE_BUF_SIZE) { + ret = __file_write_buf_make_buf(file_info); + if (ret != DA_RESULT_OK) + goto ERR; + __file_write_buf_copy_to_buf(file_info, body, body_len); + } else { + ret = __file_write_buf_directly_write(file_info, + body, body_len); + if (ret != DA_RESULT_OK) + goto ERR; + } + } else { + if (DA_FILE_BUF_SIZE <= body_len) { + ret = __file_write_buf_flush_buf(file_info); + if (ret != DA_RESULT_OK) + goto ERR; + ret = __file_write_buf_directly_write(file_info, + body, body_len); + if (ret != DA_RESULT_OK) + goto ERR; + } else if ((DA_FILE_BUF_SIZE - buffer_size) <= body_len) { + ret = __file_write_buf_flush_buf(file_info); + if (ret != DA_RESULT_OK) + goto ERR; + __file_write_buf_copy_to_buf(file_info, body, body_len); } else { - free(file_name_without_extension); - file_name_without_extension = DA_NULL; + __file_write_buf_copy_to_buf(file_info, body, body_len); } } +ERR: + if (ret != DA_RESULT_OK) { + file_info->buffer_len = 0; + free(file_info->buffer); + file_info->buffer = DA_NULL; + } + return ret; +} - if (extension) { - if (!GET_CONTENT_STORE_EXTENSION(file_storage)) { - GET_CONTENT_STORE_EXTENSION(file_storage) = extension; - extension = DA_NULL; - } else { - free(extension); - extension = DA_NULL; +#ifdef _RAF_SUPPORT +da_ret_t file_write_complete_for_raf(file_info_t *file_info) { + da_ret_t ret = DA_RESULT_OK; + char *buffer = DA_NULL; + da_size_t wrriten_size = 0; + da_size_t file_size = 0; + void *fd = DA_NULL; + + DA_LOGV(""); + fd = file_info->file_handle; + + wrriten_size = file_info->bytes_written_to_file; + // test code + get_file_size(file_info->file_path, &file_size); + DA_LOGI("wrriten_size:%llu file_size:%llu file[%s]", + wrriten_size, file_size, file_info->file_path); + if (fd) { + fclose(fd); + fd = DA_NULL; + } + file_info->file_handle = DA_NULL; + if (wrriten_size < file_size) { + DA_LOGD("Try truncate"); + if (truncate(file_info->file_path, wrriten_size) < 0) { + DA_LOGE("Fail to ftruncate: errno[%d,%s]", errno, strerror(errno)); } + DA_LOGD("Try truncate done"); } - ret = __set_file_size(stage); - if (DA_RESULT_OK != ret) - goto ERR; - get_file_size(temp_file_path, &temp_file_size); - if (temp_file_size < 1) - goto ERR; + ERR: + return ret; +} +#endif - GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)) - = temp_file_size; +da_ret_t file_write_complete(file_info_t *file_info) +{ + da_ret_t ret = DA_RESULT_OK; + char *buffer = DA_NULL; + unsigned int buffer_size = 0; + void *fd = DA_NULL; - ret = __saved_file_open(stage); - return ret; -ERR: - if (file_name_without_extension) { - free(file_name_without_extension); - file_name_without_extension = DA_NULL; + DA_LOGV(""); + + buffer = file_info->buffer; + buffer_size = file_info->buffer_len; + + if (DA_NULL == buffer) { + DA_LOGE("file buffer is NULL"); + } else { + if (buffer_size != 0) { + ret = __file_write_buf_flush_buf(file_info); + if (ret != DA_RESULT_OK) + goto ERR; + } + __file_write_buf_destroy_buf(file_info); } + fd = file_info->file_handle; - if (extension) { - free(extension); - extension = DA_NULL; + if (fd) { + fclose(fd); + fd = DA_NULL; } + file_info->file_handle = DA_NULL; +ERR: return ret; } -da_result_t discard_download(stage_info *stage) +da_ret_t discard_download(file_info_t *file_info) { - da_result_t ret = DA_RESULT_OK; - file_info *file_storage = DA_NULL; + da_ret_t ret = DA_RESULT_OK; FILE *f_handle = DA_NULL; - DA_LOG_FUNC_LOGD(FileManager); - - file_storage = GET_STAGE_CONTENT_STORE_INFO(stage); + DA_LOGV(""); - f_handle = GET_CONTENT_STORE_FILE_HANDLE(file_storage); + f_handle = file_info->file_handle; if (f_handle) { fclose(f_handle); - GET_CONTENT_STORE_FILE_HANDLE(file_storage) = DA_NULL; + file_info->file_handle = DA_NULL; } return ret; } -void clean_paused_file(stage_info *stage) +void clean_paused_file(file_info_t *file_info) { - file_info *file_info_data = DA_NULL; char *paused_file_path = DA_NULL; FILE *fd = DA_NULL; - DA_LOG_FUNC_LOGD(FileManager); + DA_LOGV(""); - file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage); - - fd = GET_CONTENT_STORE_FILE_HANDLE(file_info_data); + fd = file_info->file_handle; if (fd) { fclose(fd); - GET_CONTENT_STORE_FILE_HANDLE(file_info_data) = DA_NULL; + file_info->file_handle = DA_NULL; } - paused_file_path = GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_info_data); + paused_file_path = file_info->file_path; + file_info->bytes_written_to_file = 0; // Ignore resume flow after failed or cancled. remove_file((const char*) paused_file_path); return; } -da_result_t replace_content_file_in_stage(stage_info *stage, - const char *dest_dd_file_path) +da_bool_t is_file_exist(const char *file_path) { - da_result_t ret = DA_RESULT_OK; - char *dd_file_path = DA_NULL; - int len; + struct stat dir_state; + int stat_ret; - DA_LOG_FUNC_LOGD(FileManager); + if (file_path == DA_NULL) { + DA_LOGE("file path is DA_NULL"); + return DA_FALSE; + } + stat_ret = stat(file_path, &dir_state); + if (stat_ret == 0) { + if (dir_state.st_mode & S_IFREG) { + //DA_SECURE_LOGD("Exist! %s is a regular file & its size = %lu", file_path, dir_state.st_size); + return DA_TRUE; + } - if (!dest_dd_file_path - && (DA_FALSE == is_file_exist(dest_dd_file_path))) { - ret = DA_ERR_INVALID_ARGUMENT; - goto ERR; + return DA_FALSE; } + return DA_FALSE; - dd_file_path - =GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)); +} - if (DA_NULL != dd_file_path) { - remove_file((const char*) dd_file_path); - free(dd_file_path); - } - len = strlen(dest_dd_file_path); - dd_file_path = calloc(1, len + 1); - if (!dd_file_path) { - ret = DA_ERR_FAIL_TO_MEMALLOC; - goto ERR; - } - strncpy(dd_file_path, dest_dd_file_path, len); - GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)) - = dd_file_path; +void get_file_size(char *file_path, da_size_t *out_file_size) +{ + struct stat dir_state; + int stat_ret; -ERR: - return ret; + *out_file_size = -1; + if (file_path == DA_NULL) { + DA_LOGE("file path is DA_NULL"); + return; + } + /* Please do not use ftell() to obtain file size, use stat instead. + * This is a guide from www.securecoding.cert.org + * : FIO19-C. Do not use fseek() and ftell() to compute the size of a file + */ + stat_ret = stat(file_path, &dir_state); + if (stat_ret == 0) { + if (dir_state.st_mode & S_IFREG) { + DA_LOGV( "size = %lu", dir_state.st_size); + *out_file_size = dir_state.st_size; + } + } + return; } -da_result_t copy_file(const char *src, const char *dest) +char *get_full_path_avoided_duplication(char *in_dir, + char *in_candidate_file_name, char *in_extension) { - FILE *fs = DA_NULL; - FILE *fd = DA_NULL; - int freadnum = 0; - int fwritenum = 0; - char buff[4096] = { 0, }; + char *dir = in_dir; + char *file_name = in_candidate_file_name; + char *extension = in_extension; + char *final_path = DA_NULL; + + int dir_path_len = 0; + int final_path_len = 0; + int extension_len = 0; - DA_LOG_FUNC_LOGD(FileManager); + int suffix_count = 0; /* means suffix on file name. up to "_99" */ + int suffix_len = (int)log10(MAX_SUFFIX_COUNT + 1) + 1; /* 1 means "_" */ - /* open files to copy */ - fs = fopen(src, "rb"); - if (!fs) { - DA_LOG_ERR(FileManager, "Fail to open src file"); - return DA_ERR_FAIL_TO_ACCESS_FILE; + if (!in_dir || !in_candidate_file_name) + return DA_NULL; + + //DA_SECURE_LOGI("in_candidate_file_name=[%s],in_extension=[%s]", + //in_candidate_file_name, in_extension); + + if (extension) + extension_len = strlen(extension); + + // to remove trailing slash from dir path + dir_path_len = strlen(dir); + if (dir[dir_path_len - 1] == '/') { + dir[dir_path_len - 1] = '\0'; + --dir_path_len; } - fd = fopen(dest, "wb"); - if (!fd) { - DA_LOG_ERR(FileManager, "Fail to open dest file"); + /* first 1 for "/", second 1 for ".", last 1 for DA_NULL */ + final_path_len = dir_path_len + 1 + strlen(file_name) + 1 + + suffix_len + extension_len + 1; - fclose(fs); - return DA_ERR_FAIL_TO_ACCESS_FILE; + final_path = (char*)calloc(1, final_path_len); + if (!final_path) { + DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC"); + return DA_NULL; } - /* actual copy */ - while (!feof(fs)) { - memset(buff, 0x00, 4096); - freadnum = fread(buff, sizeof(char), sizeof(buff), fs); - if (freadnum > 0) { - fwritenum = fwrite(buff, sizeof(char), freadnum, fd); - if (fwritenum <= 0) { - DA_LOG(FileManager, "written = %d",fwritenum); - break; + do { + /* e.g) /tmp/abc.jpg + * if there is no extension name, just make a file name without extension */ + if (0 == extension_len) { + if (suffix_count == 0) { + snprintf(final_path, final_path_len, + "%s/%s", dir, file_name); + } else { + snprintf(final_path, final_path_len, + "%s/%s_%d", dir, file_name, suffix_count); } } else { - DA_LOG(FileManager, "read = %d",freadnum); - break; + if (suffix_count == 0) { + snprintf(final_path, final_path_len, + "%s/%s.%s", dir, file_name, extension); + } else { + snprintf(final_path, final_path_len, + "%s/%s_%d.%s", + dir, file_name, suffix_count, extension); + } } - } - - fclose(fd); - fclose(fs); + if (is_file_exist(final_path)) { + suffix_count++; + if (suffix_count > MAX_SUFFIX_COUNT) { + free(final_path); + final_path = DA_NULL; + break; + } else { + memset(final_path, 0x00, final_path_len); + continue; + } + } + break; + } while (1); - return DA_RESULT_OK; + //DA_SECURE_LOGD("decided path = [%s]", final_path); + return final_path; } -da_result_t create_dir(const char *install_dir) + +da_ret_t check_drm_convert(file_info_t *file_info) { - da_result_t ret = DA_RESULT_OK; - /* read/write/search permissions for owner and group, - * and with read/search permissions for others. */ - if (mkdir(install_dir, S_IRWXU | S_IRWXG | S_IRWXO)) { - DA_LOG_ERR(FileManager, "Fail to creaate directory"); - ret = DA_ERR_FAIL_TO_ACCESS_STORAGE; + da_ret_t ret = DA_RESULT_OK; + da_bool_t ret_b = DA_TRUE; + + DA_LOGD(""); + + NULL_CHECK_RET(file_info); + +#ifdef _ENABLE_OMA_DRM + + /* In case of OMA DRM 1.0 SD, it is not necessary to call DRM convert API. + * Because it is already converted itself. + * And, the case will return fail because The SD is not supported now. + */ + if (is_content_drm_dcf(file_info->mime_type)) { + DA_LOGI("DRM SD case"); + unlink(file_info->file_path); + free(file_info->file_path); + file_info->file_path = DA_NULL; + return DA_ERR_DRM_FAIL; + } + if (is_content_drm_dm(file_info->mime_type)) { + char *actual_file_path = DA_NULL; + char *out_file_path = DA_NULL; + + actual_file_path = file_info->file_path; + DA_SECURE_LOGD("actual_file_path = %s", actual_file_path); + if (!actual_file_path) + return DA_ERR_INVALID_ARGUMENT; + ret_b = EDRM_convert(actual_file_path, &out_file_path); + unlink(actual_file_path); + free(actual_file_path); + if (!ret_b) + ret = DA_ERR_DRM_FAIL; + file_info->file_path = out_file_path; } else { - DA_SECURE_LOGD("[%s] is created!", install_dir); - if (chown(install_dir, 5000, 5000) < 0) { - DA_LOG_ERR(FileManager, "Fail to chown"); - ret = DA_ERR_FAIL_TO_ACCESS_STORAGE; - } + return ret; } +#endif + return ret; } -da_result_t get_default_install_dir(char **out_path) +void remove_file(const char *file_path) { - char *default_path = DA_NULL; - da_result_t ret = DA_RESULT_OK; - int len = 0; + DA_LOGV(""); - if (!out_path) { - DA_LOG_ERR(ClientNoti, "DA_ERR_INVALID_ARGUMENT"); - return DA_ERR_INVALID_ARGUMENT; + if (file_path && is_file_exist(file_path)) { + DA_SECURE_LOGD("remove file [%s]", file_path); + if (unlink(file_path) < 0) { + DA_LOGE("file removing failed."); + } } +} - len = strlen(DA_DEFAULT_INSTALL_PATH_FOR_PHONE); +da_ret_t get_available_memory(char *dir_path, da_size_t len) +{ + da_ret_t ret = DA_RESULT_OK; + int fs_ret = 0; + //struct statfs filesys_info = {0, }; + struct statvfs filesys_info; - default_path = calloc(len + 1, sizeof(char)); - if (!default_path) { - return DA_ERR_FAIL_TO_MEMALLOC; - } + DA_LOGV(""); - memcpy(default_path, DA_DEFAULT_INSTALL_PATH_FOR_PHONE, len); - default_path[len] = '\0'; + if (!dir_path) + return DA_ERR_INVALID_INSTALL_PATH; - *out_path = default_path; + //fs_ret = statfs(dir_path, &filesys_info); + // Using this as it considers FOTA memory while returning available memory + fs_ret = storage_get_internal_memory_size(&filesys_info); - if (!is_dir_exist(default_path)) { - ret = create_dir(default_path); + if (fs_ret != 0) { + // DA_LOGE("statfs error[%s]", strerror(errno)); + return DA_ERR_INVALID_ARGUMENT; + // return DA_ERR_INVALID_INSTALL_PATH; } - DA_SECURE_LOGD("default temp path = [%s]", *out_path); - return DA_RESULT_OK; + + double available_size = (double)filesys_info.f_bsize * filesys_info.f_bavail; + double total_size = (double)filesys_info.f_frsize * filesys_info.f_blocks; + DA_SECURE_LOGI(" total = %lf ", total_size); + DA_SECURE_LOGI(" available = %lf ",available_size); + + DA_LOGV("Available Memory(f_bavail) : %lu", filesys_info.f_bavail); + DA_LOGV("Available Memory(f_bsize) : %d", filesys_info.f_bsize); + DA_LOGD("Available Memory(kbytes) : %d", (filesys_info.f_bavail/1024)*filesys_info.f_bsize); + DA_LOGV("Content: %llu", len); + if (available_size < (len + + SAVE_FILE_BUFFERING_SIZE_50KB)) /* 50KB buffering */ + ret = DA_ERR_DISK_FULL; + + return ret; } |