diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/downloader.c | 85 | ||||
-rw-r--r-- | src/pm_downloader.c | 286 | ||||
-rw-r--r-- | src/pm_installer.c (renamed from src/installer.c) | 7 | ||||
-rw-r--r-- | src/pm_result.c (renamed from src/package-manager-result.c) | 0 | ||||
-rw-r--r-- | src/pm_worker.c (renamed from src/package-manager-worker.c) | 90 |
5 files changed, 356 insertions, 112 deletions
diff --git a/src/downloader.c b/src/downloader.c deleted file mode 100644 index 0c2d34f..0000000 --- a/src/downloader.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. - * - * Licensed under the Flora License, Version 1.1 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://floralicense.org/license/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <app_common.h> -#include <curl/curl.h> -#include <stdlib.h> -#include <glib.h> -#include "log.h" - -static size_t _write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) -{ - size_t written = fwrite(ptr, size, nmemb, stream); - return written; -} - -char *pm_downloader_download(const char *url, const char *download_dir) -{ - CURL *curl = NULL; - FILE *fp = NULL; - char *downloaded_path = NULL; - - curl_global_init(CURL_GLOBAL_DEFAULT); - curl = curl_easy_init(); - - if (curl) { - CURLcode res; - char *file_name = NULL; - - file_name = g_path_get_basename(url); - downloaded_path = g_strdup_printf("%s%s", download_dir, file_name); - - free(file_name); - file_name = NULL; - - _D("download_path : {%s}", url); - _D("downloaded_path : {%s}", downloaded_path); - - fp = fopen(downloaded_path, "wb"); - if (!fp) { - _E("Failed to open file - %s", downloaded_path); - goto ERROR; - } - - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _write_data); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); - res = curl_easy_perform(curl); - - if (res != CURLE_OK) { - _E("curl_easy_perform() failed: %s", curl_easy_strerror(res)); - goto ERROR; - } - - _D("Download Success: {%s}", downloaded_path); - curl_easy_cleanup(curl); - fclose(fp); - } - curl_global_cleanup(); - return downloaded_path; - -ERROR: - free(downloaded_path); - - if (curl) - curl_easy_cleanup(curl); - - if (fp) - fclose(fp); - - curl_global_cleanup(); - return NULL; -} diff --git a/src/pm_downloader.c b/src/pm_downloader.c new file mode 100644 index 0000000..620aa55 --- /dev/null +++ b/src/pm_downloader.c @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <app_common.h> +#include <curl/curl.h> +#include <stdlib.h> +#include <glib.h> +#include <json-glib/json-glib.h> +#include <openssl/md5.h> +#include "log.h" +#include "pm_downloader.h" + + +static size_t _write_data(void *ptr, size_t size, size_t nmemb, char **data) +{ +/* + size_t old_length = data ? strlen(data) : 0; + char** temp = (char**)data; + _D("%d",old_length); + size_t new_length = size * nmemb + old_length; + _D("%d",new_length); + //_D("%s", data); + *temp = realloc(data, new_length + 1) ; + //_D("%s", data); + if(data == NULL){ + _D("FAIL"); + return 0; + } + memcpy(data + old_length, ptr, size * nmemb); + //_D("%s", data); + //temp[new_length] = '\0'; +*/ +/* + char **result = (char **)data; + if (NULL == *result) { + *result = malloc(size * nmemb + 1); + memcpy(*result, ptr, size * nmemb); + } else { + size_t len = strlen(*result); + char* result_temp = *result; + *result = realloc(*result, len + size * nmemb + 1); + if (*result == NULL) + free(result_temp); + memcpy(*result + len, ptr, size * nmemb); + (*result)[len+size*nmemb] = '\0'; + } +*/ + char *c; + + if(asprintf(&c, "%.*s%.*s", strlen(data), *data, size * nmemb, ptr) == -1){ + free(*data); + data = NULL; + return -1; + } + + free(*data); + *data = strdup(c); + free (c); + + return size * nmemb; +} + +static size_t _write_file(void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + size_t written = fwrite(ptr, size, nmemb, stream); + return written; +} + +pm_downloader_metadata_s *_parsing_metadata(const char *data) +{ + pm_downloader_metadata_s *ret = (pm_downloader_metadata_s*)malloc(sizeof(pm_downloader_metadata_s)); + JsonParser *parser = json_parser_new(); + JsonNode *root = NULL; + GError *error = NULL; + + if(json_parser_load_from_data(parser, data, -1, &error)){ + _D("Start Parse"); + root = json_parser_get_root(parser); + JsonObject *object = NULL; + object = json_node_get_object(root); + if (object != NULL) { + GList * keysList = NULL; + GList * valsList = NULL; + guint size; + + keysList = json_object_get_members(object); + valsList = json_object_get_values(object); + size = json_object_get_size(object); + + JsonNode *tmpNode; + + for (int j = 0; j < size; j++) { + if(keysList && valsList){ + char *key = (char *)keysList->data; + JsonNode *value = (JsonNode *)valsList->data; + _D("%s", key); + _D("%s", (char *) json_node_dup_string(value)); + if(!strcmp(key, "url")){ + ret->url = (char *) json_node_dup_string(value); + } else if(!strcmp(key, "filename")){ + ret->file_name = (char *) json_node_dup_string(value); + } else if(!strcmp(key, "hash")){ + ret->hash = (char *) json_node_dup_string(value); + } + } + keysList = g_list_next(keysList); + valsList = g_list_next(valsList); + } + + g_object_unref(tmpNode); + g_list_free(keysList); + g_list_free(valsList); + } + if(object){ + g_object_unref(object); + } + } + + if(root){ + g_object_unref(root); + } + + if (parser){ + g_object_unref(parser); + } + + if (error){ + g_error_free(error); + } + return ret; +} + +pm_downloader_metadata_s *pm_downloader_get_metadata(const char *url) +{ + CURL *curl = NULL; + char *data = NULL; + pm_downloader_metadata_s *ret = NULL; + + curl_global_init(CURL_GLOBAL_DEFAULT); + curl = curl_easy_init(); + + if (curl) { + CURLcode res; + + _D("download_path : {%s}", url); + + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _write_data); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data); + res = curl_easy_perform(curl); + + if (res != CURLE_OK) { + _E("curl_easy_perform() failed: %s", curl_easy_strerror(res)); + goto ERROR; + } + + _D("Download Success: {%s}", data); + curl_easy_cleanup(curl); + + if(data){ + ret = _parsing_metadata(data); + } + + _D("End Parse"); + } + curl_global_cleanup(); + + return ret; +ERROR: + if(ret){ + free(ret); + } + + if (curl){ + curl_easy_cleanup(curl); + } + + curl_global_cleanup(); + return NULL; +} + +bool pm_downloader_check_compatibility(const char *hash, const char* file_path) +{ + FILE *fp = fopen (file_path, "rb"); + MD5_CTX context; + int bytes; + int i; + unsigned char data[1024]; + unsigned char digest[MD5_DIGEST_LENGTH]; + char file_hash[50] = { 0, }; + if(fp == NULL){ + _D("can't be opened"); + return false; + } + + MD5_Init(&context); + while ((bytes = fread (data, 1, 1024, fp)) != 0){ + MD5_Update(&context, data, bytes); + } + + MD5_Final(digest, &context); + for (i = 0; i<MD5_DIGEST_LENGTH; ++i){ + sprintf(file_hash + (i * 2), "%02x", digest[i]); + } + + if (fp){ + fclose(fp); + } + + if (strcmp(hash, file_hash)){ + _D("Hash is different!"); + _D("Server Hash: \t%s",hash); + _D("File Hash: \t%s",file_hash); + return false; + } + + return true; +} + +char *pm_downloader_download(const char *url, const char *file_name, const char *download_dir) +{ + CURL *curl = NULL; + FILE *fp = NULL; + char *downloaded_path = NULL; + + curl_global_init(CURL_GLOBAL_DEFAULT); + curl = curl_easy_init(); + + if (curl) { + CURLcode res; + downloaded_path = g_strdup_printf("%s%s", download_dir, file_name); + + _D("download_path : {%s}", url); + _D("downloaded_path : {%s}", downloaded_path); + + fp = fopen(downloaded_path, "wb"); + if (!fp) { + _E("Failed to open file - %s", downloaded_path); + goto ERROR; + } + + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _write_file); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); + res = curl_easy_perform(curl); + + if (res != CURLE_OK) { + _E("curl_easy_perform() failed: %s", curl_easy_strerror(res)); + goto ERROR; + } + + _D("Download Success"); + curl_easy_cleanup(curl); + fclose(fp); + } + + curl_global_cleanup(); + return downloaded_path; +ERROR: + free(downloaded_path); + + if (curl){ + curl_easy_cleanup(curl); + } + + if (fp){ + fclose(fp); + } + + curl_global_cleanup(); + return NULL; +} + diff --git a/src/installer.c b/src/pm_installer.c index 20d3e06..85ce1af 100644 --- a/src/installer.c +++ b/src/pm_installer.c @@ -15,14 +15,14 @@ */ #include "log.h" -#include "installer.h" +#include "pm_installer.h" #include <package_manager.h> #include <glib.h> typedef struct __pm_installer_s { package_manager_request_h handle; int request_id; - pm_installer_res_cb *result_cb; + pm_installer_res_cb result_cb; void * cb_data; } pm_installer_s; @@ -52,8 +52,9 @@ static void _install_cb(int id, const char *type, const char *package, } } -int pm_installer_install(const char *path, pm_installer_res_cb *result_cb, void *cb_data) +int pm_installer_install(const char *path, pm_installer_res_cb result_cb, void *cb_data) { + _D("Install Start"); int ret = 0; int request_id = 0; pm_installer_s *pmi_d = NULL; diff --git a/src/package-manager-result.c b/src/pm_result.c index 82a23a0..82a23a0 100644 --- a/src/package-manager-result.c +++ b/src/pm_result.c diff --git a/src/package-manager-worker.c b/src/pm_worker.c index 8dc94c6..b8c079e 100644 --- a/src/package-manager-worker.c +++ b/src/pm_worker.c @@ -1,4 +1,4 @@ -/* + /* * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Flora License, Version 1.1 (the License); @@ -15,24 +15,26 @@ */ #include "log.h" -#include "downloader.h" -#include "installer.h" +#include "pm_downloader.h" +#include "pm_installer.h" #include "pm_report.h" -#include "package-manager-result.h" +#include "pm_result.h" #include <service_app.h> #include <stdlib.h> -#define TEST_PKG_URL "https://s3.ap-northeast-2.amazonaws.com/dm-firmware-bucket/firmwares/sumin.lim%40samsung.com/org.example.basic-ui-1.0.0-arm.tpk" +#define TEST_URL "https://test.showiot.xyz/api/package/metadata?id=test-page1523421701067&key=175b6545cca4f96bcd9ff2d1dcd6666bbafb1bec" static void __pkg_install_result_callback(const char *package, int result, void *user_data) { char *result_str = NULL; - if (result) - result_str = pm_result_get_install(package, true, NULL); - else /* TODO : read error code from result value */ + if (result){ result_str = pm_result_get_install(package, false, "INSTALL_PKG_FAILED"); + } + else { + result_str = pm_result_get_install(package, true, "INSTALL_PKG_SUCCESS"); + } pm_worker_report_result(result_str); free(result_str); @@ -59,31 +61,71 @@ static void service_app_control(app_control_h app_control, void *data) char *downloaded_pkg = NULL; char *data_path = NULL; - + char *result_str = NULL; + bool error = false; + bool is_valid = false; + pm_downloader_metadata_s * metadata = NULL; data_path = app_get_data_path(); - downloaded_pkg = pm_downloader_download(TEST_PKG_URL, data_path); + + metadata = pm_downloader_get_metadata(TEST_URL); + downloaded_pkg = pm_downloader_download(metadata->url, metadata->file_name, data_path); + free(data_path); if (!downloaded_pkg) { /* TODO : Reasons should be redefined */ - char *result_str = + result_str = pm_result_get_install(downloaded_pkg, false, "DOWNLOAD_FAILED"); pm_worker_report_result(result_str); - free(result_str); - service_app_exit(); + error = true; } else { - int ret = 0; - ret = pm_installer_install( - downloaded_pkg, __pkg_install_result_callback, NULL); - - if (ret) { - /* TODO : Reasons should be redefined */ - char *result_str = - pm_result_get_install(downloaded_pkg, false, "PKG_MANAGER_ERROR"); - pm_worker_report_result(result_str); - free(result_str); - service_app_exit(); + + is_valid = pm_downloader_check_compatibility(metadata->hash, downloaded_pkg); + if(!is_valid) { + result_str = + pm_result_get_install(downloaded_pkg, false, "HASH_CHECK_FAILED"); + error = true; } + else { + int ret = 0; + ret = pm_installer_install( + downloaded_pkg, __pkg_install_result_callback, NULL); + + if (ret) { + /* TODO : Reasons should be redefined */ + result_str = + pm_result_get_install(downloaded_pkg, false, "PKG_MANAGER_ERROR"); + pm_worker_report_result(result_str); + error = true; + } + + + } + + } + + if(metadata->url){ + free(metadata->url); + metadata->url = NULL; + } + if(metadata->hash){ + free(metadata->hash); + metadata->hash = NULL; + } + if(metadata){ + free(metadata); + metadata = NULL; + } + if(result_str){ + free(result_str); + result_str = NULL; + } + if(downloaded_pkg){ + free(downloaded_pkg); + downloaded_pkg = NULL; + } + if(error){ + service_app_exit(); } return; } |