Make dowload provider run properly with multi-user and on 64 bit architecture 23/24123/3 accepted/tizen_3.0.2014.q3_common accepted/tizen_3.0.m14.3_ivi tizen_3.0.2014.q3_common tizen_3.0.m14.3_ivi accepted/tizen/common/20140813.164908 submit/tizen_common/20140813.163208 submit/tizen_ivi/20140818.000000 submit/tizen_ivi/20140818.000001 submit/tizen_ivi/20140818.000002 submit/tizen_ivi/20140820.000000 submit/tizen_ivi/20140822.000000 submit/tizen_ivi/20140825.000000 submit/tizen_mobile/20141120.000000 tizen_3.0.2014.q3_common_release tizen_3.0.m14.3_ivi_release
authorRomuald Texier-Marcadé <romuald.texier-marcade@open.eurogiciel.org>
Mon, 7 Jul 2014 13:01:02 +0000 (15:01 +0200)
committerRomuald Texier-Marcadé <romuald.texier-marcade@open.eurogiciel.org>
Fri, 11 Jul 2014 13:39:38 +0000 (15:39 +0200)
bug fixes:
 - get smack fs path from smack API
 - use int type with ioctl FIONREAD to get correct values on both 64 and 32 bits arches
 - fixed wrong usage of smack_new_label_from_socket
 - moved management of default destination to CAPI in order to run the code
with user privileges
 - removed code trying to guess remaining disk space because it only checked an
unreachable, hard coded folder instead of real destination. The case when the disk
is full is already handled at writing time.
 - added dependency on net-config (in specfile) because DP can't work properly
without it.

Bug-Tizen: TC-1409
Bug-Tizen: TC-1415
Change-Id: Ib98cabfd074313e2ac37300ce1af5e318de6327f
Signed-off-by: Romuald Texier-Marcadé <romuald.texier-marcade@open.eurogiciel.org>
agent/download-agent-file.c
agent/download-agent-http-mgr.c
agent/download-agent-utils.c
agent/include/download-agent-file.h
agent/include/download-agent-utils.h
packaging/download-provider.spec
provider-interface/download-provider-interface.c
provider/download-provider-request.c
provider/download-provider-thread-request.c

index 59b093a..f871b7c 100755 (executable)
@@ -19,7 +19,6 @@
 #include <unistd.h>
 #include <math.h>
 #include <errno.h>
-#include <tzplatform_config.h>
 
 #include "download-agent-client-mgr.h"
 #include "download-agent-debug.h"
@@ -457,26 +456,19 @@ da_result_t __decide_file_path(stage_info *stage)
                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.
+       /* The destination path is set by user or by CAPI already
         */
        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';
+    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)
@@ -1144,50 +1136,3 @@ da_result_t copy_file(const char *src, const char *dest)
        return DA_RESULT_OK;
 }
 
-da_result_t create_dir(const char *install_dir)
-{
-       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;
-       } else {
-               DA_SECURE_LOGD("[%s] is created!", install_dir);
-               if (chown(install_dir, tzplatform_getuid(TZ_USER_NAME),tzplatform_getuid(TZ_SYS_USER_GROUP)) < 0) {
-                       DA_LOG_ERR(FileManager, "Fail to chown");
-                       ret = DA_ERR_FAIL_TO_ACCESS_STORAGE;
-               }
-       }
-       return ret;
-}
-
-da_result_t get_default_install_dir(char **out_path)
-{
-       char *default_path = DA_NULL;
-       da_result_t ret = DA_RESULT_OK;
-       int len = 0;
-
-       if (!out_path) {
-               DA_LOG_ERR(ClientNoti, "DA_ERR_INVALID_ARGUMENT");
-               return DA_ERR_INVALID_ARGUMENT;
-       }
-
-       len = strlen(DA_DEFAULT_INSTALL_PATH_FOR_PHONE);
-
-       default_path = calloc(len + 1, sizeof(char));
-       if (!default_path) {
-               return DA_ERR_FAIL_TO_MEMALLOC;
-       }
-
-       memcpy(default_path, DA_DEFAULT_INSTALL_PATH_FOR_PHONE, len);
-       default_path[len] = '\0';
-
-       *out_path = default_path;
-
-       if (!is_dir_exist(default_path)) {
-               ret = create_dir(default_path);
-       }
-       DA_SECURE_LOGD("default temp path = [%s]", *out_path);
-       return DA_RESULT_OK;
-}
index bbc69f0..e951308 100755 (executable)
@@ -63,7 +63,6 @@ da_result_t handle_http_body(stage_info *stage, char *body, int body_len);
 da_result_t set_hdr_fields_on_download_info(stage_info *stage);
 
 da_result_t _check_content_type_is_matched(stage_info *stage);
-da_result_t _check_enough_memory_for_this_download(stage_info *stage);
 da_result_t _check_downloaded_file_size_is_same_with_header_content_size(
                stage_info *stage);
 
@@ -1210,9 +1209,6 @@ da_result_t handle_http_status_code(stage_info *stage,
                ret = _check_content_type_is_matched(stage);
                if (ret != DA_RESULT_OK)
                        goto ERR;
-               ret = _check_enough_memory_for_this_download(stage);
-               if (ret != DA_RESULT_OK)
-                       goto ERR;
                CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_STARTED,stage);
                CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD,stage); // ?
                break;
@@ -1471,40 +1467,6 @@ da_result_t _check_content_type_is_matched(stage_info *stage)
        return ret;
 }
 
-da_result_t _check_enough_memory_for_this_download(stage_info *stage)
-{
-       da_result_t ret = DA_RESULT_OK;
-
-       req_dl_info *request_info = DA_NULL;
-
-       unsigned long long cont_len = 0;
-       da_storage_size_t memory;
-
-       DA_LOG_FUNC_LOGV(HTTPManager);
-
-       memset(&memory, 0x00, sizeof(da_storage_size_t));
-       request_info = GET_STAGE_TRANSACTION_INFO(stage);
-
-       cont_len = (unsigned long long) GET_REQUEST_HTTP_HDR_CONT_LEN(request_info);
-       if (cont_len) {
-               ret = get_available_memory(&memory);
-               if (DA_RESULT_OK == ret) {
-                       DA_LOG(HTTPManager, "Memory avail: %lu, Memory block :%lu Content: %llu",
-                                       memory.b_available,memory.b_size, cont_len);
-                       if (memory.b_available < ((cont_len
-                                       + (unsigned long long)SAVE_FILE_BUFFERING_SIZE_50KB)
-                                       / (unsigned long long)memory.b_size)) /* 50KB buffering */
-                       {
-                               ret = DA_ERR_DISK_FULL;
-                               goto ERR;
-                       }
-               }
-       }
-
-ERR:
-       return ret;
-}
-
 da_result_t _check_this_partial_download_is_available(stage_info *stage,
                http_msg_response_t *new_http_msg_response)
 {
@@ -1513,7 +1475,6 @@ da_result_t _check_this_partial_download_is_available(stage_info *stage,
        char *origin_ETag = NULL;
        char *new_ETag = NULL;
        unsigned long long remained_content_len = 0;
-       da_storage_size_t memory;
        char *value = NULL;
        unsigned long long size = 0;
 
@@ -1548,21 +1509,6 @@ da_result_t _check_this_partial_download_is_available(stage_info *stage,
                goto ERR;
        }
 
-       if (remained_content_len) {
-               ret = get_available_memory(&memory);
-               if (DA_RESULT_OK == ret) {
-                       DA_LOG(HTTPManager, "Memory avail: %lu, Memory block :%lu Content: %llu",
-                                       memory.b_available,memory.b_size, remained_content_len);
-                       if (memory.b_available < ((remained_content_len
-                                       + SAVE_FILE_BUFFERING_SIZE_50KB)
-                                       / memory.b_size)) /* 50KB buffering */
-                       {
-                               ret = DA_ERR_DISK_FULL;
-                               goto ERR;
-                       }
-               }
-       }
-
 ERR:
        if (new_ETag) {
                free(new_ETag);
@@ -1580,7 +1526,6 @@ da_result_t _check_resume_download_is_available(stage_info *stage,
        char *origin_ETag = NULL;
        char *new_ETag = NULL;
        unsigned long long remained_content_len = 0;
-       da_storage_size_t memory;
        char *value = NULL;
        unsigned long long size = 0;
        char *temp_file_path = DA_NULL;
@@ -1618,20 +1563,6 @@ da_result_t _check_resume_download_is_available(stage_info *stage,
                goto ERR;
        }
 
-       if (remained_content_len) {
-               ret = get_available_memory(&memory);
-               if (DA_RESULT_OK == ret) {
-                       DA_LOG(HTTPManager, "Memory avail: %lu, Memory block :%lu Content: %llu",
-                                       memory.b_available,memory.b_size, remained_content_len);
-                       if (memory.b_available < ((remained_content_len
-                                       + SAVE_FILE_BUFFERING_SIZE_50KB)
-                                       / memory.b_size)) /* 50KB buffering */
-                       {
-                               ret = DA_ERR_DISK_FULL;
-                               goto ERR;
-                       }
-               }
-       }
        b_ret = http_msg_response_get_content_type(new_http_msg_response, &value);
        if (b_ret) {
                GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info) = value;
index 71aca16..3be2257 100755 (executable)
@@ -137,43 +137,6 @@ int read_data_from_file(char *file, char **out_buffer)
        return buffer_len;
 }
 
-da_result_t get_available_memory(da_storage_size_t *avail_memory)
-{
-       da_result_t ret = DA_RESULT_OK;
-       int fs_ret = 0;
-       struct statfs filesys_info = {0, };
-       char *default_install_dir = NULL;
-
-       DA_LOG_FUNC_LOGD(Default);
-
-       if (!avail_memory)
-               return DA_ERR_INVALID_ARGUMENT;
-
-       ret = get_default_install_dir(&default_install_dir);
-
-       if (ret == DA_RESULT_OK && default_install_dir) {
-               fs_ret = statfs(default_install_dir, &filesys_info);
-       } else {
-               return DA_ERR_FAIL_TO_ACCESS_STORAGE;
-       }
-
-       if (fs_ret != 0) {
-               DA_LOG_ERR(Default,"Phone file path :statfs error - [%d]", errno);
-               free(default_install_dir);
-               return DA_ERR_INVALID_INSTALL_PATH;
-       }
-
-       avail_memory->b_available = filesys_info.f_bavail;
-       avail_memory->b_size = filesys_info.f_bsize;
-
-       DA_LOG_VERBOSE(Default, "Available Memory(f_bavail) : %llu", filesys_info.f_bavail);
-       DA_LOG_VERBOSE(Default, "Available Memory(f_bsize) : %d", filesys_info.f_bsize);
-       DA_LOG_VERBOSE(Default, "Available Memory(kbytes) : %lu", (filesys_info.f_bavail/1024)*filesys_info.f_bsize);
-
-       free(default_install_dir);
-       return DA_RESULT_OK;
-}
-
 da_mime_type_id_t get_mime_type_id(char *content_type)
 {
        int i = 0;
index a537bb7..e9ff05f 100755 (executable)
@@ -24,8 +24,6 @@
 #include "download-agent-type.h"
 #include "download-agent-dl-mgr.h"
 
-#define DA_DEFAULT_INSTALL_PATH_FOR_PHONE tzplatform_getenv(TZ_USER_DOWNLOADS)
-
 da_bool_t is_file_exist(const char *file_path);
 da_bool_t is_dir_exist(const char *dir_path);
 
@@ -42,11 +40,8 @@ da_result_t  get_mime_type(stage_info *stage, char **out_mime_type);
 da_result_t  discard_download(stage_info *stage) ;
 void clean_paused_file(stage_info *stage);
 da_result_t  replace_content_file_in_stage(stage_info *stage, const char *dest_dd_file_path);
-da_result_t  decide_tmp_file_path(stage_info *stage);
 char *get_full_path_avoided_duplication(char *in_dir, char *in_candidate_file_name, char *in_extension);
 
 da_result_t copy_file(const char *src, const char *dest);
-da_result_t create_dir(const char *install_dir);
-da_result_t get_default_install_dir(char **out_path);
 
 #endif
index ee73307..488cf3c 100755 (executable)
                nanosleep(&interval,&remainder); \
        } while(0)
 
-typedef struct _da_storage_size_t {
-       unsigned long b_available;
-       unsigned long b_size;
-} da_storage_size_t;
-
 typedef enum {
        DA_MIME_TYPE_NONE,
        DA_MIME_TYPE_DRM1_MESSATE,
@@ -49,7 +44,6 @@ void get_random_number(int *out_num);
 da_result_t  get_available_dd_id(int *available_id);
 da_result_t  get_extension_from_mime_type(char *mime_type, char **extension);
 da_mime_type_id_t get_mime_type_id(char *content_type);
-da_result_t  get_available_memory(da_storage_size_t *avail_memory);
 da_bool_t is_valid_url(const char *url, da_result_t *err_code);
 
 int read_data_from_file(char *file, char**out_buffer);
index 195a277..762d4fe 100755 (executable)
@@ -30,6 +30,7 @@ Requires(post): /sbin/ldconfig
 Requires(post): vconf
 Requires:       sqlite
 Requires:       connman
+Requires:       net-config
 
 %description
 Description: download the contents in background
index 5bccd8c..c5ca554 100755 (executable)
@@ -30,6 +30,9 @@
 #include <dlog.h>
 #include <download-provider-interface.h>
 #include <download-provider.h>
+#include <tzplatform_config.h>
+
+#define DEFAULT_INSTALL_PATH tzplatform_getenv(TZ_USER_DOWNLOADS)
 
 #ifdef SUPPORT_CHECK_IPC
 #include <sys/ioctl.h>
@@ -691,8 +694,8 @@ static int __disconnect_from_provider()
 // clear read buffer. call in head of API before calling IPC_SEND
 static void __clear_read_buffer(int fd)
 {
-       long i;
-       long unread_count;
+       int i;
+       int unread_count;
        char tmp_char;
 
        // FIONREAD : Returns the number of bytes immediately readable
@@ -1338,6 +1341,37 @@ static dp_error_type __dp_interface_get_raw_bundle
 }
 
 
+static int _mkdir(const char *dir, mode_t mode) {
+        char tmp[256];
+        char *p = NULL;
+        size_t len;
+
+        snprintf(tmp, sizeof(tmp),"%s",dir);
+        len = strlen(tmp);
+        if(tmp[len - 1] == '/')
+                tmp[len - 1] = 0;
+        for(p = tmp + 1; *p; p++)
+                if(*p == '/') {
+                        *p = 0;
+                        mkdir(tmp, mode);
+                        *p = '/';
+                }
+        return mkdir(tmp, mode);
+}
+
+static dp_error_type __create_dir(const char *install_dir)
+{
+    dp_error_type ret = DP_ERROR_NONE;
+        /* read/write/search permissions for owner and group,
+         * and with read/search permissions for others as fas as
+         * umask allows. */
+    if (_mkdir(install_dir, S_IRWXU | S_IRWXG | S_IRWXO)) {
+        ret = DP_ERROR_PERMISSION_DENIED;
+    }
+    return ret;
+}
+
+
 /////////////////////// APIs /////////////////////////////////
 
 int dp_interface_create(int *id)
@@ -1386,6 +1420,18 @@ int dp_interface_create(int *id)
        if (errorcode == DP_ERROR_IO_ERROR)
                __disconnect_from_provider();
        pthread_mutex_unlock(&g_function_mutex);
+       if (errorcode == DP_ERROR_NONE){
+           // safely set the default path, maybe overwritten by the user later
+           const char* dest_path = DEFAULT_INSTALL_PATH;
+        if (dest_path){
+            struct stat dir_state;
+            int stat_ret = stat(dest_path, &dir_state);
+            if (stat_ret != 0) {
+                __create_dir(dest_path);
+            }
+            dp_interface_set_destination(t_id, dest_path);
+        }
+       }
        return __dp_interface_convert_errorcode(errorcode);
 }
 
@@ -1425,10 +1471,11 @@ int dp_interface_destroy(const int id)
        return __dp_interface_convert_errorcode(errorcode);
 }
 
+
 int dp_interface_start(const int id)
 {
-       int errorcode = DP_ERROR_NONE;
 
+    int errorcode = DP_ERROR_NONE;
        DP_PRE_CHECK_ID;
 
        pthread_mutex_lock(&g_function_mutex);
@@ -1524,7 +1571,11 @@ int dp_interface_get_network_type(const int id, int *net_type)
 
 int dp_interface_set_destination(const int id, const char *path)
 {
-       return __dp_interface_set_string(id, DP_CMD_SET_DESTINATION, path);
+    if (path && strlen(path)>0) {
+        return __dp_interface_set_string(id, DP_CMD_SET_DESTINATION, path);
+    } else {
+        return __dp_interface_convert_errorcode(DP_ERROR_NONE);
+    }
 }
 
 
index 10fea00..cbd4af6 100755 (executable)
@@ -19,6 +19,7 @@
 
 #include <sys/time.h>
 #include <sys/statfs.h>
+#include <sys/smack.h>
 #include "download-provider.h"
 #include "download-provider-log.h"
 
@@ -29,8 +30,6 @@
 
 #include "download-provider-notification.h"
 
-#define SMACKFS_MAGIC 0x43415d53
-#define SMACKFS_MNT "/smack"
 ///////// below functions are called by main thread of thread-request.c
 
 //////////////////////////////////////////////////////////////////////////
@@ -158,18 +157,8 @@ char *dp_print_errorcode(dp_error_type errorcode)
 
 int dp_is_smackfs_mounted()
 {
-       struct statfs sfs;
-       int ret;
-       do {
-               ret = statfs(SMACKFS_MNT, &sfs);
-       } while (ret < 0 && errno == EINTR);
-       if (ret) {
-               TRACE_ERROR("[SMACK ERROR]");
-               return -1;
-       }
-       if (sfs.f_type == SMACKFS_MAGIC) {
-               return 1;
-       }
+       if(smack_smackfs_path() != NULL)
+         return 1;
        TRACE_ERROR("[SMACK DISABLE]");
        return 0;
 }
index 1f1e151..6b03c08 100755 (executable)
@@ -773,7 +773,7 @@ static int __dp_set_group_new(int clientfd, dp_group_slots *groups,
 
        if (dp_is_smackfs_mounted() == 1) {
                ret = smack_new_label_from_socket(clientfd, &smack_label);
-               if (ret != 0) {
+               if (ret < 0) {
                        TRACE_ERROR("[CRITICAL] cannot get smack label");
                        free(pkgname);
                        free(smack_label);